@wordpress/dom
Advanced tools
Comparing version 2.13.1 to 2.14.0
/** | ||
* External dependencies | ||
*/ | ||
import { includes } from 'lodash'; | ||
import { includes, noop } from 'lodash'; | ||
/** | ||
* Internal dependencies | ||
*/ | ||
import { isPhrasingContent } from './phrasing-content'; | ||
/** | ||
* Browser dependencies | ||
@@ -703,2 +708,172 @@ */ | ||
} | ||
/** | ||
* Given a schema, unwraps or removes nodes, attributes and classes on a node | ||
* list. | ||
* | ||
* @param {NodeList} nodeList The nodeList to filter. | ||
* @param {Document} doc The document of the nodeList. | ||
* @param {Object} schema An array of functions that can mutate with the provided node. | ||
* @param {Object} inline Whether to clean for inline mode. | ||
*/ | ||
function cleanNodeList(nodeList, doc, schema, inline) { | ||
Array.from(nodeList).forEach(function (node) { | ||
var tag = node.nodeName.toLowerCase(); // It's a valid child, if the tag exists in the schema without an isMatch | ||
// function, or with an isMatch function that matches the node. | ||
if (schema.hasOwnProperty(tag) && (!schema[tag].isMatch || schema[tag].isMatch(node))) { | ||
if (node.nodeType === ELEMENT_NODE) { | ||
var _schema$tag = schema[tag], | ||
_schema$tag$attribute = _schema$tag.attributes, | ||
attributes = _schema$tag$attribute === void 0 ? [] : _schema$tag$attribute, | ||
_schema$tag$classes = _schema$tag.classes, | ||
classes = _schema$tag$classes === void 0 ? [] : _schema$tag$classes, | ||
children = _schema$tag.children, | ||
_schema$tag$require = _schema$tag.require, | ||
require = _schema$tag$require === void 0 ? [] : _schema$tag$require, | ||
allowEmpty = _schema$tag.allowEmpty; // If the node is empty and it's supposed to have children, | ||
// remove the node. | ||
if (children && !allowEmpty && isEmpty(node)) { | ||
remove(node); | ||
return; | ||
} | ||
if (node.hasAttributes()) { | ||
// Strip invalid attributes. | ||
Array.from(node.attributes).forEach(function (_ref) { | ||
var name = _ref.name; | ||
if (name !== 'class' && !includes(attributes, name)) { | ||
node.removeAttribute(name); | ||
} | ||
}); // Strip invalid classes. | ||
// In jsdom-jscore, 'node.classList' can be undefined. | ||
// TODO: Explore patching this in jsdom-jscore. | ||
if (node.classList && node.classList.length) { | ||
var mattchers = classes.map(function (item) { | ||
if (typeof item === 'string') { | ||
return function (className) { | ||
return className === item; | ||
}; | ||
} else if (item instanceof RegExp) { | ||
return function (className) { | ||
return item.test(className); | ||
}; | ||
} | ||
return noop; | ||
}); | ||
Array.from(node.classList).forEach(function (name) { | ||
if (!mattchers.some(function (isMatch) { | ||
return isMatch(name); | ||
})) { | ||
node.classList.remove(name); | ||
} | ||
}); | ||
if (!node.classList.length) { | ||
node.removeAttribute('class'); | ||
} | ||
} | ||
} | ||
if (node.hasChildNodes()) { | ||
// Do not filter any content. | ||
if (children === '*') { | ||
return; | ||
} // Continue if the node is supposed to have children. | ||
if (children) { | ||
// If a parent requires certain children, but it does | ||
// not have them, drop the parent and continue. | ||
if (require.length && !node.querySelector(require.join(','))) { | ||
cleanNodeList(node.childNodes, doc, schema, inline); | ||
unwrap(node); // If the node is at the top, phrasing content, and | ||
// contains children that are block content, unwrap | ||
// the node because it is invalid. | ||
} else if (node.parentNode.nodeName === 'BODY' && isPhrasingContent(node)) { | ||
cleanNodeList(node.childNodes, doc, schema, inline); | ||
if (Array.from(node.childNodes).some(function (child) { | ||
return !isPhrasingContent(child); | ||
})) { | ||
unwrap(node); | ||
} | ||
} else { | ||
cleanNodeList(node.childNodes, doc, children, inline); | ||
} // Remove children if the node is not supposed to have any. | ||
} else { | ||
while (node.firstChild) { | ||
remove(node.firstChild); | ||
} | ||
} | ||
} | ||
} // Invalid child. Continue with schema at the same place and unwrap. | ||
} else { | ||
cleanNodeList(node.childNodes, doc, schema, inline); // For inline mode, insert a line break when unwrapping nodes that | ||
// are not phrasing content. | ||
if (inline && !isPhrasingContent(node) && node.nextElementSibling) { | ||
insertAfter(doc.createElement('br'), node); | ||
} | ||
unwrap(node); | ||
} | ||
}); | ||
} | ||
/** | ||
* Recursively checks if an element is empty. An element is not empty if it | ||
* contains text or contains elements with attributes such as images. | ||
* | ||
* @param {Element} element The element to check. | ||
* | ||
* @return {boolean} Wether or not the element is empty. | ||
*/ | ||
export function isEmpty(element) { | ||
if (!element.hasChildNodes()) { | ||
return true; | ||
} | ||
return Array.from(element.childNodes).every(function (node) { | ||
if (node.nodeType === TEXT_NODE) { | ||
return !node.nodeValue.trim(); | ||
} | ||
if (node.nodeType === ELEMENT_NODE) { | ||
if (node.nodeName === 'BR') { | ||
return true; | ||
} else if (node.hasAttributes()) { | ||
return false; | ||
} | ||
return isEmpty(node); | ||
} | ||
return true; | ||
}); | ||
} | ||
/** | ||
* Given a schema, unwraps or removes nodes, attributes and classes on HTML. | ||
* | ||
* @param {string} HTML The HTML to clean up. | ||
* @param {Object} schema Schema for the HTML. | ||
* @param {Object} inline Whether to clean for inline mode. | ||
* | ||
* @return {string} The cleaned up HTML. | ||
*/ | ||
export function removeInvalidHTML(HTML, schema, inline) { | ||
var doc = document.implementation.createHTMLDocument(''); | ||
doc.body.innerHTML = HTML; | ||
cleanNodeList(doc.body.childNodes, doc, schema, inline); | ||
return doc.body.innerHTML; | ||
} | ||
//# sourceMappingURL=dom.js.map |
@@ -16,2 +16,3 @@ /** | ||
export * from './dom'; | ||
export * from './phrasing-content'; | ||
//# sourceMappingURL=index.js.map |
180
build/dom.js
@@ -27,5 +27,9 @@ "use strict"; | ||
exports.__unstableStripHTML = __unstableStripHTML; | ||
exports.isEmpty = isEmpty; | ||
exports.removeInvalidHTML = removeInvalidHTML; | ||
var _lodash = require("lodash"); | ||
var _phrasingContent = require("./phrasing-content"); | ||
/** | ||
@@ -36,2 +40,6 @@ * External dependencies | ||
/** | ||
* Internal dependencies | ||
*/ | ||
/** | ||
* Browser dependencies | ||
@@ -753,2 +761,174 @@ */ | ||
} | ||
/** | ||
* Given a schema, unwraps or removes nodes, attributes and classes on a node | ||
* list. | ||
* | ||
* @param {NodeList} nodeList The nodeList to filter. | ||
* @param {Document} doc The document of the nodeList. | ||
* @param {Object} schema An array of functions that can mutate with the provided node. | ||
* @param {Object} inline Whether to clean for inline mode. | ||
*/ | ||
function cleanNodeList(nodeList, doc, schema, inline) { | ||
Array.from(nodeList).forEach(function (node) { | ||
var tag = node.nodeName.toLowerCase(); // It's a valid child, if the tag exists in the schema without an isMatch | ||
// function, or with an isMatch function that matches the node. | ||
if (schema.hasOwnProperty(tag) && (!schema[tag].isMatch || schema[tag].isMatch(node))) { | ||
if (node.nodeType === ELEMENT_NODE) { | ||
var _schema$tag = schema[tag], | ||
_schema$tag$attribute = _schema$tag.attributes, | ||
attributes = _schema$tag$attribute === void 0 ? [] : _schema$tag$attribute, | ||
_schema$tag$classes = _schema$tag.classes, | ||
classes = _schema$tag$classes === void 0 ? [] : _schema$tag$classes, | ||
children = _schema$tag.children, | ||
_schema$tag$require = _schema$tag.require, | ||
require = _schema$tag$require === void 0 ? [] : _schema$tag$require, | ||
allowEmpty = _schema$tag.allowEmpty; // If the node is empty and it's supposed to have children, | ||
// remove the node. | ||
if (children && !allowEmpty && isEmpty(node)) { | ||
remove(node); | ||
return; | ||
} | ||
if (node.hasAttributes()) { | ||
// Strip invalid attributes. | ||
Array.from(node.attributes).forEach(function (_ref) { | ||
var name = _ref.name; | ||
if (name !== 'class' && !(0, _lodash.includes)(attributes, name)) { | ||
node.removeAttribute(name); | ||
} | ||
}); // Strip invalid classes. | ||
// In jsdom-jscore, 'node.classList' can be undefined. | ||
// TODO: Explore patching this in jsdom-jscore. | ||
if (node.classList && node.classList.length) { | ||
var mattchers = classes.map(function (item) { | ||
if (typeof item === 'string') { | ||
return function (className) { | ||
return className === item; | ||
}; | ||
} else if (item instanceof RegExp) { | ||
return function (className) { | ||
return item.test(className); | ||
}; | ||
} | ||
return _lodash.noop; | ||
}); | ||
Array.from(node.classList).forEach(function (name) { | ||
if (!mattchers.some(function (isMatch) { | ||
return isMatch(name); | ||
})) { | ||
node.classList.remove(name); | ||
} | ||
}); | ||
if (!node.classList.length) { | ||
node.removeAttribute('class'); | ||
} | ||
} | ||
} | ||
if (node.hasChildNodes()) { | ||
// Do not filter any content. | ||
if (children === '*') { | ||
return; | ||
} // Continue if the node is supposed to have children. | ||
if (children) { | ||
// If a parent requires certain children, but it does | ||
// not have them, drop the parent and continue. | ||
if (require.length && !node.querySelector(require.join(','))) { | ||
cleanNodeList(node.childNodes, doc, schema, inline); | ||
unwrap(node); // If the node is at the top, phrasing content, and | ||
// contains children that are block content, unwrap | ||
// the node because it is invalid. | ||
} else if (node.parentNode.nodeName === 'BODY' && (0, _phrasingContent.isPhrasingContent)(node)) { | ||
cleanNodeList(node.childNodes, doc, schema, inline); | ||
if (Array.from(node.childNodes).some(function (child) { | ||
return !(0, _phrasingContent.isPhrasingContent)(child); | ||
})) { | ||
unwrap(node); | ||
} | ||
} else { | ||
cleanNodeList(node.childNodes, doc, children, inline); | ||
} // Remove children if the node is not supposed to have any. | ||
} else { | ||
while (node.firstChild) { | ||
remove(node.firstChild); | ||
} | ||
} | ||
} | ||
} // Invalid child. Continue with schema at the same place and unwrap. | ||
} else { | ||
cleanNodeList(node.childNodes, doc, schema, inline); // For inline mode, insert a line break when unwrapping nodes that | ||
// are not phrasing content. | ||
if (inline && !(0, _phrasingContent.isPhrasingContent)(node) && node.nextElementSibling) { | ||
insertAfter(doc.createElement('br'), node); | ||
} | ||
unwrap(node); | ||
} | ||
}); | ||
} | ||
/** | ||
* Recursively checks if an element is empty. An element is not empty if it | ||
* contains text or contains elements with attributes such as images. | ||
* | ||
* @param {Element} element The element to check. | ||
* | ||
* @return {boolean} Wether or not the element is empty. | ||
*/ | ||
function isEmpty(element) { | ||
if (!element.hasChildNodes()) { | ||
return true; | ||
} | ||
return Array.from(element.childNodes).every(function (node) { | ||
if (node.nodeType === TEXT_NODE) { | ||
return !node.nodeValue.trim(); | ||
} | ||
if (node.nodeType === ELEMENT_NODE) { | ||
if (node.nodeName === 'BR') { | ||
return true; | ||
} else if (node.hasAttributes()) { | ||
return false; | ||
} | ||
return isEmpty(node); | ||
} | ||
return true; | ||
}); | ||
} | ||
/** | ||
* Given a schema, unwraps or removes nodes, attributes and classes on HTML. | ||
* | ||
* @param {string} HTML The HTML to clean up. | ||
* @param {Object} schema Schema for the HTML. | ||
* @param {Object} inline Whether to clean for inline mode. | ||
* | ||
* @return {string} The cleaned up HTML. | ||
*/ | ||
function removeInvalidHTML(HTML, schema, inline) { | ||
var doc = document.implementation.createHTMLDocument(''); | ||
doc.body.innerHTML = HTML; | ||
cleanNodeList(doc.body.childNodes, doc, schema, inline); | ||
return doc.body.innerHTML; | ||
} | ||
//# sourceMappingURL=dom.js.map |
@@ -30,2 +30,15 @@ "use strict"; | ||
var _phrasingContent = require("./phrasing-content"); | ||
Object.keys(_phrasingContent).forEach(function (key) { | ||
if (key === "default" || key === "__esModule") return; | ||
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return; | ||
Object.defineProperty(exports, key, { | ||
enumerable: true, | ||
get: function get() { | ||
return _phrasingContent[key]; | ||
} | ||
}); | ||
}); | ||
/** | ||
@@ -32,0 +45,0 @@ * Internal dependencies |
{ | ||
"name": "@wordpress/dom", | ||
"version": "2.13.1", | ||
"version": "2.14.0", | ||
"description": "DOM utilities module for WordPress.", | ||
@@ -28,3 +28,3 @@ "author": "The WordPress Contributors", | ||
"@babel/runtime": "^7.9.2", | ||
"lodash": "^4.17.15" | ||
"lodash": "^4.17.19" | ||
}, | ||
@@ -34,3 +34,3 @@ "publishConfig": { | ||
}, | ||
"gitHead": "862bb53a4af8aa5852a22445b5d12591d5500e52" | ||
"gitHead": "07baf5a12007d31bbd4ee22113b07952f7eacc26" | ||
} |
@@ -79,2 +79,18 @@ # DOM | ||
<a name="getPhrasingContentSchema" href="#getPhrasingContentSchema">#</a> **getPhrasingContentSchema** | ||
Get schema of possible paths for phrasing content. | ||
_Related_ | ||
- <https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Content_categories#Phrasing_content> | ||
_Parameters_ | ||
- _context_ `string`: Set to "paste" to exclude invisible elements and sensitive data. | ||
_Returns_ | ||
- `Object`: Schema. | ||
<a name="getRectangleFromRange" href="#getRectangleFromRange">#</a> **getRectangleFromRange** | ||
@@ -118,2 +134,15 @@ | ||
<a name="isEmpty" href="#isEmpty">#</a> **isEmpty** | ||
Recursively checks if an element is empty. An element is not empty if it | ||
contains text or contains elements with attributes such as images. | ||
_Parameters_ | ||
- _element_ `Element`: The element to check. | ||
_Returns_ | ||
- `boolean`: Wether or not the element is empty. | ||
<a name="isEntirelySelected" href="#isEntirelySelected">#</a> **isEntirelySelected** | ||
@@ -158,2 +187,22 @@ | ||
<a name="isPhrasingContent" href="#isPhrasingContent">#</a> **isPhrasingContent** | ||
Find out whether or not the given node is phrasing content. | ||
_Related_ | ||
- <https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Content_categories#Phrasing_content> | ||
_Parameters_ | ||
- _node_ `Element`: The node to test. | ||
_Returns_ | ||
- `boolean`: True if phrasing content, false if not. | ||
<a name="isTextContent" href="#isTextContent">#</a> **isTextContent** | ||
Undocumented declaration. | ||
<a name="isTextField" href="#isTextField">#</a> **isTextField** | ||
@@ -219,2 +268,16 @@ | ||
<a name="removeInvalidHTML" href="#removeInvalidHTML">#</a> **removeInvalidHTML** | ||
Given a schema, unwraps or removes nodes, attributes and classes on HTML. | ||
_Parameters_ | ||
- _HTML_ `string`: The HTML to clean up. | ||
- _schema_ `Object`: Schema for the HTML. | ||
- _inline_ `Object`: Whether to clean for inline mode. | ||
_Returns_ | ||
- `string`: The cleaned up HTML. | ||
<a name="replace" href="#replace">#</a> **replace** | ||
@@ -221,0 +284,0 @@ |
211
src/dom.js
/** | ||
* External dependencies | ||
*/ | ||
import { includes } from 'lodash'; | ||
import { includes, noop } from 'lodash'; | ||
/** | ||
* Internal dependencies | ||
*/ | ||
import { isPhrasingContent } from './phrasing-content'; | ||
/** | ||
* Browser dependencies | ||
@@ -766,1 +771,205 @@ */ | ||
} | ||
/** | ||
* Given a schema, unwraps or removes nodes, attributes and classes on a node | ||
* list. | ||
* | ||
* @param {NodeList} nodeList The nodeList to filter. | ||
* @param {Document} doc The document of the nodeList. | ||
* @param {Object} schema An array of functions that can mutate with the provided node. | ||
* @param {Object} inline Whether to clean for inline mode. | ||
*/ | ||
function cleanNodeList( nodeList, doc, schema, inline ) { | ||
Array.from( nodeList ).forEach( ( node ) => { | ||
const tag = node.nodeName.toLowerCase(); | ||
// It's a valid child, if the tag exists in the schema without an isMatch | ||
// function, or with an isMatch function that matches the node. | ||
if ( | ||
schema.hasOwnProperty( tag ) && | ||
( ! schema[ tag ].isMatch || schema[ tag ].isMatch( node ) ) | ||
) { | ||
if ( node.nodeType === ELEMENT_NODE ) { | ||
const { | ||
attributes = [], | ||
classes = [], | ||
children, | ||
require = [], | ||
allowEmpty, | ||
} = schema[ tag ]; | ||
// If the node is empty and it's supposed to have children, | ||
// remove the node. | ||
if ( children && ! allowEmpty && isEmpty( node ) ) { | ||
remove( node ); | ||
return; | ||
} | ||
if ( node.hasAttributes() ) { | ||
// Strip invalid attributes. | ||
Array.from( node.attributes ).forEach( ( { name } ) => { | ||
if ( | ||
name !== 'class' && | ||
! includes( attributes, name ) | ||
) { | ||
node.removeAttribute( name ); | ||
} | ||
} ); | ||
// Strip invalid classes. | ||
// In jsdom-jscore, 'node.classList' can be undefined. | ||
// TODO: Explore patching this in jsdom-jscore. | ||
if ( node.classList && node.classList.length ) { | ||
const mattchers = classes.map( ( item ) => { | ||
if ( typeof item === 'string' ) { | ||
return ( className ) => className === item; | ||
} else if ( item instanceof RegExp ) { | ||
return ( className ) => item.test( className ); | ||
} | ||
return noop; | ||
} ); | ||
Array.from( node.classList ).forEach( ( name ) => { | ||
if ( | ||
! mattchers.some( ( isMatch ) => | ||
isMatch( name ) | ||
) | ||
) { | ||
node.classList.remove( name ); | ||
} | ||
} ); | ||
if ( ! node.classList.length ) { | ||
node.removeAttribute( 'class' ); | ||
} | ||
} | ||
} | ||
if ( node.hasChildNodes() ) { | ||
// Do not filter any content. | ||
if ( children === '*' ) { | ||
return; | ||
} | ||
// Continue if the node is supposed to have children. | ||
if ( children ) { | ||
// If a parent requires certain children, but it does | ||
// not have them, drop the parent and continue. | ||
if ( | ||
require.length && | ||
! node.querySelector( require.join( ',' ) ) | ||
) { | ||
cleanNodeList( | ||
node.childNodes, | ||
doc, | ||
schema, | ||
inline | ||
); | ||
unwrap( node ); | ||
// If the node is at the top, phrasing content, and | ||
// contains children that are block content, unwrap | ||
// the node because it is invalid. | ||
} else if ( | ||
node.parentNode.nodeName === 'BODY' && | ||
isPhrasingContent( node ) | ||
) { | ||
cleanNodeList( | ||
node.childNodes, | ||
doc, | ||
schema, | ||
inline | ||
); | ||
if ( | ||
Array.from( node.childNodes ).some( | ||
( child ) => ! isPhrasingContent( child ) | ||
) | ||
) { | ||
unwrap( node ); | ||
} | ||
} else { | ||
cleanNodeList( | ||
node.childNodes, | ||
doc, | ||
children, | ||
inline | ||
); | ||
} | ||
// Remove children if the node is not supposed to have any. | ||
} else { | ||
while ( node.firstChild ) { | ||
remove( node.firstChild ); | ||
} | ||
} | ||
} | ||
} | ||
// Invalid child. Continue with schema at the same place and unwrap. | ||
} else { | ||
cleanNodeList( node.childNodes, doc, schema, inline ); | ||
// For inline mode, insert a line break when unwrapping nodes that | ||
// are not phrasing content. | ||
if ( | ||
inline && | ||
! isPhrasingContent( node ) && | ||
node.nextElementSibling | ||
) { | ||
insertAfter( doc.createElement( 'br' ), node ); | ||
} | ||
unwrap( node ); | ||
} | ||
} ); | ||
} | ||
/** | ||
* Recursively checks if an element is empty. An element is not empty if it | ||
* contains text or contains elements with attributes such as images. | ||
* | ||
* @param {Element} element The element to check. | ||
* | ||
* @return {boolean} Wether or not the element is empty. | ||
*/ | ||
export function isEmpty( element ) { | ||
if ( ! element.hasChildNodes() ) { | ||
return true; | ||
} | ||
return Array.from( element.childNodes ).every( ( node ) => { | ||
if ( node.nodeType === TEXT_NODE ) { | ||
return ! node.nodeValue.trim(); | ||
} | ||
if ( node.nodeType === ELEMENT_NODE ) { | ||
if ( node.nodeName === 'BR' ) { | ||
return true; | ||
} else if ( node.hasAttributes() ) { | ||
return false; | ||
} | ||
return isEmpty( node ); | ||
} | ||
return true; | ||
} ); | ||
} | ||
/** | ||
* Given a schema, unwraps or removes nodes, attributes and classes on HTML. | ||
* | ||
* @param {string} HTML The HTML to clean up. | ||
* @param {Object} schema Schema for the HTML. | ||
* @param {Object} inline Whether to clean for inline mode. | ||
* | ||
* @return {string} The cleaned up HTML. | ||
*/ | ||
export function removeInvalidHTML( HTML, schema, inline ) { | ||
const doc = document.implementation.createHTMLDocument( '' ); | ||
doc.body.innerHTML = HTML; | ||
cleanNodeList( doc.body.childNodes, doc, schema, inline ); | ||
return doc.body.innerHTML; | ||
} |
@@ -14,1 +14,2 @@ /** | ||
export * from './dom'; | ||
export * from './phrasing-content'; |
@@ -10,4 +10,8 @@ /** | ||
isNumberInput, | ||
removeInvalidHTML, | ||
isEmpty, | ||
} from '../dom'; | ||
import { getPhrasingContentSchema } from '../phrasing-content'; | ||
describe( 'DOM', () => { | ||
@@ -201,1 +205,152 @@ let parent; | ||
} ); | ||
describe( 'removeInvalidHTML', () => { | ||
const phrasingContentSchema = getPhrasingContentSchema(); | ||
const schema = { | ||
p: { | ||
children: phrasingContentSchema, | ||
}, | ||
figure: { | ||
require: [ 'img' ], | ||
children: { | ||
img: { | ||
attributes: [ 'src', 'alt' ], | ||
classes: [ 'alignleft' ], | ||
}, | ||
figcaption: { | ||
children: phrasingContentSchema, | ||
}, | ||
}, | ||
}, | ||
...phrasingContentSchema, | ||
}; | ||
it( 'should leave plain text alone', () => { | ||
const input = 'test'; | ||
expect( removeInvalidHTML( input, schema ) ).toBe( input ); | ||
} ); | ||
it( 'should leave valid phrasing content alone', () => { | ||
const input = '<strong>test</strong>'; | ||
expect( removeInvalidHTML( input, schema ) ).toBe( input ); | ||
} ); | ||
it( 'should remove unrecognised tags from phrasing content', () => { | ||
const input = '<strong><div>test</div></strong>'; | ||
const output = '<strong>test</strong>'; | ||
expect( removeInvalidHTML( input, schema ) ).toBe( output ); | ||
} ); | ||
it( 'should remove unwanted whitespace outside phrasing content', () => { | ||
const input = '<figure><img src=""> </figure>'; | ||
const output = '<figure><img src=""></figure>'; | ||
expect( removeInvalidHTML( input, schema ) ).toBe( output ); | ||
} ); | ||
it( 'should remove attributes', () => { | ||
const input = '<p class="test">test</p>'; | ||
const output = '<p>test</p>'; | ||
expect( removeInvalidHTML( input, schema ) ).toBe( output ); | ||
} ); | ||
it( 'should remove id attributes', () => { | ||
const input = '<p id="foo">test</p>'; | ||
const output = '<p>test</p>'; | ||
expect( removeInvalidHTML( input, schema ) ).toBe( output ); | ||
} ); | ||
it( 'should remove multiple attributes', () => { | ||
const input = '<p class="test" id="test">test</p>'; | ||
const output = '<p>test</p>'; | ||
expect( removeInvalidHTML( input, schema ) ).toBe( output ); | ||
} ); | ||
it( 'should deep remove attributes', () => { | ||
const input = '<p class="test">test <em id="test">test</em></p>'; | ||
const output = '<p>test <em>test</em></p>'; | ||
expect( removeInvalidHTML( input, schema ) ).toBe( output ); | ||
} ); | ||
it( 'should remove data-* attributes', () => { | ||
const input = '<p data-reactid="1">test</p>'; | ||
const output = '<p>test</p>'; | ||
expect( removeInvalidHTML( input, schema ) ).toBe( output ); | ||
} ); | ||
it( 'should keep some attributes', () => { | ||
const input = '<a href="#keep" target="_blank">test</a>'; | ||
const output = '<a href="#keep" target="_blank">test</a>'; | ||
expect( removeInvalidHTML( input, schema ) ).toBe( output ); | ||
} ); | ||
it( 'should keep some classes', () => { | ||
const input = '<figure><img class="alignleft test" src=""></figure>'; | ||
const output = '<figure><img class="alignleft" src=""></figure>'; | ||
expect( removeInvalidHTML( input, schema ) ).toBe( output ); | ||
} ); | ||
it( 'should remove empty nodes that should have children', () => { | ||
const input = '<figure> </figure>'; | ||
const output = ''; | ||
expect( removeInvalidHTML( input, schema ) ).toBe( output ); | ||
} ); | ||
it( 'should break up block content with phrasing schema', () => { | ||
const input = '<p>test</p><p>test</p>'; | ||
const output = 'test<br>test'; | ||
expect( removeInvalidHTML( input, phrasingContentSchema, true ) ).toBe( | ||
output | ||
); | ||
} ); | ||
it( 'should unwrap node that does not satisfy require', () => { | ||
const input = | ||
'<figure><p>test</p><figcaption>test</figcaption></figure>'; | ||
const output = '<p>test</p>test'; | ||
expect( removeInvalidHTML( input, schema ) ).toBe( output ); | ||
} ); | ||
it( 'should remove invalid phrasing content', () => { | ||
const input = '<strong><p>test</p></strong>'; | ||
const output = '<p>test</p>'; | ||
expect( removeInvalidHTML( input, schema ) ).toEqual( output ); | ||
} ); | ||
} ); | ||
describe( 'isEmpty', () => { | ||
function isEmptyHTML( HTML ) { | ||
const doc = document.implementation.createHTMLDocument( '' ); | ||
doc.body.innerHTML = HTML; | ||
return isEmpty( doc.body ); | ||
} | ||
it( 'should return true for empty element', () => { | ||
expect( isEmptyHTML( '' ) ).toBe( true ); | ||
} ); | ||
it( 'should return true for element with only whitespace', () => { | ||
expect( isEmptyHTML( ' ' ) ).toBe( true ); | ||
} ); | ||
it( 'should return true for element with non breaking space', () => { | ||
expect( isEmptyHTML( ' ' ) ).toBe( true ); | ||
} ); | ||
it( 'should return true for element with BR', () => { | ||
expect( isEmptyHTML( '<br>' ) ).toBe( true ); | ||
} ); | ||
it( 'should return true for element with empty element', () => { | ||
expect( isEmptyHTML( '<em></em>' ) ).toBe( true ); | ||
} ); | ||
it( 'should return false for element with image', () => { | ||
expect( isEmptyHTML( '<img src="">' ) ).toBe( false ); | ||
} ); | ||
it( 'should return true for element with mixed empty pieces', () => { | ||
expect( isEmptyHTML( ' <br><br><em> </em>' ) ).toBe( true ); | ||
} ); | ||
} ); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
318083
33
4219
330
4
Updatedlodash@^4.17.19