mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-08-17 20:51:20 +02:00
Remove parse5 (#1531)
Fix stripUnwantedAttrs Remove .only Remove parse5 from deps Better imports Cleanup More succint removal of attributes
This commit is contained in:
committed by
Ian Storm Taylor
parent
48f198b210
commit
62ffb4681b
@@ -42,7 +42,7 @@ A set of properties to use for blocks which do not match any rule. Can be a stri
|
||||
### `parseHtml`
|
||||
`Function`
|
||||
|
||||
A function to parse an HTML string and return a DOM object. Defaults to using the native `DOMParser` in browser environments that support it. For older browsers or server-side rendering, you can include the [parse5](https://www.npmjs.com/package/parse5) package and pass `parse5.parseFragment` as the `parseHtml` option.
|
||||
A function to parse an HTML string and return a DOM object. Defaults to using the native `DOMParser` in browser environments that support it. For older browsers or server-side rendering, you can include the [jsdom](https://www.npmjs.com/package/jsdom) package and pass `JSDOM.fragment` as the `parseHtml` option.
|
||||
|
||||
This parse function should return the `<body>` node of the DOM.
|
||||
|
||||
|
@@ -66,8 +66,6 @@ const rules = [
|
||||
|
||||
The `el` argument that the `deserialize` function receives is just a DOM element. And the `next` argument is a function that will deserialize any element(s) we pass it, which is how you recurse through each node's children.
|
||||
|
||||
A quick note on `el.tagName` -- in browser environments, Slate uses the native `DOMParser` to parse HTML, which returns uppercase tag names. In server-side or node environments, we recommend [providing parse5](https://docs.slatejs.org/reference/serializers/html.html#parsehtml) to parse HTML; however, parse5 returns lowercase tag names due to some subtle complexities in specifications. Consequentially, we recommend using case-insensitive tag comparisons, so your code just works everywhere without having to worry about the parser implementation.
|
||||
|
||||
Okay, that's `deserialize`, now let's define the `serialize` property of the paragraph rule as well:
|
||||
|
||||
```js
|
||||
|
@@ -35,7 +35,6 @@
|
||||
"matcha": "^0.7.0",
|
||||
"mocha": "^2.5.3",
|
||||
"npm-run-all": "^4.1.1",
|
||||
"parse5": "^3.0.2",
|
||||
"prismjs": "^1.5.1",
|
||||
"react": "^16.0.0",
|
||||
"react-dom": "^16.0.0",
|
||||
|
@@ -3,10 +3,10 @@
|
||||
|
||||
import Html from '../..'
|
||||
import React from 'react'
|
||||
import parse5 from 'parse5' // eslint-disable-line import/no-extraneous-dependencies
|
||||
import { JSDOM } from 'jsdom' // eslint-disable-line import/no-extraneous-dependencies
|
||||
|
||||
const html = new Html({
|
||||
parseHtml: parse5.parseFragment,
|
||||
parseHtml: JSDOM.fragment,
|
||||
rules: [
|
||||
{
|
||||
serialize(obj, children) {
|
||||
|
@@ -4,10 +4,10 @@
|
||||
import Html from '../..'
|
||||
import React from 'react'
|
||||
import h from '../../test/helpers/h'
|
||||
import parse5 from 'parse5' // eslint-disable-line import/no-extraneous-dependencies
|
||||
import { JSDOM } from 'jsdom' // eslint-disable-line import/no-extraneous-dependencies
|
||||
|
||||
const html = new Html({
|
||||
parseHtml: parse5.parseFragment,
|
||||
parseHtml: JSDOM.fragment,
|
||||
rules: [
|
||||
{
|
||||
serialize(obj, children) {
|
||||
|
@@ -1,5 +1,5 @@
|
||||
|
||||
import parse5 from 'parse5' // eslint-disable-line import/no-extraneous-dependencies
|
||||
import { JSDOM } from 'jsdom' // eslint-disable-line import/no-extraneous-dependencies
|
||||
|
||||
const UNWANTED_ATTRS = [
|
||||
'data-key',
|
||||
@@ -21,20 +21,20 @@ const UNWANTED_TOP_LEVEL_ATTRS = [
|
||||
*/
|
||||
|
||||
function stripUnwantedAttrs(element) {
|
||||
if (Array.isArray(element.attrs)) {
|
||||
element.attrs = element.attrs.filter(({ name }) => { return !UNWANTED_ATTRS.includes(name) })
|
||||
if (typeof element.removeAttribute === 'function') {
|
||||
UNWANTED_ATTRS.forEach(attr => element.removeAttribute(attr))
|
||||
|
||||
if (element.parentNode.nodeName === '#document-fragment') {
|
||||
element.attrs = element.attrs.filter(({ name }) => { return !UNWANTED_TOP_LEVEL_ATTRS.includes(name) })
|
||||
UNWANTED_TOP_LEVEL_ATTRS.forEach(attr => element.removeAttribute(attr))
|
||||
}
|
||||
}
|
||||
|
||||
if (Array.isArray(element.childNodes)) {
|
||||
if (element.childNodes.length) {
|
||||
element.childNodes.forEach(stripUnwantedAttrs)
|
||||
}
|
||||
|
||||
if (element.nodeName === '#text') {
|
||||
element.value = element.value.trim()
|
||||
element.textContent = element.textContent.trim()
|
||||
}
|
||||
|
||||
return element
|
||||
@@ -48,7 +48,7 @@ function stripUnwantedAttrs(element) {
|
||||
*/
|
||||
|
||||
export default function clean(html) {
|
||||
const $ = parse5.parseFragment(html)
|
||||
const $ = JSDOM.fragment(html)
|
||||
$.childNodes.forEach(stripUnwantedAttrs)
|
||||
return parse5.serialize($)
|
||||
return $.firstChild.outerHTML
|
||||
}
|
||||
|
@@ -4,7 +4,7 @@ import ReactDOM from 'react-dom/server'
|
||||
import assert from 'assert'
|
||||
import clean from '../helpers/clean'
|
||||
import fs from 'fs-promise' // eslint-disable-line import/no-extraneous-dependencies
|
||||
import parse5 from 'parse5' // eslint-disable-line import/no-extraneous-dependencies
|
||||
import { JSDOM } from 'jsdom' // eslint-disable-line import/no-extraneous-dependencies
|
||||
import { Editor } from '../..'
|
||||
import { basename, extname, resolve } from 'path'
|
||||
|
||||
@@ -27,7 +27,8 @@ describe('rendering', () => {
|
||||
}
|
||||
|
||||
const string = ReactDOM.renderToStaticMarkup(<Editor {...p} />)
|
||||
const expected = parse5.serialize(parse5.parseFragment(output))
|
||||
const dom = JSDOM.fragment(output)
|
||||
const expected = dom.firstChild.outerHTML
|
||||
.trim()
|
||||
.replace(/\n/gm, '')
|
||||
.replace(/>\s*</g, '><')
|
||||
|
Reference in New Issue
Block a user