Skip to content

Commit

Permalink
ensure style tags are skipped when parsing HTML/dom
Browse files Browse the repository at this point in the history
  • Loading branch information
bantic committed Dec 16, 2015
1 parent e687d3d commit 5409b1a
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 10 deletions.
24 changes: 14 additions & 10 deletions src/js/parsers/section.js
Expand Up @@ -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={}) {
Expand All @@ -61,14 +57,17 @@ export default class SectionParser {
}

parse(element) {
if (this._isSkippable(element)) {
return [];
}
this.sections = [];
this.state = {};

this._updateStateFromElement(element);

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

if (isListSection(this.state.section)) {
if (this.state.section.isListSection) {
this.parseListItems(childNodes);
} else {
forEach(childNodes, el => {
Expand All @@ -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);
}
});
Expand Down Expand Up @@ -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));
}
}
File renamed without changes.
26 changes: 26 additions & 0 deletions 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 = `<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta http-equiv="Content-Style-Type" content="text/css"> <title></title> <meta name="Generator" content="Cocoa HTML Writer"> <meta name="CocoaVersion" content="1348.17"> <style type="text/css"> p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 15.0px Times; color: #2c2d30; -webkit-text-stroke: #2c2d30; background-color: #f9f9f9} span.s1 {font-kerning: none} </style> </head> <body> <p class="p1"><span class="s1">cool</span></p> </body> </html>`;
let post = parseHTML(html);

let expected = Helpers.postAbstract.build(
({post, markupSection, marker}) => {
return post([markupSection('p', [marker('cool')])]);
});

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

10 changes: 10 additions & 0 deletions tests/unit/parsers/section-test.js
Expand Up @@ -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(`
<style>.rule { font-color: red; }</style>
`).firstChild;
parser = new SectionParser(builder);
let sections = parser.parse(element);

assert.equal(sections.length, 0, 'does not parse style');
});

0 comments on commit 5409b1a

Please sign in to comment.