wp/wp-includes/js/dist/block-serialization-default-parser.js
changeset 9 177826044cd9
child 16 a86126ab1dd4
equal deleted inserted replaced
8:c7c34916027a 9:177826044cd9
       
     1 this["wp"] = this["wp"] || {}; this["wp"]["blockSerializationDefaultParser"] =
       
     2 /******/ (function(modules) { // webpackBootstrap
       
     3 /******/ 	// The module cache
       
     4 /******/ 	var installedModules = {};
       
     5 /******/
       
     6 /******/ 	// The require function
       
     7 /******/ 	function __webpack_require__(moduleId) {
       
     8 /******/
       
     9 /******/ 		// Check if module is in cache
       
    10 /******/ 		if(installedModules[moduleId]) {
       
    11 /******/ 			return installedModules[moduleId].exports;
       
    12 /******/ 		}
       
    13 /******/ 		// Create a new module (and put it into the cache)
       
    14 /******/ 		var module = installedModules[moduleId] = {
       
    15 /******/ 			i: moduleId,
       
    16 /******/ 			l: false,
       
    17 /******/ 			exports: {}
       
    18 /******/ 		};
       
    19 /******/
       
    20 /******/ 		// Execute the module function
       
    21 /******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
       
    22 /******/
       
    23 /******/ 		// Flag the module as loaded
       
    24 /******/ 		module.l = true;
       
    25 /******/
       
    26 /******/ 		// Return the exports of the module
       
    27 /******/ 		return module.exports;
       
    28 /******/ 	}
       
    29 /******/
       
    30 /******/
       
    31 /******/ 	// expose the modules object (__webpack_modules__)
       
    32 /******/ 	__webpack_require__.m = modules;
       
    33 /******/
       
    34 /******/ 	// expose the module cache
       
    35 /******/ 	__webpack_require__.c = installedModules;
       
    36 /******/
       
    37 /******/ 	// define getter function for harmony exports
       
    38 /******/ 	__webpack_require__.d = function(exports, name, getter) {
       
    39 /******/ 		if(!__webpack_require__.o(exports, name)) {
       
    40 /******/ 			Object.defineProperty(exports, name, { enumerable: true, get: getter });
       
    41 /******/ 		}
       
    42 /******/ 	};
       
    43 /******/
       
    44 /******/ 	// define __esModule on exports
       
    45 /******/ 	__webpack_require__.r = function(exports) {
       
    46 /******/ 		if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
       
    47 /******/ 			Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
       
    48 /******/ 		}
       
    49 /******/ 		Object.defineProperty(exports, '__esModule', { value: true });
       
    50 /******/ 	};
       
    51 /******/
       
    52 /******/ 	// create a fake namespace object
       
    53 /******/ 	// mode & 1: value is a module id, require it
       
    54 /******/ 	// mode & 2: merge all properties of value into the ns
       
    55 /******/ 	// mode & 4: return value when already ns object
       
    56 /******/ 	// mode & 8|1: behave like require
       
    57 /******/ 	__webpack_require__.t = function(value, mode) {
       
    58 /******/ 		if(mode & 1) value = __webpack_require__(value);
       
    59 /******/ 		if(mode & 8) return value;
       
    60 /******/ 		if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
       
    61 /******/ 		var ns = Object.create(null);
       
    62 /******/ 		__webpack_require__.r(ns);
       
    63 /******/ 		Object.defineProperty(ns, 'default', { enumerable: true, value: value });
       
    64 /******/ 		if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
       
    65 /******/ 		return ns;
       
    66 /******/ 	};
       
    67 /******/
       
    68 /******/ 	// getDefaultExport function for compatibility with non-harmony modules
       
    69 /******/ 	__webpack_require__.n = function(module) {
       
    70 /******/ 		var getter = module && module.__esModule ?
       
    71 /******/ 			function getDefault() { return module['default']; } :
       
    72 /******/ 			function getModuleExports() { return module; };
       
    73 /******/ 		__webpack_require__.d(getter, 'a', getter);
       
    74 /******/ 		return getter;
       
    75 /******/ 	};
       
    76 /******/
       
    77 /******/ 	// Object.prototype.hasOwnProperty.call
       
    78 /******/ 	__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
       
    79 /******/
       
    80 /******/ 	// __webpack_public_path__
       
    81 /******/ 	__webpack_require__.p = "";
       
    82 /******/
       
    83 /******/
       
    84 /******/ 	// Load entry module and return exports
       
    85 /******/ 	return __webpack_require__(__webpack_require__.s = 258);
       
    86 /******/ })
       
    87 /************************************************************************/
       
    88 /******/ ({
       
    89 
       
    90 /***/ 258:
       
    91 /***/ (function(module, __webpack_exports__, __webpack_require__) {
       
    92 
       
    93 "use strict";
       
    94 __webpack_require__.r(__webpack_exports__);
       
    95 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "parse", function() { return parse; });
       
    96 /* harmony import */ var _babel_runtime_helpers_esm_slicedToArray__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(28);
       
    97 
       
    98 var document;
       
    99 var offset;
       
   100 var output;
       
   101 var stack;
       
   102 /**
       
   103  * Matches block comment delimiters
       
   104  *
       
   105  * While most of this pattern is straightforward the attribute parsing
       
   106  * incorporates a tricks to make sure we don't choke on specific input
       
   107  *
       
   108  *  - since JavaScript has no possessive quantifier or atomic grouping
       
   109  *    we are emulating it with a trick
       
   110  *
       
   111  *    we want a possessive quantifier or atomic group to prevent backtracking
       
   112  *    on the `}`s should we fail to match the remainder of the pattern
       
   113  *
       
   114  *    we can emulate this with a positive lookahead and back reference
       
   115  *    (a++)*c === ((?=(a+))\1)*c
       
   116  *
       
   117  *    let's examine an example:
       
   118  *      - /(a+)*c/.test('aaaaaaaaaaaaad') fails after over 49,000 steps
       
   119  *      - /(a++)*c/.test('aaaaaaaaaaaaad') fails after 85 steps
       
   120  *      - /(?>a+)*c/.test('aaaaaaaaaaaaad') fails after 126 steps
       
   121  *
       
   122  *    this is because the possessive `++` and the atomic group `(?>)`
       
   123  *    tell the engine that all those `a`s belong together as a single group
       
   124  *    and so it won't split it up when stepping backwards to try and match
       
   125  *
       
   126  *    if we use /((?=(a+))\1)*c/ then we get the same behavior as the atomic group
       
   127  *    or possessive and prevent the backtracking because the `a+` is matched but
       
   128  *    not captured. thus, we find the long string of `a`s and remember it, then
       
   129  *    reference it as a whole unit inside our pattern
       
   130  *
       
   131  *    @cite http://instanceof.me/post/52245507631/regex-emulate-atomic-grouping-with-lookahead
       
   132  *    @cite http://blog.stevenlevithan.com/archives/mimic-atomic-groups
       
   133  *    @cite https://javascript.info/regexp-infinite-backtracking-problem
       
   134  *
       
   135  *    once browsers reliably support atomic grouping or possessive
       
   136  *    quantifiers natively we should remove this trick and simplify
       
   137  *
       
   138  * @type RegExp
       
   139  *
       
   140  * @since 3.8.0
       
   141  * @since 4.6.1 added optimization to prevent backtracking on attribute parsing
       
   142  */
       
   143 
       
   144 var tokenizer = /<!--\s+(\/)?wp:([a-z][a-z0-9_-]*\/)?([a-z][a-z0-9_-]*)\s+({(?:(?=([^}]+|}+(?=})|(?!}\s+\/?-->)[^])*)\5|[^]*?)}\s+)?(\/)?-->/g;
       
   145 
       
   146 function Block(blockName, attrs, innerBlocks, innerHTML, innerContent) {
       
   147   return {
       
   148     blockName: blockName,
       
   149     attrs: attrs,
       
   150     innerBlocks: innerBlocks,
       
   151     innerHTML: innerHTML,
       
   152     innerContent: innerContent
       
   153   };
       
   154 }
       
   155 
       
   156 function Freeform(innerHTML) {
       
   157   return Block(null, {}, [], innerHTML, [innerHTML]);
       
   158 }
       
   159 
       
   160 function Frame(block, tokenStart, tokenLength, prevOffset, leadingHtmlStart) {
       
   161   return {
       
   162     block: block,
       
   163     tokenStart: tokenStart,
       
   164     tokenLength: tokenLength,
       
   165     prevOffset: prevOffset || tokenStart + tokenLength,
       
   166     leadingHtmlStart: leadingHtmlStart
       
   167   };
       
   168 }
       
   169 /**
       
   170  * Parser function, that converts input HTML into a block based structure.
       
   171  *
       
   172  * @param {string} doc The HTML document to parse.
       
   173  *
       
   174  * @example
       
   175  * Input post:
       
   176  * ```html
       
   177  * <!-- wp:columns {"columns":3} -->
       
   178  * <div class="wp-block-columns has-3-columns"><!-- wp:column -->
       
   179  * <div class="wp-block-column"><!-- wp:paragraph -->
       
   180  * <p>Left</p>
       
   181  * <!-- /wp:paragraph --></div>
       
   182  * <!-- /wp:column -->
       
   183  *
       
   184  * <!-- wp:column -->
       
   185  * <div class="wp-block-column"><!-- wp:paragraph -->
       
   186  * <p><strong>Middle</strong></p>
       
   187  * <!-- /wp:paragraph --></div>
       
   188  * <!-- /wp:column -->
       
   189  *
       
   190  * <!-- wp:column -->
       
   191  * <div class="wp-block-column"></div>
       
   192  * <!-- /wp:column --></div>
       
   193  * <!-- /wp:columns -->
       
   194  * ```
       
   195  *
       
   196  * Parsing code:
       
   197  * ```js
       
   198  * import { parse } from '@wordpress/block-serialization-default-parser';
       
   199  *
       
   200  * parse( post ) === [
       
   201  *     {
       
   202  *         blockName: "core/columns",
       
   203  *         attrs: {
       
   204  *             columns: 3
       
   205  *         },
       
   206  *         innerBlocks: [
       
   207  *             {
       
   208  *                 blockName: "core/column",
       
   209  *                 attrs: null,
       
   210  *                 innerBlocks: [
       
   211  *                     {
       
   212  *                         blockName: "core/paragraph",
       
   213  *                         attrs: null,
       
   214  *                         innerBlocks: [],
       
   215  *                         innerHTML: "\n<p>Left</p>\n"
       
   216  *                     }
       
   217  *                 ],
       
   218  *                 innerHTML: '\n<div class="wp-block-column"></div>\n'
       
   219  *             },
       
   220  *             {
       
   221  *                 blockName: "core/column",
       
   222  *                 attrs: null,
       
   223  *                 innerBlocks: [
       
   224  *                     {
       
   225  *                         blockName: "core/paragraph",
       
   226  *                         attrs: null,
       
   227  *                         innerBlocks: [],
       
   228  *                         innerHTML: "\n<p><strong>Middle</strong></p>\n"
       
   229  *                     }
       
   230  *                 ],
       
   231  *                 innerHTML: '\n<div class="wp-block-column"></div>\n'
       
   232  *             },
       
   233  *             {
       
   234  *                 blockName: "core/column",
       
   235  *                 attrs: null,
       
   236  *                 innerBlocks: [],
       
   237  *                 innerHTML: '\n<div class="wp-block-column"></div>\n'
       
   238  *             }
       
   239  *         ],
       
   240  *         innerHTML: '\n<div class="wp-block-columns has-3-columns">\n\n\n\n</div>\n'
       
   241  *     }
       
   242  * ];
       
   243  * ```
       
   244  * @return {Array} A block-based representation of the input HTML.
       
   245  */
       
   246 
       
   247 
       
   248 var parse = function parse(doc) {
       
   249   document = doc;
       
   250   offset = 0;
       
   251   output = [];
       
   252   stack = [];
       
   253   tokenizer.lastIndex = 0;
       
   254 
       
   255   do {// twiddle our thumbs
       
   256   } while (proceed());
       
   257 
       
   258   return output;
       
   259 };
       
   260 
       
   261 function proceed() {
       
   262   var next = nextToken();
       
   263 
       
   264   var _next = Object(_babel_runtime_helpers_esm_slicedToArray__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])(next, 5),
       
   265       tokenType = _next[0],
       
   266       blockName = _next[1],
       
   267       attrs = _next[2],
       
   268       startOffset = _next[3],
       
   269       tokenLength = _next[4];
       
   270 
       
   271   var stackDepth = stack.length; // we may have some HTML soup before the next block
       
   272 
       
   273   var leadingHtmlStart = startOffset > offset ? offset : null;
       
   274 
       
   275   switch (tokenType) {
       
   276     case 'no-more-tokens':
       
   277       // if not in a block then flush output
       
   278       if (0 === stackDepth) {
       
   279         addFreeform();
       
   280         return false;
       
   281       } // Otherwise we have a problem
       
   282       // This is an error
       
   283       // we have options
       
   284       //  - treat it all as freeform text
       
   285       //  - assume an implicit closer (easiest when not nesting)
       
   286       // for the easy case we'll assume an implicit closer
       
   287 
       
   288 
       
   289       if (1 === stackDepth) {
       
   290         addBlockFromStack();
       
   291         return false;
       
   292       } // for the nested case where it's more difficult we'll
       
   293       // have to assume that multiple closers are missing
       
   294       // and so we'll collapse the whole stack piecewise
       
   295 
       
   296 
       
   297       while (0 < stack.length) {
       
   298         addBlockFromStack();
       
   299       }
       
   300 
       
   301       return false;
       
   302 
       
   303     case 'void-block':
       
   304       // easy case is if we stumbled upon a void block
       
   305       // in the top-level of the document
       
   306       if (0 === stackDepth) {
       
   307         if (null !== leadingHtmlStart) {
       
   308           output.push(Freeform(document.substr(leadingHtmlStart, startOffset - leadingHtmlStart)));
       
   309         }
       
   310 
       
   311         output.push(Block(blockName, attrs, [], '', []));
       
   312         offset = startOffset + tokenLength;
       
   313         return true;
       
   314       } // otherwise we found an inner block
       
   315 
       
   316 
       
   317       addInnerBlock(Block(blockName, attrs, [], '', []), startOffset, tokenLength);
       
   318       offset = startOffset + tokenLength;
       
   319       return true;
       
   320 
       
   321     case 'block-opener':
       
   322       // track all newly-opened blocks on the stack
       
   323       stack.push(Frame(Block(blockName, attrs, [], '', []), startOffset, tokenLength, startOffset + tokenLength, leadingHtmlStart));
       
   324       offset = startOffset + tokenLength;
       
   325       return true;
       
   326 
       
   327     case 'block-closer':
       
   328       // if we're missing an opener we're in trouble
       
   329       // This is an error
       
   330       if (0 === stackDepth) {
       
   331         // we have options
       
   332         //  - assume an implicit opener
       
   333         //  - assume _this_ is the opener
       
   334         //  - give up and close out the document
       
   335         addFreeform();
       
   336         return false;
       
   337       } // if we're not nesting then this is easy - close the block
       
   338 
       
   339 
       
   340       if (1 === stackDepth) {
       
   341         addBlockFromStack(startOffset);
       
   342         offset = startOffset + tokenLength;
       
   343         return true;
       
   344       } // otherwise we're nested and we have to close out the current
       
   345       // block and add it as a innerBlock to the parent
       
   346 
       
   347 
       
   348       var stackTop = stack.pop();
       
   349       var html = document.substr(stackTop.prevOffset, startOffset - stackTop.prevOffset);
       
   350       stackTop.block.innerHTML += html;
       
   351       stackTop.block.innerContent.push(html);
       
   352       stackTop.prevOffset = startOffset + tokenLength;
       
   353       addInnerBlock(stackTop.block, stackTop.tokenStart, stackTop.tokenLength, startOffset + tokenLength);
       
   354       offset = startOffset + tokenLength;
       
   355       return true;
       
   356 
       
   357     default:
       
   358       // This is an error
       
   359       addFreeform();
       
   360       return false;
       
   361   }
       
   362 }
       
   363 /**
       
   364  * Parse JSON if valid, otherwise return null
       
   365  *
       
   366  * Note that JSON coming from the block comment
       
   367  * delimiters is constrained to be an object
       
   368  * and cannot be things like `true` or `null`
       
   369  *
       
   370  * @param {string} input JSON input string to parse
       
   371  * @return {Object|null} parsed JSON if valid
       
   372  */
       
   373 
       
   374 
       
   375 function parseJSON(input) {
       
   376   try {
       
   377     return JSON.parse(input);
       
   378   } catch (e) {
       
   379     return null;
       
   380   }
       
   381 }
       
   382 
       
   383 function nextToken() {
       
   384   // aye the magic
       
   385   // we're using a single RegExp to tokenize the block comment delimiters
       
   386   // we're also using a trick here because the only difference between a
       
   387   // block opener and a block closer is the leading `/` before `wp:` (and
       
   388   // a closer has no attributes). we can trap them both and process the
       
   389   // match back in Javascript to see which one it was.
       
   390   var matches = tokenizer.exec(document); // we have no more tokens
       
   391 
       
   392   if (null === matches) {
       
   393     return ['no-more-tokens'];
       
   394   }
       
   395 
       
   396   var startedAt = matches.index;
       
   397 
       
   398   var _matches = Object(_babel_runtime_helpers_esm_slicedToArray__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"])(matches, 7),
       
   399       match = _matches[0],
       
   400       closerMatch = _matches[1],
       
   401       namespaceMatch = _matches[2],
       
   402       nameMatch = _matches[3],
       
   403       attrsMatch = _matches[4],
       
   404 
       
   405   /* internal/unused */
       
   406   voidMatch = _matches[6];
       
   407 
       
   408   var length = match.length;
       
   409   var isCloser = !!closerMatch;
       
   410   var isVoid = !!voidMatch;
       
   411   var namespace = namespaceMatch || 'core/';
       
   412   var name = namespace + nameMatch;
       
   413   var hasAttrs = !!attrsMatch;
       
   414   var attrs = hasAttrs ? parseJSON(attrsMatch) : {}; // This state isn't allowed
       
   415   // This is an error
       
   416 
       
   417   if (isCloser && (isVoid || hasAttrs)) {// we can ignore them since they don't hurt anything
       
   418     // we may warn against this at some point or reject it
       
   419   }
       
   420 
       
   421   if (isVoid) {
       
   422     return ['void-block', name, attrs, startedAt, length];
       
   423   }
       
   424 
       
   425   if (isCloser) {
       
   426     return ['block-closer', name, null, startedAt, length];
       
   427   }
       
   428 
       
   429   return ['block-opener', name, attrs, startedAt, length];
       
   430 }
       
   431 
       
   432 function addFreeform(rawLength) {
       
   433   var length = rawLength ? rawLength : document.length - offset;
       
   434 
       
   435   if (0 === length) {
       
   436     return;
       
   437   }
       
   438 
       
   439   output.push(Freeform(document.substr(offset, length)));
       
   440 }
       
   441 
       
   442 function addInnerBlock(block, tokenStart, tokenLength, lastOffset) {
       
   443   var parent = stack[stack.length - 1];
       
   444   parent.block.innerBlocks.push(block);
       
   445   var html = document.substr(parent.prevOffset, tokenStart - parent.prevOffset);
       
   446 
       
   447   if (html) {
       
   448     parent.block.innerHTML += html;
       
   449     parent.block.innerContent.push(html);
       
   450   }
       
   451 
       
   452   parent.block.innerContent.push(null);
       
   453   parent.prevOffset = lastOffset ? lastOffset : tokenStart + tokenLength;
       
   454 }
       
   455 
       
   456 function addBlockFromStack(endOffset) {
       
   457   var _stack$pop = stack.pop(),
       
   458       block = _stack$pop.block,
       
   459       leadingHtmlStart = _stack$pop.leadingHtmlStart,
       
   460       prevOffset = _stack$pop.prevOffset,
       
   461       tokenStart = _stack$pop.tokenStart;
       
   462 
       
   463   var html = endOffset ? document.substr(prevOffset, endOffset - prevOffset) : document.substr(prevOffset);
       
   464 
       
   465   if (html) {
       
   466     block.innerHTML += html;
       
   467     block.innerContent.push(html);
       
   468   }
       
   469 
       
   470   if (null !== leadingHtmlStart) {
       
   471     output.push(Freeform(document.substr(leadingHtmlStart, tokenStart - leadingHtmlStart)));
       
   472   }
       
   473 
       
   474   output.push(block);
       
   475 }
       
   476 
       
   477 
       
   478 /***/ }),
       
   479 
       
   480 /***/ 28:
       
   481 /***/ (function(module, __webpack_exports__, __webpack_require__) {
       
   482 
       
   483 "use strict";
       
   484 
       
   485 // EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/esm/arrayWithHoles.js
       
   486 var arrayWithHoles = __webpack_require__(37);
       
   487 
       
   488 // CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/iterableToArrayLimit.js
       
   489 function _iterableToArrayLimit(arr, i) {
       
   490   var _arr = [];
       
   491   var _n = true;
       
   492   var _d = false;
       
   493   var _e = undefined;
       
   494 
       
   495   try {
       
   496     for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
       
   497       _arr.push(_s.value);
       
   498 
       
   499       if (i && _arr.length === i) break;
       
   500     }
       
   501   } catch (err) {
       
   502     _d = true;
       
   503     _e = err;
       
   504   } finally {
       
   505     try {
       
   506       if (!_n && _i["return"] != null) _i["return"]();
       
   507     } finally {
       
   508       if (_d) throw _e;
       
   509     }
       
   510   }
       
   511 
       
   512   return _arr;
       
   513 }
       
   514 // EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/esm/nonIterableRest.js
       
   515 var nonIterableRest = __webpack_require__(38);
       
   516 
       
   517 // CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/slicedToArray.js
       
   518 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return _slicedToArray; });
       
   519 
       
   520 
       
   521 
       
   522 function _slicedToArray(arr, i) {
       
   523   return Object(arrayWithHoles["a" /* default */])(arr) || _iterableToArrayLimit(arr, i) || Object(nonIterableRest["a" /* default */])();
       
   524 }
       
   525 
       
   526 /***/ }),
       
   527 
       
   528 /***/ 37:
       
   529 /***/ (function(module, __webpack_exports__, __webpack_require__) {
       
   530 
       
   531 "use strict";
       
   532 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return _arrayWithHoles; });
       
   533 function _arrayWithHoles(arr) {
       
   534   if (Array.isArray(arr)) return arr;
       
   535 }
       
   536 
       
   537 /***/ }),
       
   538 
       
   539 /***/ 38:
       
   540 /***/ (function(module, __webpack_exports__, __webpack_require__) {
       
   541 
       
   542 "use strict";
       
   543 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return _nonIterableRest; });
       
   544 function _nonIterableRest() {
       
   545   throw new TypeError("Invalid attempt to destructure non-iterable instance");
       
   546 }
       
   547 
       
   548 /***/ })
       
   549 
       
   550 /******/ });