return log.apply(void 0, Object(toConsumableArray["a" /* default */])(args));
* Serializes a block node into the native HTML-comment-powered block format.
* CAVEAT: This function is intended for reserializing blocks as parsed by
* valid parsers and skips any validation steps. This is NOT a generic
* serialization function for in-memory blocks. For most purposes, see the
* following functions available in the `@wordpress/blocks` package:
* For more on the format of block nodes as returned by valid parsers:
* @see `@wordpress/block-serialization-default-parser` package
* @see `@wordpress/block-serialization-spec-parser` package
* @param {Object} blockNode A block node as returned by a valid parser.
* @param {?Object} options Serialization options.
* @param {?boolean} options.isCommentDelimited Whether to output HTML comments around blocks.
* @return {string} An HTML string representing a block.
function serializeBlockNode(blockNode) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var _options$isCommentDel = options.isCommentDelimited,
isCommentDelimited = _options$isCommentDel === void 0 ? true : _options$isCommentDel;
var blockName = blockNode.blockName,
_blockNode$attrs = blockNode.attrs,
attrs = _blockNode$attrs === void 0 ? {} : _blockNode$attrs,
_blockNode$innerBlock2 = blockNode.innerBlocks,
innerBlocks = _blockNode$innerBlock2 === void 0 ? [] : _blockNode$innerBlock2,
_blockNode$innerConte = blockNode.innerContent,
innerContent = _blockNode$innerConte === void 0 ? [] : _blockNode$innerConte;
var content = innerContent.map(function (item) {
return (// `null` denotes a nested block, otherwise we have an HTML fragment.
item !== null ? item : serializeBlockNode(innerBlocks[childIndex++], options)
}).join('\n').replace(/\n+/g, '\n').trim();
return isCommentDelimited ? getCommentDelimitedContent(blockName, attrs, content) : content;
* Creates a parse implementation for the post content which returns a list of blocks.
* @param {Function} parseImplementation Parse implementation.
* @return {Function} An implementation which parses the post content.
var createParse = function createParse(parseImplementation) {
return function (content) {
return parseImplementation(content).reduce(function (accumulator, blockNode) {
var block = createBlockWithFallback(blockNode);
* Utilizes an optimized token-driven parser based on the Gutenberg grammar spec
* defined through a parsing expression grammar to take advantage of the regular
* cadence provided by block delimiters -- composed syntactically through HTML
* comments -- which, given a general HTML document as an input, returns a block
* list array representation.
* This is a recursive-descent parser that scans linearly once through the input
* document. Instead of directly recursing it utilizes a trampoline mechanism to
* prevent stack overflow. This initial pass is mainly interested in separating
* and isolating the blocks serialized in the document and manifestly not in the
* content within the blocks.
* https://developer.wordpress.org/block-editor/packages/packages-block-serialization-default-parser/
* @param {string} content The post content.
* @return {Array} Block list.
var parseWithGrammar = createParse(external_wp_blockSerializationDefaultParser_["parse"]);
/* harmony default export */ var parser = (parseWithGrammar);
// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/get-raw-transforms.js
function get_raw_transforms_ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
function get_raw_transforms_objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { get_raw_transforms_ownKeys(Object(source), true).forEach(function (key) { Object(defineProperty["a" /* default */])(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { get_raw_transforms_ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
function getRawTransforms() {
return Object(external_lodash_["filter"])(getBlockTransforms('from'), {
}).map(function (transform) {
return transform.isMatch ? transform : get_raw_transforms_objectSpread(get_raw_transforms_objectSpread({}, transform), {}, {
isMatch: function isMatch(node) {
return transform.selector && node.matches(transform.selector);
// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/html-to-blocks.js
* Converts HTML directly to blocks. Looks for a matching transform for each
* top-level tag. The HTML should be filtered to not have any text between
* top-level tags and formatted in a way that blocks can handle the HTML.
* @param {string} html HTML to convert.
* @return {Array} An array of blocks.
function htmlToBlocks(html) {
var doc = document.implementation.createHTMLDocument('');
doc.body.innerHTML = html;
return Array.from(doc.body.children).flatMap(function (node) {
var rawTransform = findTransform(getRawTransforms(), function (_ref) {
var isMatch = _ref.isMatch;
return createBlock( // Should not be hardcoded.
'core/html', getBlockAttributes('core/html', node.outerHTML));
var transform = rawTransform.transform,
blockName = rawTransform.blockName;
return createBlock(blockName, getBlockAttributes(blockName, node.outerHTML));
// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/normalise-blocks.js
function normaliseBlocks(HTML) {
var decuDoc = document.implementation.createHTMLDocument('');
var accuDoc = document.implementation.createHTMLDocument('');
while (decu.firstChild) {
var node = decu.firstChild; // Text nodes: wrap in a paragraph, or append to previous.
if (node.nodeType === node.TEXT_NODE) {
if (!node.nodeValue.trim()) {
if (!accu.lastChild || accu.lastChild.nodeName !== 'P') {
accu.appendChild(accuDoc.createElement('P'));
accu.lastChild.appendChild(node);
} else if (node.nodeType === node.ELEMENT_NODE) {
// BR nodes: create a new paragraph on double, or append to previous.
if (node.nodeName === 'BR') {
if (node.nextSibling && node.nextSibling.nodeName === 'BR') {
accu.appendChild(accuDoc.createElement('P'));
decu.removeChild(node.nextSibling);
} // Don't append to an empty paragraph.
if (accu.lastChild && accu.lastChild.nodeName === 'P' && accu.lastChild.hasChildNodes()) {
accu.lastChild.appendChild(node);
} else if (node.nodeName === 'P') {
// Only append non-empty paragraph nodes.
if (Object(external_wp_dom_["isEmpty"])(node)) {
} else if (Object(external_wp_dom_["isPhrasingContent"])(node)) {
if (!accu.lastChild || accu.lastChild.nodeName !== 'P') {
accu.appendChild(accuDoc.createElement('P'));
accu.lastChild.appendChild(node);
// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/special-comment-converter.js
* Looks for `<!--nextpage-->` and `<!--more-->` comments, as well as the
* `<!--more Some text-->` variant and its `<!--noteaser-->` companion,
* and replaces them with a custom element representing a future block.
* The custom element is a way to bypass the rest of the `raw-handling`
* transforms, which would eliminate other kinds of node with which to carry
* `<!--more-->`'s data: nodes with `data` attributes, empty paragraphs, etc.
* The custom element is then expected to be recognized by any registered
* block's `raw` transform.
* @param {Node} node The node to be processed.
* @param {Document} doc The document of the node.
function specialCommentConverter(node, doc) {
if (node.nodeType !== node.COMMENT_NODE) {
if (node.nodeValue === 'nextpage') {
Object(external_wp_dom_["replace"])(node, createNextpage(doc));
if (node.nodeValue.indexOf('more') === 0) {
// Grab any custom text in the comment.
var customText = node.nodeValue.slice(4).trim();
* When a `<!--more-->` comment is found, we need to look for any
* `<!--noteaser-->` sibling, but it may not be a direct sibling
* (whitespace typically lies in between)
while (sibling = sibling.nextSibling) {
if (sibling.nodeType === sibling.COMMENT_NODE && sibling.nodeValue === 'noteaser') {
Object(external_wp_dom_["remove"])(sibling);
Object(external_wp_dom_["replace"])(node, createMore(customText, noTeaser, doc));
function createMore(customText, noTeaser, doc) {
var node = doc.createElement('wp-block');
node.dataset.block = 'core/more';
node.dataset.customText = customText;
// "Boolean" data attribute
node.dataset.noTeaser = '';
function createNextpage(doc) {
var node = doc.createElement('wp-block');
node.dataset.block = 'core/nextpage';
// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/comment-remover.js
* Looks for comments, and removes them.
* @param {Node} node The node to be processed.
function commentRemover(node) {
if (node.nodeType === node.COMMENT_NODE) {
Object(external_wp_dom_["remove"])(node);
// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/is-inline-content.js
* Checks if the given node should be considered inline content, optionally
* depending on a context tag.
* @param {Node} node Node name.
* @param {string} contextTag Tag name.
* @return {boolean} True if the node is inline content, false if nohe.
function isInline(node, contextTag) {
if (Object(external_wp_dom_["isTextContent"])(node)) {
var tag = node.nodeName.toLowerCase();
var inlineAllowedTagGroups = [['ul', 'li', 'ol'], ['h1', 'h2', 'h3', 'h4', 'h5', 'h6']];
return inlineAllowedTagGroups.some(function (tagGroup) {
return Object(external_lodash_["difference"])([tag, contextTag], tagGroup).length === 0;
function deepCheck(nodes, contextTag) {
return nodes.every(function (node) {
return isInline(node, contextTag) && deepCheck(Array.from(node.children), contextTag);
function isDoubleBR(node) {
return node.nodeName === 'BR' && node.previousSibling && node.previousSibling.nodeName === 'BR';
function isInlineContent(HTML, contextTag) {
var doc = document.implementation.createHTMLDocument('');
doc.body.innerHTML = HTML;
var nodes = Array.from(doc.body.children);
return !nodes.some(isDoubleBR) && deepCheck(nodes, contextTag);
// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/phrasing-content-reducer.js
function phrasingContentReducer(node, doc) {
// In jsdom-jscore, 'node.style' can be null.
// TODO: Explore fixing this by patching jsdom-jscore.
if (node.nodeName === 'SPAN' && node.style) {
var _node$style = node.style,
fontWeight = _node$style.fontWeight,
fontStyle = _node$style.fontStyle,
textDecorationLine = _node$style.textDecorationLine,
textDecoration = _node$style.textDecoration,
verticalAlign = _node$style.verticalAlign;
if (fontWeight === 'bold' || fontWeight === '700') {
Object(external_wp_dom_["wrap"])(doc.createElement('strong'), node);
if (fontStyle === 'italic') {
Object(external_wp_dom_["wrap"])(doc.createElement('em'), node);
} // Some DOM implementations (Safari, JSDom) don't support
// style.textDecorationLine, so we check style.textDecoration as a
if (textDecorationLine === 'line-through' || Object(external_lodash_["includes"])(textDecoration, 'line-through')) {
Object(external_wp_dom_["wrap"])(doc.createElement('s'), node);
if (verticalAlign === 'super') {
Object(external_wp_dom_["wrap"])(doc.createElement('sup'), node);
} else if (verticalAlign === 'sub') {
Object(external_wp_dom_["wrap"])(doc.createElement('sub'), node);
} else if (node.nodeName === 'B') {
node = Object(external_wp_dom_["replaceTag"])(node, 'strong');
} else if (node.nodeName === 'I') {
node = Object(external_wp_dom_["replaceTag"])(node, 'em');
} else if (node.nodeName === 'A') {
// In jsdom-jscore, 'node.target' can be null.
// TODO: Explore fixing this by patching jsdom-jscore.
if (node.target && node.target.toLowerCase() === '_blank') {
node.rel = 'noreferrer noopener';
node.removeAttribute('target');
node.removeAttribute('rel');
// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/head-remover.js
function headRemover(node) {
if (node.nodeName !== 'SCRIPT' && node.nodeName !== 'NOSCRIPT' && node.nodeName !== 'TEMPLATE' && node.nodeName !== 'STYLE') {
node.parentNode.removeChild(node);
// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/ms-list-converter.js
ms_list_converter_parseInt = _window.parseInt;
return node.nodeName === 'OL' || node.nodeName === 'UL';
function msListConverter(node, doc) {
if (node.nodeName !== 'P') {
var style = node.getAttribute('style');
if (style.indexOf('mso-list') === -1) {
var matches = /mso-list\s*:[^;]+level([0-9]+)/i.exec(style);
var level = ms_list_converter_parseInt(matches[1], 10) - 1 || 0;
var prevNode = node.previousElementSibling; // Add new list if no previous.
if (!prevNode || !isList(prevNode)) {
// See https://html.spec.whatwg.org/multipage/grouping-content.html#attr-ol-type.
var type = node.textContent.trim().slice(0, 1);
var isNumeric = /[1iIaA]/.test(type);
var newListNode = doc.createElement(isNumeric ? 'ol' : 'ul');
newListNode.setAttribute('type', type);
node.parentNode.insertBefore(newListNode, node);
var listNode = node.previousElementSibling;
var listType = listNode.nodeName;
var listItem = doc.createElement('li');
var receivingNode = listNode; // Remove the first span with list info.
node.removeChild(node.firstElementChild); // Add content.