: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
type: "Comment" /* Comment */,
Tokenizer.prototype.appendToCommentData = function (char) {
this.current("Comment" /* Comment */).chars += char;
Tokenizer.prototype.finishComment = function () {
Tokenizer.prototype.tagOpen = function () { };
Tokenizer.prototype.beginStartTag = function () {
type: "StartTag" /* StartTag */,
Tokenizer.prototype.beginEndTag = function () {
type: "EndTag" /* EndTag */,
Tokenizer.prototype.finishTag = function () {
Tokenizer.prototype.markTagAsSelfClosing = function () {
this.current("StartTag" /* StartTag */).selfClosing = true;
Tokenizer.prototype.appendToTagName = function (char) {
this.current("StartTag" /* StartTag */, "EndTag" /* EndTag */).tagName += char;
Tokenizer.prototype.beginAttribute = function () {
this._currentAttribute = ['', '', false];
Tokenizer.prototype.appendToAttributeName = function (char) {
this.currentAttribute()[0] += char;
Tokenizer.prototype.beginAttributeValue = function (isQuoted) {
this.currentAttribute()[2] = isQuoted;
Tokenizer.prototype.appendToAttributeValue = function (char) {
this.currentAttribute()[1] += char;
Tokenizer.prototype.finishAttributeValue = function () {
this.current("StartTag" /* StartTag */).attributes.push(this._currentAttribute);
Tokenizer.prototype.reportSyntaxError = function (message) {
this.current().syntaxError = message;
function tokenize(input, options) {
var tokenizer = new Tokenizer(new EntityParser(namedCharRefs), options);
return tokenizer.tokenize(input);
// EXTERNAL MODULE: ./node_modules/fast-deep-equal/es6/index.js
var es6 = __webpack_require__(7734);
var es6_default = /*#__PURE__*/__webpack_require__.n(es6);
;// CONCATENATED MODULE: external ["wp","htmlEntities"]
const external_wp_htmlEntities_namespaceObject = window["wp"]["htmlEntities"];
;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/validation/logger.js
* @property {Function} log Which logger recorded the message
* @property {Array<any>} args White arguments were supplied to the logger
function createLogger() {
* Creates a log handler with block validation prefix.
* @param {Function} logger Original logger function.
* @return {Function} Augmented logger function.
function createLogHandler(logger) {
let log = (message, ...args) => logger('Block validation: ' + message, ...args);
// In test environments, pre-process string substitutions to improve
// readability of error messages. We'd prefer to avoid pulling in this
// dependency in runtime environments, and it can be dropped by a combo
// of Webpack env substitution + UglifyJS dead code elimination.
// eslint-disable-next-line no-console
error: createLogHandler(console.error),
// eslint-disable-next-line no-console
warning: createLogHandler(console.warn),
function createQueuedLogger() {
* The list of enqueued log actions to print.
* @type {Array<LoggerItem>}
const logger = createLogger();
;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/validation/index.js
/** @typedef {import('../parser').WPBlock} WPBlock */
/** @typedef {import('../registration').WPBlockType} WPBlockType */
/** @typedef {import('./logger').LoggerItem} LoggerItem */
* Globally matches any consecutive whitespace
const REGEXP_WHITESPACE = /[\t\n\r\v\f ]+/g;
* Matches a string containing only whitespace
const REGEXP_ONLY_WHITESPACE = /^[\t\n\r\v\f ]*$/;
* Matches a CSS URL type value
const REGEXP_STYLE_URL_TYPE = /^url\s*\(['"\s]*(.*?)['"\s]*\)$/;
* Boolean attributes are attributes whose presence as being assigned is
* meaningful, even if only empty.
* See: https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#boolean-attributes
* Extracted from: https://html.spec.whatwg.org/multipage/indices.html#attributes-3
* Object.keys( Array.from( document.querySelectorAll( '#attributes-1 > tbody > tr' ) )
* .filter( ( tr ) => tr.lastChild.textContent.indexOf( 'Boolean attribute' ) !== -1 )
* .reduce( ( result, tr ) => Object.assign( result, {
* [ tr.firstChild.textContent.trim() ]: true
const BOOLEAN_ATTRIBUTES = ['allowfullscreen', 'allowpaymentrequest', 'allowusermedia', 'async', 'autofocus', 'autoplay', 'checked', 'controls', 'default', 'defer', 'disabled', 'download', 'formnovalidate', 'hidden', 'ismap', 'itemscope', 'loop', 'multiple', 'muted', 'nomodule', 'novalidate', 'open', 'playsinline', 'readonly', 'required', 'reversed', 'selected', 'typemustmatch'];
* Enumerated attributes are attributes which must be of a specific value form.
* Like boolean attributes, these are meaningful if specified, even if not of a
* valid enumerated value.
* See: https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#enumerated-attribute
* Extracted from: https://html.spec.whatwg.org/multipage/indices.html#attributes-3
* Object.keys( Array.from( document.querySelectorAll( '#attributes-1 > tbody > tr' ) )
* .filter( ( tr ) => /^("(.+?)";?\s*)+/.test( tr.lastChild.textContent.trim() ) )
* .reduce( ( result, tr ) => Object.assign( result, {
* [ tr.firstChild.textContent.trim() ]: true
const ENUMERATED_ATTRIBUTES = ['autocapitalize', 'autocomplete', 'charset', 'contenteditable', 'crossorigin', 'decoding', 'dir', 'draggable', 'enctype', 'formenctype', 'formmethod', 'http-equiv', 'inputmode', 'kind', 'method', 'preload', 'scope', 'shape', 'spellcheck', 'translate', 'type', 'wrap'];
* Meaningful attributes are those who cannot be safely ignored when omitted in
* one HTML markup string and not another.
const MEANINGFUL_ATTRIBUTES = [...BOOLEAN_ATTRIBUTES, ...ENUMERATED_ATTRIBUTES];
* Array of functions which receive a text string on which to apply normalizing
* behavior for consideration in text token equivalence, carefully ordered from
* least-to-most expensive operations.
const TEXT_NORMALIZATIONS = [identity, getTextWithCollapsedWhitespace];
* Regular expression matching a named character reference. In lieu of bundling
* a full set of references, the pattern covers the minimal necessary to test
* positively against the full set.
* "The ampersand must be followed by one of the names given in the named
* character references section, using the same case."
* Tested aginst "12.5 Named character references":
* const references = Array.from( document.querySelectorAll(
* '#named-character-references-table tr[id^=entity-] td:first-child'
* ) ).map( ( code ) => code.textContent )
* references.every( ( reference ) => /^[\da-z]+$/i.test( reference ) )
* @see https://html.spec.whatwg.org/multipage/syntax.html#character-references
* @see https://html.spec.whatwg.org/multipage/named-characters.html#named-character-references
const REGEXP_NAMED_CHARACTER_REFERENCE = /^[\da-z]+$/i;
* Regular expression matching a decimal character reference.
* "The ampersand must be followed by a U+0023 NUMBER SIGN character (#),
* followed by one or more ASCII digits, representing a base-ten integer"
* @see https://html.spec.whatwg.org/multipage/syntax.html#character-references
const REGEXP_DECIMAL_CHARACTER_REFERENCE = /^#\d+$/;
* Regular expression matching a hexadecimal character reference.
* "The ampersand must be followed by a U+0023 NUMBER SIGN character (#), which
* must be followed by either a U+0078 LATIN SMALL LETTER X character (x) or a
* U+0058 LATIN CAPITAL LETTER X character (X), which must then be followed by
* one or more ASCII hex digits, representing a hexadecimal integer"
* @see https://html.spec.whatwg.org/multipage/syntax.html#character-references
const REGEXP_HEXADECIMAL_CHARACTER_REFERENCE = /^#x[\da-f]+$/i;
* Returns true if the given string is a valid character reference segment, or
* false otherwise. The text should be stripped of `&` and `;` demarcations.
* @param {string} text Text to test.
* @return {boolean} Whether text is valid character reference.
function isValidCharacterReference(text) {
return REGEXP_NAMED_CHARACTER_REFERENCE.test(text) || REGEXP_DECIMAL_CHARACTER_REFERENCE.test(text) || REGEXP_HEXADECIMAL_CHARACTER_REFERENCE.test(text);
* Subsitute EntityParser class for `simple-html-tokenizer` which uses the
* implementation of `decodeEntities` from `html-entities`, in order to avoid
* bundling a massive named character reference.
* @see https://github.com/tildeio/simple-html-tokenizer/tree/HEAD/src/entity-parser.ts
class DecodeEntityParser {
* Returns a substitute string for an entity string sequence between `&`
* and `;`, or undefined if no substitution should occur.
* @param {string} entity Entity fragment discovered in HTML.
* @return {string | undefined} Entity substitute value.
if (isValidCharacterReference(entity)) {
return (0,external_wp_htmlEntities_namespaceObject.decodeEntities)('&' + entity + ';');
* Given a specified string, returns an array of strings split by consecutive
* whitespace, ignoring leading or trailing whitespace.
* @param {string} text Original text.
* @return {string[]} Text pieces split on whitespace.
function getTextPiecesSplitOnWhitespace(text) {
return text.trim().split(REGEXP_WHITESPACE);
* Given a specified string, returns a new trimmed string where all consecutive
* whitespace is collapsed to a single space.
* @param {string} text Original text.
* @return {string} Trimmed text with consecutive whitespace collapsed.
function getTextWithCollapsedWhitespace(text) {
// This is an overly simplified whitespace comparison. The specification is
// more prescriptive of whitespace behavior in inline and block contexts.
// See: https://medium.com/@patrickbrosset/when-does-white-space-matter-in-html-b90e8a7cdd33
return getTextPiecesSplitOnWhitespace(text).join(' ');
* Returns attribute pairs of the given StartTag token, including only pairs
* where the value is non-empty or the attribute is a boolean attribute, an
* enumerated attribute, or a custom data- attribute.
* @see MEANINGFUL_ATTRIBUTES
* @param {Object} token StartTag token.
* @return {Array[]} Attribute pairs.
function getMeaningfulAttributePairs(token) {
return token.attributes.filter(pair => {
const [key, value] = pair;
return value || key.indexOf('data-') === 0 || MEANINGFUL_ATTRIBUTES.includes(key);
* Returns true if two text tokens (with `chars` property) are equivalent, or
* @param {Object} actual Actual token.
* @param {Object} expected Expected token.
* @param {Object} logger Validation logger object.
* @return {boolean} Whether two text tokens are equivalent.
function isEquivalentTextTokens(actual, expected, logger = createLogger()) {
// This function is intentionally written as syntactically "ugly" as a hot
// path optimization. Text is progressively normalized in order from least-
// to-most operationally expensive, until the earliest point at which text
// can be confidently inferred as being equal.
let actualChars = actual.chars;
let expectedChars = expected.chars;
for (let i = 0; i < TEXT_NORMALIZATIONS.length; i++) {
const normalize = TEXT_NORMALIZATIONS[i];
actualChars = normalize(actualChars);
expectedChars = normalize(expectedChars);
if (actualChars === expectedChars) {
logger.warning('Expected text `%s`, saw `%s`.', expected.chars, actual.chars);
* Given a CSS length value, returns a normalized CSS length value for strict equality
* @param {string} value CSS length value.
* @return {string} Normalized CSS length value.
function getNormalizedLength(value) {
if (0 === parseFloat(value)) {
// Normalize strings with floats to always include a leading zero.
if (value.indexOf('.') === 0) {
* Given a style value, returns a normalized style value for strict equality
* @param {string} value Style value.
* @return {string} Normalized style value.
function getNormalizedStyleValue(value) {
const textPieces = getTextPiecesSplitOnWhitespace(value);
const normalizedPieces = textPieces.map(getNormalizedLength);
const result = normalizedPieces.join(' ');
// Normalize URL type to omit whitespace or quotes.
.replace(REGEXP_STYLE_URL_TYPE, 'url($1)');
* Given a style attribute string, returns an object of style properties.
* @param {string} text Style attribute.
* @return {Object} Style properties.
function getStyleProperties(text) {
// Trim ending semicolon (avoid including in split)
// Split on property assignment.
// For each property assignment...
// ...split further into key-value pairs.
const [key, ...valueParts] = style.split(':');
const value = valueParts.join(':');
return [key.trim(), getNormalizedStyleValue(value.trim())];
return Object.fromEntries(pairs);
* Attribute-specific equality handlers
const isEqualAttributesOfName = {
class: (actual, expected) => {
// Class matches if members are the same, even if out of order or
// superfluous whitespace between.
const [actualPieces, expectedPieces] = [actual, expected].map(getTextPiecesSplitOnWhitespace);
const actualDiff = actualPieces.filter(c => !expectedPieces.includes(c));
const expectedDiff = expectedPieces.filter(c => !actualPieces.includes(c));
return actualDiff.length === 0 && expectedDiff.length === 0;
style: (actual, expected) => {
return es6_default()(...[actual, expected].map(getStyleProperties));
// For each boolean attribute, mere presence of attribute in both is enough
// to assume equivalence.
...Object.fromEntries(BOOLEAN_ATTRIBUTES.map(attribute => [attribute, () => true]))
* Given two sets of attribute tuples, returns true if the attribute sets are
* @param {Array[]} actual Actual attributes tuples.
* @param {Array[]} expected Expected attributes tuples.
* @param {Object} logger Validation logger object.
* @return {boolean} Whether attributes are equivalent.
function isEqualTagAttributePairs(actual, expected, logger = createLogger()) {
// Attributes is tokenized as tuples. Their lengths should match. This also
// avoids us needing to check both attributes sets, since if A has any keys
// which do not exist in B, we know the sets to be different.
if (actual.length !== expected.length) {
logger.warning('Expected attributes %o, instead saw %o.', expected, actual);
// Attributes are not guaranteed to occur in the same order. For validating
// actual attributes, first convert the set of expected attribute values to
// an object, for lookup by key.
const expectedAttributes = {};
for (let i = 0; i < expected.length; i++) {
expectedAttributes[expected[i][0].toLowerCase()] = expected[i][1];
for (let i = 0; i < actual.length; i++) {