Skip to content

Commit 96710ce

Browse files
committed
🐛 Fixed parser plugin handling of top-level comment nodes
no issue - the section parser allows comment nodes to be parsed by parser plugins but due to top-level comment nodes being skipped it meant that they wouldn't be seen in certain circumstances - removes the top-level skip of comment nodes so that they will be passed through the parser plugins - adds specific skips for comment nodes in areas that create/update state from elements - allows for `addMarkerable` to be called by a parser plugin when no state has been set up yet such as in the case where the first element in a parsed section is a comment node that is handled by a parser plugin
1 parent f40c273 commit 96710ce

File tree

2 files changed

+57
-6
lines changed

2 files changed

+57
-6
lines changed

src/js/parsers/section.js

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ class SectionParser {
9898
addSection: (section) => {
9999
// avoid creating empty paragraphs due to wrapper elements around
100100
// parser-plugin-handled elements
101-
if (this.state.section.isMarkerable && !this.state.text && !this.state.section.text) {
101+
if (this.state.section && this.state.section.isMarkerable && !this.state.section.text && !this.state.text) {
102102
this.state.section = null;
103103
} else {
104104
this._closeCurrentSection();
@@ -108,6 +108,13 @@ class SectionParser {
108108
addMarkerable: (marker) => {
109109
let { state } = this;
110110
let { section } = state;
111+
// if the first element doesn't create it's own state and it's plugin
112+
// handler uses `addMarkerable` we won't have a section yet
113+
if (!section) {
114+
state.text = '';
115+
state.section = this.builder.createMarkupSection(normalizeTagName('p'));
116+
section = state.section;
117+
}
111118
assert(
112119
'Markerables can only be appended to markup sections and list item sections',
113120
section && section.isMarkerable
@@ -271,6 +278,10 @@ class SectionParser {
271278
}
272279

273280
_updateStateFromElement(element) {
281+
if (isCommentNode(element)) {
282+
return;
283+
}
284+
274285
let { state } = this;
275286
state.section = this._createSectionFromElement(element);
276287
state.markups = this._markupsFromElement(element);
@@ -408,8 +419,11 @@ class SectionParser {
408419
}
409420

410421
_createSectionFromElement(element) {
411-
let { builder } = this;
422+
if (isCommentNode(element)) {
423+
return;
424+
}
412425

426+
let { builder } = this;
413427
let section;
414428
let {tagName, sectionType, inferredTagName} =
415429
this._getSectionDetails(element);
@@ -433,10 +447,9 @@ class SectionParser {
433447
}
434448

435449
_isSkippable(element) {
436-
return isCommentNode(element) ||
437-
(element.nodeType === NODE_TYPES.ELEMENT &&
438-
contains(SKIPPABLE_ELEMENT_TAG_NAMES,
439-
normalizeTagName(element.tagName)));
450+
return element.nodeType === NODE_TYPES.ELEMENT &&
451+
contains(SKIPPABLE_ELEMENT_TAG_NAMES,
452+
normalizeTagName(element.tagName));
440453
}
441454
}
442455

tests/unit/parsers/section-test.js

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -615,3 +615,41 @@ test('#parse handles <p> inside <blockquote>', (assert) => {
615615
assert.equal(sections[1].tagName, 'blockquote');
616616
assert.equal(sections[1].text.trim(), 'Two');
617617
});
618+
619+
test('#parse allows top-level Comment nodes to be parsed by parser plugins', (assert) => {
620+
let element = buildDOM(`<!--parse me-->`).firstChild;
621+
let plugins = [function(element, builder, {addMarkerable}) {
622+
if (element.nodeType !== 8 && element.nodeValue !== 'parse me') {
623+
return;
624+
}
625+
let marker = builder.createMarker('oh my');
626+
addMarkerable(marker);
627+
}];
628+
629+
parser = new SectionParser(builder, {plugins});
630+
let sections = parser.parse(element);
631+
632+
assert.equal(sections.length, 1);
633+
let [section] = sections;
634+
assert.equal(section.text, 'oh my', 'parses comment with parser plugin');
635+
assert.equal(section.markers.length, 1, 'only 1 marker');
636+
});
637+
638+
test('#parse allows nested Comment nodes to be parsed by parser plugins', (assert) => {
639+
let element = buildDOM(`<p><!--parse me--></p>`).firstChild;
640+
let plugins = [function(element, builder, {addMarkerable}) {
641+
if (element.nodeType !== 8 && element.nodeValue !== 'parse me') {
642+
return;
643+
}
644+
let marker = builder.createMarker('oh my');
645+
addMarkerable(marker);
646+
}];
647+
648+
parser = new SectionParser(builder, {plugins});
649+
let sections = parser.parse(element);
650+
651+
assert.equal(sections.length, 1);
652+
let [section] = sections;
653+
assert.equal(section.text, 'oh my', 'parses comment with parser plugin');
654+
assert.equal(section.markers.length, 1, 'only 1 marker');
655+
});

0 commit comments

Comments
 (0)