1
0
mirror of https://github.com/ianstormtaylor/slate.git synced 2025-08-20 14:11:35 +02:00

Reckon with inconsistencies between parse5 and native DOMParser (#952)

This commit is contained in:
Zach Schneider
2017-07-31 21:18:30 -04:00
committed by Ian Storm Taylor
parent 1e3cdafb59
commit f8b103d75e
2 changed files with 19 additions and 10 deletions

View File

@@ -80,7 +80,7 @@ const MARK_TAGS = {
const RULES = [ const RULES = [
{ {
deserialize(el, next) { deserialize(el, next) {
const block = BLOCK_TAGS[el.tagName] const block = BLOCK_TAGS[el.tagName.toLowerCase()]
if (!block) return if (!block) return
return { return {
kind: 'block', kind: 'block',
@@ -91,7 +91,7 @@ const RULES = [
}, },
{ {
deserialize(el, next) { deserialize(el, next) {
const mark = MARK_TAGS[el.tagName] const mark = MARK_TAGS[el.tagName.toLowerCase()]
if (!mark) return if (!mark) return
return { return {
kind: 'mark', kind: 'mark',
@@ -103,9 +103,9 @@ const RULES = [
{ {
// Special case for code blocks, which need to grab the nested childNodes. // Special case for code blocks, which need to grab the nested childNodes.
deserialize(el, next) { deserialize(el, next) {
if (el.tagName != 'pre') return if (el.tagName.toLowerCase() != 'pre') return
const code = el.childNodes[0] const code = el.childNodes[0]
const childNodes = code && code.tagName == 'code' const childNodes = code && code.tagName.toLowerCase() == 'code'
? code.childNodes ? code.childNodes
: el.childNodes : el.childNodes
@@ -119,7 +119,7 @@ const RULES = [
{ {
// Special case for links, to grab their href. // Special case for links, to grab their href.
deserialize(el, next) { deserialize(el, next) {
if (el.tagName != 'a') return if (el.tagName.toLowerCase() != 'a') return
return { return {
kind: 'inline', kind: 'inline',
type: 'link', type: 'link',

View File

@@ -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 if (el.value && el.value.match(/<!--.*?-->/)) return
return { return {
kind: 'text', kind: 'text',
text: el.value text: el.value || el.nodeValue
} }
} }
}, },
@@ -83,11 +83,13 @@ class Html {
this.defaultBlockType = options.defaultBlockType || 'paragraph' this.defaultBlockType = options.defaultBlockType || 'paragraph'
// Set DOM parser function or fallback to native DOMParser if present. // Set DOM parser function or fallback to native DOMParser if present.
if (options.parseHtml !== null) { if (typeof options.parseHtml === 'function') {
this.parseHtml = options.parseHtml this.parseHtml = options.parseHtml
} else if (typeof DOMParser !== 'undefined') { } else if (typeof DOMParser !== 'undefined') {
this.parseHtml = (html) => { this.parseHtml = (html) => {
return new DOMParser().parseFromString(html, 'application/xml') const parsed = new DOMParser().parseFromString(html, 'text/html')
// Unwrap from <html> and <body>
return parsed.childNodes[0].childNodes[1]
} }
} else { } else {
throw new Error( throw new Error(
@@ -106,7 +108,7 @@ class Html {
*/ */
deserialize = (html, options = {}) => { deserialize = (html, options = {}) => {
const children = this.parseHtml(html).childNodes const children = Array.from(this.parseHtml(html).childNodes)
let nodes = this.deserializeElements(children) let nodes = this.deserializeElements(children)
const { defaultBlockType } = this const { defaultBlockType } = this
@@ -196,7 +198,14 @@ class Html {
deserializeElement = (element) => { deserializeElement = (element) => {
let node let node
if (!element.tagName) {
element.tagName = ''
}
const next = (elements) => { const next = (elements) => {
if (typeof NodeList !== 'undefined' && elements instanceof NodeList) {
elements = Array.from(elements)
}
switch (typeOf(elements)) { switch (typeOf(elements)) {
case 'array': case 'array':
return this.deserializeElements(elements) return this.deserializeElements(elements)