From f8b103d75e4a9fc9ab17e9ecc810e5eb86a26686 Mon Sep 17 00:00:00 2001 From: Zach Schneider Date: Mon, 31 Jul 2017 21:18:30 -0400 Subject: [PATCH] Reckon with inconsistencies between parse5 and native DOMParser (#952) --- examples/paste-html/index.js | 10 +++++----- src/serializers/html.js | 19 ++++++++++++++----- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/examples/paste-html/index.js b/examples/paste-html/index.js index 8db714b83..7d1c9739c 100644 --- a/examples/paste-html/index.js +++ b/examples/paste-html/index.js @@ -80,7 +80,7 @@ const MARK_TAGS = { const RULES = [ { deserialize(el, next) { - const block = BLOCK_TAGS[el.tagName] + const block = BLOCK_TAGS[el.tagName.toLowerCase()] if (!block) return return { kind: 'block', @@ -91,7 +91,7 @@ const RULES = [ }, { deserialize(el, next) { - const mark = MARK_TAGS[el.tagName] + const mark = MARK_TAGS[el.tagName.toLowerCase()] if (!mark) return return { kind: 'mark', @@ -103,9 +103,9 @@ const RULES = [ { // Special case for code blocks, which need to grab the nested childNodes. deserialize(el, next) { - if (el.tagName != 'pre') return + if (el.tagName.toLowerCase() != 'pre') return const code = el.childNodes[0] - const childNodes = code && code.tagName == 'code' + const childNodes = code && code.tagName.toLowerCase() == 'code' ? code.childNodes : el.childNodes @@ -119,7 +119,7 @@ const RULES = [ { // Special case for links, to grab their href. deserialize(el, next) { - if (el.tagName != 'a') return + if (el.tagName.toLowerCase() != 'a') return return { kind: 'inline', type: 'link', diff --git a/src/serializers/html.js b/src/serializers/html.js index bf58971f7..77c69fecf 100644 --- a/src/serializers/html.js +++ b/src/serializers/html.js @@ -33,12 +33,12 @@ const TEXT_RULE = { } } - if (el.nodeName == '#text') { + if (el.tagName == 'span' || el.nodeName == '#text') { if (el.value && el.value.match(//)) return return { kind: 'text', - text: el.value + text: el.value || el.nodeValue } } }, @@ -83,11 +83,13 @@ class Html { this.defaultBlockType = options.defaultBlockType || 'paragraph' // Set DOM parser function or fallback to native DOMParser if present. - if (options.parseHtml !== null) { + if (typeof options.parseHtml === 'function') { this.parseHtml = options.parseHtml } else if (typeof DOMParser !== 'undefined') { this.parseHtml = (html) => { - return new DOMParser().parseFromString(html, 'application/xml') + const parsed = new DOMParser().parseFromString(html, 'text/html') + // Unwrap from and + return parsed.childNodes[0].childNodes[1] } } else { throw new Error( @@ -106,7 +108,7 @@ class Html { */ deserialize = (html, options = {}) => { - const children = this.parseHtml(html).childNodes + const children = Array.from(this.parseHtml(html).childNodes) let nodes = this.deserializeElements(children) const { defaultBlockType } = this @@ -196,7 +198,14 @@ class Html { deserializeElement = (element) => { let node + if (!element.tagName) { + element.tagName = '' + } + const next = (elements) => { + if (typeof NodeList !== 'undefined' && elements instanceof NodeList) { + elements = Array.from(elements) + } switch (typeOf(elements)) { case 'array': return this.deserializeElements(elements)