@wordpress/block-serialization-default-parser 5.32.0 → 5.32.1-next.b8c8708f3.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/build/index.js CHANGED
@@ -1,65 +1,31 @@
1
1
  "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var index_exports = {};
20
+ __export(index_exports, {
21
+ parse: () => parse
5
22
  });
6
- exports.parse = void 0;
23
+ module.exports = __toCommonJS(index_exports);
7
24
  let document;
8
25
  let offset;
9
26
  let output;
10
27
  let stack;
11
- /**
12
- * Matches block comment delimiters
13
- *
14
- * While most of this pattern is straightforward the attribute parsing
15
- * incorporates a tricks to make sure we don't choke on specific input
16
- *
17
- * - since JavaScript has no possessive quantifier or atomic grouping
18
- * we are emulating it with a trick
19
- *
20
- * we want a possessive quantifier or atomic group to prevent backtracking
21
- * on the `}`s should we fail to match the remainder of the pattern
22
- *
23
- * we can emulate this with a positive lookahead and back reference
24
- * (a++)*c === ((?=(a+))\1)*c
25
- *
26
- * let's examine an example:
27
- * - /(a+)*c/.test('aaaaaaaaaaaaad') fails after over 49,000 steps
28
- * - /(a++)*c/.test('aaaaaaaaaaaaad') fails after 85 steps
29
- * - /(?>a+)*c/.test('aaaaaaaaaaaaad') fails after 126 steps
30
- *
31
- * this is because the possessive `++` and the atomic group `(?>)`
32
- * tell the engine that all those `a`s belong together as a single group
33
- * and so it won't split it up when stepping backwards to try and match
34
- *
35
- * if we use /((?=(a+))\1)*c/ then we get the same behavior as the atomic group
36
- * or possessive and prevent the backtracking because the `a+` is matched but
37
- * not captured. thus, we find the long string of `a`s and remember it, then
38
- * reference it as a whole unit inside our pattern
39
- *
40
- * @see http://instanceof.me/post/52245507631/regex-emulate-atomic-grouping-with-lookahead
41
- * @see http://blog.stevenlevithan.com/archives/mimic-atomic-groups
42
- * @see https://javascript.info/regexp-infinite-backtracking-problem
43
- *
44
- * once browsers reliably support atomic grouping or possessive
45
- * quantifiers natively we should remove this trick and simplify
46
- *
47
- * @since 3.8.0
48
- * @since 4.6.1 added optimization to prevent backtracking on attribute parsing
49
- */
50
28
  const tokenizer = /<!--\s+(\/)?wp:([a-z][a-z0-9_-]*\/)?([a-z][a-z0-9_-]*)\s+({(?:(?=([^}]+|}+(?=})|(?!}\s+\/?-->)[^])*)\5|[^]*?)}\s+)?(\/)?-->/g;
