if (actualToken.type !== expectedToken.type) {
logger.warning('Expected token of type `%s` (%o), instead saw `%s` (%o).', expectedToken.type, expectedToken, actualToken.type, actualToken);
} // Defer custom token type equality handling, otherwise continue and
var isEqualTokens = isEqualTokensOfType[actualToken.type];
if (isEqualTokens && !isEqualTokens(actualToken, expectedToken, logger)) {
} // Peek at the next tokens (actual and expected) to see if they close
if (isClosedByToken(actualToken, expectedTokens[0])) {
// Consume the next expected token that closes the current actual
getNextNonWhitespaceToken(expectedTokens);
} else if (isClosedByToken(expectedToken, actualTokens[0])) {
// Consume the next actual token that closes the current expected
getNextNonWhitespaceToken(actualTokens);
if (expectedToken = getNextNonWhitespaceToken(expectedTokens)) {
// If any non-whitespace tokens remain in expected token set, this
logger.warning('Expected %o, instead saw end of content.', expectedToken);
* Returns an object with `isValid` property set to `true` if the parsed block
* is valid given the input content. A block is considered valid if, when serialized
* with assumed attributes, the content matches the original value. If block is
* invalid, this function returns all validations issues as well.
* @param {string|Object} blockTypeOrName Block type.
* @param {Object} attributes Parsed block attributes.
* @param {string} originalBlockContent Original block content.
* @param {Object} logger Validation logger object.
* @return {Object} Whether block is valid and contains validation messages.
function getBlockContentValidationResult(blockTypeOrName, attributes, originalBlockContent) {
var logger = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : createQueuedLogger();
var blockType = normalizeBlockType(blockTypeOrName);
var generatedBlockContent;
generatedBlockContent = getSaveContent(blockType, attributes);
logger.error('Block validation failed because an error occurred while generating block content:\n\n%s', error.toString());
validationIssues: logger.getItems()
var isValid = isEquivalentHTML(originalBlockContent, generatedBlockContent, logger);
logger.error('Block validation failed for `%s` (%o).\n\nContent generated by `save` function:\n\n%s\n\nContent retrieved from post body:\n\n%s', blockType.name, blockType, generatedBlockContent, originalBlockContent);
validationIssues: logger.getItems()
* Returns true if the parsed block is valid given the input content. A block
* is considered valid if, when serialized with assumed attributes, the content
* matches the original value.
* Logs to console in development environments when invalid.
* @param {string|Object} blockTypeOrName Block type.
* @param {Object} attributes Parsed block attributes.
* @param {string} originalBlockContent Original block content.
* @return {boolean} Whether block is valid.
function isValidBlockContent(blockTypeOrName, attributes, originalBlockContent) {
var _getBlockContentValid = getBlockContentValidationResult(blockTypeOrName, attributes, originalBlockContent, createLogger()),
isValid = _getBlockContentValid.isValid;
// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/matchers.js
function matchers_html(selector, multilineTag) {
return function (domNode) {
match = domNode.querySelector(selector);
var length = match.children.length;
for (var index = 0; index < length; index++) {
var child = match.children[index];
if (child.nodeName.toLowerCase() !== multilineTag) {
value += child.outerHTML;
// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/node.js
function node_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 node_objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { node_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 { node_ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
* A representation of a single node within a block's rich text value. If
* representing a text node, the value is simply a string of the node value.
* As representing an element node, it is an object of:
* 1. `type` (string): Tag name.
* 2. `props` (object): Attributes and children array of WPBlockNode.
* @typedef {string|Object} WPBlockNode
* Given a single node and a node type (e.g. `'br'`), returns true if the node
* corresponds to that type, false otherwise.
* @param {WPBlockNode} node Block node to test
* @param {string} type Node to type to test against.
* @return {boolean} Whether node is of intended type.
function isNodeOfType(node, type) {
return node && node.type === type;
* Given an object implementing the NamedNodeMap interface, returns a plain
* object equivalent value of name, value key-value pairs.
* @see https://dom.spec.whatwg.org/#interface-namednodemap
* @param {NamedNodeMap} nodeMap NamedNodeMap to convert to object.
* @return {Object} Object equivalent value of NamedNodeMap.
function getNamedNodeMapAsObject(nodeMap) {
for (var i = 0; i < nodeMap.length; i++) {
var _nodeMap$i = nodeMap[i],
value = _nodeMap$i.value;
* Given a DOM Element or Text node, returns an equivalent block node. Throws
* if passed any node type other than element or text.
* @throws {TypeError} If non-element/text node is passed.
* @param {Node} domNode DOM node to convert.
* @return {WPBlockNode} Block node equivalent to DOM node.
function fromDOM(domNode) {
if (domNode.nodeType === domNode.TEXT_NODE) {
return domNode.nodeValue;
if (domNode.nodeType !== domNode.ELEMENT_NODE) {
throw new TypeError('A block node can only be created from a node of type text or ' + 'element.');
type: domNode.nodeName.toLowerCase(),
props: node_objectSpread(node_objectSpread({}, getNamedNodeMapAsObject(domNode.attributes)), {}, {
children: children_fromDOM(domNode.childNodes)
* Given a block node, returns its HTML string representation.
* @param {WPBlockNode} node Block node to convert to string.
* @return {string} String HTML representation of block node.
return children_toHTML([node]);
* Given a selector, returns an hpq matcher generating a WPBlockNode value
* matching the selector result.
* @param {string} selector DOM selector.
* @return {Function} hpq matcher.
function node_matcher(selector) {
return function (domNode) {
match = domNode.querySelector(selector);
* Object of utility functions used in managing block attribute values of
* @see https://github.com/WordPress/gutenberg/pull/10439
* @deprecated since 4.0. The `node` source should not be used, and can be
* replaced by the `html` source.
/* harmony default export */ var api_node = ({
isNodeOfType: isNodeOfType,
// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/children.js
* A representation of a block's rich text value.
* @typedef {WPBlockNode[]} WPBlockChildren
* Given block children, returns a serialize-capable WordPress element.
* @param {WPBlockChildren} children Block children object to convert.
* @return {WPElement} A serialize-capable element.
function getSerializeCapableElement(children) {
// The fact that block children are compatible with the element serializer is
// merely an implementation detail that currently serves to be true, but
// should not be mistaken as being a guarantee on the external API. The
// public API only offers guarantees to work with strings (toHTML) and DOM
// elements (fromDOM), and should provide utilities to manipulate the value
// rather than expect consumers to inspect or construct its shape (concat).
* Given block children, returns an array of block nodes.
* @param {WPBlockChildren} children Block children object to convert.
* @return {Array<WPBlockNode>} An array of individual block nodes.
function getChildrenArray(children) {
// The fact that block children are compatible with the element serializer
// is merely an implementation detail that currently serves to be true, but
// should not be mistaken as being a guarantee on the external API.
* Given two or more block nodes, returns a new block node representing a
* concatenation of its values.
* @param {...WPBlockChildren} blockNodes Block nodes to concatenate.
* @return {WPBlockChildren} Concatenated block node.
for (var i = 0; i < arguments.length; i++) {
var blockNode = Object(external_lodash_["castArray"])(i < 0 || arguments.length <= i ? undefined : arguments[i]);
for (var j = 0; j < blockNode.length; j++) {
var child = blockNode[j];
var canConcatToPreviousString = typeof child === 'string' && typeof result[result.length - 1] === 'string';
if (canConcatToPreviousString) {
result[result.length - 1] += child;
* Given an iterable set of DOM nodes, returns equivalent block children.
* Ignores any non-element/text nodes included in set.
* @param {Iterable.<Node>} domNodes Iterable set of DOM nodes to convert.
* @return {WPBlockChildren} Block children equivalent to DOM nodes.
function children_fromDOM(domNodes) {
for (var i = 0; i < domNodes.length; i++) {
result.push(fromDOM(domNodes[i]));
} catch (error) {// Simply ignore if DOM node could not be converted.
* Given a block node, returns its HTML string representation.
* @param {WPBlockChildren} children Block node(s) to convert to string.
* @return {string} String HTML representation of block node.
function children_toHTML(children) {
var element = getSerializeCapableElement(children);
return Object(external_wp_element_["renderToString"])(element);
* Given a selector, returns an hpq matcher generating a WPBlockChildren value
* matching the selector result.
* @param {string} selector DOM selector.
* @return {Function} hpq matcher.
function children_matcher(selector) {
return function (domNode) {
match = domNode.querySelector(selector);
return children_fromDOM(match.childNodes);
* Object of utility functions used in managing block attribute values of
* @see https://github.com/WordPress/gutenberg/pull/10439
* @deprecated since 4.0. The `children` source should not be used, and can be
* replaced by the `html` source.
/* harmony default export */ var api_children = ({
getChildrenArray: getChildrenArray,
fromDOM: children_fromDOM,
matcher: children_matcher
// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/parser.js
function parser_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 parser_objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { parser_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 { parser_ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
* Sources which are guaranteed to return a string value.
var STRING_SOURCES = new Set(['attribute', 'html', 'text', 'tag']);
* Higher-order hpq matcher which enhances an attribute matcher to return true
* or false depending on whether the original matcher returns undefined. This
* is useful for boolean attributes (e.g. disabled) whose attribute values may
* be technically falsey (empty string), though their mere presence should be
* enough to infer as true.
* @param {Function} matcher Original hpq matcher.
* @return {Function} Enhanced hpq matcher.
var parser_toBooleanAttributeMatcher = function toBooleanAttributeMatcher(matcher) {
return Object(external_lodash_["flow"])([matcher, // Expected values from `attr( 'disabled' )`:
// - Transformed: `false`