/******/ (() => { // webpackBootstrap /******/ "use strict"; /******/ // The require scope /******/ var __webpack_require__ = {}; /******/ /************************************************************************/ /******/ /* webpack/runtime/define property getters */ /******/ (() => { /******/ // define getter functions for harmony exports /******/ __webpack_require__.d = (exports, definition) => { /******/ for(var key in definition) { /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); /******/ } /******/ } /******/ }; /******/ })(); /******/ /******/ /* webpack/runtime/hasOwnProperty shorthand */ /******/ (() => { /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) /******/ })(); /******/ /******/ /* webpack/runtime/make namespace object */ /******/ (() => { /******/ // define __esModule on exports /******/ __webpack_require__.r = (exports) => { /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); /******/ } /******/ Object.defineProperty(exports, '__esModule', { value: true }); /******/ }; /******/ })(); /******/ /************************************************************************/ var __webpack_exports__ = {}; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ parse: () => (/* binding */ parse) /* harmony export */ }); /** * @type {string} */ let document; /** * @type {number} */ let offset; /** * @type {ParsedBlock[]} */ let output; /** * @type {ParsedFrame[]} */ let stack; /** * @typedef {Object|null} Attributes */ /** * @typedef {Object} ParsedBlock * @property {string|null} blockName Block name. * @property {Attributes} attrs Block attributes. * @property {ParsedBlock[]} innerBlocks Inner blocks. * @property {string} innerHTML Inner HTML. * @property {Array<string|null>} innerContent Inner content. */ /** * @typedef {Object} ParsedFrame * @property {ParsedBlock} block Block. * @property {number} tokenStart Token start. * @property {number} tokenLength Token length. * @property {number} prevOffset Previous offset. * @property {number|null} leadingHtmlStart Leading HTML start. */ /** * @typedef {'no-more-tokens'|'void-block'|'block-opener'|'block-closer'} TokenType */ /** * @typedef {[TokenType, string, Attributes, number, number]} Token */ /** * Matches block comment delimiters * * While most of this pattern is straightforward the attribute parsing * incorporates a tricks to make sure we don't choke on specific input * * - since JavaScript has no possessive quantifier or atomic grouping * we are emulating it with a trick * * we want a possessive quantifier or atomic group to prevent backtracking * on the `}`s should we fail to match the remainder of the pattern * * we can emulate this with a positive lookahead and back reference * (a++)*c === ((?=(a+))\1)*c * * let's examine an example: * - /(a+)*c/.test('aaaaaaaaaaaaad') fails after over 49,000 steps * - /(a++)*c/.test('aaaaaaaaaaaaad') fails after 85 steps * - /(?>a+)*c/.test('aaaaaaaaaaaaad') fails after 126 steps * * this is because the possessive `++` and the atomic group `(?>)` * tell the engine that all those `a`s belong together as a single group * and so it won't split it up when stepping backwards to try and match * * if we use /((?=(a+))\1)*c/ then we get the same behavior as the atomic group * or possessive and prevent the backtracking because the `a+` is matched but * not captured. thus, we find the long string of `a`s and remember it, then * reference it as a whole unit inside our pattern * * @see http://instanceof.me/post/52245507631/regex-emulate-atomic-grouping-with-lookahead * @see http://blog.stevenlevithan.com/archives/mimic-atomic-groups * @see https://javascript.info/regexp-infinite-backtracking-problem * * once browsers reliably support atomic grouping or possessive * quantifiers natively we should remove this trick and simplify * * @type {RegExp} * * @since 3.8.0 * @since 4.6.1 added optimization to prevent backtracking on attribute parsing */ const tokenizer = /<!--\s+(\/)?wp:([a-z][a-z0-9_-]*\/)?([a-z][a-z0-9_-]*)\s+({(?:(?=([^}]+|}+(?=})|(?!}\s+\/?-->)[^])*)\5|[^]*?)}\s+)?(\/)?-->/g; /** * Constructs a block object. * * @param {string|null} blockName * @param {Attributes} attrs * @param {ParsedBlock[]} innerBlocks * @param {string} innerHTML * @param {string[]} innerContent * @return {ParsedBlock} The block object. */ function Block(blockName, attrs, innerBlocks, innerHTML, innerContent) { return { blockName, attrs, innerBlocks, innerHTML, innerContent }; } /** * Constructs a freeform block object. * * @param {string} innerHTML * @return {ParsedBlock} The freeform block object. */ function Freeform(innerHTML) { return Block(null, {}, [], innerHTML, [innerHTML]); } /** * Constructs a frame object. * * @param {ParsedBlock} block * @param {number} tokenStart * @param {number} tokenLength * @param {number} prevOffset * @param {number|null} leadingHtmlStart * @return {ParsedFrame} The frame object. */ function Frame(block, tokenStart, tokenLength, prevOffset, leadingHtmlStart) { return { block, tokenStart, tokenLength, prevOffset: prevOffset || tokenStart + tokenLength, leadingHtmlStart }; } /** * Parser function, that converts input HTML into a block based structure. * * @param {string} doc The HTML document to parse. * * @example * Input post: * ```html * <!-- wp:columns {"columns":3} --> * <div class="wp-block-columns has-3-columns"><!-- wp:column --> * <div class="wp-block-column"><!-- wp:paragraph --> * <p>Left</p> * <!-- /wp:paragraph --></div> * <!-- /wp:column --> * * <!-- wp:column --> * <div class="wp-block-column"><!-- wp:paragraph --> * <p><strong>Middle</strong></p> * <!-- /wp:paragraph --></div> * <!-- /wp:column --> * * <!-- wp:column --> * <div class="wp-block-column"></div> * <!-- /wp:column --></div> * <!-- /wp:columns --> * ``` * * Parsing code: * ```js * import { parse } from '@wordpress/block-serialization-default-parser'; * * parse( post ) === [ * { * blockName: "core/columns", * attrs: { * columns: 3 * }, * innerBlocks: [ * { * blockName: "core/column", * attrs: null, * innerBlocks: [ * { * blockName: "core/paragraph", * attrs: null, * innerBlocks: [], * innerHTML: "\n<p>Left</p>\n" * } * ], * innerHTML: '\n<div class="wp-block-column"></div>\n' * }, * { * blockName: "core/column", * attrs: null, * innerBlocks: [ * { * blockName: "core/paragraph", * attrs: null, * innerBlocks: [], * innerHTML: "\n<p><strong>Middle</strong></p>\n" * } * ], * innerHTML: '\n<div class="wp-block-column"></div>\n' * }, * { * blockName: "core/column", * attrs: null, * innerBlocks: [], * innerHTML: '\n<div class="wp-block-column"></div>\n' * } * ], * innerHTML: '\n<div class="wp-block-columns has-3-columns">\n\n\n\n</div>\n' * } * ]; * ``` * @return {ParsedBlock[]} A block-based representation of the input HTML. */ const parse = doc => { document = doc; offset = 0; output = []; stack = []; tokenizer.lastIndex = 0; do { // twiddle our thumbs } while (proceed()); return output; }; /** * Parses the next token in the input document. * * @return {boolean} Returns true when there is more tokens to parse. */ function proceed() { const stackDepth = stack.length; const next = nextToken(); const [tokenType, blockName, attrs, startOffset, tokenLength] = next; // We may have some HTML soup before the next block. const leadingHtmlStart = startOffset > offset ? offset : null; switch (tokenType) { case 'no-more-tokens': // If not in a block then flush output. if (0 === stackDepth) { addFreeform(); return false; } // Otherwise we have a problem // This is an error // we have options // - treat it all as freeform text // - assume an implicit closer (easiest when not nesting) // For the easy case we'll assume an implicit closer. if (1 === stackDepth) { addBlockFromStack(); return false; } // For the nested case where it's more difficult we'll // have to assume that multiple closers are missing // and so we'll collapse the whole stack piecewise. while (0 < stack.length) { addBlockFromStack(); } return false; case 'void-block': // easy case is if we stumbled upon a void block // in the top-level of the document. if (0 === stackDepth) { if (null !== leadingHtmlStart) { output.push(Freeform(document.substr(leadingHtmlStart, startOffset - leadingHtmlStart))); } output.push(Block(blockName, attrs, [], '', [])); offset = startOffset + tokenLength; return true; } // Otherwise we found an inner block. addInnerBlock(Block(blockName, attrs, [], '', []), startOffset, tokenLength); offset = startOffset + tokenLength; return true; case 'block-opener': // Track all newly-opened blocks on the stack. stack.push(Frame(Block(blockName, attrs, [], '', []), startOffset, tokenLength, startOffset + tokenLength, leadingHtmlStart)); offset = startOffset + tokenLength; return true; case 'block-closer': // If we're missing an opener we're in trouble // This is an error. if (0 === stackDepth) { // We have options // - assume an implicit opener // - assume _this_ is the opener // - give up and close out the document. addFreeform(); return false; } // If we're not nesting then this is easy - close the block. if (1 === stackDepth) { addBlockFromStack(startOffset); offset = startOffset + tokenLength; return true; } // Otherwise we're nested and we have to close out the current // block and add it as a innerBlock to the parent. const stackTop = /** @type {ParsedFrame} */stack.pop(); const html = document.substr(stackTop.prevOffset, startOffset - stackTop.prevOffset); stackTop.block.innerHTML += html; stackTop.block.innerContent.push(html); stackTop.prevOffset = startOffset + tokenLength; addInnerBlock(stackTop.block, stackTop.tokenStart, stackTop.tokenLength, startOffset + tokenLength); offset = startOffset + tokenLength; return true; default: // This is an error. addFreeform(); return false; } } /** * Parse JSON if valid, otherwise return null * * Note that JSON coming from the block comment * delimiters is constrained to be an object * and cannot be things like `true` or `null` * * @param {string} input JSON input string to parse * @return {Object|null} parsed JSON if valid */ function parseJSON(input) { try { return JSON.parse(input); } catch (e) { return null; } } /** * Finds the next token in the document. * * @return {Token} The next matched token. */ function nextToken() { // Aye the magic // we're using a single RegExp to tokenize the block comment delimiters // we're also using a trick here because the only difference between a // block opener and a block closer is the leading `/` before `wp:` (and // a closer has no attributes). we can trap them both and process the // match back in JavaScript to see which one it was. const matches = tokenizer.exec(document); // We have no more tokens. if (null === matches) { return ['no-more-tokens', '', null, 0, 0]; } const startedAt = matches.index; const [match, closerMatch, namespaceMatch, nameMatch, attrsMatch /* Internal/unused. */,, voidMatch] = matches; const length = match.length; const isCloser = !!closerMatch; const isVoid = !!voidMatch; const namespace = namespaceMatch || 'core/'; const name = namespace + nameMatch; const hasAttrs = !!attrsMatch; const attrs = hasAttrs ? parseJSON(attrsMatch) : {}; // This state isn't allowed // This is an error. if (isCloser && (isVoid || hasAttrs)) { // We can ignore them since they don't hurt anything // we may warn against this at some point or reject it. } if (isVoid) { return ['void-block', name, attrs, startedAt, length]; } if (isCloser) { return ['block-closer', name, null, startedAt, length]; } return ['block-opener', name, attrs, startedAt, length]; } /** * Adds a freeform block to the output. * * @param {number} [rawLength] */ function addFreeform(rawLength) { const length = rawLength ? rawLength : document.length - offset; if (0 === length) { return; } output.push(Freeform(document.substr(offset, length))); } /** * Adds inner block to the parent block. * * @param {ParsedBlock} block * @param {number} tokenStart * @param {number} tokenLength * @param {number} [lastOffset] */ function addInnerBlock(block, tokenStart, tokenLength, lastOffset) { const parent = stack[stack.length - 1]; parent.block.innerBlocks.push(block); const html = document.substr(parent.prevOffset, tokenStart - parent.prevOffset); if (html) { parent.block.innerHTML += html; parent.block.innerContent.push(html); } parent.block.innerContent.push(null); parent.prevOffset = lastOffset ? lastOffset : tokenStart + tokenLength; } /** * Adds block from the stack to the output. * * @param {number} [endOffset] */ function addBlockFromStack(endOffset) { const { block, leadingHtmlStart, prevOffset, tokenStart } = /** @type {ParsedFrame} */stack.pop(); const html = endOffset ? document.substr(prevOffset, endOffset - prevOffset) : document.substr(prevOffset); if (html) { block.innerHTML += html; block.innerContent.push(html); } if (null !== leadingHtmlStart) { output.push(Freeform(document.substr(leadingHtmlStart, tokenStart - leadingHtmlStart))); } output.push(block); } (window.wp = window.wp || {}).blockSerializationDefaultParser = __webpack_exports__; /******/ })() ;
Name | Type | Size | Permission | Actions |
---|---|---|---|---|
development | Folder | 0755 |
|
|
script-modules | Folder | 0755 |
|
|
vendor | Folder | 0755 |
|
|
a11y.js | File | 8.53 KB | 0644 |
|
a11y.min.js | File | 2.3 KB | 0644 |
|
annotations.js | File | 23 KB | 0644 |
|
annotations.min.js | File | 5.39 KB | 0644 |
|
api-fetch.js | File | 22.97 KB | 0644 |
|
api-fetch.min.js | File | 5.41 KB | 0644 |
|
autop.js | File | 15.61 KB | 0644 |
|
autop.min.js | File | 5.48 KB | 0644 |
|
blob.js | File | 4.51 KB | 0644 |
|
blob.min.js | File | 1.08 KB | 0644 |
|
block-directory.js | File | 79.43 KB | 0644 |
|
block-directory.min.js | File | 20.37 KB | 0644 |
|
block-editor.js | File | 2.52 MB | 0644 |
|
block-editor.min.js | File | 822.17 KB | 0644 |
|
block-library.js | File | 2.06 MB | 0644 |
|
block-library.min.js | File | 823.01 KB | 0644 |
|
block-serialization-default-parser.js | File | 14.87 KB | 0644 |
|
block-serialization-default-parser.min.js | File | 2.34 KB | 0644 |
|
blocks.js | File | 552.73 KB | 0644 |
|
blocks.min.js | File | 169.02 KB | 0644 |
|
commands.js | File | 179.21 KB | 0644 |
|
commands.min.js | File | 48.33 KB | 0644 |
|
components.js | File | 2.24 MB | 0644 |
|
components.min.js | File | 689.07 KB | 0644 |
|
compose.js | File | 197.47 KB | 0644 |
|
compose.min.js | File | 36.09 KB | 0644 |
|
core-commands.js | File | 25 KB | 0644 |
|
core-commands.min.js | File | 9.2 KB | 0644 |
|
core-data.js | File | 258.18 KB | 0644 |
|
core-data.min.js | File | 62.68 KB | 0644 |
|
customize-widgets.js | File | 97.13 KB | 0644 |
|
customize-widgets.min.js | File | 34.32 KB | 0644 |
|
data-controls.js | File | 7.14 KB | 0644 |
|
data-controls.min.js | File | 1.44 KB | 0644 |
|
data.js | File | 154.61 KB | 0644 |
|
data.min.js | File | 26.46 KB | 0644 |
|
date.js | File | 798.19 KB | 0644 |
|
date.min.js | File | 765.07 KB | 0644 |
|
deprecated.js | File | 4.63 KB | 0644 |
|
deprecated.min.js | File | 684 B | 0644 |
|
dom-ready.js | File | 2.41 KB | 0644 |
|
dom-ready.min.js | File | 457 B | 0644 |
|
dom.js | File | 61.52 KB | 0644 |
|
dom.min.js | File | 12.23 KB | 0644 |
|
edit-post.js | File | 123.54 KB | 0644 |
|
edit-post.min.js | File | 42.15 KB | 0644 |
|
edit-site.js | File | 1.52 MB | 0644 |
|
edit-site.min.js | File | 608.94 KB | 0644 |
|
edit-widgets.js | File | 175.48 KB | 0644 |
|
edit-widgets.min.js | File | 58 KB | 0644 |
|
editor.js | File | 1.01 MB | 0644 |
|
editor.min.js | File | 337.36 KB | 0644 |
|
element.js | File | 66.28 KB | 0644 |
|
element.min.js | File | 11.7 KB | 0644 |
|
escape-html.js | File | 5.9 KB | 0644 |
|
escape-html.min.js | File | 1000 B | 0644 |
|
fields.js | File | 71.26 KB | 0644 |
|
fields.min.js | File | 22.33 KB | 0644 |
|
format-library.js | File | 68.36 KB | 0644 |
|
format-library.min.js | File | 22.39 KB | 0644 |
|
hooks.js | File | 20.43 KB | 0644 |
|
hooks.min.js | File | 4.66 KB | 0644 |
|
html-entities.js | File | 3.62 KB | 0644 |
|
html-entities.min.js | File | 788 B | 0644 |
|
i18n.js | File | 48.74 KB | 0644 |
|
i18n.min.js | File | 8.93 KB | 0644 |
|
is-shallow-equal.js | File | 4.25 KB | 0644 |
|
is-shallow-equal.min.js | File | 1018 B | 0644 |
|
keyboard-shortcuts.js | File | 24.17 KB | 0644 |
|
keyboard-shortcuts.min.js | File | 2.95 KB | 0644 |
|
keycodes.js | File | 13.77 KB | 0644 |
|
keycodes.min.js | File | 2.58 KB | 0644 |
|
list-reusable-blocks.js | File | 30.79 KB | 0644 |
|
list-reusable-blocks.min.js | File | 4.8 KB | 0644 |
|
media-utils.js | File | 25.47 KB | 0644 |
|
media-utils.min.js | File | 8.05 KB | 0644 |
|
notices.js | File | 21.64 KB | 0644 |
|
notices.min.js | File | 2.02 KB | 0644 |
|
nux.js | File | 13.29 KB | 0644 |
|
nux.min.js | File | 3.43 KB | 0644 |
|
patterns.js | File | 63 KB | 0644 |
|
patterns.min.js | File | 20.89 KB | 0644 |
|
plugins.js | File | 17.72 KB | 0644 |
|
plugins.min.js | File | 4.05 KB | 0644 |
|
preferences-persistence.js | File | 29.58 KB | 0644 |
|
preferences-persistence.min.js | File | 5.49 KB | 0644 |
|
preferences.js | File | 25.71 KB | 0644 |
|
preferences.min.js | File | 6.92 KB | 0644 |
|
primitives.js | File | 6.73 KB | 0644 |
|
primitives.min.js | File | 1.62 KB | 0644 |
|
priority-queue.js | File | 13.91 KB | 0644 |
|
priority-queue.min.js | File | 3.3 KB | 0644 |
|
private-apis.js | File | 8.68 KB | 0644 |
|
private-apis.min.js | File | 2.74 KB | 0644 |
|
redux-routine.js | File | 23.42 KB | 0644 |
|
redux-routine.min.js | File | 8.69 KB | 0644 |
|
reusable-blocks.js | File | 20.39 KB | 0644 |
|
reusable-blocks.min.js | File | 5.97 KB | 0644 |
|
rich-text.js | File | 115.4 KB | 0644 |
|
rich-text.min.js | File | 29.11 KB | 0644 |
|
router.js | File | 26.29 KB | 0644 |
|
router.min.js | File | 4.29 KB | 0644 |
|
server-side-render.js | File | 14.61 KB | 0644 |
|
server-side-render.min.js | File | 4.28 KB | 0644 |
|
shortcode.js | File | 14.92 KB | 0644 |
|
shortcode.min.js | File | 2.83 KB | 0644 |
|
style-engine.js | File | 38.81 KB | 0644 |
|
style-engine.min.js | File | 5.91 KB | 0644 |
|
token-list.js | File | 5.91 KB | 0644 |
|
token-list.min.js | File | 1.24 KB | 0644 |
|
undo-manager.js | File | 8.22 KB | 0644 |
|
undo-manager.min.js | File | 1.64 KB | 0644 |
|
url.js | File | 34.24 KB | 0644 |
|
url.min.js | File | 8.18 KB | 0644 |
|
viewport.js | File | 10.45 KB | 0644 |
|
viewport.min.js | File | 1.82 KB | 0644 |
|
warning.js | File | 2.43 KB | 0644 |
|
warning.min.js | File | 311 B | 0644 |
|
widgets.js | File | 53.32 KB | 0644 |
|
widgets.min.js | File | 19.68 KB | 0644 |
|
wordcount.js | File | 14.63 KB | 0644 |
|
wordcount.min.js | File | 2.42 KB | 0644 |
|