51
-
52
- /**
53
- * Constructs a block object.
54
- *
55
- * @param blockName Either the abbreviated core types, e.g. "paragraph", or the fully-qualified
56
- * block type with namespace and type, e.g. "core/paragraph" or "my-plugin/csv-table".
57
- * @param attrs The attributes for the block, or null if there are no attributes.
58
- * @param innerBlocks An array of inner blocks.
59
- * @param innerHTML The inner HTML of the block.
60
- * @param innerContent An array of inner content strings.
61
- * @return The block object.
62
- */
63
29
  function Block(blockName, attrs, innerBlocks, innerHTML, innerContent) {
64
30
  return {
65
31
  blockName,
@@ -69,27 +35,9 @@ function Block(blockName, attrs, innerBlocks, innerHTML, innerContent) {
69
35
  innerContent
70
36
  };
71
37
  }
72
-
73
- /**
74
- * Constructs a freeform block object.
75
- *
76
- * @param innerHTML The inner HTML of the block.
77
- * @return The freeform block object.
78
- */
79
38
  function Freeform(innerHTML) {
80
39
  return Block(null, {}, [], innerHTML, [innerHTML]);
81
40
  }
82
-
83
- /**
84
- * Constructs a frame object.
85
- *
86
- * @param block The block object.
87
- * @param tokenStart The start offset of the token in the document.
88
- * @param tokenLength The length of the token in the document.
89
- * @param prevOffset The offset of the previous token in the document.
90
- * @param leadingHtmlStart The start offset of leading HTML before the block.
91
- * @return The frame object.
92
- */
93
41
  function Frame(block, tokenStart, tokenLength, prevOffset, leadingHtmlStart) {
94
42
  return {
95
43
  block,
@@ -99,203 +47,101 @@ function Frame(block, tokenStart, tokenLength, prevOffset, leadingHtmlStart) {
99
47
  leadingHtmlStart
100
48
  };
101
49
  }
102
-
103
- /**
104
- * Parser function, that converts input HTML into a block based structure.
105
- *
106
- * @param doc The HTML document to parse.
107
- *
108
- * @example
109
- * Input post:
110
- * ```html
111
- * <!-- wp:columns {"columns":3} -->
112
- * <div class="wp-block-columns has-3-columns"><!-- wp:column -->
113
- * <div class="wp-block-column"><!-- wp:paragraph -->
114
- * <p>Left</p>
115
- * <!-- /wp:paragraph --></div>
116
- * <!-- /wp:column -->
117
- *
118
- * <!-- wp:column -->
119
- * <div class="wp-block-column"><!-- wp:paragraph -->
120
- * <p><strong>Middle</strong></p>
121
- * <!-- /wp:paragraph --></div>
122
- * <!-- /wp:column -->
123
- *
124
- * <!-- wp:column -->
125
- * <div class="wp-block-column"></div>
126
- * <!-- /wp:column --></div>
127
- * <!-- /wp:columns -->
128
- * ```
129
- *
130
- * Parsing code:
131
- * ```js
132
- * import { parse } from '@wordpress/block-serialization-default-parser';
133
- *
134
- * parse( post ) === [
135
- * {
136
- * blockName: "core/columns",
137
- * attrs: {
138
- * columns: 3
139
- * },
140
- * innerBlocks: [
141
- * {
142
- * blockName: "core/column",
143
- * attrs: null,
144
- * innerBlocks: [
145
- * {
146
- * blockName: "core/paragraph",
147
- * attrs: null,
148
- * innerBlocks: [],
149
- * innerHTML: "\n<p>Left</p>\n"
150
- * }
151
- * ],
152
- * innerHTML: '\n<div class="wp-block-column"></div>\n'
153
- * },
154
- * {
155
- * blockName: "core/column",
156
- * attrs: null,
157
- * innerBlocks: [
158
- * {
159
- * blockName: "core/paragraph",
160
- * attrs: null,
161
- * innerBlocks: [],
162
- * innerHTML: "\n<p><strong>Middle</strong></p>\n"
163
- * }
164
- * ],
165
- * innerHTML: '\n<div class="wp-block-column"></div>\n'
166
- * },
167
- * {
168
- * blockName: "core/column",
169
- * attrs: null,
170
- * innerBlocks: [],
171
- * innerHTML: '\n<div class="wp-block-column"></div>\n'
172
- * }
173
- * ],
174
- * innerHTML: '\n<div class="wp-block-columns has-3-columns">\n\n\n\n</div>\n'
175
- * }
176
- * ];
177
- * ```
178
- * @return A block-based representation of the input HTML.
179
- */
180
- const parse = doc => {
50
+ const parse = (doc) => {
181
51
  document = doc;
182
52
  offset = 0;
183
53
  output = [];
184
54
  stack = [];
185
55
  tokenizer.lastIndex = 0;
186
56
  do {
187
- // twiddle our thumbs
188
57
  } while (proceed());
189
58
  return output;
190
59
  };
191
-
192
- /**
193
- * Parses the next token in the input document.
194
- *
195
- * @return Returns true when there is more tokens to parse.
196
- */
197
- exports.parse = parse;
198
60
  function proceed() {
199
61
  const stackDepth = stack.length;
200
62
  const next = nextToken();
201
63
  const [tokenType, blockName, attrs, startOffset, tokenLength] = next;
202
-
203
- // We may have some HTML soup before the next block.
204
64
  const leadingHtmlStart = startOffset > offset ? offset : null;
205
65
  switch (tokenType) {
206
- case 'no-more-tokens':
207
- // If not in a block then flush output.
66
+ case "no-more-tokens":
208
67
  if (0 === stackDepth) {
209
68
  addFreeform();
210
69
  return false;
211
70
  }
212
-
213
- // Otherwise we have a problem
214
- // This is an error
215
- // we have options
216
- // - treat it all as freeform text
217
- // - assume an implicit closer (easiest when not nesting)
218
-
219
- // For the easy case we'll assume an implicit closer.
220
71
  if (1 === stackDepth) {
221
72
  addBlockFromStack();
222
73
  return false;
223
74
  }
224
-
225
- // For the nested case where it's more difficult we'll
226
- // have to assume that multiple closers are missing
227
- // and so we'll collapse the whole stack piecewise.
228
75
  while (0 < stack.length) {
229
76
  addBlockFromStack();
230
77
  }
231
78
  return false;
232
- case 'void-block':
233
- // easy case is if we stumbled upon a void block
234
- // in the top-level of the document.
79
+ case "void-block":
235
80
  if (0 === stackDepth) {
236
81
  if (null !== leadingHtmlStart) {
237
- output.push(Freeform(document.substr(leadingHtmlStart, startOffset - leadingHtmlStart)));
82
+ output.push(
83
+ Freeform(
84
+ document.substr(
85
+ leadingHtmlStart,
86
+ startOffset - leadingHtmlStart
87
+ )
88
+ )
89
+ );
238
90
  }
239
- output.push(Block(blockName, attrs, [], '', []));
91
+ output.push(Block(blockName, attrs, [], "", []));
240
92
  offset = startOffset + tokenLength;
241
93
  return true;
242
94
  }
243
-
244
- // Otherwise we found an inner block.
245
- addInnerBlock(Block(blockName, attrs, [], '', []), startOffset, tokenLength);
95
+ addInnerBlock(
96
+ Block(blockName, attrs, [], "", []),
97
+ startOffset,
98
+ tokenLength
99
+ );
246
100
  offset = startOffset + tokenLength;
247
101
  return true;
248
- case 'block-opener':
249
- // Track all newly-opened blocks on the stack.
250
- stack.push(Frame(Block(blockName, attrs, [], '', []), startOffset, tokenLength, startOffset + tokenLength, leadingHtmlStart));
102
+ case "block-opener":
103
+ stack.push(
104
+ Frame(
105
+ Block(blockName, attrs, [], "", []),
106
+ startOffset,
107
+ tokenLength,
108
+ startOffset + tokenLength,
109
+ leadingHtmlStart
110
+ )
111
+ );
251
112
  offset = startOffset + tokenLength;
252
113
  return true;
253
- case 'block-closer':
254
- // If we're missing an opener we're in trouble
255
- // This is an error.
114
+ case "block-closer":
256
115
  if (0 === stackDepth) {
257
- // We have options
258
- // - assume an implicit opener
259
- // - assume _this_ is the opener
260
- // - give up and close out the document.
261
116
  addFreeform();
262
117
  return false;
263
118
  }
264
-
265
- // If we're not nesting then this is easy - close the block.
266
119
  if (1 === stackDepth) {
267
120
  addBlockFromStack(startOffset);
268
121
  offset = startOffset + tokenLength;
269
122
  return true;
270
123
  }
271
-
272
- // Otherwise we're nested and we have to close out the current
273
- // block and add it as a innerBlock to the parent.
274
124
  const stackTop = stack.pop();
275
- const html = document.substr(stackTop.prevOffset, startOffset - stackTop.prevOffset);
125
+ const html = document.substr(
126
+ stackTop.prevOffset,
127
+ startOffset - stackTop.prevOffset
128
+ );
276
129
  stackTop.block.innerHTML += html;
277
130
  stackTop.block.innerContent.push(html);
278
131
  stackTop.prevOffset = startOffset + tokenLength;
279
- addInnerBlock(stackTop.block, stackTop.tokenStart, stackTop.tokenLength, startOffset + tokenLength);
132
+ addInnerBlock(
133
+ stackTop.block,
134
+ stackTop.tokenStart,
135
+ stackTop.tokenLength,
136
+ startOffset + tokenLength
137
+ );
280
138
  offset = startOffset + tokenLength;
281
139
  return true;
282
140
  default:
283
- // This is an error.
284
141
  addFreeform();
285
142
  return false;
286
143
  }
287
144
  }
288
-
289
- /**
290
- * Parse JSON if valid, otherwise return null
291
- *
292
- * Note that JSON coming from the block comment
293
- * delimiters is constrained to be an object
294
- * and cannot be things like `true` or `null`
295
- *
296
- * @param input JSON input string to parse
297
- * @return parsed JSON if valid or null if invalid
298
- */
299
145
  function parseJSON(input) {
300
146
  try {
301
147
  return JSON.parse(input);
@@ -303,55 +149,38 @@ function parseJSON(input) {
303
149
  return null;
304
150
  }
305
151
  }
306
-
307
- /**
308
- * Finds the next token in the document.
309
- *
310
- * @return The next matched token.
311
- */
312
152
  function nextToken() {
313
- // Aye the magic
314
- // we're using a single RegExp to tokenize the block comment delimiters
315
- // we're also using a trick here because the only difference between a
316
- // block opener and a block closer is the leading `/` before `wp:` (and
317
- // a closer has no attributes). we can trap them both and process the
318
- // match back in JavaScript to see which one it was.
319
153
  const matches = tokenizer.exec(document);
320
-
321
- // We have no more tokens.
322
154
  if (null === matches) {
323
- return ['no-more-tokens', '', null, 0, 0];
155
+ return ["no-more-tokens", "", null, 0, 0];
324
156
  }
325
157
  const startedAt = matches.index;
326
- const [match, closerMatch, namespaceMatch, nameMatch, attrsMatch /* Internal/unused. */,, voidMatch] = matches;
158
+ const [
159
+ match,
160
+ closerMatch,
161
+ namespaceMatch,
162
+ nameMatch,
163
+ attrsMatch,
164
+ ,
165
+ voidMatch
166
+ ] = matches;
327
167
  const length = match.length;
328
168
  const isCloser = !!closerMatch;
329
169
  const isVoid = !!voidMatch;
330
- const namespace = namespaceMatch || 'core/';
170
+ const namespace = namespaceMatch || "core/";
331
171
  const name = namespace + nameMatch;
332
172
  const hasAttrs = !!attrsMatch;
333
173
  const attrs = hasAttrs ? parseJSON(attrsMatch) : {};
334
-
335
- // This state isn't allowed
336
- // This is an error.
337
174
  if (isCloser && (isVoid || hasAttrs)) {
338
- // We can ignore them since they don't hurt anything
339
- // we may warn against this at some point or reject it.
340
175
  }
341
176
  if (isVoid) {
342
- return ['void-block', name, attrs, startedAt, length];
177
+ return ["void-block", name, attrs, startedAt, length];
343
178
  }
344
179
  if (isCloser) {
345
- return ['block-closer', name, null, startedAt, length];
180
+ return ["block-closer", name, null, startedAt, length];
346
181
  }
347
- return ['block-opener', name, attrs, startedAt, length];
182
+ return ["block-opener", name, attrs, startedAt, length];
348
183
  }
349
-
350
- /**
351
- * Adds a freeform block to the output.
352
- *
353
- * @param rawLength Optional length of the raw HTML to include as freeform content.
354
- */
355
184
  function addFreeform(rawLength) {
356
185
  const length = rawLength ? rawLength : document.length - offset;
357
186
  if (0 === length) {
@@ -359,20 +188,13 @@ function addFreeform(rawLength) {
359
188
  }
360
189
  output.push(Freeform(document.substr(offset, length)));
361
190
  }
362
-
363
- /**
364
- * Adds inner block to the parent block.
365
- *
366
- * @param block The inner block to be added to the parent.
367
- * @param tokenStart The start offset of the block token in the document.
368
- * @param tokenLength The total length of the block token.
369
- * @param lastOffset Optional offset marking the end of the current block,
370
- * used to update the parent's HTML content boundaries.
371
- */
372
191
  function addInnerBlock(block, tokenStart, tokenLength, lastOffset) {
373
192
  const parent = stack[stack.length - 1];
374
193
  parent.block.innerBlocks.push(block);
375
- const html = document.substr(parent.prevOffset, tokenStart - parent.prevOffset);
194
+ const html = document.substr(
195
+ parent.prevOffset,
196
+ tokenStart - parent.prevOffset
197
+ );
376
198
  if (html) {
377
199
  parent.block.innerHTML += html;
378
200
  parent.block.innerContent.push(html);
@@ -380,27 +202,27 @@ function addInnerBlock(block, tokenStart, tokenLength, lastOffset) {
380
202
  parent.block.innerContent.push(null);
381
203
  parent.prevOffset = lastOffset ? lastOffset : tokenStart + tokenLength;
382
204
  }
383
-
384
- /**
385
- * Adds block from the stack to the output.
386
- *
387
- * @param endOffset Optional offset marking the end of the block's HTML content.
388
- */
389
205
  function addBlockFromStack(endOffset) {
390
- const {
391
- block,
392
- leadingHtmlStart,
393
- prevOffset,
394
- tokenStart
395
- } = stack.pop();
206
+ const { block, leadingHtmlStart, prevOffset, tokenStart } = stack.pop();
396
207
  const html = endOffset ? document.substr(prevOffset, endOffset - prevOffset) : document.substr(prevOffset);
397
208
  if (html) {
398
209
  block.innerHTML += html;
399
210
  block.innerContent.push(html);
400
211
  }
401
212
  if (null !== leadingHtmlStart) {
402
- output.push(Freeform(document.substr(leadingHtmlStart, tokenStart - leadingHtmlStart)));
213
+ output.push(
214
+ Freeform(
215
+ document.substr(
216
+ leadingHtmlStart,
217
+ tokenStart - leadingHtmlStart
218
+ )
219
+ )
220
+ );
403
221
  }
404
222
  output.push(block);
405
223
  }
406
- //# sourceMappingURL=index.js.map
224
+ // Annotate the CommonJS export names for ESM import in node:
225
+ 0 && (module.exports = {
226
+ parse
227
+ });
228
+ //# sourceMappingURL=index.js.map
@@ -1 +1,7 @@
1
- {"version":3,"names":["document","offset","output","stack","tokenizer","Block","blockName","attrs","innerBlocks","innerHTML","innerContent","Freeform","Frame","block","tokenStart","tokenLength","prevOffset","leadingHtmlStart","parse","doc","lastIndex","proceed","exports","stackDepth","length","next","nextToken","tokenType","startOffset","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"],"sources":["@wordpress/block-serialization-default-parser/src/index.ts"],"sourcesContent":["let document: string;\nlet offset: number;\nlet output: ParsedBlock[];\nlet stack: ParsedFrame[];\n\ntype Attributes = Record< string, any > | null;\n\ntype ParsedBlock = {\n\tblockName: string | null;\n\tattrs: Attributes;\n\tinnerBlocks: ParsedBlock[];\n\tinnerHTML: string;\n\tinnerContent: Array< string | null >;\n};\n\ntype ParsedFrame = {\n\tblock: ParsedBlock;\n\ttokenStart: number;\n\ttokenLength: number;\n\tprevOffset: number;\n\tleadingHtmlStart: number | null;\n};\n\ntype TokenType =\n\t| 'no-more-tokens'\n\t| 'void-block'\n\t| 'block-opener'\n\t| 'block-closer';\n\ntype Token = [ TokenType, string, Attributes, number, number ];\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 * @since 3.8.0\n * @since 4.6.1 added optimization to prevent backtracking on attribute parsing\n */\nconst tokenizer =\n\t/<!--\\s+(\\/)?wp:([a-z][a-z0-9_-]*\\/)?([a-z][a-z0-9_-]*)\\s+({(?:(?=([^}]+|}+(?=})|(?!}\\s+\\/?-->)[^])*)\\5|[^]*?)}\\s+)?(\\/)?-->/g;\n\n/**\n * Constructs a block object.\n *\n * @param blockName Either the abbreviated core types, e.g. \"paragraph\", or the fully-qualified\n * block type with namespace and type, e.g. \"core/paragraph\" or \"my-plugin/csv-table\".\n * @param attrs The attributes for the block, or null if there are no attributes.\n * @param innerBlocks An array of inner blocks.\n * @param innerHTML The inner HTML of the block.\n * @param innerContent An array of inner content strings.\n * @return The block object.\n */\nfunction Block(\n\tblockName: string | null,\n\tattrs: Attributes,\n\tinnerBlocks: ParsedBlock[],\n\tinnerHTML: string,\n\tinnerContent: string[]\n): ParsedBlock {\n\treturn {\n\t\tblockName,\n\t\tattrs,\n\t\tinnerBlocks,\n\t\tinnerHTML,\n\t\tinnerContent,\n\t};\n}\n\n/**\n * Constructs a freeform block object.\n *\n * @param innerHTML The inner HTML of the block.\n * @return The freeform block object.\n */\nfunction Freeform( innerHTML: string ): ParsedBlock {\n\treturn Block( null, {}, [], innerHTML, [ innerHTML ] );\n}\n\n/**\n * Constructs a frame object.\n *\n * @param block The block object.\n * @param tokenStart The start offset of the token in the document.\n * @param tokenLength The length of the token in the document.\n * @param prevOffset The offset of the previous token in the document.\n * @param leadingHtmlStart The start offset of leading HTML before the block.\n * @return The frame object.\n */\nfunction Frame(\n\tblock: ParsedBlock,\n\ttokenStart: number,\n\ttokenLength: number,\n\tprevOffset: number | null,\n\tleadingHtmlStart: number | null\n): ParsedFrame {\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 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 A block-based representation of the input HTML.\n */\nexport const parse = ( doc: string ): ParsedBlock[] => {\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\n/**\n * Parses the next token in the input document.\n *\n * @return Returns true when there is more tokens to parse.\n */\nfunction proceed(): boolean {\n\tconst stackDepth = stack.length;\n\tconst next = nextToken();\n\tconst [ tokenType, blockName, attrs, startOffset, tokenLength ] = next;\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\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() as ParsedFrame;\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 input JSON input string to parse\n * @return parsed JSON if valid or null if invalid\n */\nfunction parseJSON( input: string ): Object | null {\n\ttry {\n\t\treturn JSON.parse( input );\n\t} catch ( e ) {\n\t\treturn null;\n\t}\n}\n\n/**\n * Finds the next token in the document.\n *\n * @return The next matched token.\n */\nfunction nextToken(): Token {\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', '', null, 0, 0 ];\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\n/**\n * Adds a freeform block to the output.\n *\n * @param rawLength Optional length of the raw HTML to include as freeform content.\n */\nfunction addFreeform( rawLength?: number ) {\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\n/**\n * Adds inner block to the parent block.\n *\n * @param block The inner block to be added to the parent.\n * @param tokenStart The start offset of the block token in the document.\n * @param tokenLength The total length of the block token.\n * @param lastOffset Optional offset marking the end of the current block,\n * used to update the parent's HTML content boundaries.\n */\nfunction addInnerBlock(\n\tblock: ParsedBlock,\n\ttokenStart: number,\n\ttokenLength: number,\n\tlastOffset?: number\n) {\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\n/**\n * Adds block from the stack to the output.\n *\n * @param endOffset Optional offset marking the end of the block's HTML content.\n */\nfunction addBlockFromStack( endOffset?: number ) {\n\tconst { block, leadingHtmlStart, prevOffset, tokenStart } =\n\t\tstack.pop() as ParsedFrame;\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"],"mappings":";;;;;;AAAA,IAAIA,QAAgB;AACpB,IAAIC,MAAc;AAClB,IAAIC,MAAqB;AACzB,IAAIC,KAAoB;AA4BxB;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,GACd,8HAA8H;;AAE/H;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASC,KAAKA,CACbC,SAAwB,EACxBC,KAAiB,EACjBC,WAA0B,EAC1BC,SAAiB,EACjBC,YAAsB,EACR;EACd,OAAO;IACNJ,SAAS;IACTC,KAAK;IACLC,WAAW;IACXC,SAAS;IACTC;EACD,CAAC;AACF;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,SAASC,QAAQA,CAAEF,SAAiB,EAAgB;EACnD,OAAOJ,KAAK,CAAE,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,EAAEI,SAAS,EAAE,CAAEA,SAAS,CAAG,CAAC;AACvD;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASG,KAAKA,CACbC,KAAkB,EAClBC,UAAkB,EAClBC,WAAmB,EACnBC,UAAyB,EACzBC,gBAA+B,EACjB;EACd,OAAO;IACNJ,KAAK;IACLC,UAAU;IACVC,WAAW;IACXC,UAAU,EAAEA,UAAU,IAAIF,UAAU,GAAGC,WAAW;IAClDE;EACD,CAAC;AACF;;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;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;A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","ignoreList":[]}
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/index.ts"],
4
+ "sourcesContent": ["let document: string;\nlet offset: number;\nlet output: ParsedBlock[];\nlet stack: ParsedFrame[];\n\ntype Attributes = Record< string, any > | null;\n\ntype ParsedBlock = {\n\tblockName: string | null;\n\tattrs: Attributes;\n\tinnerBlocks: ParsedBlock[];\n\tinnerHTML: string;\n\tinnerContent: Array< string | null >;\n};\n\ntype ParsedFrame = {\n\tblock: ParsedBlock;\n\ttokenStart: number;\n\ttokenLength: number;\n\tprevOffset: number;\n\tleadingHtmlStart: number | null;\n};\n\ntype TokenType =\n\t| 'no-more-tokens'\n\t| 'void-block'\n\t| 'block-opener'\n\t| 'block-closer';\n\ntype Token = [ TokenType, string, Attributes, number, number ];\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 * @since 3.8.0\n * @since 4.6.1 added optimization to prevent backtracking on attribute parsing\n */\nconst tokenizer =\n\t/<!--\\s+(\\/)?wp:([a-z][a-z0-9_-]*\\/)?([a-z][a-z0-9_-]*)\\s+({(?:(?=([^}]+|}+(?=})|(?!}\\s+\\/?-->)[^])*)\\5|[^]*?)}\\s+)?(\\/)?-->/g;\n\n/**\n * Constructs a block object.\n *\n * @param blockName Either the abbreviated core types, e.g. \"paragraph\", or the fully-qualified\n * block type with namespace and type, e.g. \"core/paragraph\" or \"my-plugin/csv-table\".\n * @param attrs The attributes for the block, or null if there are no attributes.\n * @param innerBlocks An array of inner blocks.\n * @param innerHTML The inner HTML of the block.\n * @param innerContent An array of inner content strings.\n * @return The block object.\n */\nfunction Block(\n\tblockName: string | null,\n\tattrs: Attributes,\n\tinnerBlocks: ParsedBlock[],\n\tinnerHTML: string,\n\tinnerContent: string[]\n): ParsedBlock {\n\treturn {\n\t\tblockName,\n\t\tattrs,\n\t\tinnerBlocks,\n\t\tinnerHTML,\n\t\tinnerContent,\n\t};\n}\n\n/**\n * Constructs a freeform block object.\n *\n * @param innerHTML The inner HTML of the block.\n * @return The freeform block object.\n */\nfunction Freeform( innerHTML: string ): ParsedBlock {\n\treturn Block( null, {}, [], innerHTML, [ innerHTML ] );\n}\n\n/**\n * Constructs a frame object.\n *\n * @param block The block object.\n * @param tokenStart The start offset of the token in the document.\n * @param tokenLength The length of the token in the document.\n * @param prevOffset The offset of the previous token in the document.\n * @param leadingHtmlStart The start offset of leading HTML before the block.\n * @return The frame object.\n */\nfunction Frame(\n\tblock: ParsedBlock,\n\ttokenStart: number,\n\ttokenLength: number,\n\tprevOffset: number | null,\n\tleadingHtmlStart: number | null\n): ParsedFrame {\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 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 A block-based representation of the input HTML.\n */\nexport const parse = ( doc: string ): ParsedBlock[] => {\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\n/**\n * Parses the next token in the input document.\n *\n * @return Returns true when there is more tokens to parse.\n */\nfunction proceed(): boolean {\n\tconst stackDepth = stack.length;\n\tconst next = nextToken();\n\tconst [ tokenType, blockName, attrs, startOffset, tokenLength ] = next;\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\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() as ParsedFrame;\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 input JSON input string to parse\n * @return parsed JSON if valid or null if invalid\n */\nfunction parseJSON( input: string ): Object | null {\n\ttry {\n\t\treturn JSON.parse( input );\n\t} catch ( e ) {\n\t\treturn null;\n\t}\n}\n\n/**\n * Finds the next token in the document.\n *\n * @return The next matched token.\n */\nfunction nextToken(): Token {\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', '', null, 0, 0 ];\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\n/**\n * Adds a freeform block to the output.\n *\n * @param rawLength Optional length of the raw HTML to include as freeform content.\n */\nfunction addFreeform( rawLength?: number ) {\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\n/**\n * Adds inner block to the parent block.\n *\n * @param block The inner block to be added to the parent.\n * @param tokenStart The start offset of the block token in the document.\n * @param tokenLength The total length of the block token.\n * @param lastOffset Optional offset marking the end of the current block,\n * used to update the parent's HTML content boundaries.\n */\nfunction addInnerBlock(\n\tblock: ParsedBlock,\n\ttokenStart: number,\n\ttokenLength: number,\n\tlastOffset?: number\n) {\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\n/**\n * Adds block from the stack to the output.\n *\n * @param endOffset Optional offset marking the end of the block's HTML content.\n */\nfunction addBlockFromStack( endOffset?: number ) {\n\tconst { block, leadingHtmlStart, prevOffset, tokenStart } =\n\t\tstack.pop() as ParsedFrame;\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"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -2,58 +2,7 @@ let document;
2
2
  let offset;
3
3
  let output;
4
4
  let stack;
5
- /**
6
- * Matches block comment delimiters
7
- *
8
- * While most of this pattern is straightforward the attribute parsing
9
- * incorporates a tricks to make sure we don't choke on specific input
10
- *
11
- * - since JavaScript has no possessive quantifier or atomic grouping
12
- * we are emulating it with a trick
13
- *
14
- * we want a possessive quantifier or atomic group to prevent backtracking
15
- * on the `}`s should we fail to match the remainder of the pattern
16
- *
17
- * we can emulate this with a positive lookahead and back reference
18
- * (a++)*c === ((?=(a+))\1)*c
19
- *
20
- * let's examine an example:
21
- * - /(a+)*c/.test('aaaaaaaaaaaaad') fails after over 49,000 steps
22
- * - /(a++)*c/.test('aaaaaaaaaaaaad') fails after 85 steps
23
- * - /(?>a+)*c/.test('aaaaaaaaaaaaad') fails after 126 steps
24
- *
25
- * this is because the possessive `++` and the atomic group `(?>)`
26
- * tell the engine that all those `a`s belong together as a single group
27
- * and so it won't split it up when stepping backwards to try and match
28
- *
29
- * if we use /((?=(a+))\1)*c/ then we get the same behavior as the atomic group
30
- * or possessive and prevent the backtracking because the `a+` is matched but
31
- * not captured. thus, we find the long string of `a`s and remember it, then
32
- * reference it as a whole unit inside our pattern
33
- *
34
- * @see http://instanceof.me/post/52245507631/regex-emulate-atomic-grouping-with-lookahead
35
- * @see http://blog.stevenlevithan.com/archives/mimic-atomic-groups
36
- * @see https://javascript.info/regexp-infinite-backtracking-problem
37
- *
38
- * once browsers reliably support atomic grouping or possessive
39
- * quantifiers natively we should remove this trick and simplify
40
- *
41
- * @since 3.8.0
42
- * @since 4.6.1 added optimization to prevent backtracking on attribute parsing
43
- */
44
5
  const tokenizer = /<!--\s+(\/)?wp:([a-z][a-z0-9_-]*\/)?([a-z][a-z0-9_-]*)\s+({(?:(?=([^}]+|}+(?=})|(?!}\s+\/?-->)[^])*)\5|[^]*?)}\s+)?(\/)?-->/g;
45
-
46
- /**
47
- * Constructs a block object.
48
- *
49
- * @param blockName Either the abbreviated core types, e.g. "paragraph", or the fully-qualified
50
- * block type with namespace and type, e.g. "core/paragraph" or "my-plugin/csv-table".
51
- * @param attrs The attributes for the block, or null if there are no attributes.
52
- * @param innerBlocks An array of inner blocks.
53
- * @param innerHTML The inner HTML of the block.
54
- * @param innerContent An array of inner content strings.
55
- * @return The block object.
56
- */
57
6
  function Block(blockName, attrs, innerBlocks, innerHTML, innerContent) {
58
7
  return {
59
8
  blockName,
@@ -63,27 +12,9 @@ function Block(blockName, attrs, innerBlocks, innerHTML, innerContent) {
63
12
  innerContent
64
13
  };
65
14
  }
66
-
67
- /**
68
- * Constructs a freeform block object.
69
- *
70
- * @param innerHTML The inner HTML of the block.
71
- * @return The freeform block object.
72
- */
73
15
  function Freeform(innerHTML) {
74
16
  return Block(null, {}, [], innerHTML, [innerHTML]);
75
17
  }
76
-
77
- /**
78
- * Constructs a frame object.
79
- *
80
- * @param block The block object.
81
- * @param tokenStart The start offset of the token in the document.
82
- * @param tokenLength The length of the token in the document.
83
- * @param prevOffset The offset of the previous token in the document.
84
- * @param leadingHtmlStart The start offset of leading HTML before the block.
85
- * @return The frame object.
86
- */
87
18
  function Frame(block, tokenStart, tokenLength, prevOffset, leadingHtmlStart) {
88
19
  return {
89
20
  block,
@@ -93,202 +24,101 @@ function Frame(block, tokenStart, tokenLength, prevOffset, leadingHtmlStart) {
93
24
  leadingHtmlStart
94
25
  };
95
26
  }
96
-
97
- /**
98
- * Parser function, that converts input HTML into a block based structure.
99
- *
100
- * @param doc The HTML document to parse.
101
- *
102
- * @example
103
- * Input post:
104
- * ```html
105
- * <!-- wp:columns {"columns":3} -->
106
- * <div class="wp-block-columns has-3-columns"><!-- wp:column -->
107
- * <div class="wp-block-column"><!-- wp:paragraph -->
108
- * <p>Left</p>
109
- * <!-- /wp:paragraph --></div>
110
- * <!-- /wp:column -->
111
- *
112
- * <!-- wp:column -->
113
- * <div class="wp-block-column"><!-- wp:paragraph -->
114
- * <p><strong>Middle</strong></p>
115
- * <!-- /wp:paragraph --></div>
116
- * <!-- /wp:column -->
117
- *
118
- * <!-- wp:column -->
119
- * <div class="wp-block-column"></div>
120
- * <!-- /wp:column --></div>
121
- * <!-- /wp:columns -->
122
- * ```
123
- *
124
- * Parsing code:
125
- * ```js
126
- * import { parse } from '@wordpress/block-serialization-default-parser';
127
- *
128
- * parse( post ) === [
129
- * {
130
- * blockName: "core/columns",
131
- * attrs: {
132
- * columns: 3
133
- * },
134
- * innerBlocks: [
135
- * {
136
- * blockName: "core/column",
137
- * attrs: null,
138
- * innerBlocks: [
139
- * {
140
- * blockName: "core/paragraph",
141
- * attrs: null,
142
- * innerBlocks: [],
143
- * innerHTML: "\n<p>Left</p>\n"
144
- * }
145
- * ],
146
- * innerHTML: '\n<div class="wp-block-column"></div>\n'
147
- * },
148
- * {
149
- * blockName: "core/column",
150
- * attrs: null,
151
- * innerBlocks: [
152
- * {
153
- * blockName: "core/paragraph",
154
- * attrs: null,
155
- * innerBlocks: [],
156
- * innerHTML: "\n<p><strong>Middle</strong></p>\n"
157
- * }
158
- * ],
159
- * innerHTML: '\n<div class="wp-block-column"></div>\n'
160
- * },
161
- * {
162
- * blockName: "core/column",
163
- * attrs: null,
164
- * innerBlocks: [],
165
- * innerHTML: '\n<div class="wp-block-column"></div>\n'
166
- * }
167
- * ],
168
- * innerHTML: '\n<div class="wp-block-columns has-3-columns">\n\n\n\n</div>\n'
169
- * }
170
- * ];
171
- * ```
172
- * @return A block-based representation of the input HTML.
173
- */
174
- export const parse = doc => {
27
+ const parse = (doc) => {
175
28
  document = doc;
176
29
  offset = 0;
177
30
  output = [];
178
31
  stack = [];
179
32
  tokenizer.lastIndex = 0;
180
33
  do {
181
- // twiddle our thumbs
182
34
  } while (proceed());
183
35
  return output;
184
36
  };
185
-
186
- /**
187
- * Parses the next token in the input document.
188
- *
189
- * @return Returns true when there is more tokens to parse.
190
- */
191
37
  function proceed() {
192
38
  const stackDepth = stack.length;
193
39
  const next = nextToken();
194
40
  const [tokenType, blockName, attrs, startOffset, tokenLength] = next;
195
-
196
- // We may have some HTML soup before the next block.
197
41
  const leadingHtmlStart = startOffset > offset ? offset : null;
198
42
  switch (tokenType) {
199
- case 'no-more-tokens':
200
- // If not in a block then flush output.
43
+ case "no-more-tokens":
201
44
  if (0 === stackDepth) {
202
45
  addFreeform();
203
46
  return false;
204
47
  }
205
-
206
- // Otherwise we have a problem
207
- // This is an error
208
- // we have options
209
- // - treat it all as freeform text
210
- // - assume an implicit closer (easiest when not nesting)
211
-
212
- // For the easy case we'll assume an implicit closer.
213
48
  if (1 === stackDepth) {
214
49
  addBlockFromStack();
215
50
  return false;
216
51
  }
217
-
218
- // For the nested case where it's more difficult we'll
219
- // have to assume that multiple closers are missing
220
- // and so we'll collapse the whole stack piecewise.
221
52
  while (0 < stack.length) {
222
53
  addBlockFromStack();
223
54
  }
224
55
  return false;
225
- case 'void-block':
226
- // easy case is if we stumbled upon a void block
227
- // in the top-level of the document.
56
+ case "void-block":
228
57
  if (0 === stackDepth) {
229
58
  if (null !== leadingHtmlStart) {
230
- output.push(Freeform(document.substr(leadingHtmlStart, startOffset - leadingHtmlStart)));
59
+ output.push(
60
+ Freeform(
61
+ document.substr(
62
+ leadingHtmlStart,
63
+ startOffset - leadingHtmlStart
64
+ )
65
+ )
66
+ );
231
67
  }
232
- output.push(Block(blockName, attrs, [], '', []));
68
+ output.push(Block(blockName, attrs, [], "", []));
233
69
  offset = startOffset + tokenLength;
234
70
  return true;
235
71
  }
236
-
237
- // Otherwise we found an inner block.
238
- addInnerBlock(Block(blockName, attrs, [], '', []), startOffset, tokenLength);
72
+ addInnerBlock(
73
+ Block(blockName, attrs, [], "", []),
74
+ startOffset,
75
+ tokenLength
76
+ );
239
77
  offset = startOffset + tokenLength;
240
78
  return true;
241
- case 'block-opener':
242
- // Track all newly-opened blocks on the stack.
243
- stack.push(Frame(Block(blockName, attrs, [], '', []), startOffset, tokenLength, startOffset + tokenLength, leadingHtmlStart));
79
+ case "block-opener":
80
+ stack.push(
81
+ Frame(
82
+ Block(blockName, attrs, [], "", []),
83
+ startOffset,
84
+ tokenLength,
85
+ startOffset + tokenLength,
86
+ leadingHtmlStart
87
+ )
88
+ );
244
89
  offset = startOffset + tokenLength;
245
90
  return true;
246
- case 'block-closer':
247
- // If we're missing an opener we're in trouble
248
- // This is an error.
91
+ case "block-closer":
249
92
  if (0 === stackDepth) {
250
- // We have options
251
- // - assume an implicit opener
252
- // - assume _this_ is the opener
253
- // - give up and close out the document.
254
93
  addFreeform();
255
94
  return false;
256
95
  }
257
-
258
- // If we're not nesting then this is easy - close the block.
259
96
  if (1 === stackDepth) {
260
97
  addBlockFromStack(startOffset);
261
98
  offset = startOffset + tokenLength;
262
99
  return true;
263
100
  }
264
-
265
- // Otherwise we're nested and we have to close out the current
266
- // block and add it as a innerBlock to the parent.
267
101
  const stackTop = stack.pop();
268
- const html = document.substr(stackTop.prevOffset, startOffset - stackTop.prevOffset);
102
+ const html = document.substr(
103
+ stackTop.prevOffset,
104
+ startOffset - stackTop.prevOffset
105
+ );
269
106
  stackTop.block.innerHTML += html;
270
107
  stackTop.block.innerContent.push(html);
271
108
  stackTop.prevOffset = startOffset + tokenLength;
272
- addInnerBlock(stackTop.block, stackTop.tokenStart, stackTop.tokenLength, startOffset + tokenLength);
109
+ addInnerBlock(
110
+ stackTop.block,
111
+ stackTop.tokenStart,
112
+ stackTop.tokenLength,
113
+ startOffset + tokenLength
114
+ );
273
115
  offset = startOffset + tokenLength;
274
116
  return true;
275
117
  default:
276
- // This is an error.
277
118
  addFreeform();
278
119
  return false;
279
120
  }
280
121
  }
281
-
282
- /**
283
- * Parse JSON if valid, otherwise return null
284
- *
285
- * Note that JSON coming from the block comment
286
- * delimiters is constrained to be an object
287
- * and cannot be things like `true` or `null`
288
- *
289
- * @param input JSON input string to parse
290
- * @return parsed JSON if valid or null if invalid
291
- */
292
122
  function parseJSON(input) {
293
123
  try {
294
124
  return JSON.parse(input);
@@ -296,55 +126,38 @@ function parseJSON(input) {
296
126
  return null;
297
127
  }
298
128
  }
299
-
300
- /**
301
- * Finds the next token in the document.
302
- *
303
- * @return The next matched token.
304
- */
305
129
  function nextToken() {
306
- // Aye the magic
307
- // we're using a single RegExp to tokenize the block comment delimiters
308
- // we're also using a trick here because the only difference between a
309
- // block opener and a block closer is the leading `/` before `wp:` (and
310
- // a closer has no attributes). we can trap them both and process the
311
- // match back in JavaScript to see which one it was.
312
130
  const matches = tokenizer.exec(document);
313
-
314
- // We have no more tokens.
315
131
  if (null === matches) {
316
- return ['no-more-tokens', '', null, 0, 0];
132
+ return ["no-more-tokens", "", null, 0, 0];
317
133
  }
318
134
  const startedAt = matches.index;
319
- const [match, closerMatch, namespaceMatch, nameMatch, attrsMatch /* Internal/unused. */,, voidMatch] = matches;
135
+ const [
136
+ match,
137
+ closerMatch,
138
+ namespaceMatch,
139
+ nameMatch,
140
+ attrsMatch,
141
+ ,
142
+ voidMatch
143
+ ] = matches;
320
144
  const length = match.length;
321
145
  const isCloser = !!closerMatch;
322
146
  const isVoid = !!voidMatch;
323
- const namespace = namespaceMatch || 'core/';
147
+ const namespace = namespaceMatch || "core/";
324
148
  const name = namespace + nameMatch;
325
149
  const hasAttrs = !!attrsMatch;
326
150
  const attrs = hasAttrs ? parseJSON(attrsMatch) : {};
327
-
328
- // This state isn't allowed
329
- // This is an error.
330
151
  if (isCloser && (isVoid || hasAttrs)) {
331
- // We can ignore them since they don't hurt anything
332
- // we may warn against this at some point or reject it.
333
152
  }
334
153
  if (isVoid) {
335
- return ['void-block', name, attrs, startedAt, length];
154
+ return ["void-block", name, attrs, startedAt, length];
336
155
  }
337
156
  if (isCloser) {
338
- return ['block-closer', name, null, startedAt, length];
157
+ return ["block-closer", name, null, startedAt, length];
339
158
  }
340
- return ['block-opener', name, attrs, startedAt, length];
159
+ return ["block-opener", name, attrs, startedAt, length];
341
160
  }
342
-
343
- /**
344
- * Adds a freeform block to the output.
345
- *
346
- * @param rawLength Optional length of the raw HTML to include as freeform content.
347
- */
348
161
  function addFreeform(rawLength) {
349
162
  const length = rawLength ? rawLength : document.length - offset;
350
163
  if (0 === length) {
@@ -352,20 +165,13 @@ function addFreeform(rawLength) {
352
165
  }
353
166
  output.push(Freeform(document.substr(offset, length)));
354
167
  }
355
-
356
- /**
357
- * Adds inner block to the parent block.
358
- *
359
- * @param block The inner block to be added to the parent.
360
- * @param tokenStart The start offset of the block token in the document.
361
- * @param tokenLength The total length of the block token.
362
- * @param lastOffset Optional offset marking the end of the current block,
363
- * used to update the parent's HTML content boundaries.
364
- */
365
168
  function addInnerBlock(block, tokenStart, tokenLength, lastOffset) {
366
169
  const parent = stack[stack.length - 1];
367
170
  parent.block.innerBlocks.push(block);
368
- const html = document.substr(parent.prevOffset, tokenStart - parent.prevOffset);
171
+ const html = document.substr(
172
+ parent.prevOffset,
173
+ tokenStart - parent.prevOffset
174
+ );
369
175
  if (html) {
370
176
  parent.block.innerHTML += html;
371
177
  parent.block.innerContent.push(html);
@@ -373,27 +179,26 @@ function addInnerBlock(block, tokenStart, tokenLength, lastOffset) {
373
179
  parent.block.innerContent.push(null);
374
180
  parent.prevOffset = lastOffset ? lastOffset : tokenStart + tokenLength;
375
181
  }
376
-
377
- /**
378
- * Adds block from the stack to the output.
379
- *
380
- * @param endOffset Optional offset marking the end of the block's HTML content.
381
- */
382
182
  function addBlockFromStack(endOffset) {
383
- const {
384
- block,
385
- leadingHtmlStart,
386
- prevOffset,
387
- tokenStart
388
- } = stack.pop();
183
+ const { block, leadingHtmlStart, prevOffset, tokenStart } = stack.pop();
389
184
  const html = endOffset ? document.substr(prevOffset, endOffset - prevOffset) : document.substr(prevOffset);
390
185
  if (html) {
391
186
  block.innerHTML += html;
392
187
  block.innerContent.push(html);
393
188
  }
394
189
  if (null !== leadingHtmlStart) {
395
- output.push(Freeform(document.substr(leadingHtmlStart, tokenStart - leadingHtmlStart)));
190
+ output.push(
191
+ Freeform(
192
+ document.substr(
193
+ leadingHtmlStart,
194
+ tokenStart - leadingHtmlStart
195
+ )
196
+ )
197
+ );
396
198
  }
397
199
  output.push(block);
398
200
  }
399
- //# sourceMappingURL=index.js.map
201
+ export {
202
+ parse
203
+ };
204
+ //# sourceMappingURL=index.js.map
@@ -1 +1,7 @@
1
- {"version":3,"names":["document","offset","output","stack","tokenizer","Block","blockName","attrs","innerBlocks","innerHTML","innerContent","Freeform","Frame","block","tokenStart","tokenLength","prevOffset","leadingHtmlStart","parse","doc","lastIndex","proceed","stackDepth","length","next","nextToken","tokenType","startOffset","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"],"sources":["@wordpress/block-serialization-default-parser/src/index.ts"],"sourcesContent":["let document: string;\nlet offset: number;\nlet output: ParsedBlock[];\nlet stack: ParsedFrame[];\n\ntype Attributes = Record< string, any > | null;\n\ntype ParsedBlock = {\n\tblockName: string | null;\n\tattrs: Attributes;\n\tinnerBlocks: ParsedBlock[];\n\tinnerHTML: string;\n\tinnerContent: Array< string | null >;\n};\n\ntype ParsedFrame = {\n\tblock: ParsedBlock;\n\ttokenStart: number;\n\ttokenLength: number;\n\tprevOffset: number;\n\tleadingHtmlStart: number | null;\n};\n\ntype TokenType =\n\t| 'no-more-tokens'\n\t| 'void-block'\n\t| 'block-opener'\n\t| 'block-closer';\n\ntype Token = [ TokenType, string, Attributes, number, number ];\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 * @since 3.8.0\n * @since 4.6.1 added optimization to prevent backtracking on attribute parsing\n */\nconst tokenizer =\n\t/<!--\\s+(\\/)?wp:([a-z][a-z0-9_-]*\\/)?([a-z][a-z0-9_-]*)\\s+({(?:(?=([^}]+|}+(?=})|(?!}\\s+\\/?-->)[^])*)\\5|[^]*?)}\\s+)?(\\/)?-->/g;\n\n/**\n * Constructs a block object.\n *\n * @param blockName Either the abbreviated core types, e.g. \"paragraph\", or the fully-qualified\n * block type with namespace and type, e.g. \"core/paragraph\" or \"my-plugin/csv-table\".\n * @param attrs The attributes for the block, or null if there are no attributes.\n * @param innerBlocks An array of inner blocks.\n * @param innerHTML The inner HTML of the block.\n * @param innerContent An array of inner content strings.\n * @return The block object.\n */\nfunction Block(\n\tblockName: string | null,\n\tattrs: Attributes,\n\tinnerBlocks: ParsedBlock[],\n\tinnerHTML: string,\n\tinnerContent: string[]\n): ParsedBlock {\n\treturn {\n\t\tblockName,\n\t\tattrs,\n\t\tinnerBlocks,\n\t\tinnerHTML,\n\t\tinnerContent,\n\t};\n}\n\n/**\n * Constructs a freeform block object.\n *\n * @param innerHTML The inner HTML of the block.\n * @return The freeform block object.\n */\nfunction Freeform( innerHTML: string ): ParsedBlock {\n\treturn Block( null, {}, [], innerHTML, [ innerHTML ] );\n}\n\n/**\n * Constructs a frame object.\n *\n * @param block The block object.\n * @param tokenStart The start offset of the token in the document.\n * @param tokenLength The length of the token in the document.\n * @param prevOffset The offset of the previous token in the document.\n * @param leadingHtmlStart The start offset of leading HTML before the block.\n * @return The frame object.\n */\nfunction Frame(\n\tblock: ParsedBlock,\n\ttokenStart: number,\n\ttokenLength: number,\n\tprevOffset: number | null,\n\tleadingHtmlStart: number | null\n): ParsedFrame {\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 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 A block-based representation of the input HTML.\n */\nexport const parse = ( doc: string ): ParsedBlock[] => {\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\n/**\n * Parses the next token in the input document.\n *\n * @return Returns true when there is more tokens to parse.\n */\nfunction proceed(): boolean {\n\tconst stackDepth = stack.length;\n\tconst next = nextToken();\n\tconst [ tokenType, blockName, attrs, startOffset, tokenLength ] = next;\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\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() as ParsedFrame;\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 input JSON input string to parse\n * @return parsed JSON if valid or null if invalid\n */\nfunction parseJSON( input: string ): Object | null {\n\ttry {\n\t\treturn JSON.parse( input );\n\t} catch ( e ) {\n\t\treturn null;\n\t}\n}\n\n/**\n * Finds the next token in the document.\n *\n * @return The next matched token.\n */\nfunction nextToken(): Token {\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', '', null, 0, 0 ];\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\n/**\n * Adds a freeform block to the output.\n *\n * @param rawLength Optional length of the raw HTML to include as freeform content.\n */\nfunction addFreeform( rawLength?: number ) {\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\n/**\n * Adds inner block to the parent block.\n *\n * @param block The inner block to be added to the parent.\n * @param tokenStart The start offset of the block token in the document.\n * @param tokenLength The total length of the block token.\n * @param lastOffset Optional offset marking the end of the current block,\n * used to update the parent's HTML content boundaries.\n */\nfunction addInnerBlock(\n\tblock: ParsedBlock,\n\ttokenStart: number,\n\ttokenLength: number,\n\tlastOffset?: number\n) {\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\n/**\n * Adds block from the stack to the output.\n *\n * @param endOffset Optional offset marking the end of the block's HTML content.\n */\nfunction addBlockFromStack( endOffset?: number ) {\n\tconst { block, leadingHtmlStart, prevOffset, tokenStart } =\n\t\tstack.pop() as ParsedFrame;\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"],"mappings":"AAAA,IAAIA,QAAgB;AACpB,IAAIC,MAAc;AAClB,IAAIC,MAAqB;AACzB,IAAIC,KAAoB;AA4BxB;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,GACd,8HAA8H;;AAE/H;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASC,KAAKA,CACbC,SAAwB,EACxBC,KAAiB,EACjBC,WAA0B,EAC1BC,SAAiB,EACjBC,YAAsB,EACR;EACd,OAAO;IACNJ,SAAS;IACTC,KAAK;IACLC,WAAW;IACXC,SAAS;IACTC;EACD,CAAC;AACF;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,SAASC,QAAQA,CAAEF,SAAiB,EAAgB;EACnD,OAAOJ,KAAK,CAAE,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,EAAEI,SAAS,EAAE,CAAEA,SAAS,CAAG,CAAC;AACvD;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASG,KAAKA,CACbC,KAAkB,EAClBC,UAAkB,EAClBC,WAAmB,EACnBC,UAAyB,EACzBC,gBAA+B,EACjB;EACd,OAAO;IACNJ,KAAK;IACLC,UAAU;IACVC,WAAW;IACXC,UAAU,EAAEA,UAAU,IAAIF,UAAU,GAAGC,WAAW;IAClDE;EACD,CAAC;AACF;;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;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AA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","ignoreList":[]}
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/index.ts"],
4
+ "sourcesContent": ["let document: string;\nlet offset: number;\nlet output: ParsedBlock[];\nlet stack: ParsedFrame[];\n\ntype Attributes = Record< string, any > | null;\n\ntype ParsedBlock = {\n\tblockName: string | null;\n\tattrs: Attributes;\n\tinnerBlocks: ParsedBlock[];\n\tinnerHTML: string;\n\tinnerContent: Array< string | null >;\n};\n\ntype ParsedFrame = {\n\tblock: ParsedBlock;\n\ttokenStart: number;\n\ttokenLength: number;\n\tprevOffset: number;\n\tleadingHtmlStart: number | null;\n};\n\ntype TokenType =\n\t| 'no-more-tokens'\n\t| 'void-block'\n\t| 'block-opener'\n\t| 'block-closer';\n\ntype Token = [ TokenType, string, Attributes, number, number ];\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 * @since 3.8.0\n * @since 4.6.1 added optimization to prevent backtracking on attribute parsing\n */\nconst tokenizer =\n\t/<!--\\s+(\\/)?wp:([a-z][a-z0-9_-]*\\/)?([a-z][a-z0-9_-]*)\\s+({(?:(?=([^}]+|}+(?=})|(?!}\\s+\\/?-->)[^])*)\\5|[^]*?)}\\s+)?(\\/)?-->/g;\n\n/**\n * Constructs a block object.\n *\n * @param blockName Either the abbreviated core types, e.g. \"paragraph\", or the fully-qualified\n * block type with namespace and type, e.g. \"core/paragraph\" or \"my-plugin/csv-table\".\n * @param attrs The attributes for the block, or null if there are no attributes.\n * @param innerBlocks An array of inner blocks.\n * @param innerHTML The inner HTML of the block.\n * @param innerContent An array of inner content strings.\n * @return The block object.\n */\nfunction Block(\n\tblockName: string | null,\n\tattrs: Attributes,\n\tinnerBlocks: ParsedBlock[],\n\tinnerHTML: string,\n\tinnerContent: string[]\n): ParsedBlock {\n\treturn {\n\t\tblockName,\n\t\tattrs,\n\t\tinnerBlocks,\n\t\tinnerHTML,\n\t\tinnerContent,\n\t};\n}\n\n/**\n * Constructs a freeform block object.\n *\n * @param innerHTML The inner HTML of the block.\n * @return The freeform block object.\n */\nfunction Freeform( innerHTML: string ): ParsedBlock {\n\treturn Block( null, {}, [], innerHTML, [ innerHTML ] );\n}\n\n/**\n * Constructs a frame object.\n *\n * @param block The block object.\n * @param tokenStart The start offset of the token in the document.\n * @param tokenLength The length of the token in the document.\n * @param prevOffset The offset of the previous token in the document.\n * @param leadingHtmlStart The start offset of leading HTML before the block.\n * @return The frame object.\n */\nfunction Frame(\n\tblock: ParsedBlock,\n\ttokenStart: number,\n\ttokenLength: number,\n\tprevOffset: number | null,\n\tleadingHtmlStart: number | null\n): ParsedFrame {\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 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 A block-based representation of the input HTML.\n */\nexport const parse = ( doc: string ): ParsedBlock[] => {\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\n/**\n * Parses the next token in the input document.\n *\n * @return Returns true when there is more tokens to parse.\n */\nfunction proceed(): boolean {\n\tconst stackDepth = stack.length;\n\tconst next = nextToken();\n\tconst [ tokenType, blockName, attrs, startOffset, tokenLength ] = next;\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\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() as ParsedFrame;\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 input JSON input string to parse\n * @return parsed JSON if valid or null if invalid\n */\nfunction parseJSON( input: string ): Object | null {\n\ttry {\n\t\treturn JSON.parse( input );\n\t} catch ( e ) {\n\t\treturn null;\n\t}\n}\n\n/**\n * Finds the next token in the document.\n *\n * @return The next matched token.\n */\nfunction nextToken(): Token {\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', '', null, 0, 0 ];\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\n/**\n * Adds a freeform block to the output.\n *\n * @param rawLength Optional length of the raw HTML to include as freeform content.\n */\nfunction addFreeform( rawLength?: number ) {\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\n/**\n * Adds inner block to the parent block.\n *\n * @param block The inner block to be added to the parent.\n * @param tokenStart The start offset of the block token in the document.\n * @param tokenLength The total length of the block token.\n * @param lastOffset Optional offset marking the end of the current block,\n * used to update the parent's HTML content boundaries.\n */\nfunction addInnerBlock(\n\tblock: ParsedBlock,\n\ttokenStart: number,\n\ttokenLength: number,\n\tlastOffset?: number\n) {\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\n/**\n * Adds block from the stack to the output.\n *\n * @param endOffset Optional offset marking the end of the block's HTML content.\n */\nfunction addBlockFromStack( endOffset?: number ) {\n\tconst { block, leadingHtmlStart, prevOffset, tokenStart } =\n\t\tstack.pop() as ParsedFrame;\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"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wordpress/block-serialization-default-parser",
3
- "version": "5.32.0",
3
+ "version": "5.32.1-next.b8c8708f3.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",
@@ -25,15 +25,20 @@
25
25
  },
26
26
  "main": "build/index.js",
27
27
  "module": "build-module/index.js",
28
+ "exports": {
29
+ ".": {
30
+ "types": "./build-types/index.d.ts",
31
+ "import": "./build-module/index.js",
32
+ "require": "./build/index.js"
33
+ },
34
+ "./package.json": "./package.json"
35
+ },
28
36
  "react-native": "src/index",
29
37
  "wpScript": true,
30
38
  "types": "build-types",
31
39
  "sideEffects": false,
32
- "dependencies": {
33
- "@babel/runtime": "7.25.7"
34
- },
35
40
  "publishConfig": {
36
41
  "access": "public"
37
42
  },
38
- "gitHead": "a030b4c0e0695239b942c7dc18511782b64f10ed"
43
+ "gitHead": "67cfd7e661931aeb0d06bec894599d287a4f8d0f"
39
44
  }