diff --git a/app/assets/javascripts/pretty-text/engines/markdown-it/bbcode-block.js.es6 b/app/assets/javascripts/pretty-text/engines/markdown-it/bbcode-block.js.es6 index ff8860c688c..ec072ff5f47 100644 --- a/app/assets/javascripts/pretty-text/engines/markdown-it/bbcode-block.js.es6 +++ b/app/assets/javascripts/pretty-text/engines/markdown-it/bbcode-block.js.es6 @@ -1,6 +1,19 @@ +let isWhiteSpace; + +function trailingSpaceOnly(src, start, max) { + let i; + for(i=start;i= endLine) { @@ -150,14 +174,24 @@ function applyBBCode(state, startLine, endLine, silent, md) { continue; } + closeTag = parseBBCodeTag(state.src, start, max, true); - if (state.src.slice(start+2, max-1) !== rule.tag) { continue; } + if (closeTag && closeTag.closing && closeTag.tag === info.tag) { + if (nesting === 0) { + break; + } + nesting--; + } - if (pos < max) { continue; } + if (closeTag && !closeTag.closing && closeTag.tag === info.tag) { + nesting++; + } - // found! - auto_closed = true; - break; + closeTag = null; + } + + if (!closeTag) { + return false; } old_parent = state.parentType; @@ -199,9 +233,8 @@ function applyBBCode(state, startLine, endLine, silent, md) { lastToken = state.tokens[state.tokens.length-1]; state.parentType = old_parent; - state.lineMax = old_line_max; - state.line = nextLine + (auto_closed ? 1 : 0); + state.line = nextLine+1; return true; } @@ -210,8 +243,9 @@ export function setup(helper) { if (!helper.markdownIt) { return; } helper.registerPlugin(md => { + isWhiteSpace = md.utils.isWhiteSpace; md.block.ruler.after('fence', 'bbcode', (state, startLine, endLine, silent)=> { return applyBBCode(state, startLine, endLine, silent, md); - }); + }, { alt: ['paragraph', 'reference', 'blockquote', 'list'] }); }); } diff --git a/spec/components/pretty_text_spec.rb b/spec/components/pretty_text_spec.rb index 40beccda495..b960cf5024b 100644 --- a/spec/components/pretty_text_spec.rb +++ b/spec/components/pretty_text_spec.rb @@ -637,9 +637,25 @@ HTML end it "can handle quote edge cases" do - # expect(cook("a\n[quote]\ntest\n[quote]")).to include('aside') - expect(cook("[quote]\ntest")).not_to include('aside') - # expect(cook("[quote]abc\ntest\n[quote]")).not_to include('aside') + expect(PrettyText.cook("a\n[quote]\ntest\n[/quote]\n\n\na")).to include('aside') + expect(PrettyText.cook("- a\n[quote]\ntest\n[/quote]\n\n\na")).to include('aside') + expect(PrettyText.cook("[quote]\ntest")).not_to include('aside') + expect(PrettyText.cook("[quote]abc\ntest\n[/quote]")).not_to include('aside') + expect(PrettyText.cook("[quote]\ntest\n[/quote]z")).not_to include('aside') + + nested = <<~QUOTE + [quote] + a + [quote] + b + [/quote] + c + [/quote] + QUOTE + + cooked = PrettyText.cook(nested) + expect(cooked.scan('aside').length).to eq(4) + expect(cooked.scan('quote]').length).to eq(0) end it "do off topic quoting with emoji unescape" do