@wordpress/block-serialization-default-parser 4.3.0 → 4.3.2-next.a55ed9455a.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -2
- package/build/index.js +22 -22
- package/build/index.js.map +1 -1
- package/build-module/index.js +22 -22
- package/build-module/index.js.map +1 -1
- package/package.json +2 -2
- package/src/index.js +22 -22
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Block Serialization Default Parser
|
|
2
2
|
|
|
3
|
-
This library contains the default block serialization parser implementations for WordPress documents. It provides native PHP and JavaScript parsers that implement the [specification](/docs/contributors/grammar.md) from [`@wordpress/block-serialization-spec-parser`](/packages/block-serialization-spec-parser/README.md) and which normally operates on the document stored in `post_content`.
|
|
3
|
+
This library contains the default block serialization parser implementations for WordPress documents. It provides native PHP and JavaScript parsers that implement the [specification](https://github.com/WordPress/gutenberg/tree/HEAD/docs/contributors/code/grammar.md) from [`@wordpress/block-serialization-spec-parser`](https://github.com/WordPress/gutenberg/tree/HEAD/packages/block-serialization-spec-parser/README.md) and which normally operates on the document stored in `post_content`.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -151,4 +151,10 @@ Further, tokenizing with a RegExp brings an additional advantage. The parser gen
|
|
|
151
151
|
|
|
152
152
|
However, since our "token language" of the block comment delimiters is _regular_ and _can_ be trivially matched with RegExp patterns, we can do that here and then something magical happens: we jump out of PHP or JavaScript and into a highly-optimized RegExp engine written in C or C++ on the host system. We thereby leave the virtual machine and its overhead.
|
|
153
153
|
|
|
154
|
-
|
|
154
|
+
## Contributing to this package
|
|
155
|
+
|
|
156
|
+
This is an individual package that's part of the Gutenberg project. The project is organized as a monorepo. It's made up of multiple self-contained software packages, each with a specific purpose. The packages in this monorepo are published to [npm](https://www.npmjs.com/) and used by [WordPress](https://make.wordpress.org/core/) as well as other software projects.
|
|
157
|
+
|
|
158
|
+
To find out more about contributing to this package or Gutenberg as a whole, please read the project's main [contributor guide](https://github.com/WordPress/gutenberg/tree/HEAD/CONTRIBUTING.md).
|
|
159
|
+
|
|
160
|
+
<br /><br /><p align="center"><img src="https://s.w.org/style/images/codeispoetry.png?1" alt="Code is Poetry." /></p>
|
package/build/index.js
CHANGED
|
@@ -172,13 +172,13 @@ exports.parse = parse;
|
|
|
172
172
|
function proceed() {
|
|
173
173
|
const next = nextToken();
|
|
174
174
|
const [tokenType, blockName, attrs, startOffset, tokenLength] = next;
|
|
175
|
-
const stackDepth = stack.length; //
|
|
175
|
+
const stackDepth = stack.length; // We may have some HTML soup before the next block.
|
|
176
176
|
|
|
177
177
|
const leadingHtmlStart = startOffset > offset ? offset : null;
|
|
178
178
|
|
|
179
179
|
switch (tokenType) {
|
|
180
180
|
case 'no-more-tokens':
|
|
181
|
-
//
|
|
181
|
+
// If not in a block then flush output.
|
|
182
182
|
if (0 === stackDepth) {
|
|
183
183
|
addFreeform();
|
|
184
184
|
return false;
|
|
@@ -187,15 +187,15 @@ function proceed() {
|
|
|
187
187
|
// we have options
|
|
188
188
|
// - treat it all as freeform text
|
|
189
189
|
// - assume an implicit closer (easiest when not nesting)
|
|
190
|
-
//
|
|
190
|
+
// For the easy case we'll assume an implicit closer.
|
|
191
191
|
|
|
192
192
|
|
|
193
193
|
if (1 === stackDepth) {
|
|
194
194
|
addBlockFromStack();
|
|
195
195
|
return false;
|
|
196
|
-
} //
|
|
196
|
+
} // For the nested case where it's more difficult we'll
|
|
197
197
|
// have to assume that multiple closers are missing
|
|
198
|
-
// and so we'll collapse the whole stack piecewise
|
|
198
|
+
// and so we'll collapse the whole stack piecewise.
|
|
199
199
|
|
|
200
200
|
|
|
201
201
|
while (0 < stack.length) {
|
|
@@ -206,7 +206,7 @@ function proceed() {
|
|
|
206
206
|
|
|
207
207
|
case 'void-block':
|
|
208
208
|
// easy case is if we stumbled upon a void block
|
|
209
|
-
// in the top-level of the document
|
|
209
|
+
// in the top-level of the document.
|
|
210
210
|
if (0 === stackDepth) {
|
|
211
211
|
if (null !== leadingHtmlStart) {
|
|
212
212
|
output.push(Freeform(document.substr(leadingHtmlStart, startOffset - leadingHtmlStart)));
|
|
@@ -215,7 +215,7 @@ function proceed() {
|
|
|
215
215
|
output.push(Block(blockName, attrs, [], '', []));
|
|
216
216
|
offset = startOffset + tokenLength;
|
|
217
217
|
return true;
|
|
218
|
-
} //
|
|
218
|
+
} // Otherwise we found an inner block.
|
|
219
219
|
|
|
220
220
|
|
|
221
221
|
addInnerBlock(Block(blockName, attrs, [], '', []), startOffset, tokenLength);
|
|
@@ -223,30 +223,30 @@ function proceed() {
|
|
|
223
223
|
return true;
|
|
224
224
|
|
|
225
225
|
case 'block-opener':
|
|
226
|
-
//
|
|
226
|
+
// Track all newly-opened blocks on the stack.
|
|
227
227
|
stack.push(Frame(Block(blockName, attrs, [], '', []), startOffset, tokenLength, startOffset + tokenLength, leadingHtmlStart));
|
|
228
228
|
offset = startOffset + tokenLength;
|
|
229
229
|
return true;
|
|
230
230
|
|
|
231
231
|
case 'block-closer':
|
|
232
|
-
//
|
|
233
|
-
// This is an error
|
|
232
|
+
// If we're missing an opener we're in trouble
|
|
233
|
+
// This is an error.
|
|
234
234
|
if (0 === stackDepth) {
|
|
235
|
-
//
|
|
235
|
+
// We have options
|
|
236
236
|
// - assume an implicit opener
|
|
237
237
|
// - assume _this_ is the opener
|
|
238
|
-
//
|
|
238
|
+
// - give up and close out the document.
|
|
239
239
|
addFreeform();
|
|
240
240
|
return false;
|
|
241
|
-
} //
|
|
241
|
+
} // If we're not nesting then this is easy - close the block.
|
|
242
242
|
|
|
243
243
|
|
|
244
244
|
if (1 === stackDepth) {
|
|
245
245
|
addBlockFromStack(startOffset);
|
|
246
246
|
offset = startOffset + tokenLength;
|
|
247
247
|
return true;
|
|
248
|
-
} //
|
|
249
|
-
// block and add it as a innerBlock to the parent
|
|
248
|
+
} // Otherwise we're nested and we have to close out the current
|
|
249
|
+
// block and add it as a innerBlock to the parent.
|
|
250
250
|
|
|
251
251
|
|
|
252
252
|
const stackTop = stack.pop();
|
|
@@ -259,7 +259,7 @@ function proceed() {
|
|
|
259
259
|
return true;
|
|
260
260
|
|
|
261
261
|
default:
|
|
262
|
-
// This is an error
|
|
262
|
+
// This is an error.
|
|
263
263
|
addFreeform();
|
|
264
264
|
return false;
|
|
265
265
|
}
|
|
@@ -285,13 +285,13 @@ function parseJSON(input) {
|
|
|
285
285
|
}
|
|
286
286
|
|
|
287
287
|
function nextToken() {
|
|
288
|
-
//
|
|
288
|
+
// Aye the magic
|
|
289
289
|
// we're using a single RegExp to tokenize the block comment delimiters
|
|
290
290
|
// we're also using a trick here because the only difference between a
|
|
291
291
|
// block opener and a block closer is the leading `/` before `wp:` (and
|
|
292
292
|
// a closer has no attributes). we can trap them both and process the
|
|
293
293
|
// match back in JavaScript to see which one it was.
|
|
294
|
-
const matches = tokenizer.exec(document); //
|
|
294
|
+
const matches = tokenizer.exec(document); // We have no more tokens.
|
|
295
295
|
|
|
296
296
|
if (null === matches) {
|
|
297
297
|
return ['no-more-tokens'];
|
|
@@ -299,7 +299,7 @@ function nextToken() {
|
|
|
299
299
|
|
|
300
300
|
const startedAt = matches.index;
|
|
301
301
|
const [match, closerMatch, namespaceMatch, nameMatch, attrsMatch
|
|
302
|
-
/*
|
|
302
|
+
/* Internal/unused. */
|
|
303
303
|
,, voidMatch] = matches;
|
|
304
304
|
const length = match.length;
|
|
305
305
|
const isCloser = !!closerMatch;
|
|
@@ -308,10 +308,10 @@ function nextToken() {
|
|
|
308
308
|
const name = namespace + nameMatch;
|
|
309
309
|
const hasAttrs = !!attrsMatch;
|
|
310
310
|
const attrs = hasAttrs ? parseJSON(attrsMatch) : {}; // This state isn't allowed
|
|
311
|
-
// This is an error
|
|
311
|
+
// This is an error.
|
|
312
312
|
|
|
313
|
-
if (isCloser && (isVoid || hasAttrs)) {//
|
|
314
|
-
// we may warn against this at some point or reject it
|
|
313
|
+
if (isCloser && (isVoid || hasAttrs)) {// We can ignore them since they don't hurt anything
|
|
314
|
+
// we may warn against this at some point or reject it.
|
|
315
315
|
}
|
|
316
316
|
|
|
317
317
|
if (isVoid) {
|
package/build/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["@wordpress/block-serialization-default-parser/src/index.js"],"names":["document","offset","output","stack","tokenizer","Block","blockName","attrs","innerBlocks","innerHTML","innerContent","Freeform","Frame","block","tokenStart","tokenLength","prevOffset","leadingHtmlStart","parse","doc","lastIndex","proceed","next","nextToken","tokenType","startOffset","stackDepth","length","addFreeform","addBlockFromStack","push","substr","addInnerBlock","stackTop","pop","html","parseJSON","input","JSON","e","matches","exec","startedAt","index","match","closerMatch","namespaceMatch","nameMatch","attrsMatch","voidMatch","isCloser","isVoid","namespace","name","hasAttrs","rawLength","lastOffset","parent","endOffset"],"mappings":";;;;;;AAAA,IAAIA,QAAJ;AACA,IAAIC,MAAJ;AACA,IAAIC,MAAJ;AACA,IAAIC,KAAJ;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AACA,MAAMC,SAAS,GAAG,8HAAlB;;AAEA,SAASC,KAAT,CAAgBC,SAAhB,EAA2BC,KAA3B,EAAkCC,WAAlC,EAA+CC,SAA/C,EAA0DC,YAA1D,EAAyE;AACxE,SAAO;AACNJ,IAAAA,SADM;AAENC,IAAAA,KAFM;AAGNC,IAAAA,WAHM;AAINC,IAAAA,SAJM;AAKNC,IAAAA;AALM,GAAP;AAOA;;AAED,SAASC,QAAT,CAAmBF,SAAnB,EAA+B;AAC9B,SAAOJ,KAAK,CAAE,IAAF,EAAQ,EAAR,EAAY,EAAZ,EAAgBI,SAAhB,EAA2B,CAAEA,SAAF,CAA3B,CAAZ;AACA;;AAED,SAASG,KAAT,CAAgBC,KAAhB,EAAuBC,UAAvB,EAAmCC,WAAnC,EAAgDC,UAAhD,EAA4DC,gBAA5D,EAA+E;AAC9E,SAAO;AACNJ,IAAAA,KADM;AAENC,IAAAA,UAFM;AAGNC,IAAAA,WAHM;AAINC,IAAAA,UAAU,EAAEA,UAAU,IAAIF,UAAU,GAAGC,WAJjC;AAKNE,IAAAA;AALM,GAAP;AAOA;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA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","sourcesContent":["let document;\nlet offset;\nlet output;\nlet stack;\n\n/**\n * Matches block comment delimiters\n *\n * While most of this pattern is straightforward the attribute parsing\n * incorporates a tricks to make sure we don't choke on specific input\n *\n * - since JavaScript has no possessive quantifier or atomic grouping\n * we are emulating it with a trick\n *\n * we want a possessive quantifier or atomic group to prevent backtracking\n * on the `}`s should we fail to match the remainder of the pattern\n *\n * we can emulate this with a positive lookahead and back reference\n * (a++)*c === ((?=(a+))\\1)*c\n *\n * let's examine an example:\n * - /(a+)*c/.test('aaaaaaaaaaaaad') fails after over 49,000 steps\n * - /(a++)*c/.test('aaaaaaaaaaaaad') fails after 85 steps\n * - /(?>a+)*c/.test('aaaaaaaaaaaaad') fails after 126 steps\n *\n * this is because the possessive `++` and the atomic group `(?>)`\n * tell the engine that all those `a`s belong together as a single group\n * and so it won't split it up when stepping backwards to try and match\n *\n * if we use /((?=(a+))\\1)*c/ then we get the same behavior as the atomic group\n * or possessive and prevent the backtracking because the `a+` is matched but\n * not captured. thus, we find the long string of `a`s and remember it, then\n * reference it as a whole unit inside our pattern\n *\n * @see http://instanceof.me/post/52245507631/regex-emulate-atomic-grouping-with-lookahead\n * @see http://blog.stevenlevithan.com/archives/mimic-atomic-groups\n * @see https://javascript.info/regexp-infinite-backtracking-problem\n *\n * once browsers reliably support atomic grouping or possessive\n * quantifiers natively we should remove this trick and simplify\n *\n * @type {RegExp}\n *\n * @since 3.8.0\n * @since 4.6.1 added optimization to prevent backtracking on attribute parsing\n */\nconst tokenizer = /<!--\\s+(\\/)?wp:([a-z][a-z0-9_-]*\\/)?([a-z][a-z0-9_-]*)\\s+({(?:(?=([^}]+|}+(?=})|(?!}\\s+\\/?-->)[^])*)\\5|[^]*?)}\\s+)?(\\/)?-->/g;\n\nfunction Block( blockName, attrs, innerBlocks, innerHTML, innerContent ) {\n\treturn {\n\t\tblockName,\n\t\tattrs,\n\t\tinnerBlocks,\n\t\tinnerHTML,\n\t\tinnerContent,\n\t};\n}\n\nfunction Freeform( innerHTML ) {\n\treturn Block( null, {}, [], innerHTML, [ innerHTML ] );\n}\n\nfunction Frame( block, tokenStart, tokenLength, prevOffset, leadingHtmlStart ) {\n\treturn {\n\t\tblock,\n\t\ttokenStart,\n\t\ttokenLength,\n\t\tprevOffset: prevOffset || tokenStart + tokenLength,\n\t\tleadingHtmlStart,\n\t};\n}\n\n/**\n * Parser function, that converts input HTML into a block based structure.\n *\n * @param {string} doc The HTML document to parse.\n *\n * @example\n * Input post:\n * ```html\n * <!-- wp:columns {\"columns\":3} -->\n * <div class=\"wp-block-columns has-3-columns\"><!-- wp:column -->\n * <div class=\"wp-block-column\"><!-- wp:paragraph -->\n * <p>Left</p>\n * <!-- /wp:paragraph --></div>\n * <!-- /wp:column -->\n *\n * <!-- wp:column -->\n * <div class=\"wp-block-column\"><!-- wp:paragraph -->\n * <p><strong>Middle</strong></p>\n * <!-- /wp:paragraph --></div>\n * <!-- /wp:column -->\n *\n * <!-- wp:column -->\n * <div class=\"wp-block-column\"></div>\n * <!-- /wp:column --></div>\n * <!-- /wp:columns -->\n * ```\n *\n * Parsing code:\n * ```js\n * import { parse } from '@wordpress/block-serialization-default-parser';\n *\n * parse( post ) === [\n * {\n * blockName: \"core/columns\",\n * attrs: {\n * columns: 3\n * },\n * innerBlocks: [\n * {\n * blockName: \"core/column\",\n * attrs: null,\n * innerBlocks: [\n * {\n * blockName: \"core/paragraph\",\n * attrs: null,\n * innerBlocks: [],\n * innerHTML: \"\\n<p>Left</p>\\n\"\n * }\n * ],\n * innerHTML: '\\n<div class=\"wp-block-column\"></div>\\n'\n * },\n * {\n * blockName: \"core/column\",\n * attrs: null,\n * innerBlocks: [\n * {\n * blockName: \"core/paragraph\",\n * attrs: null,\n * innerBlocks: [],\n * innerHTML: \"\\n<p><strong>Middle</strong></p>\\n\"\n * }\n * ],\n * innerHTML: '\\n<div class=\"wp-block-column\"></div>\\n'\n * },\n * {\n * blockName: \"core/column\",\n * attrs: null,\n * innerBlocks: [],\n * innerHTML: '\\n<div class=\"wp-block-column\"></div>\\n'\n * }\n * ],\n * innerHTML: '\\n<div class=\"wp-block-columns has-3-columns\">\\n\\n\\n\\n</div>\\n'\n * }\n * ];\n * ```\n * @return {Array} A block-based representation of the input HTML.\n */\nexport const parse = ( doc ) => {\n\tdocument = doc;\n\toffset = 0;\n\toutput = [];\n\tstack = [];\n\ttokenizer.lastIndex = 0;\n\n\tdo {\n\t\t// twiddle our thumbs\n\t} while ( proceed() );\n\n\treturn output;\n};\n\nfunction proceed() {\n\tconst next = nextToken();\n\tconst [ tokenType, blockName, attrs, startOffset, tokenLength ] = next;\n\tconst stackDepth = stack.length;\n\n\t// we may have some HTML soup before the next block\n\tconst leadingHtmlStart = startOffset > offset ? offset : null;\n\n\tswitch ( tokenType ) {\n\t\tcase 'no-more-tokens':\n\t\t\t// if not in a block then flush output\n\t\t\tif ( 0 === stackDepth ) {\n\t\t\t\taddFreeform();\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// Otherwise we have a problem\n\t\t\t// This is an error\n\t\t\t// we have options\n\t\t\t// - treat it all as freeform text\n\t\t\t// - assume an implicit closer (easiest when not nesting)\n\n\t\t\t// for the easy case we'll assume an implicit closer\n\t\t\tif ( 1 === stackDepth ) {\n\t\t\t\taddBlockFromStack();\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// for the nested case where it's more difficult we'll\n\t\t\t// have to assume that multiple closers are missing\n\t\t\t// and so we'll collapse the whole stack piecewise\n\t\t\twhile ( 0 < stack.length ) {\n\t\t\t\taddBlockFromStack();\n\t\t\t}\n\t\t\treturn false;\n\n\t\tcase 'void-block':\n\t\t\t// easy case is if we stumbled upon a void block\n\t\t\t// in the top-level of the document\n\t\t\tif ( 0 === stackDepth ) {\n\t\t\t\tif ( null !== leadingHtmlStart ) {\n\t\t\t\t\toutput.push(\n\t\t\t\t\t\tFreeform(\n\t\t\t\t\t\t\tdocument.substr(\n\t\t\t\t\t\t\t\tleadingHtmlStart,\n\t\t\t\t\t\t\t\tstartOffset - leadingHtmlStart\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t)\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\toutput.push( Block( blockName, attrs, [], '', [] ) );\n\t\t\t\toffset = startOffset + tokenLength;\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\t// otherwise we found an inner block\n\t\t\taddInnerBlock(\n\t\t\t\tBlock( blockName, attrs, [], '', [] ),\n\t\t\t\tstartOffset,\n\t\t\t\ttokenLength\n\t\t\t);\n\t\t\toffset = startOffset + tokenLength;\n\t\t\treturn true;\n\n\t\tcase 'block-opener':\n\t\t\t// track all newly-opened blocks on the stack\n\t\t\tstack.push(\n\t\t\t\tFrame(\n\t\t\t\t\tBlock( blockName, attrs, [], '', [] ),\n\t\t\t\t\tstartOffset,\n\t\t\t\t\ttokenLength,\n\t\t\t\t\tstartOffset + tokenLength,\n\t\t\t\t\tleadingHtmlStart\n\t\t\t\t)\n\t\t\t);\n\t\t\toffset = startOffset + tokenLength;\n\t\t\treturn true;\n\n\t\tcase 'block-closer':\n\t\t\t// if we're missing an opener we're in trouble\n\t\t\t// This is an error\n\t\t\tif ( 0 === stackDepth ) {\n\t\t\t\t// we have options\n\t\t\t\t// - assume an implicit opener\n\t\t\t\t// - assume _this_ is the opener\n\t\t\t\t// - give up and close out the document\n\t\t\t\taddFreeform();\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// if we're not nesting then this is easy - close the block\n\t\t\tif ( 1 === stackDepth ) {\n\t\t\t\taddBlockFromStack( startOffset );\n\t\t\t\toffset = startOffset + tokenLength;\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\t// otherwise we're nested and we have to close out the current\n\t\t\t// block and add it as a innerBlock to the parent\n\t\t\tconst stackTop = stack.pop();\n\t\t\tconst html = document.substr(\n\t\t\t\tstackTop.prevOffset,\n\t\t\t\tstartOffset - stackTop.prevOffset\n\t\t\t);\n\t\t\tstackTop.block.innerHTML += html;\n\t\t\tstackTop.block.innerContent.push( html );\n\t\t\tstackTop.prevOffset = startOffset + tokenLength;\n\n\t\t\taddInnerBlock(\n\t\t\t\tstackTop.block,\n\t\t\t\tstackTop.tokenStart,\n\t\t\t\tstackTop.tokenLength,\n\t\t\t\tstartOffset + tokenLength\n\t\t\t);\n\t\t\toffset = startOffset + tokenLength;\n\t\t\treturn true;\n\n\t\tdefault:\n\t\t\t// This is an error\n\t\t\taddFreeform();\n\t\t\treturn false;\n\t}\n}\n\n/**\n * Parse JSON if valid, otherwise return null\n *\n * Note that JSON coming from the block comment\n * delimiters is constrained to be an object\n * and cannot be things like `true` or `null`\n *\n * @param {string} input JSON input string to parse\n * @return {Object|null} parsed JSON if valid\n */\nfunction parseJSON( input ) {\n\ttry {\n\t\treturn JSON.parse( input );\n\t} catch ( e ) {\n\t\treturn null;\n\t}\n}\n\nfunction nextToken() {\n\t// aye the magic\n\t// we're using a single RegExp to tokenize the block comment delimiters\n\t// we're also using a trick here because the only difference between a\n\t// block opener and a block closer is the leading `/` before `wp:` (and\n\t// a closer has no attributes). we can trap them both and process the\n\t// match back in JavaScript to see which one it was.\n\tconst matches = tokenizer.exec( document );\n\n\t// we have no more tokens\n\tif ( null === matches ) {\n\t\treturn [ 'no-more-tokens' ];\n\t}\n\n\tconst startedAt = matches.index;\n\tconst [\n\t\tmatch,\n\t\tcloserMatch,\n\t\tnamespaceMatch,\n\t\tnameMatch,\n\t\tattrsMatch /* internal/unused */,\n\t\t,\n\t\tvoidMatch,\n\t] = matches;\n\n\tconst length = match.length;\n\tconst isCloser = !! closerMatch;\n\tconst isVoid = !! voidMatch;\n\tconst namespace = namespaceMatch || 'core/';\n\tconst name = namespace + nameMatch;\n\tconst hasAttrs = !! attrsMatch;\n\tconst attrs = hasAttrs ? parseJSON( attrsMatch ) : {};\n\n\t// This state isn't allowed\n\t// This is an error\n\tif ( isCloser && ( isVoid || hasAttrs ) ) {\n\t\t// we can ignore them since they don't hurt anything\n\t\t// we may warn against this at some point or reject it\n\t}\n\n\tif ( isVoid ) {\n\t\treturn [ 'void-block', name, attrs, startedAt, length ];\n\t}\n\n\tif ( isCloser ) {\n\t\treturn [ 'block-closer', name, null, startedAt, length ];\n\t}\n\n\treturn [ 'block-opener', name, attrs, startedAt, length ];\n}\n\nfunction addFreeform( rawLength ) {\n\tconst length = rawLength ? rawLength : document.length - offset;\n\n\tif ( 0 === length ) {\n\t\treturn;\n\t}\n\n\toutput.push( Freeform( document.substr( offset, length ) ) );\n}\n\nfunction addInnerBlock( block, tokenStart, tokenLength, lastOffset ) {\n\tconst parent = stack[ stack.length - 1 ];\n\tparent.block.innerBlocks.push( block );\n\tconst html = document.substr(\n\t\tparent.prevOffset,\n\t\ttokenStart - parent.prevOffset\n\t);\n\n\tif ( html ) {\n\t\tparent.block.innerHTML += html;\n\t\tparent.block.innerContent.push( html );\n\t}\n\n\tparent.block.innerContent.push( null );\n\tparent.prevOffset = lastOffset ? lastOffset : tokenStart + tokenLength;\n}\n\nfunction addBlockFromStack( endOffset ) {\n\tconst { block, leadingHtmlStart, prevOffset, tokenStart } = stack.pop();\n\n\tconst html = endOffset\n\t\t? document.substr( prevOffset, endOffset - prevOffset )\n\t\t: document.substr( prevOffset );\n\n\tif ( html ) {\n\t\tblock.innerHTML += html;\n\t\tblock.innerContent.push( html );\n\t}\n\n\tif ( null !== leadingHtmlStart ) {\n\t\toutput.push(\n\t\t\tFreeform(\n\t\t\t\tdocument.substr(\n\t\t\t\t\tleadingHtmlStart,\n\t\t\t\t\ttokenStart - leadingHtmlStart\n\t\t\t\t)\n\t\t\t)\n\t\t);\n\t}\n\n\toutput.push( block );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["@wordpress/block-serialization-default-parser/src/index.js"],"names":["document","offset","output","stack","tokenizer","Block","blockName","attrs","innerBlocks","innerHTML","innerContent","Freeform","Frame","block","tokenStart","tokenLength","prevOffset","leadingHtmlStart","parse","doc","lastIndex","proceed","next","nextToken","tokenType","startOffset","stackDepth","length","addFreeform","addBlockFromStack","push","substr","addInnerBlock","stackTop","pop","html","parseJSON","input","JSON","e","matches","exec","startedAt","index","match","closerMatch","namespaceMatch","nameMatch","attrsMatch","voidMatch","isCloser","isVoid","namespace","name","hasAttrs","rawLength","lastOffset","parent","endOffset"],"mappings":";;;;;;AAAA,IAAIA,QAAJ;AACA,IAAIC,MAAJ;AACA,IAAIC,MAAJ;AACA,IAAIC,KAAJ;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AACA,MAAMC,SAAS,GAAG,8HAAlB;;AAEA,SAASC,KAAT,CAAgBC,SAAhB,EAA2BC,KAA3B,EAAkCC,WAAlC,EAA+CC,SAA/C,EAA0DC,YAA1D,EAAyE;AACxE,SAAO;AACNJ,IAAAA,SADM;AAENC,IAAAA,KAFM;AAGNC,IAAAA,WAHM;AAINC,IAAAA,SAJM;AAKNC,IAAAA;AALM,GAAP;AAOA;;AAED,SAASC,QAAT,CAAmBF,SAAnB,EAA+B;AAC9B,SAAOJ,KAAK,CAAE,IAAF,EAAQ,EAAR,EAAY,EAAZ,EAAgBI,SAAhB,EAA2B,CAAEA,SAAF,CAA3B,CAAZ;AACA;;AAED,SAASG,KAAT,CAAgBC,KAAhB,EAAuBC,UAAvB,EAAmCC,WAAnC,EAAgDC,UAAhD,EAA4DC,gBAA5D,EAA+E;AAC9E,SAAO;AACNJ,IAAAA,KADM;AAENC,IAAAA,UAFM;AAGNC,IAAAA,WAHM;AAINC,IAAAA,UAAU,EAAEA,UAAU,IAAIF,UAAU,GAAGC,WAJjC;AAKNE,IAAAA;AALM,GAAP;AAOA;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA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","sourcesContent":["let document;\nlet offset;\nlet output;\nlet stack;\n\n/**\n * Matches block comment delimiters\n *\n * While most of this pattern is straightforward the attribute parsing\n * incorporates a tricks to make sure we don't choke on specific input\n *\n * - since JavaScript has no possessive quantifier or atomic grouping\n * we are emulating it with a trick\n *\n * we want a possessive quantifier or atomic group to prevent backtracking\n * on the `}`s should we fail to match the remainder of the pattern\n *\n * we can emulate this with a positive lookahead and back reference\n * (a++)*c === ((?=(a+))\\1)*c\n *\n * let's examine an example:\n * - /(a+)*c/.test('aaaaaaaaaaaaad') fails after over 49,000 steps\n * - /(a++)*c/.test('aaaaaaaaaaaaad') fails after 85 steps\n * - /(?>a+)*c/.test('aaaaaaaaaaaaad') fails after 126 steps\n *\n * this is because the possessive `++` and the atomic group `(?>)`\n * tell the engine that all those `a`s belong together as a single group\n * and so it won't split it up when stepping backwards to try and match\n *\n * if we use /((?=(a+))\\1)*c/ then we get the same behavior as the atomic group\n * or possessive and prevent the backtracking because the `a+` is matched but\n * not captured. thus, we find the long string of `a`s and remember it, then\n * reference it as a whole unit inside our pattern\n *\n * @see http://instanceof.me/post/52245507631/regex-emulate-atomic-grouping-with-lookahead\n * @see http://blog.stevenlevithan.com/archives/mimic-atomic-groups\n * @see https://javascript.info/regexp-infinite-backtracking-problem\n *\n * once browsers reliably support atomic grouping or possessive\n * quantifiers natively we should remove this trick and simplify\n *\n * @type {RegExp}\n *\n * @since 3.8.0\n * @since 4.6.1 added optimization to prevent backtracking on attribute parsing\n */\nconst tokenizer = /<!--\\s+(\\/)?wp:([a-z][a-z0-9_-]*\\/)?([a-z][a-z0-9_-]*)\\s+({(?:(?=([^}]+|}+(?=})|(?!}\\s+\\/?-->)[^])*)\\5|[^]*?)}\\s+)?(\\/)?-->/g;\n\nfunction Block( blockName, attrs, innerBlocks, innerHTML, innerContent ) {\n\treturn {\n\t\tblockName,\n\t\tattrs,\n\t\tinnerBlocks,\n\t\tinnerHTML,\n\t\tinnerContent,\n\t};\n}\n\nfunction Freeform( innerHTML ) {\n\treturn Block( null, {}, [], innerHTML, [ innerHTML ] );\n}\n\nfunction Frame( block, tokenStart, tokenLength, prevOffset, leadingHtmlStart ) {\n\treturn {\n\t\tblock,\n\t\ttokenStart,\n\t\ttokenLength,\n\t\tprevOffset: prevOffset || tokenStart + tokenLength,\n\t\tleadingHtmlStart,\n\t};\n}\n\n/**\n * Parser function, that converts input HTML into a block based structure.\n *\n * @param {string} doc The HTML document to parse.\n *\n * @example\n * Input post:\n * ```html\n * <!-- wp:columns {\"columns\":3} -->\n * <div class=\"wp-block-columns has-3-columns\"><!-- wp:column -->\n * <div class=\"wp-block-column\"><!-- wp:paragraph -->\n * <p>Left</p>\n * <!-- /wp:paragraph --></div>\n * <!-- /wp:column -->\n *\n * <!-- wp:column -->\n * <div class=\"wp-block-column\"><!-- wp:paragraph -->\n * <p><strong>Middle</strong></p>\n * <!-- /wp:paragraph --></div>\n * <!-- /wp:column -->\n *\n * <!-- wp:column -->\n * <div class=\"wp-block-column\"></div>\n * <!-- /wp:column --></div>\n * <!-- /wp:columns -->\n * ```\n *\n * Parsing code:\n * ```js\n * import { parse } from '@wordpress/block-serialization-default-parser';\n *\n * parse( post ) === [\n * {\n * blockName: \"core/columns\",\n * attrs: {\n * columns: 3\n * },\n * innerBlocks: [\n * {\n * blockName: \"core/column\",\n * attrs: null,\n * innerBlocks: [\n * {\n * blockName: \"core/paragraph\",\n * attrs: null,\n * innerBlocks: [],\n * innerHTML: \"\\n<p>Left</p>\\n\"\n * }\n * ],\n * innerHTML: '\\n<div class=\"wp-block-column\"></div>\\n'\n * },\n * {\n * blockName: \"core/column\",\n * attrs: null,\n * innerBlocks: [\n * {\n * blockName: \"core/paragraph\",\n * attrs: null,\n * innerBlocks: [],\n * innerHTML: \"\\n<p><strong>Middle</strong></p>\\n\"\n * }\n * ],\n * innerHTML: '\\n<div class=\"wp-block-column\"></div>\\n'\n * },\n * {\n * blockName: \"core/column\",\n * attrs: null,\n * innerBlocks: [],\n * innerHTML: '\\n<div class=\"wp-block-column\"></div>\\n'\n * }\n * ],\n * innerHTML: '\\n<div class=\"wp-block-columns has-3-columns\">\\n\\n\\n\\n</div>\\n'\n * }\n * ];\n * ```\n * @return {Array} A block-based representation of the input HTML.\n */\nexport const parse = ( doc ) => {\n\tdocument = doc;\n\toffset = 0;\n\toutput = [];\n\tstack = [];\n\ttokenizer.lastIndex = 0;\n\n\tdo {\n\t\t// twiddle our thumbs\n\t} while ( proceed() );\n\n\treturn output;\n};\n\nfunction proceed() {\n\tconst next = nextToken();\n\tconst [ tokenType, blockName, attrs, startOffset, tokenLength ] = next;\n\tconst stackDepth = stack.length;\n\n\t// We may have some HTML soup before the next block.\n\tconst leadingHtmlStart = startOffset > offset ? offset : null;\n\n\tswitch ( tokenType ) {\n\t\tcase 'no-more-tokens':\n\t\t\t// If not in a block then flush output.\n\t\t\tif ( 0 === stackDepth ) {\n\t\t\t\taddFreeform();\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// Otherwise we have a problem\n\t\t\t// This is an error\n\t\t\t// we have options\n\t\t\t// - treat it all as freeform text\n\t\t\t// - assume an implicit closer (easiest when not nesting)\n\n\t\t\t// For the easy case we'll assume an implicit closer.\n\t\t\tif ( 1 === stackDepth ) {\n\t\t\t\taddBlockFromStack();\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// For the nested case where it's more difficult we'll\n\t\t\t// have to assume that multiple closers are missing\n\t\t\t// and so we'll collapse the whole stack piecewise.\n\t\t\twhile ( 0 < stack.length ) {\n\t\t\t\taddBlockFromStack();\n\t\t\t}\n\t\t\treturn false;\n\n\t\tcase 'void-block':\n\t\t\t// easy case is if we stumbled upon a void block\n\t\t\t// in the top-level of the document.\n\t\t\tif ( 0 === stackDepth ) {\n\t\t\t\tif ( null !== leadingHtmlStart ) {\n\t\t\t\t\toutput.push(\n\t\t\t\t\t\tFreeform(\n\t\t\t\t\t\t\tdocument.substr(\n\t\t\t\t\t\t\t\tleadingHtmlStart,\n\t\t\t\t\t\t\t\tstartOffset - leadingHtmlStart\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t)\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\toutput.push( Block( blockName, attrs, [], '', [] ) );\n\t\t\t\toffset = startOffset + tokenLength;\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\t// Otherwise we found an inner block.\n\t\t\taddInnerBlock(\n\t\t\t\tBlock( blockName, attrs, [], '', [] ),\n\t\t\t\tstartOffset,\n\t\t\t\ttokenLength\n\t\t\t);\n\t\t\toffset = startOffset + tokenLength;\n\t\t\treturn true;\n\n\t\tcase 'block-opener':\n\t\t\t// Track all newly-opened blocks on the stack.\n\t\t\tstack.push(\n\t\t\t\tFrame(\n\t\t\t\t\tBlock( blockName, attrs, [], '', [] ),\n\t\t\t\t\tstartOffset,\n\t\t\t\t\ttokenLength,\n\t\t\t\t\tstartOffset + tokenLength,\n\t\t\t\t\tleadingHtmlStart\n\t\t\t\t)\n\t\t\t);\n\t\t\toffset = startOffset + tokenLength;\n\t\t\treturn true;\n\n\t\tcase 'block-closer':\n\t\t\t// If we're missing an opener we're in trouble\n\t\t\t// This is an error.\n\t\t\tif ( 0 === stackDepth ) {\n\t\t\t\t// We have options\n\t\t\t\t// - assume an implicit opener\n\t\t\t\t// - assume _this_ is the opener\n\t\t\t\t// - give up and close out the document.\n\t\t\t\taddFreeform();\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// If we're not nesting then this is easy - close the block.\n\t\t\tif ( 1 === stackDepth ) {\n\t\t\t\taddBlockFromStack( startOffset );\n\t\t\t\toffset = startOffset + tokenLength;\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\t// Otherwise we're nested and we have to close out the current\n\t\t\t// block and add it as a innerBlock to the parent.\n\t\t\tconst stackTop = stack.pop();\n\t\t\tconst html = document.substr(\n\t\t\t\tstackTop.prevOffset,\n\t\t\t\tstartOffset - stackTop.prevOffset\n\t\t\t);\n\t\t\tstackTop.block.innerHTML += html;\n\t\t\tstackTop.block.innerContent.push( html );\n\t\t\tstackTop.prevOffset = startOffset + tokenLength;\n\n\t\t\taddInnerBlock(\n\t\t\t\tstackTop.block,\n\t\t\t\tstackTop.tokenStart,\n\t\t\t\tstackTop.tokenLength,\n\t\t\t\tstartOffset + tokenLength\n\t\t\t);\n\t\t\toffset = startOffset + tokenLength;\n\t\t\treturn true;\n\n\t\tdefault:\n\t\t\t// This is an error.\n\t\t\taddFreeform();\n\t\t\treturn false;\n\t}\n}\n\n/**\n * Parse JSON if valid, otherwise return null\n *\n * Note that JSON coming from the block comment\n * delimiters is constrained to be an object\n * and cannot be things like `true` or `null`\n *\n * @param {string} input JSON input string to parse\n * @return {Object|null} parsed JSON if valid\n */\nfunction parseJSON( input ) {\n\ttry {\n\t\treturn JSON.parse( input );\n\t} catch ( e ) {\n\t\treturn null;\n\t}\n}\n\nfunction nextToken() {\n\t// Aye the magic\n\t// we're using a single RegExp to tokenize the block comment delimiters\n\t// we're also using a trick here because the only difference between a\n\t// block opener and a block closer is the leading `/` before `wp:` (and\n\t// a closer has no attributes). we can trap them both and process the\n\t// match back in JavaScript to see which one it was.\n\tconst matches = tokenizer.exec( document );\n\n\t// We have no more tokens.\n\tif ( null === matches ) {\n\t\treturn [ 'no-more-tokens' ];\n\t}\n\n\tconst startedAt = matches.index;\n\tconst [\n\t\tmatch,\n\t\tcloserMatch,\n\t\tnamespaceMatch,\n\t\tnameMatch,\n\t\tattrsMatch /* Internal/unused. */,\n\t\t,\n\t\tvoidMatch,\n\t] = matches;\n\n\tconst length = match.length;\n\tconst isCloser = !! closerMatch;\n\tconst isVoid = !! voidMatch;\n\tconst namespace = namespaceMatch || 'core/';\n\tconst name = namespace + nameMatch;\n\tconst hasAttrs = !! attrsMatch;\n\tconst attrs = hasAttrs ? parseJSON( attrsMatch ) : {};\n\n\t// This state isn't allowed\n\t// This is an error.\n\tif ( isCloser && ( isVoid || hasAttrs ) ) {\n\t\t// We can ignore them since they don't hurt anything\n\t\t// we may warn against this at some point or reject it.\n\t}\n\n\tif ( isVoid ) {\n\t\treturn [ 'void-block', name, attrs, startedAt, length ];\n\t}\n\n\tif ( isCloser ) {\n\t\treturn [ 'block-closer', name, null, startedAt, length ];\n\t}\n\n\treturn [ 'block-opener', name, attrs, startedAt, length ];\n}\n\nfunction addFreeform( rawLength ) {\n\tconst length = rawLength ? rawLength : document.length - offset;\n\n\tif ( 0 === length ) {\n\t\treturn;\n\t}\n\n\toutput.push( Freeform( document.substr( offset, length ) ) );\n}\n\nfunction addInnerBlock( block, tokenStart, tokenLength, lastOffset ) {\n\tconst parent = stack[ stack.length - 1 ];\n\tparent.block.innerBlocks.push( block );\n\tconst html = document.substr(\n\t\tparent.prevOffset,\n\t\ttokenStart - parent.prevOffset\n\t);\n\n\tif ( html ) {\n\t\tparent.block.innerHTML += html;\n\t\tparent.block.innerContent.push( html );\n\t}\n\n\tparent.block.innerContent.push( null );\n\tparent.prevOffset = lastOffset ? lastOffset : tokenStart + tokenLength;\n}\n\nfunction addBlockFromStack( endOffset ) {\n\tconst { block, leadingHtmlStart, prevOffset, tokenStart } = stack.pop();\n\n\tconst html = endOffset\n\t\t? document.substr( prevOffset, endOffset - prevOffset )\n\t\t: document.substr( prevOffset );\n\n\tif ( html ) {\n\t\tblock.innerHTML += html;\n\t\tblock.innerContent.push( html );\n\t}\n\n\tif ( null !== leadingHtmlStart ) {\n\t\toutput.push(\n\t\t\tFreeform(\n\t\t\t\tdocument.substr(\n\t\t\t\t\tleadingHtmlStart,\n\t\t\t\t\ttokenStart - leadingHtmlStart\n\t\t\t\t)\n\t\t\t)\n\t\t);\n\t}\n\n\toutput.push( block );\n}\n"]}
|
package/build-module/index.js
CHANGED
|
@@ -164,13 +164,13 @@ export const parse = doc => {
|
|
|
164
164
|
function proceed() {
|
|
165
165
|
const next = nextToken();
|
|
166
166
|
const [tokenType, blockName, attrs, startOffset, tokenLength] = next;
|
|
167
|
-
const stackDepth = stack.length; //
|
|
167
|
+
const stackDepth = stack.length; // We may have some HTML soup before the next block.
|
|
168
168
|
|
|
169
169
|
const leadingHtmlStart = startOffset > offset ? offset : null;
|
|
170
170
|
|
|
171
171
|
switch (tokenType) {
|
|
172
172
|
case 'no-more-tokens':
|
|
173
|
-
//
|
|
173
|
+
// If not in a block then flush output.
|
|
174
174
|
if (0 === stackDepth) {
|
|
175
175
|
addFreeform();
|
|
176
176
|
return false;
|
|
@@ -179,15 +179,15 @@ function proceed() {
|
|
|
179
179
|
// we have options
|
|
180
180
|
// - treat it all as freeform text
|
|
181
181
|
// - assume an implicit closer (easiest when not nesting)
|
|
182
|
-
//
|
|
182
|
+
// For the easy case we'll assume an implicit closer.
|
|
183
183
|
|
|
184
184
|
|
|
185
185
|
if (1 === stackDepth) {
|
|
186
186
|
addBlockFromStack();
|
|
187
187
|
return false;
|
|
188
|
-
} //
|
|
188
|
+
} // For the nested case where it's more difficult we'll
|
|
189
189
|
// have to assume that multiple closers are missing
|
|
190
|
-
// and so we'll collapse the whole stack piecewise
|
|
190
|
+
// and so we'll collapse the whole stack piecewise.
|
|
191
191
|
|
|
192
192
|
|
|
193
193
|
while (0 < stack.length) {
|
|
@@ -198,7 +198,7 @@ function proceed() {
|
|
|
198
198
|
|
|
199
199
|
case 'void-block':
|
|
200
200
|
// easy case is if we stumbled upon a void block
|
|
201
|
-
// in the top-level of the document
|
|
201
|
+
// in the top-level of the document.
|
|
202
202
|
if (0 === stackDepth) {
|
|
203
203
|
if (null !== leadingHtmlStart) {
|
|
204
204
|
output.push(Freeform(document.substr(leadingHtmlStart, startOffset - leadingHtmlStart)));
|
|
@@ -207,7 +207,7 @@ function proceed() {
|
|
|
207
207
|
output.push(Block(blockName, attrs, [], '', []));
|
|
208
208
|
offset = startOffset + tokenLength;
|
|
209
209
|
return true;
|
|
210
|
-
} //
|
|
210
|
+
} // Otherwise we found an inner block.
|
|
211
211
|
|
|
212
212
|
|
|
213
213
|
addInnerBlock(Block(blockName, attrs, [], '', []), startOffset, tokenLength);
|
|
@@ -215,30 +215,30 @@ function proceed() {
|
|
|
215
215
|
return true;
|
|
216
216
|
|
|
217
217
|
case 'block-opener':
|
|
218
|
-
//
|
|
218
|
+
// Track all newly-opened blocks on the stack.
|
|
219
219
|
stack.push(Frame(Block(blockName, attrs, [], '', []), startOffset, tokenLength, startOffset + tokenLength, leadingHtmlStart));
|
|
220
220
|
offset = startOffset + tokenLength;
|
|
221
221
|
return true;
|
|
222
222
|
|
|
223
223
|
case 'block-closer':
|
|
224
|
-
//
|
|
225
|
-
// This is an error
|
|
224
|
+
// If we're missing an opener we're in trouble
|
|
225
|
+
// This is an error.
|
|
226
226
|
if (0 === stackDepth) {
|
|
227
|
-
//
|
|
227
|
+
// We have options
|
|
228
228
|
// - assume an implicit opener
|
|
229
229
|
// - assume _this_ is the opener
|
|
230
|
-
//
|
|
230
|
+
// - give up and close out the document.
|
|
231
231
|
addFreeform();
|
|
232
232
|
return false;
|
|
233
|
-
} //
|
|
233
|
+
} // If we're not nesting then this is easy - close the block.
|
|
234
234
|
|
|
235
235
|
|
|
236
236
|
if (1 === stackDepth) {
|
|
237
237
|
addBlockFromStack(startOffset);
|
|
238
238
|
offset = startOffset + tokenLength;
|
|
239
239
|
return true;
|
|
240
|
-
} //
|
|
241
|
-
// block and add it as a innerBlock to the parent
|
|
240
|
+
} // Otherwise we're nested and we have to close out the current
|
|
241
|
+
// block and add it as a innerBlock to the parent.
|
|
242
242
|
|
|
243
243
|
|
|
244
244
|
const stackTop = stack.pop();
|
|
@@ -251,7 +251,7 @@ function proceed() {
|
|
|
251
251
|
return true;
|
|
252
252
|
|
|
253
253
|
default:
|
|
254
|
-
// This is an error
|
|
254
|
+
// This is an error.
|
|
255
255
|
addFreeform();
|
|
256
256
|
return false;
|
|
257
257
|
}
|
|
@@ -277,13 +277,13 @@ function parseJSON(input) {
|
|
|
277
277
|
}
|
|
278
278
|
|
|
279
279
|
function nextToken() {
|
|
280
|
-
//
|
|
280
|
+
// Aye the magic
|
|
281
281
|
// we're using a single RegExp to tokenize the block comment delimiters
|
|
282
282
|
// we're also using a trick here because the only difference between a
|
|
283
283
|
// block opener and a block closer is the leading `/` before `wp:` (and
|
|
284
284
|
// a closer has no attributes). we can trap them both and process the
|
|
285
285
|
// match back in JavaScript to see which one it was.
|
|
286
|
-
const matches = tokenizer.exec(document); //
|
|
286
|
+
const matches = tokenizer.exec(document); // We have no more tokens.
|
|
287
287
|
|
|
288
288
|
if (null === matches) {
|
|
289
289
|
return ['no-more-tokens'];
|
|
@@ -291,7 +291,7 @@ function nextToken() {
|
|
|
291
291
|
|
|
292
292
|
const startedAt = matches.index;
|
|
293
293
|
const [match, closerMatch, namespaceMatch, nameMatch, attrsMatch
|
|
294
|
-
/*
|
|
294
|
+
/* Internal/unused. */
|
|
295
295
|
,, voidMatch] = matches;
|
|
296
296
|
const length = match.length;
|
|
297
297
|
const isCloser = !!closerMatch;
|
|
@@ -300,10 +300,10 @@ function nextToken() {
|
|
|
300
300
|
const name = namespace + nameMatch;
|
|
301
301
|
const hasAttrs = !!attrsMatch;
|
|
302
302
|
const attrs = hasAttrs ? parseJSON(attrsMatch) : {}; // This state isn't allowed
|
|
303
|
-
// This is an error
|
|
303
|
+
// This is an error.
|
|
304
304
|
|
|
305
|
-
if (isCloser && (isVoid || hasAttrs)) {//
|
|
306
|
-
// we may warn against this at some point or reject it
|
|
305
|
+
if (isCloser && (isVoid || hasAttrs)) {// We can ignore them since they don't hurt anything
|
|
306
|
+
// we may warn against this at some point or reject it.
|
|
307
307
|
}
|
|
308
308
|
|
|
309
309
|
if (isVoid) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["@wordpress/block-serialization-default-parser/src/index.js"],"names":["document","offset","output","stack","tokenizer","Block","blockName","attrs","innerBlocks","innerHTML","innerContent","Freeform","Frame","block","tokenStart","tokenLength","prevOffset","leadingHtmlStart","parse","doc","lastIndex","proceed","next","nextToken","tokenType","startOffset","stackDepth","length","addFreeform","addBlockFromStack","push","substr","addInnerBlock","stackTop","pop","html","parseJSON","input","JSON","e","matches","exec","startedAt","index","match","closerMatch","namespaceMatch","nameMatch","attrsMatch","voidMatch","isCloser","isVoid","namespace","name","hasAttrs","rawLength","lastOffset","parent","endOffset"],"mappings":"AAAA,IAAIA,QAAJ;AACA,IAAIC,MAAJ;AACA,IAAIC,MAAJ;AACA,IAAIC,KAAJ;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AACA,MAAMC,SAAS,GAAG,8HAAlB;;AAEA,SAASC,KAAT,CAAgBC,SAAhB,EAA2BC,KAA3B,EAAkCC,WAAlC,EAA+CC,SAA/C,EAA0DC,YAA1D,EAAyE;AACxE,SAAO;AACNJ,IAAAA,SADM;AAENC,IAAAA,KAFM;AAGNC,IAAAA,WAHM;AAINC,IAAAA,SAJM;AAKNC,IAAAA;AALM,GAAP;AAOA;;AAED,SAASC,QAAT,CAAmBF,SAAnB,EAA+B;AAC9B,SAAOJ,KAAK,CAAE,IAAF,EAAQ,EAAR,EAAY,EAAZ,EAAgBI,SAAhB,EAA2B,CAAEA,SAAF,CAA3B,CAAZ;AACA;;AAED,SAASG,KAAT,CAAgBC,KAAhB,EAAuBC,UAAvB,EAAmCC,WAAnC,EAAgDC,UAAhD,EAA4DC,gBAA5D,EAA+E;AAC9E,SAAO;AACNJ,IAAAA,KADM;AAENC,IAAAA,UAFM;AAGNC,IAAAA,WAHM;AAINC,IAAAA,UAAU,EAAEA,UAAU,IAAIF,UAAU,GAAGC,WAJjC;AAKNE,IAAAA;AALM,GAAP;AAOA;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;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","sourcesContent":["let document;\nlet offset;\nlet output;\nlet stack;\n\n/**\n * Matches block comment delimiters\n *\n * While most of this pattern is straightforward the attribute parsing\n * incorporates a tricks to make sure we don't choke on specific input\n *\n * - since JavaScript has no possessive quantifier or atomic grouping\n * we are emulating it with a trick\n *\n * we want a possessive quantifier or atomic group to prevent backtracking\n * on the `}`s should we fail to match the remainder of the pattern\n *\n * we can emulate this with a positive lookahead and back reference\n * (a++)*c === ((?=(a+))\\1)*c\n *\n * let's examine an example:\n * - /(a+)*c/.test('aaaaaaaaaaaaad') fails after over 49,000 steps\n * - /(a++)*c/.test('aaaaaaaaaaaaad') fails after 85 steps\n * - /(?>a+)*c/.test('aaaaaaaaaaaaad') fails after 126 steps\n *\n * this is because the possessive `++` and the atomic group `(?>)`\n * tell the engine that all those `a`s belong together as a single group\n * and so it won't split it up when stepping backwards to try and match\n *\n * if we use /((?=(a+))\\1)*c/ then we get the same behavior as the atomic group\n * or possessive and prevent the backtracking because the `a+` is matched but\n * not captured. thus, we find the long string of `a`s and remember it, then\n * reference it as a whole unit inside our pattern\n *\n * @see http://instanceof.me/post/52245507631/regex-emulate-atomic-grouping-with-lookahead\n * @see http://blog.stevenlevithan.com/archives/mimic-atomic-groups\n * @see https://javascript.info/regexp-infinite-backtracking-problem\n *\n * once browsers reliably support atomic grouping or possessive\n * quantifiers natively we should remove this trick and simplify\n *\n * @type {RegExp}\n *\n * @since 3.8.0\n * @since 4.6.1 added optimization to prevent backtracking on attribute parsing\n */\nconst tokenizer = /<!--\\s+(\\/)?wp:([a-z][a-z0-9_-]*\\/)?([a-z][a-z0-9_-]*)\\s+({(?:(?=([^}]+|}+(?=})|(?!}\\s+\\/?-->)[^])*)\\5|[^]*?)}\\s+)?(\\/)?-->/g;\n\nfunction Block( blockName, attrs, innerBlocks, innerHTML, innerContent ) {\n\treturn {\n\t\tblockName,\n\t\tattrs,\n\t\tinnerBlocks,\n\t\tinnerHTML,\n\t\tinnerContent,\n\t};\n}\n\nfunction Freeform( innerHTML ) {\n\treturn Block( null, {}, [], innerHTML, [ innerHTML ] );\n}\n\nfunction Frame( block, tokenStart, tokenLength, prevOffset, leadingHtmlStart ) {\n\treturn {\n\t\tblock,\n\t\ttokenStart,\n\t\ttokenLength,\n\t\tprevOffset: prevOffset || tokenStart + tokenLength,\n\t\tleadingHtmlStart,\n\t};\n}\n\n/**\n * Parser function, that converts input HTML into a block based structure.\n *\n * @param {string} doc The HTML document to parse.\n *\n * @example\n * Input post:\n * ```html\n * <!-- wp:columns {\"columns\":3} -->\n * <div class=\"wp-block-columns has-3-columns\"><!-- wp:column -->\n * <div class=\"wp-block-column\"><!-- wp:paragraph -->\n * <p>Left</p>\n * <!-- /wp:paragraph --></div>\n * <!-- /wp:column -->\n *\n * <!-- wp:column -->\n * <div class=\"wp-block-column\"><!-- wp:paragraph -->\n * <p><strong>Middle</strong></p>\n * <!-- /wp:paragraph --></div>\n * <!-- /wp:column -->\n *\n * <!-- wp:column -->\n * <div class=\"wp-block-column\"></div>\n * <!-- /wp:column --></div>\n * <!-- /wp:columns -->\n * ```\n *\n * Parsing code:\n * ```js\n * import { parse } from '@wordpress/block-serialization-default-parser';\n *\n * parse( post ) === [\n * {\n * blockName: \"core/columns\",\n * attrs: {\n * columns: 3\n * },\n * innerBlocks: [\n * {\n * blockName: \"core/column\",\n * attrs: null,\n * innerBlocks: [\n * {\n * blockName: \"core/paragraph\",\n * attrs: null,\n * innerBlocks: [],\n * innerHTML: \"\\n<p>Left</p>\\n\"\n * }\n * ],\n * innerHTML: '\\n<div class=\"wp-block-column\"></div>\\n'\n * },\n * {\n * blockName: \"core/column\",\n * attrs: null,\n * innerBlocks: [\n * {\n * blockName: \"core/paragraph\",\n * attrs: null,\n * innerBlocks: [],\n * innerHTML: \"\\n<p><strong>Middle</strong></p>\\n\"\n * }\n * ],\n * innerHTML: '\\n<div class=\"wp-block-column\"></div>\\n'\n * },\n * {\n * blockName: \"core/column\",\n * attrs: null,\n * innerBlocks: [],\n * innerHTML: '\\n<div class=\"wp-block-column\"></div>\\n'\n * }\n * ],\n * innerHTML: '\\n<div class=\"wp-block-columns has-3-columns\">\\n\\n\\n\\n</div>\\n'\n * }\n * ];\n * ```\n * @return {Array} A block-based representation of the input HTML.\n */\nexport const parse = ( doc ) => {\n\tdocument = doc;\n\toffset = 0;\n\toutput = [];\n\tstack = [];\n\ttokenizer.lastIndex = 0;\n\n\tdo {\n\t\t// twiddle our thumbs\n\t} while ( proceed() );\n\n\treturn output;\n};\n\nfunction proceed() {\n\tconst next = nextToken();\n\tconst [ tokenType, blockName, attrs, startOffset, tokenLength ] = next;\n\tconst stackDepth = stack.length;\n\n\t// we may have some HTML soup before the next block\n\tconst leadingHtmlStart = startOffset > offset ? offset : null;\n\n\tswitch ( tokenType ) {\n\t\tcase 'no-more-tokens':\n\t\t\t// if not in a block then flush output\n\t\t\tif ( 0 === stackDepth ) {\n\t\t\t\taddFreeform();\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// Otherwise we have a problem\n\t\t\t// This is an error\n\t\t\t// we have options\n\t\t\t// - treat it all as freeform text\n\t\t\t// - assume an implicit closer (easiest when not nesting)\n\n\t\t\t// for the easy case we'll assume an implicit closer\n\t\t\tif ( 1 === stackDepth ) {\n\t\t\t\taddBlockFromStack();\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// for the nested case where it's more difficult we'll\n\t\t\t// have to assume that multiple closers are missing\n\t\t\t// and so we'll collapse the whole stack piecewise\n\t\t\twhile ( 0 < stack.length ) {\n\t\t\t\taddBlockFromStack();\n\t\t\t}\n\t\t\treturn false;\n\n\t\tcase 'void-block':\n\t\t\t// easy case is if we stumbled upon a void block\n\t\t\t// in the top-level of the document\n\t\t\tif ( 0 === stackDepth ) {\n\t\t\t\tif ( null !== leadingHtmlStart ) {\n\t\t\t\t\toutput.push(\n\t\t\t\t\t\tFreeform(\n\t\t\t\t\t\t\tdocument.substr(\n\t\t\t\t\t\t\t\tleadingHtmlStart,\n\t\t\t\t\t\t\t\tstartOffset - leadingHtmlStart\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t)\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\toutput.push( Block( blockName, attrs, [], '', [] ) );\n\t\t\t\toffset = startOffset + tokenLength;\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\t// otherwise we found an inner block\n\t\t\taddInnerBlock(\n\t\t\t\tBlock( blockName, attrs, [], '', [] ),\n\t\t\t\tstartOffset,\n\t\t\t\ttokenLength\n\t\t\t);\n\t\t\toffset = startOffset + tokenLength;\n\t\t\treturn true;\n\n\t\tcase 'block-opener':\n\t\t\t// track all newly-opened blocks on the stack\n\t\t\tstack.push(\n\t\t\t\tFrame(\n\t\t\t\t\tBlock( blockName, attrs, [], '', [] ),\n\t\t\t\t\tstartOffset,\n\t\t\t\t\ttokenLength,\n\t\t\t\t\tstartOffset + tokenLength,\n\t\t\t\t\tleadingHtmlStart\n\t\t\t\t)\n\t\t\t);\n\t\t\toffset = startOffset + tokenLength;\n\t\t\treturn true;\n\n\t\tcase 'block-closer':\n\t\t\t// if we're missing an opener we're in trouble\n\t\t\t// This is an error\n\t\t\tif ( 0 === stackDepth ) {\n\t\t\t\t// we have options\n\t\t\t\t// - assume an implicit opener\n\t\t\t\t// - assume _this_ is the opener\n\t\t\t\t// - give up and close out the document\n\t\t\t\taddFreeform();\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// if we're not nesting then this is easy - close the block\n\t\t\tif ( 1 === stackDepth ) {\n\t\t\t\taddBlockFromStack( startOffset );\n\t\t\t\toffset = startOffset + tokenLength;\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\t// otherwise we're nested and we have to close out the current\n\t\t\t// block and add it as a innerBlock to the parent\n\t\t\tconst stackTop = stack.pop();\n\t\t\tconst html = document.substr(\n\t\t\t\tstackTop.prevOffset,\n\t\t\t\tstartOffset - stackTop.prevOffset\n\t\t\t);\n\t\t\tstackTop.block.innerHTML += html;\n\t\t\tstackTop.block.innerContent.push( html );\n\t\t\tstackTop.prevOffset = startOffset + tokenLength;\n\n\t\t\taddInnerBlock(\n\t\t\t\tstackTop.block,\n\t\t\t\tstackTop.tokenStart,\n\t\t\t\tstackTop.tokenLength,\n\t\t\t\tstartOffset + tokenLength\n\t\t\t);\n\t\t\toffset = startOffset + tokenLength;\n\t\t\treturn true;\n\n\t\tdefault:\n\t\t\t// This is an error\n\t\t\taddFreeform();\n\t\t\treturn false;\n\t}\n}\n\n/**\n * Parse JSON if valid, otherwise return null\n *\n * Note that JSON coming from the block comment\n * delimiters is constrained to be an object\n * and cannot be things like `true` or `null`\n *\n * @param {string} input JSON input string to parse\n * @return {Object|null} parsed JSON if valid\n */\nfunction parseJSON( input ) {\n\ttry {\n\t\treturn JSON.parse( input );\n\t} catch ( e ) {\n\t\treturn null;\n\t}\n}\n\nfunction nextToken() {\n\t// aye the magic\n\t// we're using a single RegExp to tokenize the block comment delimiters\n\t// we're also using a trick here because the only difference between a\n\t// block opener and a block closer is the leading `/` before `wp:` (and\n\t// a closer has no attributes). we can trap them both and process the\n\t// match back in JavaScript to see which one it was.\n\tconst matches = tokenizer.exec( document );\n\n\t// we have no more tokens\n\tif ( null === matches ) {\n\t\treturn [ 'no-more-tokens' ];\n\t}\n\n\tconst startedAt = matches.index;\n\tconst [\n\t\tmatch,\n\t\tcloserMatch,\n\t\tnamespaceMatch,\n\t\tnameMatch,\n\t\tattrsMatch /* internal/unused */,\n\t\t,\n\t\tvoidMatch,\n\t] = matches;\n\n\tconst length = match.length;\n\tconst isCloser = !! closerMatch;\n\tconst isVoid = !! voidMatch;\n\tconst namespace = namespaceMatch || 'core/';\n\tconst name = namespace + nameMatch;\n\tconst hasAttrs = !! attrsMatch;\n\tconst attrs = hasAttrs ? parseJSON( attrsMatch ) : {};\n\n\t// This state isn't allowed\n\t// This is an error\n\tif ( isCloser && ( isVoid || hasAttrs ) ) {\n\t\t// we can ignore them since they don't hurt anything\n\t\t// we may warn against this at some point or reject it\n\t}\n\n\tif ( isVoid ) {\n\t\treturn [ 'void-block', name, attrs, startedAt, length ];\n\t}\n\n\tif ( isCloser ) {\n\t\treturn [ 'block-closer', name, null, startedAt, length ];\n\t}\n\n\treturn [ 'block-opener', name, attrs, startedAt, length ];\n}\n\nfunction addFreeform( rawLength ) {\n\tconst length = rawLength ? rawLength : document.length - offset;\n\n\tif ( 0 === length ) {\n\t\treturn;\n\t}\n\n\toutput.push( Freeform( document.substr( offset, length ) ) );\n}\n\nfunction addInnerBlock( block, tokenStart, tokenLength, lastOffset ) {\n\tconst parent = stack[ stack.length - 1 ];\n\tparent.block.innerBlocks.push( block );\n\tconst html = document.substr(\n\t\tparent.prevOffset,\n\t\ttokenStart - parent.prevOffset\n\t);\n\n\tif ( html ) {\n\t\tparent.block.innerHTML += html;\n\t\tparent.block.innerContent.push( html );\n\t}\n\n\tparent.block.innerContent.push( null );\n\tparent.prevOffset = lastOffset ? lastOffset : tokenStart + tokenLength;\n}\n\nfunction addBlockFromStack( endOffset ) {\n\tconst { block, leadingHtmlStart, prevOffset, tokenStart } = stack.pop();\n\n\tconst html = endOffset\n\t\t? document.substr( prevOffset, endOffset - prevOffset )\n\t\t: document.substr( prevOffset );\n\n\tif ( html ) {\n\t\tblock.innerHTML += html;\n\t\tblock.innerContent.push( html );\n\t}\n\n\tif ( null !== leadingHtmlStart ) {\n\t\toutput.push(\n\t\t\tFreeform(\n\t\t\t\tdocument.substr(\n\t\t\t\t\tleadingHtmlStart,\n\t\t\t\t\ttokenStart - leadingHtmlStart\n\t\t\t\t)\n\t\t\t)\n\t\t);\n\t}\n\n\toutput.push( block );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["@wordpress/block-serialization-default-parser/src/index.js"],"names":["document","offset","output","stack","tokenizer","Block","blockName","attrs","innerBlocks","innerHTML","innerContent","Freeform","Frame","block","tokenStart","tokenLength","prevOffset","leadingHtmlStart","parse","doc","lastIndex","proceed","next","nextToken","tokenType","startOffset","stackDepth","length","addFreeform","addBlockFromStack","push","substr","addInnerBlock","stackTop","pop","html","parseJSON","input","JSON","e","matches","exec","startedAt","index","match","closerMatch","namespaceMatch","nameMatch","attrsMatch","voidMatch","isCloser","isVoid","namespace","name","hasAttrs","rawLength","lastOffset","parent","endOffset"],"mappings":"AAAA,IAAIA,QAAJ;AACA,IAAIC,MAAJ;AACA,IAAIC,MAAJ;AACA,IAAIC,KAAJ;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AACA,MAAMC,SAAS,GAAG,8HAAlB;;AAEA,SAASC,KAAT,CAAgBC,SAAhB,EAA2BC,KAA3B,EAAkCC,WAAlC,EAA+CC,SAA/C,EAA0DC,YAA1D,EAAyE;AACxE,SAAO;AACNJ,IAAAA,SADM;AAENC,IAAAA,KAFM;AAGNC,IAAAA,WAHM;AAINC,IAAAA,SAJM;AAKNC,IAAAA;AALM,GAAP;AAOA;;AAED,SAASC,QAAT,CAAmBF,SAAnB,EAA+B;AAC9B,SAAOJ,KAAK,CAAE,IAAF,EAAQ,EAAR,EAAY,EAAZ,EAAgBI,SAAhB,EAA2B,CAAEA,SAAF,CAA3B,CAAZ;AACA;;AAED,SAASG,KAAT,CAAgBC,KAAhB,EAAuBC,UAAvB,EAAmCC,WAAnC,EAAgDC,UAAhD,EAA4DC,gBAA5D,EAA+E;AAC9E,SAAO;AACNJ,IAAAA,KADM;AAENC,IAAAA,UAFM;AAGNC,IAAAA,WAHM;AAINC,IAAAA,UAAU,EAAEA,UAAU,IAAIF,UAAU,GAAGC,WAJjC;AAKNE,IAAAA;AALM,GAAP;AAOA;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;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","sourcesContent":["let document;\nlet offset;\nlet output;\nlet stack;\n\n/**\n * Matches block comment delimiters\n *\n * While most of this pattern is straightforward the attribute parsing\n * incorporates a tricks to make sure we don't choke on specific input\n *\n * - since JavaScript has no possessive quantifier or atomic grouping\n * we are emulating it with a trick\n *\n * we want a possessive quantifier or atomic group to prevent backtracking\n * on the `}`s should we fail to match the remainder of the pattern\n *\n * we can emulate this with a positive lookahead and back reference\n * (a++)*c === ((?=(a+))\\1)*c\n *\n * let's examine an example:\n * - /(a+)*c/.test('aaaaaaaaaaaaad') fails after over 49,000 steps\n * - /(a++)*c/.test('aaaaaaaaaaaaad') fails after 85 steps\n * - /(?>a+)*c/.test('aaaaaaaaaaaaad') fails after 126 steps\n *\n * this is because the possessive `++` and the atomic group `(?>)`\n * tell the engine that all those `a`s belong together as a single group\n * and so it won't split it up when stepping backwards to try and match\n *\n * if we use /((?=(a+))\\1)*c/ then we get the same behavior as the atomic group\n * or possessive and prevent the backtracking because the `a+` is matched but\n * not captured. thus, we find the long string of `a`s and remember it, then\n * reference it as a whole unit inside our pattern\n *\n * @see http://instanceof.me/post/52245507631/regex-emulate-atomic-grouping-with-lookahead\n * @see http://blog.stevenlevithan.com/archives/mimic-atomic-groups\n * @see https://javascript.info/regexp-infinite-backtracking-problem\n *\n * once browsers reliably support atomic grouping or possessive\n * quantifiers natively we should remove this trick and simplify\n *\n * @type {RegExp}\n *\n * @since 3.8.0\n * @since 4.6.1 added optimization to prevent backtracking on attribute parsing\n */\nconst tokenizer = /<!--\\s+(\\/)?wp:([a-z][a-z0-9_-]*\\/)?([a-z][a-z0-9_-]*)\\s+({(?:(?=([^}]+|}+(?=})|(?!}\\s+\\/?-->)[^])*)\\5|[^]*?)}\\s+)?(\\/)?-->/g;\n\nfunction Block( blockName, attrs, innerBlocks, innerHTML, innerContent ) {\n\treturn {\n\t\tblockName,\n\t\tattrs,\n\t\tinnerBlocks,\n\t\tinnerHTML,\n\t\tinnerContent,\n\t};\n}\n\nfunction Freeform( innerHTML ) {\n\treturn Block( null, {}, [], innerHTML, [ innerHTML ] );\n}\n\nfunction Frame( block, tokenStart, tokenLength, prevOffset, leadingHtmlStart ) {\n\treturn {\n\t\tblock,\n\t\ttokenStart,\n\t\ttokenLength,\n\t\tprevOffset: prevOffset || tokenStart + tokenLength,\n\t\tleadingHtmlStart,\n\t};\n}\n\n/**\n * Parser function, that converts input HTML into a block based structure.\n *\n * @param {string} doc The HTML document to parse.\n *\n * @example\n * Input post:\n * ```html\n * <!-- wp:columns {\"columns\":3} -->\n * <div class=\"wp-block-columns has-3-columns\"><!-- wp:column -->\n * <div class=\"wp-block-column\"><!-- wp:paragraph -->\n * <p>Left</p>\n * <!-- /wp:paragraph --></div>\n * <!-- /wp:column -->\n *\n * <!-- wp:column -->\n * <div class=\"wp-block-column\"><!-- wp:paragraph -->\n * <p><strong>Middle</strong></p>\n * <!-- /wp:paragraph --></div>\n * <!-- /wp:column -->\n *\n * <!-- wp:column -->\n * <div class=\"wp-block-column\"></div>\n * <!-- /wp:column --></div>\n * <!-- /wp:columns -->\n * ```\n *\n * Parsing code:\n * ```js\n * import { parse } from '@wordpress/block-serialization-default-parser';\n *\n * parse( post ) === [\n * {\n * blockName: \"core/columns\",\n * attrs: {\n * columns: 3\n * },\n * innerBlocks: [\n * {\n * blockName: \"core/column\",\n * attrs: null,\n * innerBlocks: [\n * {\n * blockName: \"core/paragraph\",\n * attrs: null,\n * innerBlocks: [],\n * innerHTML: \"\\n<p>Left</p>\\n\"\n * }\n * ],\n * innerHTML: '\\n<div class=\"wp-block-column\"></div>\\n'\n * },\n * {\n * blockName: \"core/column\",\n * attrs: null,\n * innerBlocks: [\n * {\n * blockName: \"core/paragraph\",\n * attrs: null,\n * innerBlocks: [],\n * innerHTML: \"\\n<p><strong>Middle</strong></p>\\n\"\n * }\n * ],\n * innerHTML: '\\n<div class=\"wp-block-column\"></div>\\n'\n * },\n * {\n * blockName: \"core/column\",\n * attrs: null,\n * innerBlocks: [],\n * innerHTML: '\\n<div class=\"wp-block-column\"></div>\\n'\n * }\n * ],\n * innerHTML: '\\n<div class=\"wp-block-columns has-3-columns\">\\n\\n\\n\\n</div>\\n'\n * }\n * ];\n * ```\n * @return {Array} A block-based representation of the input HTML.\n */\nexport const parse = ( doc ) => {\n\tdocument = doc;\n\toffset = 0;\n\toutput = [];\n\tstack = [];\n\ttokenizer.lastIndex = 0;\n\n\tdo {\n\t\t// twiddle our thumbs\n\t} while ( proceed() );\n\n\treturn output;\n};\n\nfunction proceed() {\n\tconst next = nextToken();\n\tconst [ tokenType, blockName, attrs, startOffset, tokenLength ] = next;\n\tconst stackDepth = stack.length;\n\n\t// We may have some HTML soup before the next block.\n\tconst leadingHtmlStart = startOffset > offset ? offset : null;\n\n\tswitch ( tokenType ) {\n\t\tcase 'no-more-tokens':\n\t\t\t// If not in a block then flush output.\n\t\t\tif ( 0 === stackDepth ) {\n\t\t\t\taddFreeform();\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// Otherwise we have a problem\n\t\t\t// This is an error\n\t\t\t// we have options\n\t\t\t// - treat it all as freeform text\n\t\t\t// - assume an implicit closer (easiest when not nesting)\n\n\t\t\t// For the easy case we'll assume an implicit closer.\n\t\t\tif ( 1 === stackDepth ) {\n\t\t\t\taddBlockFromStack();\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// For the nested case where it's more difficult we'll\n\t\t\t// have to assume that multiple closers are missing\n\t\t\t// and so we'll collapse the whole stack piecewise.\n\t\t\twhile ( 0 < stack.length ) {\n\t\t\t\taddBlockFromStack();\n\t\t\t}\n\t\t\treturn false;\n\n\t\tcase 'void-block':\n\t\t\t// easy case is if we stumbled upon a void block\n\t\t\t// in the top-level of the document.\n\t\t\tif ( 0 === stackDepth ) {\n\t\t\t\tif ( null !== leadingHtmlStart ) {\n\t\t\t\t\toutput.push(\n\t\t\t\t\t\tFreeform(\n\t\t\t\t\t\t\tdocument.substr(\n\t\t\t\t\t\t\t\tleadingHtmlStart,\n\t\t\t\t\t\t\t\tstartOffset - leadingHtmlStart\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t)\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\toutput.push( Block( blockName, attrs, [], '', [] ) );\n\t\t\t\toffset = startOffset + tokenLength;\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\t// Otherwise we found an inner block.\n\t\t\taddInnerBlock(\n\t\t\t\tBlock( blockName, attrs, [], '', [] ),\n\t\t\t\tstartOffset,\n\t\t\t\ttokenLength\n\t\t\t);\n\t\t\toffset = startOffset + tokenLength;\n\t\t\treturn true;\n\n\t\tcase 'block-opener':\n\t\t\t// Track all newly-opened blocks on the stack.\n\t\t\tstack.push(\n\t\t\t\tFrame(\n\t\t\t\t\tBlock( blockName, attrs, [], '', [] ),\n\t\t\t\t\tstartOffset,\n\t\t\t\t\ttokenLength,\n\t\t\t\t\tstartOffset + tokenLength,\n\t\t\t\t\tleadingHtmlStart\n\t\t\t\t)\n\t\t\t);\n\t\t\toffset = startOffset + tokenLength;\n\t\t\treturn true;\n\n\t\tcase 'block-closer':\n\t\t\t// If we're missing an opener we're in trouble\n\t\t\t// This is an error.\n\t\t\tif ( 0 === stackDepth ) {\n\t\t\t\t// We have options\n\t\t\t\t// - assume an implicit opener\n\t\t\t\t// - assume _this_ is the opener\n\t\t\t\t// - give up and close out the document.\n\t\t\t\taddFreeform();\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// If we're not nesting then this is easy - close the block.\n\t\t\tif ( 1 === stackDepth ) {\n\t\t\t\taddBlockFromStack( startOffset );\n\t\t\t\toffset = startOffset + tokenLength;\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\t// Otherwise we're nested and we have to close out the current\n\t\t\t// block and add it as a innerBlock to the parent.\n\t\t\tconst stackTop = stack.pop();\n\t\t\tconst html = document.substr(\n\t\t\t\tstackTop.prevOffset,\n\t\t\t\tstartOffset - stackTop.prevOffset\n\t\t\t);\n\t\t\tstackTop.block.innerHTML += html;\n\t\t\tstackTop.block.innerContent.push( html );\n\t\t\tstackTop.prevOffset = startOffset + tokenLength;\n\n\t\t\taddInnerBlock(\n\t\t\t\tstackTop.block,\n\t\t\t\tstackTop.tokenStart,\n\t\t\t\tstackTop.tokenLength,\n\t\t\t\tstartOffset + tokenLength\n\t\t\t);\n\t\t\toffset = startOffset + tokenLength;\n\t\t\treturn true;\n\n\t\tdefault:\n\t\t\t// This is an error.\n\t\t\taddFreeform();\n\t\t\treturn false;\n\t}\n}\n\n/**\n * Parse JSON if valid, otherwise return null\n *\n * Note that JSON coming from the block comment\n * delimiters is constrained to be an object\n * and cannot be things like `true` or `null`\n *\n * @param {string} input JSON input string to parse\n * @return {Object|null} parsed JSON if valid\n */\nfunction parseJSON( input ) {\n\ttry {\n\t\treturn JSON.parse( input );\n\t} catch ( e ) {\n\t\treturn null;\n\t}\n}\n\nfunction nextToken() {\n\t// Aye the magic\n\t// we're using a single RegExp to tokenize the block comment delimiters\n\t// we're also using a trick here because the only difference between a\n\t// block opener and a block closer is the leading `/` before `wp:` (and\n\t// a closer has no attributes). we can trap them both and process the\n\t// match back in JavaScript to see which one it was.\n\tconst matches = tokenizer.exec( document );\n\n\t// We have no more tokens.\n\tif ( null === matches ) {\n\t\treturn [ 'no-more-tokens' ];\n\t}\n\n\tconst startedAt = matches.index;\n\tconst [\n\t\tmatch,\n\t\tcloserMatch,\n\t\tnamespaceMatch,\n\t\tnameMatch,\n\t\tattrsMatch /* Internal/unused. */,\n\t\t,\n\t\tvoidMatch,\n\t] = matches;\n\n\tconst length = match.length;\n\tconst isCloser = !! closerMatch;\n\tconst isVoid = !! voidMatch;\n\tconst namespace = namespaceMatch || 'core/';\n\tconst name = namespace + nameMatch;\n\tconst hasAttrs = !! attrsMatch;\n\tconst attrs = hasAttrs ? parseJSON( attrsMatch ) : {};\n\n\t// This state isn't allowed\n\t// This is an error.\n\tif ( isCloser && ( isVoid || hasAttrs ) ) {\n\t\t// We can ignore them since they don't hurt anything\n\t\t// we may warn against this at some point or reject it.\n\t}\n\n\tif ( isVoid ) {\n\t\treturn [ 'void-block', name, attrs, startedAt, length ];\n\t}\n\n\tif ( isCloser ) {\n\t\treturn [ 'block-closer', name, null, startedAt, length ];\n\t}\n\n\treturn [ 'block-opener', name, attrs, startedAt, length ];\n}\n\nfunction addFreeform( rawLength ) {\n\tconst length = rawLength ? rawLength : document.length - offset;\n\n\tif ( 0 === length ) {\n\t\treturn;\n\t}\n\n\toutput.push( Freeform( document.substr( offset, length ) ) );\n}\n\nfunction addInnerBlock( block, tokenStart, tokenLength, lastOffset ) {\n\tconst parent = stack[ stack.length - 1 ];\n\tparent.block.innerBlocks.push( block );\n\tconst html = document.substr(\n\t\tparent.prevOffset,\n\t\ttokenStart - parent.prevOffset\n\t);\n\n\tif ( html ) {\n\t\tparent.block.innerHTML += html;\n\t\tparent.block.innerContent.push( html );\n\t}\n\n\tparent.block.innerContent.push( null );\n\tparent.prevOffset = lastOffset ? lastOffset : tokenStart + tokenLength;\n}\n\nfunction addBlockFromStack( endOffset ) {\n\tconst { block, leadingHtmlStart, prevOffset, tokenStart } = stack.pop();\n\n\tconst html = endOffset\n\t\t? document.substr( prevOffset, endOffset - prevOffset )\n\t\t: document.substr( prevOffset );\n\n\tif ( html ) {\n\t\tblock.innerHTML += html;\n\t\tblock.innerContent.push( html );\n\t}\n\n\tif ( null !== leadingHtmlStart ) {\n\t\toutput.push(\n\t\t\tFreeform(\n\t\t\t\tdocument.substr(\n\t\t\t\t\tleadingHtmlStart,\n\t\t\t\t\ttokenStart - leadingHtmlStart\n\t\t\t\t)\n\t\t\t)\n\t\t);\n\t}\n\n\toutput.push( block );\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wordpress/block-serialization-default-parser",
|
|
3
|
-
"version": "4.3.0",
|
|
3
|
+
"version": "4.3.2-next.a55ed9455a.0",
|
|
4
4
|
"description": "Block serialization specification parser for WordPress posts.",
|
|
5
5
|
"author": "The WordPress Contributors",
|
|
6
6
|
"license": "GPL-2.0-or-later",
|
|
@@ -32,5 +32,5 @@
|
|
|
32
32
|
"publishConfig": {
|
|
33
33
|
"access": "public"
|
|
34
34
|
},
|
|
35
|
-
"gitHead": "
|
|
35
|
+
"gitHead": "c5108185851b824d531bce55991a3589947e8551"
|
|
36
36
|
}
|
package/src/index.js
CHANGED
|
@@ -166,12 +166,12 @@ function proceed() {
|
|
|
166
166
|
const [ tokenType, blockName, attrs, startOffset, tokenLength ] = next;
|
|
167
167
|
const stackDepth = stack.length;
|
|
168
168
|
|
|
169
|
-
//
|
|
169
|
+
// We may have some HTML soup before the next block.
|
|
170
170
|
const leadingHtmlStart = startOffset > offset ? offset : null;
|
|
171
171
|
|
|
172
172
|
switch ( tokenType ) {
|
|
173
173
|
case 'no-more-tokens':
|
|
174
|
-
//
|
|
174
|
+
// If not in a block then flush output.
|
|
175
175
|
if ( 0 === stackDepth ) {
|
|
176
176
|
addFreeform();
|
|
177
177
|
return false;
|
|
@@ -183,15 +183,15 @@ function proceed() {
|
|
|
183
183
|
// - treat it all as freeform text
|
|
184
184
|
// - assume an implicit closer (easiest when not nesting)
|
|
185
185
|
|
|
186
|
-
//
|
|
186
|
+
// For the easy case we'll assume an implicit closer.
|
|
187
187
|
if ( 1 === stackDepth ) {
|
|
188
188
|
addBlockFromStack();
|
|
189
189
|
return false;
|
|
190
190
|
}
|
|
191
191
|
|
|
192
|
-
//
|
|
192
|
+
// For the nested case where it's more difficult we'll
|
|
193
193
|
// have to assume that multiple closers are missing
|
|
194
|
-
// and so we'll collapse the whole stack piecewise
|
|
194
|
+
// and so we'll collapse the whole stack piecewise.
|
|
195
195
|
while ( 0 < stack.length ) {
|
|
196
196
|
addBlockFromStack();
|
|
197
197
|
}
|
|
@@ -199,7 +199,7 @@ function proceed() {
|
|
|
199
199
|
|
|
200
200
|
case 'void-block':
|
|
201
201
|
// easy case is if we stumbled upon a void block
|
|
202
|
-
// in the top-level of the document
|
|
202
|
+
// in the top-level of the document.
|
|
203
203
|
if ( 0 === stackDepth ) {
|
|
204
204
|
if ( null !== leadingHtmlStart ) {
|
|
205
205
|
output.push(
|
|
@@ -216,7 +216,7 @@ function proceed() {
|
|
|
216
216
|
return true;
|
|
217
217
|
}
|
|
218
218
|
|
|
219
|
-
//
|
|
219
|
+
// Otherwise we found an inner block.
|
|
220
220
|
addInnerBlock(
|
|
221
221
|
Block( blockName, attrs, [], '', [] ),
|
|
222
222
|
startOffset,
|
|
@@ -226,7 +226,7 @@ function proceed() {
|
|
|
226
226
|
return true;
|
|
227
227
|
|
|
228
228
|
case 'block-opener':
|
|
229
|
-
//
|
|
229
|
+
// Track all newly-opened blocks on the stack.
|
|
230
230
|
stack.push(
|
|
231
231
|
Frame(
|
|
232
232
|
Block( blockName, attrs, [], '', [] ),
|
|
@@ -240,26 +240,26 @@ function proceed() {
|
|
|
240
240
|
return true;
|
|
241
241
|
|
|
242
242
|
case 'block-closer':
|
|
243
|
-
//
|
|
244
|
-
// This is an error
|
|
243
|
+
// If we're missing an opener we're in trouble
|
|
244
|
+
// This is an error.
|
|
245
245
|
if ( 0 === stackDepth ) {
|
|
246
|
-
//
|
|
246
|
+
// We have options
|
|
247
247
|
// - assume an implicit opener
|
|
248
248
|
// - assume _this_ is the opener
|
|
249
|
-
//
|
|
249
|
+
// - give up and close out the document.
|
|
250
250
|
addFreeform();
|
|
251
251
|
return false;
|
|
252
252
|
}
|
|
253
253
|
|
|
254
|
-
//
|
|
254
|
+
// If we're not nesting then this is easy - close the block.
|
|
255
255
|
if ( 1 === stackDepth ) {
|
|
256
256
|
addBlockFromStack( startOffset );
|
|
257
257
|
offset = startOffset + tokenLength;
|
|
258
258
|
return true;
|
|
259
259
|
}
|
|
260
260
|
|
|
261
|
-
//
|
|
262
|
-
// block and add it as a innerBlock to the parent
|
|
261
|
+
// Otherwise we're nested and we have to close out the current
|
|
262
|
+
// block and add it as a innerBlock to the parent.
|
|
263
263
|
const stackTop = stack.pop();
|
|
264
264
|
const html = document.substr(
|
|
265
265
|
stackTop.prevOffset,
|
|
@@ -279,7 +279,7 @@ function proceed() {
|
|
|
279
279
|
return true;
|
|
280
280
|
|
|
281
281
|
default:
|
|
282
|
-
// This is an error
|
|
282
|
+
// This is an error.
|
|
283
283
|
addFreeform();
|
|
284
284
|
return false;
|
|
285
285
|
}
|
|
@@ -304,7 +304,7 @@ function parseJSON( input ) {
|
|
|
304
304
|
}
|
|
305
305
|
|
|
306
306
|
function nextToken() {
|
|
307
|
-
//
|
|
307
|
+
// Aye the magic
|
|
308
308
|
// we're using a single RegExp to tokenize the block comment delimiters
|
|
309
309
|
// we're also using a trick here because the only difference between a
|
|
310
310
|
// block opener and a block closer is the leading `/` before `wp:` (and
|
|
@@ -312,7 +312,7 @@ function nextToken() {
|
|
|
312
312
|
// match back in JavaScript to see which one it was.
|
|
313
313
|
const matches = tokenizer.exec( document );
|
|
314
314
|
|
|
315
|
-
//
|
|
315
|
+
// We have no more tokens.
|
|
316
316
|
if ( null === matches ) {
|
|
317
317
|
return [ 'no-more-tokens' ];
|
|
318
318
|
}
|
|
@@ -323,7 +323,7 @@ function nextToken() {
|
|
|
323
323
|
closerMatch,
|
|
324
324
|
namespaceMatch,
|
|
325
325
|
nameMatch,
|
|
326
|
-
attrsMatch /*
|
|
326
|
+
attrsMatch /* Internal/unused. */,
|
|
327
327
|
,
|
|
328
328
|
voidMatch,
|
|
329
329
|
] = matches;
|
|
@@ -337,10 +337,10 @@ function nextToken() {
|
|
|
337
337
|
const attrs = hasAttrs ? parseJSON( attrsMatch ) : {};
|
|
338
338
|
|
|
339
339
|
// This state isn't allowed
|
|
340
|
-
// This is an error
|
|
340
|
+
// This is an error.
|
|
341
341
|
if ( isCloser && ( isVoid || hasAttrs ) ) {
|
|
342
|
-
//
|
|
343
|
-
// we may warn against this at some point or reject it
|
|
342
|
+
// We can ignore them since they don't hurt anything
|
|
343
|
+
// we may warn against this at some point or reject it.
|
|
344
344
|
}
|
|
345
345
|
|
|
346
346
|
if ( isVoid ) {
|