diff --git a/src/js/parsers/section.js b/src/js/parsers/section.js index 3360737c8..a9b1de404 100644 --- a/src/js/parsers/section.js +++ b/src/js/parsers/section.js @@ -41,18 +41,14 @@ import { import assert from '../utils/assert'; -function isListSection(section) { - return section.type === LIST_SECTION_TYPE; -} - -function isListItem(section) { - return section.type === LIST_ITEM_TYPE; -} +const SKIPPABLE_ELEMENT_TAG_NAMES = [ + 'style', 'head', 'title', 'meta' +].map(normalizeTagName); /** * parses an element into a section, ignoring any non-markup * elements contained within - * @return {Section} + * @return {Array} sections */ export default class SectionParser { constructor(builder, options={}) { @@ -61,6 +57,9 @@ export default class SectionParser { } parse(element) { + if (this._isSkippable(element)) { + return []; + } this.sections = []; this.state = {}; @@ -68,7 +67,7 @@ export default class SectionParser { let childNodes = isTextNode(element) ? [element] : element.childNodes; - if (isListSection(this.state.section)) { + if (this.state.section.isListSection) { this.parseListItems(childNodes); } else { forEach(childNodes, el => { @@ -86,7 +85,7 @@ export default class SectionParser { forEach(childNodes, el => { let parsed = new this.constructor(this.builder).parse(el); let li = parsed[0]; - if (li && isListItem(li)) { + if (li && li.isListItem) { state.section.items.append(li); } }); @@ -300,4 +299,9 @@ export default class SectionParser { return section; } + _isSkippable(element) { + return element.nodeType === ELEMENT_NODE && + contains(SKIPPABLE_ELEMENT_TAG_NAMES, + normalizeTagName(element.tagName)); + } } diff --git a/tests/unit/parsers/dom-google-docs-test.js b/tests/unit/parsers/html-google-docs-test.js similarity index 100% rename from tests/unit/parsers/dom-google-docs-test.js rename to tests/unit/parsers/html-google-docs-test.js diff --git a/tests/unit/parsers/html-test.js b/tests/unit/parsers/html-test.js new file mode 100644 index 000000000..0a2473ae9 --- /dev/null +++ b/tests/unit/parsers/html-test.js @@ -0,0 +1,26 @@ +import HTMLParser from 'mobiledoc-kit/parsers/html'; +import PostNodeBuilder from 'mobiledoc-kit/models/post-node-builder'; +import Helpers from '../../test-helpers'; + +const {module, test} = Helpers; + +function parseHTML(html, options={}) { + let builder = new PostNodeBuilder(); + return new HTMLParser(builder, options).parse(html); +} + +module('Unit: Parser: HTMLParser'); + +test('style tags are ignored', (assert) => { + // This is the html you get when copying a message from Slack's desktop app + let html = `

cool

`; + let post = parseHTML(html); + + let expected = Helpers.postAbstract.build( + ({post, markupSection, marker}) => { + return post([markupSection('p', [marker('cool')])]); + }); + + assert.postIsSimilar(post, expected); +}); + diff --git a/tests/unit/parsers/section-test.js b/tests/unit/parsers/section-test.js index 7b2779b18..e6eafc43c 100644 --- a/tests/unit/parsers/section-test.js +++ b/tests/unit/parsers/section-test.js @@ -151,3 +151,13 @@ test('#parse allows passing in parserPlugins that can override text parsing', (a assert.equal(sections.length, 1, '1 section'); assert.equal(sections[0].text, 'oh my'); }); + +test('#parse skips STYLE nodes', (assert) => { + let element = buildDOM(` + + `).firstChild; + parser = new SectionParser(builder); + let sections = parser.parse(element); + + assert.equal(sections.length, 0, 'does not parse style'); +});