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:
committed by
Ian Storm Taylor
parent
1e3cdafb59
commit
f8b103d75e
@@ -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',
|
||||||
|
@@ -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)
|
||||||
|
Reference in New Issue
Block a user