Skip to content

Commit

Permalink
Merge pull request #627 from kevinansfield/fix-parsing-top-level-unkn…
Browse files Browse the repository at this point in the history
…own-elements

Run parser plugins for top-level unknown elements
  • Loading branch information
mixonic authored Jun 21, 2018
2 parents 79b074d + 9de4405 commit 9b4231e
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 10 deletions.
24 changes: 17 additions & 7 deletions src/js/parsers/section.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,14 +69,24 @@ class SectionParser {

this._updateStateFromElement(element);

let childNodes = isTextNode(element) ? [element] : element.childNodes;
let finished = false;

if (this.state.section.isListSection) {
this.parseListItems(childNodes);
} else {
forEach(childNodes, el => {
this.parseNode(el);
});
// top-level text nodes will be run through parseNode later so avoid running
// the node through parserPlugins twice
if (!isTextNode(element)) {
finished = this.runPlugins(element);
}

if (!finished) {
let childNodes = isTextNode(element) ? [element] : element.childNodes;

if (this.state.section.isListSection) {
this.parseListItems(childNodes);
} else {
forEach(childNodes, el => {
this.parseNode(el);
});
}
}

this._closeCurrentSection();
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/editor/editor-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,7 @@ test('editor parses HTML post using parser plugins', (assert) => {
editor = new Editor({html, parserPlugins: [parserPlugin]});
assert.ok(!!editor.post, 'editor loads post');

assert.deepEqual(seenTagNames, ['TEXTAREA', 'IMG']);
assert.deepEqual(seenTagNames, ['P', 'TEXTAREA', 'IMG']);
});

test('#activeMarkups returns the markups at cursor when range is collapsed', (assert) => {
Expand Down
51 changes: 50 additions & 1 deletion tests/unit/parsers/html-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,18 @@ function parseHTML(html, options={}) {
return new HTMLParser(builder, options).parse(html);
}

module('Unit: Parser: HTMLParser');
let didParseVideo;
function videoParserPlugin(node) {
if (node.tagName === 'VIDEO') {
didParseVideo = true;
}
}

module('Unit: Parser: HTMLParser', {
beforeEach() {
didParseVideo = false;
}
});

test('style tags are ignored', (assert) => {
// This is the html you get when copying a message from Slack's desktop app
Expand All @@ -32,3 +43,41 @@ test('newlines ("\\n") are replaced with space characters', (assert) => {

assert.postIsSimilar(post, expected);
});

// see https://github.com/bustlelabs/mobiledoc-kit/issues/494
test('top-level unknown void elements are parsed', (assert) => {
let html = `<video />`;
let post = parseHTML(html, {plugins: [videoParserPlugin]});
let {post: expected} = Helpers.postAbstract.buildFromText([]);

assert.ok(didParseVideo);
assert.postIsSimilar(post, expected);
});

// see https://github.com/bustlelabs/mobiledoc-kit/issues/494
test('top-level unknown elements are parsed', (assert) => {
let html = `<video>...inner...</video>`;
let post = parseHTML(html, {plugins: [videoParserPlugin]});
let {post: expected} = Helpers.postAbstract.buildFromText(['...inner...']);

assert.ok(didParseVideo);
assert.postIsSimilar(post, expected);
});

test('nested void unknown elements are parsed', (assert) => {
let html = `<p>...<video />...</p>`;
let post = parseHTML(html, {plugins: [videoParserPlugin]});
let {post: expected} = Helpers.postAbstract.buildFromText(['......']);

assert.ok(didParseVideo);
assert.postIsSimilar(post, expected);
});

test('nested unknown elements are parsed', (assert) => {
let html = `<p>...<video>inner</video>...</p>`;
let post = parseHTML(html, {plugins: [videoParserPlugin]});
let {post: expected} = Helpers.postAbstract.buildFromText(['...inner...']);

assert.ok(didParseVideo);
assert.postIsSimilar(post, expected);
});
23 changes: 22 additions & 1 deletion tests/unit/parsers/section-test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import PostNodeBuilder from 'mobiledoc-kit/models/post-node-builder';
import SectionParser from 'mobiledoc-kit/parsers/section';
import Helpers from '../../test-helpers';
import {
NODE_TYPES
} from 'mobiledoc-kit/utils/dom-utils';

const {module, test} = Helpers;

Expand Down Expand Up @@ -138,7 +141,7 @@ test('#parse allows passing in parserPlugins that can override text parsing', (a

let element = container.firstChild;
let plugins = [function(element, builder, {addMarkerable, nodeFinished}) {
if (element.nodeType === 3) {
if (element.nodeType === NODE_TYPES.TEXT) {
if (element.textContent === 'text 1') {
addMarkerable(builder.createMarker('oh my'));
}
Expand All @@ -152,6 +155,24 @@ test('#parse allows passing in parserPlugins that can override text parsing', (a
assert.equal(sections[0].text, 'oh my');
});

test('#parse only runs text nodes through parserPlugins once', (assert) => {
let container = buildDOM('text');
let textNode = container.firstChild;

assert.equal(textNode.nodeType, NODE_TYPES.TEXT);

let pluginRunCount = 0;
let plugins = [function (element) {
if (element.nodeType === NODE_TYPES.TEXT && element.textContent === 'text') {
pluginRunCount++;
}
}];
parser = new SectionParser(builder, {plugins});
parser.parse(textNode);

assert.equal(pluginRunCount, 1);
});

test('#parse skips STYLE nodes', (assert) => {
let element = buildDOM(`
<style>.rule { font-color: red; }</style>
Expand Down

0 comments on commit 9b4231e

Please sign in to comment.