You're Invited:Meet the Socket Team at RSAC and BSidesSF 2026, March 23–26.RSVP
Socket
Book a DemoSign in
Socket

@wordpress/block-serialization-default-parser

Package Overview
Dependencies
Maintainers
8
Versions
220
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@wordpress/block-serialization-default-parser - npm Package Compare versions

Comparing version
1.0.0
to
1.0.1
+9
-18
build-module/index.js

@@ -17,2 +17,6 @@ import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";

function Freeform(innerHTML) {
return Block(null, {}, [], innerHTML);
}
function Frame(block, tokenStart, tokenLength, prevOffset, leadingHtmlStart) {

@@ -88,6 +92,3 @@ return {

if (null !== leadingHtmlStart) {
output.push({
attrs: {},
innerHTML: document.substr(leadingHtmlStart, startOffset - leadingHtmlStart)
});
output.push(Freeform(document.substr(leadingHtmlStart, startOffset - leadingHtmlStart)));
}

@@ -194,3 +195,3 @@

var hasAttrs = !!attrsMatch;
var attrs = hasAttrs ? parseJSON(attrsMatch) : null; // This state isn't allowed
var attrs = hasAttrs ? parseJSON(attrsMatch) : {}; // This state isn't allowed
// This is an error

@@ -218,12 +219,5 @@

return;
} // why is this not a Frame? it's because the current grammar
// specifies an object that's different. we can update the
// specification and change here if we want to but for now we
// want this parser to be spec-compliant
}
output.push({
attrs: {},
innerHTML: document.substr(offset, length)
});
output.push(Freeform(document.substr(offset, length)));
}

@@ -252,6 +246,3 @@

if (null !== leadingHtmlStart) {
output.push({
attrs: {},
innerHTML: document.substr(leadingHtmlStart, tokenStart - leadingHtmlStart)
});
output.push(Freeform(document.substr(leadingHtmlStart, tokenStart - leadingHtmlStart)));
}

@@ -258,0 +249,0 @@

@@ -1,1 +0,1 @@

{"version":3,"sources":["/Users/robert/projects/gutenberg/packages/block-serialization-default-parser/src/index.js"],"names":["document","offset","output","stack","tokenizer","Block","blockName","attrs","innerBlocks","innerHTML","Frame","block","tokenStart","tokenLength","prevOffset","leadingHtmlStart","parse","doc","lastIndex","proceed","next","nextToken","tokenType","startOffset","stackDepth","length","addFreeform","addBlockFromStack","push","substr","addInnerBlock","stackTop","pop","parseJSON","input","JSON","e","matches","exec","startedAt","index","match","closerMatch","namespaceMatch","nameMatch","attrsMatch","voidMatch","isCloser","isVoid","namespace","name","hasAttrs","rawLength","lastOffset","parent","endOffset"],"mappings":"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","sourcesContent":["let document;\nlet offset;\nlet output;\nlet stack;\nconst tokenizer = /<!--\\s+(\\/)?wp:([a-z][a-z0-9_-]*\\/)?([a-z][a-z0-9_-]*)\\s+({(?:(?!}\\s+-->)[^])+?}\\s+)?(\\/)?-->/g;\n\nfunction Block( blockName, attrs, innerBlocks, innerHTML ) {\n\treturn {\n\t\tblockName,\n\t\tattrs,\n\t\tinnerBlocks,\n\t\tinnerHTML,\n\t};\n}\n\nfunction Frame( block, tokenStart, tokenLength, prevOffset, leadingHtmlStart ) {\n\treturn {\n\t\tblock,\n\t\ttokenStart,\n\t\ttokenLength,\n\t\tprevOffset: prevOffset || tokenStart + tokenLength,\n\t\tleadingHtmlStart,\n\t};\n}\n\nexport const parse = ( doc ) => {\n\tdocument = doc;\n\toffset = 0;\n\toutput = [];\n\tstack = [];\n\ttokenizer.lastIndex = 0;\n\n\tdo {\n\t\t// twiddle our thumbs\n\t} while ( proceed() );\n\n\treturn output;\n};\n\nfunction proceed() {\n\tconst next = nextToken();\n\tconst [ tokenType, blockName, attrs, startOffset, tokenLength ] = next;\n\tconst stackDepth = stack.length;\n\n\t// we may have some HTML soup before the next block\n\tconst leadingHtmlStart = ( startOffset > offset ) ? offset : null;\n\n\tswitch ( tokenType ) {\n\t\tcase 'no-more-tokens':\n\t\t\t// if not in a block then flush output\n\t\t\tif ( 0 === stackDepth ) {\n\t\t\t\taddFreeform();\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// Otherwise we have a problem\n\t\t\t// This is an error\n\t\t\t// we have options\n\t\t\t// - treat it all as freeform text\n\t\t\t// - assume an implicit closer (easiest when not nesting)\n\n\t\t\t// for the easy case we'll assume an implicit closer\n\t\t\tif ( 1 === stackDepth ) {\n\t\t\t\taddBlockFromStack();\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// for the nested case where it's more difficult we'll\n\t\t\t// have to assume that multiple closers are missing\n\t\t\t// and so we'll collapse the whole stack piecewise\n\t\t\twhile ( 0 < stack.length ) {\n\t\t\t\taddBlockFromStack();\n\t\t\t}\n\t\t\treturn false;\n\n\t\tcase 'void-block':\n\t\t\t// easy case is if we stumbled upon a void block\n\t\t\t// in the top-level of the document\n\t\t\tif ( 0 === stackDepth ) {\n\t\t\t\tif ( null !== leadingHtmlStart ) {\n\t\t\t\t\toutput.push( {\n\t\t\t\t\t\tattrs: {},\n\t\t\t\t\t\tinnerHTML: document.substr( leadingHtmlStart, startOffset - leadingHtmlStart ),\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t\toutput.push( Block( blockName, attrs, [], '' ) );\n\t\t\t\toffset = startOffset + tokenLength;\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\t// otherwise we found an inner block\n\t\t\taddInnerBlock(\n\t\t\t\tBlock( blockName, attrs, [], '' ),\n\t\t\t\tstartOffset,\n\t\t\t\ttokenLength,\n\t\t\t);\n\t\t\toffset = startOffset + tokenLength;\n\t\t\treturn true;\n\n\t\tcase 'block-opener':\n\t\t\t// track all newly-opened blocks on the stack\n\t\t\tstack.push(\n\t\t\t\tFrame(\n\t\t\t\t\tBlock( blockName, attrs, [], '' ),\n\t\t\t\t\tstartOffset,\n\t\t\t\t\ttokenLength,\n\t\t\t\t\tstartOffset + tokenLength,\n\t\t\t\t\tleadingHtmlStart,\n\t\t\t\t),\n\t\t\t);\n\t\t\toffset = startOffset + tokenLength;\n\t\t\treturn true;\n\n\t\tcase 'block-closer':\n\t\t\t// if we're missing an opener we're in trouble\n\t\t\t// This is an error\n\t\t\tif ( 0 === stackDepth ) {\n\t\t\t\t// we have options\n\t\t\t\t// - assume an implicit opener\n\t\t\t\t// - assume _this_ is the opener\n\t\t\t\t// - give up and close out the document\n\t\t\t\taddFreeform();\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// if we're not nesting then this is easy - close the block\n\t\t\tif ( 1 === stackDepth ) {\n\t\t\t\taddBlockFromStack( startOffset );\n\t\t\t\toffset = startOffset + tokenLength;\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\t// otherwise we're nested and we have to close out the current\n\t\t\t// block and add it as a innerBlock to the parent\n\t\t\tconst stackTop = stack.pop();\n\t\t\tstackTop.block.innerHTML += document.substr(\n\t\t\t\tstackTop.prevOffset,\n\t\t\t\tstartOffset - stackTop.prevOffset,\n\t\t\t);\n\t\t\tstackTop.prevOffset = startOffset + tokenLength;\n\n\t\t\taddInnerBlock(\n\t\t\t\tstackTop.block,\n\t\t\t\tstackTop.tokenStart,\n\t\t\t\tstackTop.tokenLength,\n\t\t\t\tstartOffset + tokenLength,\n\t\t\t);\n\t\t\toffset = startOffset + tokenLength;\n\t\t\treturn true;\n\n\t\tdefault:\n\t\t\t// This is an error\n\t\t\taddFreeform();\n\t\t\treturn false;\n\t}\n}\n\n/**\n * Parse JSON if valid, otherwise return null\n *\n * Note that JSON coming from the block comment\n * delimiters is constrained to be an object\n * and cannot be things like `true` or `null`\n *\n * @param {string} input JSON input string to parse\n * @return {Object|null} parsed JSON if valid\n */\nfunction parseJSON( input ) {\n\ttry {\n\t\treturn JSON.parse( input );\n\t} catch ( e ) {\n\t\treturn null;\n\t}\n}\n\nfunction nextToken() {\n\t// aye the magic\n\t// we're using a single RegExp to tokenize the block comment delimiters\n\t// we're also using a trick here because the only difference between a\n\t// block opener and a block closer is the leading `/` before `wp:` (and\n\t// a closer has no attributes). we can trap them both and process the\n\t// match back in Javascript to see which one it was.\n\tconst matches = tokenizer.exec( document );\n\n\t// we have no more tokens\n\tif ( null === matches ) {\n\t\treturn [ 'no-more-tokens' ];\n\t}\n\n\tconst startedAt = matches.index;\n\tconst [ match, closerMatch, namespaceMatch, nameMatch, attrsMatch, voidMatch ] = 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 ) : null;\n\n\t// This state isn't allowed\n\t// This is an error\n\tif ( isCloser && ( isVoid || hasAttrs ) ) {\n\t\t// we can ignore them since they don't hurt anything\n\t\t// we may warn against this at some point or reject it\n\t}\n\n\tif ( isVoid ) {\n\t\treturn [ 'void-block', name, attrs, startedAt, length ];\n\t}\n\n\tif ( isCloser ) {\n\t\treturn [ 'block-closer', name, null, startedAt, length ];\n\t}\n\n\treturn [ 'block-opener', name, attrs, startedAt, length ];\n}\n\nfunction addFreeform( rawLength ) {\n\tconst length = rawLength ? rawLength : document.length - offset;\n\n\tif ( 0 === length ) {\n\t\treturn;\n\t}\n\n\t// why is this not a Frame? it's because the current grammar\n\t// specifies an object that's different. we can update the\n\t// specification and change here if we want to but for now we\n\t// want this parser to be spec-compliant\n\toutput.push( {\n\t\tattrs: {},\n\t\tinnerHTML: document.substr( offset, length ),\n\t} );\n}\n\nfunction addInnerBlock( block, tokenStart, tokenLength, lastOffset ) {\n\tconst parent = stack[ stack.length - 1 ];\n\tparent.block.innerBlocks.push( block );\n\tparent.block.innerHTML += document.substr(\n\t\tparent.prevOffset,\n\t\ttokenStart - parent.prevOffset,\n\t);\n\tparent.prevOffset = lastOffset ? lastOffset : tokenStart + tokenLength;\n}\n\nfunction addBlockFromStack( endOffset ) {\n\tconst { block, leadingHtmlStart, prevOffset, tokenStart } = stack.pop();\n\n\tif ( endOffset ) {\n\t\tblock.innerHTML += document.substr( prevOffset, endOffset - prevOffset );\n\t} else {\n\t\tblock.innerHTML += document.substr( prevOffset );\n\t}\n\n\tif ( null !== leadingHtmlStart ) {\n\t\toutput.push( {\n\t\t\tattrs: {},\n\t\t\tinnerHTML: document.substr( leadingHtmlStart, tokenStart - leadingHtmlStart ),\n\t\t} );\n\t}\n\n\toutput.push( block );\n}\n"]}
{"version":3,"sources":["/Users/gziolo/PhpstormProjects/gutenberg/packages/block-serialization-default-parser/src/index.js"],"names":["document","offset","output","stack","tokenizer","Block","blockName","attrs","innerBlocks","innerHTML","Freeform","Frame","block","tokenStart","tokenLength","prevOffset","leadingHtmlStart","parse","doc","lastIndex","proceed","next","nextToken","tokenType","startOffset","stackDepth","length","addFreeform","addBlockFromStack","push","substr","addInnerBlock","stackTop","pop","parseJSON","input","JSON","e","matches","exec","startedAt","index","match","closerMatch","namespaceMatch","nameMatch","attrsMatch","voidMatch","isCloser","isVoid","namespace","name","hasAttrs","rawLength","lastOffset","parent","endOffset"],"mappings":"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","sourcesContent":["let document;\nlet offset;\nlet output;\nlet stack;\nconst tokenizer = /<!--\\s+(\\/)?wp:([a-z][a-z0-9_-]*\\/)?([a-z][a-z0-9_-]*)\\s+({(?:(?!}\\s+-->)[^])+?}\\s+)?(\\/)?-->/g;\n\nfunction Block( blockName, attrs, innerBlocks, innerHTML ) {\n\treturn {\n\t\tblockName,\n\t\tattrs,\n\t\tinnerBlocks,\n\t\tinnerHTML,\n\t};\n}\n\nfunction Freeform( innerHTML ) {\n\treturn Block( null, {}, [], innerHTML );\n}\n\nfunction Frame( block, tokenStart, tokenLength, prevOffset, leadingHtmlStart ) {\n\treturn {\n\t\tblock,\n\t\ttokenStart,\n\t\ttokenLength,\n\t\tprevOffset: prevOffset || tokenStart + tokenLength,\n\t\tleadingHtmlStart,\n\t};\n}\n\nexport const parse = ( doc ) => {\n\tdocument = doc;\n\toffset = 0;\n\toutput = [];\n\tstack = [];\n\ttokenizer.lastIndex = 0;\n\n\tdo {\n\t\t// twiddle our thumbs\n\t} while ( proceed() );\n\n\treturn output;\n};\n\nfunction proceed() {\n\tconst next = nextToken();\n\tconst [ tokenType, blockName, attrs, startOffset, tokenLength ] = next;\n\tconst stackDepth = stack.length;\n\n\t// we may have some HTML soup before the next block\n\tconst leadingHtmlStart = ( startOffset > offset ) ? offset : null;\n\n\tswitch ( tokenType ) {\n\t\tcase 'no-more-tokens':\n\t\t\t// if not in a block then flush output\n\t\t\tif ( 0 === stackDepth ) {\n\t\t\t\taddFreeform();\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// Otherwise we have a problem\n\t\t\t// This is an error\n\t\t\t// we have options\n\t\t\t// - treat it all as freeform text\n\t\t\t// - assume an implicit closer (easiest when not nesting)\n\n\t\t\t// for the easy case we'll assume an implicit closer\n\t\t\tif ( 1 === stackDepth ) {\n\t\t\t\taddBlockFromStack();\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// for the nested case where it's more difficult we'll\n\t\t\t// have to assume that multiple closers are missing\n\t\t\t// and so we'll collapse the whole stack piecewise\n\t\t\twhile ( 0 < stack.length ) {\n\t\t\t\taddBlockFromStack();\n\t\t\t}\n\t\t\treturn false;\n\n\t\tcase 'void-block':\n\t\t\t// easy case is if we stumbled upon a void block\n\t\t\t// in the top-level of the document\n\t\t\tif ( 0 === stackDepth ) {\n\t\t\t\tif ( null !== leadingHtmlStart ) {\n\t\t\t\t\toutput.push( Freeform( document.substr( leadingHtmlStart, startOffset - leadingHtmlStart ) ) );\n\t\t\t\t}\n\t\t\t\toutput.push( Block( blockName, attrs, [], '' ) );\n\t\t\t\toffset = startOffset + tokenLength;\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\t// otherwise we found an inner block\n\t\t\taddInnerBlock(\n\t\t\t\tBlock( blockName, attrs, [], '' ),\n\t\t\t\tstartOffset,\n\t\t\t\ttokenLength,\n\t\t\t);\n\t\t\toffset = startOffset + tokenLength;\n\t\t\treturn true;\n\n\t\tcase 'block-opener':\n\t\t\t// track all newly-opened blocks on the stack\n\t\t\tstack.push(\n\t\t\t\tFrame(\n\t\t\t\t\tBlock( blockName, attrs, [], '' ),\n\t\t\t\t\tstartOffset,\n\t\t\t\t\ttokenLength,\n\t\t\t\t\tstartOffset + tokenLength,\n\t\t\t\t\tleadingHtmlStart,\n\t\t\t\t),\n\t\t\t);\n\t\t\toffset = startOffset + tokenLength;\n\t\t\treturn true;\n\n\t\tcase 'block-closer':\n\t\t\t// if we're missing an opener we're in trouble\n\t\t\t// This is an error\n\t\t\tif ( 0 === stackDepth ) {\n\t\t\t\t// we have options\n\t\t\t\t// - assume an implicit opener\n\t\t\t\t// - assume _this_ is the opener\n\t\t\t\t// - give up and close out the document\n\t\t\t\taddFreeform();\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// if we're not nesting then this is easy - close the block\n\t\t\tif ( 1 === stackDepth ) {\n\t\t\t\taddBlockFromStack( startOffset );\n\t\t\t\toffset = startOffset + tokenLength;\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\t// otherwise we're nested and we have to close out the current\n\t\t\t// block and add it as a innerBlock to the parent\n\t\t\tconst stackTop = stack.pop();\n\t\t\tstackTop.block.innerHTML += document.substr(\n\t\t\t\tstackTop.prevOffset,\n\t\t\t\tstartOffset - stackTop.prevOffset,\n\t\t\t);\n\t\t\tstackTop.prevOffset = startOffset + tokenLength;\n\n\t\t\taddInnerBlock(\n\t\t\t\tstackTop.block,\n\t\t\t\tstackTop.tokenStart,\n\t\t\t\tstackTop.tokenLength,\n\t\t\t\tstartOffset + tokenLength,\n\t\t\t);\n\t\t\toffset = startOffset + tokenLength;\n\t\t\treturn true;\n\n\t\tdefault:\n\t\t\t// This is an error\n\t\t\taddFreeform();\n\t\t\treturn false;\n\t}\n}\n\n/**\n * Parse JSON if valid, otherwise return null\n *\n * Note that JSON coming from the block comment\n * delimiters is constrained to be an object\n * and cannot be things like `true` or `null`\n *\n * @param {string} input JSON input string to parse\n * @return {Object|null} parsed JSON if valid\n */\nfunction parseJSON( input ) {\n\ttry {\n\t\treturn JSON.parse( input );\n\t} catch ( e ) {\n\t\treturn null;\n\t}\n}\n\nfunction nextToken() {\n\t// aye the magic\n\t// we're using a single RegExp to tokenize the block comment delimiters\n\t// we're also using a trick here because the only difference between a\n\t// block opener and a block closer is the leading `/` before `wp:` (and\n\t// a closer has no attributes). we can trap them both and process the\n\t// match back in Javascript to see which one it was.\n\tconst matches = tokenizer.exec( document );\n\n\t// we have no more tokens\n\tif ( null === matches ) {\n\t\treturn [ 'no-more-tokens' ];\n\t}\n\n\tconst startedAt = matches.index;\n\tconst [ match, closerMatch, namespaceMatch, nameMatch, attrsMatch, voidMatch ] = matches;\n\n\tconst length = match.length;\n\tconst isCloser = !! closerMatch;\n\tconst isVoid = !! voidMatch;\n\tconst namespace = namespaceMatch || 'core/';\n\tconst name = namespace + nameMatch;\n\tconst hasAttrs = !! attrsMatch;\n\tconst attrs = hasAttrs ? parseJSON( attrsMatch ) : {};\n\n\t// This state isn't allowed\n\t// This is an error\n\tif ( isCloser && ( isVoid || hasAttrs ) ) {\n\t\t// we can ignore them since they don't hurt anything\n\t\t// we may warn against this at some point or reject it\n\t}\n\n\tif ( isVoid ) {\n\t\treturn [ 'void-block', name, attrs, startedAt, length ];\n\t}\n\n\tif ( isCloser ) {\n\t\treturn [ 'block-closer', name, null, startedAt, length ];\n\t}\n\n\treturn [ 'block-opener', name, attrs, startedAt, length ];\n}\n\nfunction addFreeform( rawLength ) {\n\tconst length = rawLength ? rawLength : document.length - offset;\n\n\tif ( 0 === length ) {\n\t\treturn;\n\t}\n\n\toutput.push( Freeform( document.substr( offset, length ) ) );\n}\n\nfunction addInnerBlock( block, tokenStart, tokenLength, lastOffset ) {\n\tconst parent = stack[ stack.length - 1 ];\n\tparent.block.innerBlocks.push( block );\n\tparent.block.innerHTML += document.substr(\n\t\tparent.prevOffset,\n\t\ttokenStart - parent.prevOffset,\n\t);\n\tparent.prevOffset = lastOffset ? lastOffset : tokenStart + tokenLength;\n}\n\nfunction addBlockFromStack( endOffset ) {\n\tconst { block, leadingHtmlStart, prevOffset, tokenStart } = stack.pop();\n\n\tif ( endOffset ) {\n\t\tblock.innerHTML += document.substr( prevOffset, endOffset - prevOffset );\n\t} else {\n\t\tblock.innerHTML += document.substr( prevOffset );\n\t}\n\n\tif ( null !== leadingHtmlStart ) {\n\t\toutput.push( Freeform( document.substr( leadingHtmlStart, tokenStart - leadingHtmlStart ) ) );\n\t}\n\n\toutput.push( block );\n}\n"]}

@@ -27,2 +27,6 @@ "use strict";

function Freeform(innerHTML) {
return Block(null, {}, [], innerHTML);
}
function Frame(block, tokenStart, tokenLength, prevOffset, leadingHtmlStart) {

@@ -100,6 +104,3 @@ return {

if (null !== leadingHtmlStart) {
output.push({
attrs: {},
innerHTML: document.substr(leadingHtmlStart, startOffset - leadingHtmlStart)
});
output.push(Freeform(document.substr(leadingHtmlStart, startOffset - leadingHtmlStart)));
}

@@ -206,3 +207,3 @@

var hasAttrs = !!attrsMatch;
var attrs = hasAttrs ? parseJSON(attrsMatch) : null; // This state isn't allowed
var attrs = hasAttrs ? parseJSON(attrsMatch) : {}; // This state isn't allowed
// This is an error

@@ -230,12 +231,5 @@

return;
} // why is this not a Frame? it's because the current grammar
// specifies an object that's different. we can update the
// specification and change here if we want to but for now we
// want this parser to be spec-compliant
}
output.push({
attrs: {},
innerHTML: document.substr(offset, length)
});
output.push(Freeform(document.substr(offset, length)));
}

@@ -264,6 +258,3 @@

if (null !== leadingHtmlStart) {
output.push({
attrs: {},
innerHTML: document.substr(leadingHtmlStart, tokenStart - leadingHtmlStart)
});
output.push(Freeform(document.substr(leadingHtmlStart, tokenStart - leadingHtmlStart)));
}

@@ -270,0 +261,0 @@

@@ -1,1 +0,1 @@

{"version":3,"sources":["/Users/robert/projects/gutenberg/packages/block-serialization-default-parser/src/index.js"],"names":["document","offset","output","stack","tokenizer","Block","blockName","attrs","innerBlocks","innerHTML","Frame","block","tokenStart","tokenLength","prevOffset","leadingHtmlStart","parse","doc","lastIndex","proceed","next","nextToken","tokenType","startOffset","stackDepth","length","addFreeform","addBlockFromStack","push","substr","addInnerBlock","stackTop","pop","parseJSON","input","JSON","e","matches","exec","startedAt","index","match","closerMatch","namespaceMatch","nameMatch","attrsMatch","voidMatch","isCloser","isVoid","namespace","name","hasAttrs","rawLength","lastOffset","parent","endOffset"],"mappings":"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","sourcesContent":["let document;\nlet offset;\nlet output;\nlet stack;\nconst tokenizer = /<!--\\s+(\\/)?wp:([a-z][a-z0-9_-]*\\/)?([a-z][a-z0-9_-]*)\\s+({(?:(?!}\\s+-->)[^])+?}\\s+)?(\\/)?-->/g;\n\nfunction Block( blockName, attrs, innerBlocks, innerHTML ) {\n\treturn {\n\t\tblockName,\n\t\tattrs,\n\t\tinnerBlocks,\n\t\tinnerHTML,\n\t};\n}\n\nfunction Frame( block, tokenStart, tokenLength, prevOffset, leadingHtmlStart ) {\n\treturn {\n\t\tblock,\n\t\ttokenStart,\n\t\ttokenLength,\n\t\tprevOffset: prevOffset || tokenStart + tokenLength,\n\t\tleadingHtmlStart,\n\t};\n}\n\nexport const parse = ( doc ) => {\n\tdocument = doc;\n\toffset = 0;\n\toutput = [];\n\tstack = [];\n\ttokenizer.lastIndex = 0;\n\n\tdo {\n\t\t// twiddle our thumbs\n\t} while ( proceed() );\n\n\treturn output;\n};\n\nfunction proceed() {\n\tconst next = nextToken();\n\tconst [ tokenType, blockName, attrs, startOffset, tokenLength ] = next;\n\tconst stackDepth = stack.length;\n\n\t// we may have some HTML soup before the next block\n\tconst leadingHtmlStart = ( startOffset > offset ) ? offset : null;\n\n\tswitch ( tokenType ) {\n\t\tcase 'no-more-tokens':\n\t\t\t// if not in a block then flush output\n\t\t\tif ( 0 === stackDepth ) {\n\t\t\t\taddFreeform();\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// Otherwise we have a problem\n\t\t\t// This is an error\n\t\t\t// we have options\n\t\t\t// - treat it all as freeform text\n\t\t\t// - assume an implicit closer (easiest when not nesting)\n\n\t\t\t// for the easy case we'll assume an implicit closer\n\t\t\tif ( 1 === stackDepth ) {\n\t\t\t\taddBlockFromStack();\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// for the nested case where it's more difficult we'll\n\t\t\t// have to assume that multiple closers are missing\n\t\t\t// and so we'll collapse the whole stack piecewise\n\t\t\twhile ( 0 < stack.length ) {\n\t\t\t\taddBlockFromStack();\n\t\t\t}\n\t\t\treturn false;\n\n\t\tcase 'void-block':\n\t\t\t// easy case is if we stumbled upon a void block\n\t\t\t// in the top-level of the document\n\t\t\tif ( 0 === stackDepth ) {\n\t\t\t\tif ( null !== leadingHtmlStart ) {\n\t\t\t\t\toutput.push( {\n\t\t\t\t\t\tattrs: {},\n\t\t\t\t\t\tinnerHTML: document.substr( leadingHtmlStart, startOffset - leadingHtmlStart ),\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t\toutput.push( Block( blockName, attrs, [], '' ) );\n\t\t\t\toffset = startOffset + tokenLength;\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\t// otherwise we found an inner block\n\t\t\taddInnerBlock(\n\t\t\t\tBlock( blockName, attrs, [], '' ),\n\t\t\t\tstartOffset,\n\t\t\t\ttokenLength,\n\t\t\t);\n\t\t\toffset = startOffset + tokenLength;\n\t\t\treturn true;\n\n\t\tcase 'block-opener':\n\t\t\t// track all newly-opened blocks on the stack\n\t\t\tstack.push(\n\t\t\t\tFrame(\n\t\t\t\t\tBlock( blockName, attrs, [], '' ),\n\t\t\t\t\tstartOffset,\n\t\t\t\t\ttokenLength,\n\t\t\t\t\tstartOffset + tokenLength,\n\t\t\t\t\tleadingHtmlStart,\n\t\t\t\t),\n\t\t\t);\n\t\t\toffset = startOffset + tokenLength;\n\t\t\treturn true;\n\n\t\tcase 'block-closer':\n\t\t\t// if we're missing an opener we're in trouble\n\t\t\t// This is an error\n\t\t\tif ( 0 === stackDepth ) {\n\t\t\t\t// we have options\n\t\t\t\t// - assume an implicit opener\n\t\t\t\t// - assume _this_ is the opener\n\t\t\t\t// - give up and close out the document\n\t\t\t\taddFreeform();\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// if we're not nesting then this is easy - close the block\n\t\t\tif ( 1 === stackDepth ) {\n\t\t\t\taddBlockFromStack( startOffset );\n\t\t\t\toffset = startOffset + tokenLength;\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\t// otherwise we're nested and we have to close out the current\n\t\t\t// block and add it as a innerBlock to the parent\n\t\t\tconst stackTop = stack.pop();\n\t\t\tstackTop.block.innerHTML += document.substr(\n\t\t\t\tstackTop.prevOffset,\n\t\t\t\tstartOffset - stackTop.prevOffset,\n\t\t\t);\n\t\t\tstackTop.prevOffset = startOffset + tokenLength;\n\n\t\t\taddInnerBlock(\n\t\t\t\tstackTop.block,\n\t\t\t\tstackTop.tokenStart,\n\t\t\t\tstackTop.tokenLength,\n\t\t\t\tstartOffset + tokenLength,\n\t\t\t);\n\t\t\toffset = startOffset + tokenLength;\n\t\t\treturn true;\n\n\t\tdefault:\n\t\t\t// This is an error\n\t\t\taddFreeform();\n\t\t\treturn false;\n\t}\n}\n\n/**\n * Parse JSON if valid, otherwise return null\n *\n * Note that JSON coming from the block comment\n * delimiters is constrained to be an object\n * and cannot be things like `true` or `null`\n *\n * @param {string} input JSON input string to parse\n * @return {Object|null} parsed JSON if valid\n */\nfunction parseJSON( input ) {\n\ttry {\n\t\treturn JSON.parse( input );\n\t} catch ( e ) {\n\t\treturn null;\n\t}\n}\n\nfunction nextToken() {\n\t// aye the magic\n\t// we're using a single RegExp to tokenize the block comment delimiters\n\t// we're also using a trick here because the only difference between a\n\t// block opener and a block closer is the leading `/` before `wp:` (and\n\t// a closer has no attributes). we can trap them both and process the\n\t// match back in Javascript to see which one it was.\n\tconst matches = tokenizer.exec( document );\n\n\t// we have no more tokens\n\tif ( null === matches ) {\n\t\treturn [ 'no-more-tokens' ];\n\t}\n\n\tconst startedAt = matches.index;\n\tconst [ match, closerMatch, namespaceMatch, nameMatch, attrsMatch, voidMatch ] = 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 ) : null;\n\n\t// This state isn't allowed\n\t// This is an error\n\tif ( isCloser && ( isVoid || hasAttrs ) ) {\n\t\t// we can ignore them since they don't hurt anything\n\t\t// we may warn against this at some point or reject it\n\t}\n\n\tif ( isVoid ) {\n\t\treturn [ 'void-block', name, attrs, startedAt, length ];\n\t}\n\n\tif ( isCloser ) {\n\t\treturn [ 'block-closer', name, null, startedAt, length ];\n\t}\n\n\treturn [ 'block-opener', name, attrs, startedAt, length ];\n}\n\nfunction addFreeform( rawLength ) {\n\tconst length = rawLength ? rawLength : document.length - offset;\n\n\tif ( 0 === length ) {\n\t\treturn;\n\t}\n\n\t// why is this not a Frame? it's because the current grammar\n\t// specifies an object that's different. we can update the\n\t// specification and change here if we want to but for now we\n\t// want this parser to be spec-compliant\n\toutput.push( {\n\t\tattrs: {},\n\t\tinnerHTML: document.substr( offset, length ),\n\t} );\n}\n\nfunction addInnerBlock( block, tokenStart, tokenLength, lastOffset ) {\n\tconst parent = stack[ stack.length - 1 ];\n\tparent.block.innerBlocks.push( block );\n\tparent.block.innerHTML += document.substr(\n\t\tparent.prevOffset,\n\t\ttokenStart - parent.prevOffset,\n\t);\n\tparent.prevOffset = lastOffset ? lastOffset : tokenStart + tokenLength;\n}\n\nfunction addBlockFromStack( endOffset ) {\n\tconst { block, leadingHtmlStart, prevOffset, tokenStart } = stack.pop();\n\n\tif ( endOffset ) {\n\t\tblock.innerHTML += document.substr( prevOffset, endOffset - prevOffset );\n\t} else {\n\t\tblock.innerHTML += document.substr( prevOffset );\n\t}\n\n\tif ( null !== leadingHtmlStart ) {\n\t\toutput.push( {\n\t\t\tattrs: {},\n\t\t\tinnerHTML: document.substr( leadingHtmlStart, tokenStart - leadingHtmlStart ),\n\t\t} );\n\t}\n\n\toutput.push( block );\n}\n"]}
{"version":3,"sources":["/Users/gziolo/PhpstormProjects/gutenberg/packages/block-serialization-default-parser/src/index.js"],"names":["document","offset","output","stack","tokenizer","Block","blockName","attrs","innerBlocks","innerHTML","Freeform","Frame","block","tokenStart","tokenLength","prevOffset","leadingHtmlStart","parse","doc","lastIndex","proceed","next","nextToken","tokenType","startOffset","stackDepth","length","addFreeform","addBlockFromStack","push","substr","addInnerBlock","stackTop","pop","parseJSON","input","JSON","e","matches","exec","startedAt","index","match","closerMatch","namespaceMatch","nameMatch","attrsMatch","voidMatch","isCloser","isVoid","namespace","name","hasAttrs","rawLength","lastOffset","parent","endOffset"],"mappings":"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","sourcesContent":["let document;\nlet offset;\nlet output;\nlet stack;\nconst tokenizer = /<!--\\s+(\\/)?wp:([a-z][a-z0-9_-]*\\/)?([a-z][a-z0-9_-]*)\\s+({(?:(?!}\\s+-->)[^])+?}\\s+)?(\\/)?-->/g;\n\nfunction Block( blockName, attrs, innerBlocks, innerHTML ) {\n\treturn {\n\t\tblockName,\n\t\tattrs,\n\t\tinnerBlocks,\n\t\tinnerHTML,\n\t};\n}\n\nfunction Freeform( innerHTML ) {\n\treturn Block( null, {}, [], innerHTML );\n}\n\nfunction Frame( block, tokenStart, tokenLength, prevOffset, leadingHtmlStart ) {\n\treturn {\n\t\tblock,\n\t\ttokenStart,\n\t\ttokenLength,\n\t\tprevOffset: prevOffset || tokenStart + tokenLength,\n\t\tleadingHtmlStart,\n\t};\n}\n\nexport const parse = ( doc ) => {\n\tdocument = doc;\n\toffset = 0;\n\toutput = [];\n\tstack = [];\n\ttokenizer.lastIndex = 0;\n\n\tdo {\n\t\t// twiddle our thumbs\n\t} while ( proceed() );\n\n\treturn output;\n};\n\nfunction proceed() {\n\tconst next = nextToken();\n\tconst [ tokenType, blockName, attrs, startOffset, tokenLength ] = next;\n\tconst stackDepth = stack.length;\n\n\t// we may have some HTML soup before the next block\n\tconst leadingHtmlStart = ( startOffset > offset ) ? offset : null;\n\n\tswitch ( tokenType ) {\n\t\tcase 'no-more-tokens':\n\t\t\t// if not in a block then flush output\n\t\t\tif ( 0 === stackDepth ) {\n\t\t\t\taddFreeform();\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// Otherwise we have a problem\n\t\t\t// This is an error\n\t\t\t// we have options\n\t\t\t// - treat it all as freeform text\n\t\t\t// - assume an implicit closer (easiest when not nesting)\n\n\t\t\t// for the easy case we'll assume an implicit closer\n\t\t\tif ( 1 === stackDepth ) {\n\t\t\t\taddBlockFromStack();\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// for the nested case where it's more difficult we'll\n\t\t\t// have to assume that multiple closers are missing\n\t\t\t// and so we'll collapse the whole stack piecewise\n\t\t\twhile ( 0 < stack.length ) {\n\t\t\t\taddBlockFromStack();\n\t\t\t}\n\t\t\treturn false;\n\n\t\tcase 'void-block':\n\t\t\t// easy case is if we stumbled upon a void block\n\t\t\t// in the top-level of the document\n\t\t\tif ( 0 === stackDepth ) {\n\t\t\t\tif ( null !== leadingHtmlStart ) {\n\t\t\t\t\toutput.push( Freeform( document.substr( leadingHtmlStart, startOffset - leadingHtmlStart ) ) );\n\t\t\t\t}\n\t\t\t\toutput.push( Block( blockName, attrs, [], '' ) );\n\t\t\t\toffset = startOffset + tokenLength;\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\t// otherwise we found an inner block\n\t\t\taddInnerBlock(\n\t\t\t\tBlock( blockName, attrs, [], '' ),\n\t\t\t\tstartOffset,\n\t\t\t\ttokenLength,\n\t\t\t);\n\t\t\toffset = startOffset + tokenLength;\n\t\t\treturn true;\n\n\t\tcase 'block-opener':\n\t\t\t// track all newly-opened blocks on the stack\n\t\t\tstack.push(\n\t\t\t\tFrame(\n\t\t\t\t\tBlock( blockName, attrs, [], '' ),\n\t\t\t\t\tstartOffset,\n\t\t\t\t\ttokenLength,\n\t\t\t\t\tstartOffset + tokenLength,\n\t\t\t\t\tleadingHtmlStart,\n\t\t\t\t),\n\t\t\t);\n\t\t\toffset = startOffset + tokenLength;\n\t\t\treturn true;\n\n\t\tcase 'block-closer':\n\t\t\t// if we're missing an opener we're in trouble\n\t\t\t// This is an error\n\t\t\tif ( 0 === stackDepth ) {\n\t\t\t\t// we have options\n\t\t\t\t// - assume an implicit opener\n\t\t\t\t// - assume _this_ is the opener\n\t\t\t\t// - give up and close out the document\n\t\t\t\taddFreeform();\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// if we're not nesting then this is easy - close the block\n\t\t\tif ( 1 === stackDepth ) {\n\t\t\t\taddBlockFromStack( startOffset );\n\t\t\t\toffset = startOffset + tokenLength;\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\t// otherwise we're nested and we have to close out the current\n\t\t\t// block and add it as a innerBlock to the parent\n\t\t\tconst stackTop = stack.pop();\n\t\t\tstackTop.block.innerHTML += document.substr(\n\t\t\t\tstackTop.prevOffset,\n\t\t\t\tstartOffset - stackTop.prevOffset,\n\t\t\t);\n\t\t\tstackTop.prevOffset = startOffset + tokenLength;\n\n\t\t\taddInnerBlock(\n\t\t\t\tstackTop.block,\n\t\t\t\tstackTop.tokenStart,\n\t\t\t\tstackTop.tokenLength,\n\t\t\t\tstartOffset + tokenLength,\n\t\t\t);\n\t\t\toffset = startOffset + tokenLength;\n\t\t\treturn true;\n\n\t\tdefault:\n\t\t\t// This is an error\n\t\t\taddFreeform();\n\t\t\treturn false;\n\t}\n}\n\n/**\n * Parse JSON if valid, otherwise return null\n *\n * Note that JSON coming from the block comment\n * delimiters is constrained to be an object\n * and cannot be things like `true` or `null`\n *\n * @param {string} input JSON input string to parse\n * @return {Object|null} parsed JSON if valid\n */\nfunction parseJSON( input ) {\n\ttry {\n\t\treturn JSON.parse( input );\n\t} catch ( e ) {\n\t\treturn null;\n\t}\n}\n\nfunction nextToken() {\n\t// aye the magic\n\t// we're using a single RegExp to tokenize the block comment delimiters\n\t// we're also using a trick here because the only difference between a\n\t// block opener and a block closer is the leading `/` before `wp:` (and\n\t// a closer has no attributes). we can trap them both and process the\n\t// match back in Javascript to see which one it was.\n\tconst matches = tokenizer.exec( document );\n\n\t// we have no more tokens\n\tif ( null === matches ) {\n\t\treturn [ 'no-more-tokens' ];\n\t}\n\n\tconst startedAt = matches.index;\n\tconst [ match, closerMatch, namespaceMatch, nameMatch, attrsMatch, voidMatch ] = matches;\n\n\tconst length = match.length;\n\tconst isCloser = !! closerMatch;\n\tconst isVoid = !! voidMatch;\n\tconst namespace = namespaceMatch || 'core/';\n\tconst name = namespace + nameMatch;\n\tconst hasAttrs = !! attrsMatch;\n\tconst attrs = hasAttrs ? parseJSON( attrsMatch ) : {};\n\n\t// This state isn't allowed\n\t// This is an error\n\tif ( isCloser && ( isVoid || hasAttrs ) ) {\n\t\t// we can ignore them since they don't hurt anything\n\t\t// we may warn against this at some point or reject it\n\t}\n\n\tif ( isVoid ) {\n\t\treturn [ 'void-block', name, attrs, startedAt, length ];\n\t}\n\n\tif ( isCloser ) {\n\t\treturn [ 'block-closer', name, null, startedAt, length ];\n\t}\n\n\treturn [ 'block-opener', name, attrs, startedAt, length ];\n}\n\nfunction addFreeform( rawLength ) {\n\tconst length = rawLength ? rawLength : document.length - offset;\n\n\tif ( 0 === length ) {\n\t\treturn;\n\t}\n\n\toutput.push( Freeform( document.substr( offset, length ) ) );\n}\n\nfunction addInnerBlock( block, tokenStart, tokenLength, lastOffset ) {\n\tconst parent = stack[ stack.length - 1 ];\n\tparent.block.innerBlocks.push( block );\n\tparent.block.innerHTML += document.substr(\n\t\tparent.prevOffset,\n\t\ttokenStart - parent.prevOffset,\n\t);\n\tparent.prevOffset = lastOffset ? lastOffset : tokenStart + tokenLength;\n}\n\nfunction addBlockFromStack( endOffset ) {\n\tconst { block, leadingHtmlStart, prevOffset, tokenStart } = stack.pop();\n\n\tif ( endOffset ) {\n\t\tblock.innerHTML += document.substr( prevOffset, endOffset - prevOffset );\n\t} else {\n\t\tblock.innerHTML += document.substr( prevOffset );\n\t}\n\n\tif ( null !== leadingHtmlStart ) {\n\t\toutput.push( Freeform( document.substr( leadingHtmlStart, tokenStart - leadingHtmlStart ) ) );\n\t}\n\n\toutput.push( block );\n}\n"]}

@@ -1,6 +0,3 @@

## 1.0.1 (unreleased)
- Fix: Include freeform content preceding void blocks (#9984)
## 1.0.0 (2018-09-30)
## 1.0.0
- Initial release.
{
"name": "@wordpress/block-serialization-default-parser",
"version": "1.0.0",
"version": "1.0.1",
"description": "Block serialization specification parser for WordPress posts.",

@@ -29,3 +29,3 @@ "author": "The WordPress Contributors",

},
"gitHead": "7b17d5777076896fb25170b23d6e83e8c049240d"
"gitHead": "0aa5c4340f57a69ab935f9e819d74958aad2e022"
}
+243
-231

@@ -19,3 +19,3 @@ <?php

*/
public $blockName;
public $blockName;

@@ -31,3 +31,3 @@ /**

*/
public $attrs;
public $attrs;

@@ -40,3 +40,3 @@ /**

*/
public $innerBlocks;
public $innerBlocks;

@@ -52,10 +52,10 @@ /**

*/
public $innerHTML;
public $innerHTML;
function __construct( $name, $attrs, $innerBlocks, $innerHTML ) {
$this->blockName = $name;
$this->attrs = $attrs;
$this->innerBlocks = $innerBlocks;
$this->innerHTML = $innerHTML;
}
function __construct( $name, $attrs, $innerBlocks, $innerHTML ) {
$this->blockName = $name;
$this->attrs = $attrs;
$this->innerBlocks = $innerBlocks;
$this->innerHTML = $innerHTML;
}
}

@@ -78,3 +78,3 @@

*/
public $block;
public $block;

@@ -87,3 +87,3 @@ /**

*/
public $token_start;
public $token_start;

@@ -96,3 +96,3 @@ /**

*/
public $token_length;
public $token_length;

@@ -106,3 +106,3 @@ /**

*/
public $prev_offset;
public $prev_offset;

@@ -115,11 +115,11 @@ /**

*/
public $leading_html_start;
public $leading_html_start;
function __construct( $block, $token_start, $token_length, $prev_offset = null, $leading_html_start = null ) {
$this->block = $block;
$this->token_start = $token_start;
$this->token_length = $token_length;
$this->prev_offset = isset($prev_offset) ? $prev_offset : $token_start + $token_length;
$this->leading_html_start = $leading_html_start;
}
function __construct( $block, $token_start, $token_length, $prev_offset = null, $leading_html_start = null ) {
$this->block = $block;
$this->token_start = $token_start;
$this->token_length = $token_length;
$this->prev_offset = isset( $prev_offset ) ? $prev_offset : $token_start + $token_length;
$this->leading_html_start = $leading_html_start;
}
}

@@ -133,2 +133,3 @@

* @since 3.8.0
* @since 4.0.0 returns arrays not objects, all attributes are arrays
*/

@@ -144,3 +145,3 @@ class WP_Block_Parser {

*/
public $document;
public $document;

@@ -153,3 +154,3 @@ /**

*/
public $offset;
public $offset;

@@ -162,3 +163,3 @@ /**

*/
public $output;
public $output;

@@ -171,3 +172,3 @@ /**

*/
public $stack;
public $stack;

@@ -186,14 +187,14 @@ /**

*/
function parse( $document ) {
$this->document = $document;
$this->offset = 0;
$this->output = array();
$this->stack = array();
function parse( $document ) {
$this->document = $document;
$this->offset = 0;
$this->output = array();
$this->stack = array();
do {
// twiddle our thumbs
} while ( $this->proceed() );
do {
// twiddle our thumbs
} while ( $this->proceed() );
return $this->output;
}
return $this->output;
}

@@ -214,132 +215,129 @@ /**

*/
function proceed() {
$next_token = $this->next_token();
list( $token_type, $block_name, $attrs, $start_offset, $token_length ) = $next_token;
$stack_depth = count( $this->stack );
function proceed() {
$next_token = $this->next_token();
list( $token_type, $block_name, $attrs, $start_offset, $token_length ) = $next_token;
$stack_depth = count( $this->stack );
// we may have some HTML soup before the next block
$leading_html_start = $start_offset > $this->offset ? $this->offset : null;
// we may have some HTML soup before the next block
$leading_html_start = $start_offset > $this->offset ? $this->offset : null;
switch ( $token_type ) {
case 'no-more-tokens':
// if not in a block then flush output
if ( 0 === $stack_depth ) {
$this->add_freeform();
return false;
}
switch ( $token_type ) {
case 'no-more-tokens':
// if not in a block then flush output
if ( 0 === $stack_depth ) {
$this->add_freeform();
return false;
}
/*
* Otherwise we have a problem
* This is an error
*
* we have options
* - treat it all as freeform text
* - assume an implicit closer (easiest when not nesting)
*/
/*
* Otherwise we have a problem
* This is an error
*
* we have options
* - treat it all as freeform text
* - assume an implicit closer (easiest when not nesting)
*/
// for the easy case we'll assume an implicit closer
if ( 1 === $stack_depth ) {
$this->add_block_from_stack();
return false;
}
// for the easy case we'll assume an implicit closer
if ( 1 === $stack_depth ) {
$this->add_block_from_stack();
return false;
}
/*
* for the nested case where it's more difficult we'll
* have to assume that multiple closers are missing
* and so we'll collapse the whole stack piecewise
*/
while ( 0 < count( $this->stack ) ) {
$this->add_block_from_stack();
}
return false;
/*
* for the nested case where it's more difficult we'll
* have to assume that multiple closers are missing
* and so we'll collapse the whole stack piecewise
*/
while ( 0 < count( $this->stack ) ) {
$this->add_block_from_stack();
}
return false;
case 'void-block':
/*
* easy case is if we stumbled upon a void block
* in the top-level of the document
*/
if ( 0 === $stack_depth ) {
if ( isset( $leading_html_start ) ) {
$this->output[] = array(
'attrs' => array(),
'innerHTML' => substr(
$this->document,
$leading_html_start,
$start_offset - $leading_html_start
),
);
}
case 'void-block':
/*
* easy case is if we stumbled upon a void block
* in the top-level of the document
*/
if ( 0 === $stack_depth ) {
if ( isset( $leading_html_start ) ) {
$this->output[] = (array) self::freeform( substr(
$this->document,
$leading_html_start,
$start_offset - $leading_html_start
) );
}
$this->output[] = new WP_Block_Parser_Block( $block_name, $attrs, array(), '' );
$this->offset = $start_offset + $token_length;
return true;
}
$this->output[] = (array) new WP_Block_Parser_Block( $block_name, $attrs, array(), '' );
$this->offset = $start_offset + $token_length;
return true;
}
// otherwise we found an inner block
$this->add_inner_block(
new WP_Block_Parser_Block( $block_name, $attrs, array(), '' ),
$start_offset,
$token_length
);
$this->offset = $start_offset + $token_length;
return true;
// otherwise we found an inner block
$this->add_inner_block(
new WP_Block_Parser_Block( $block_name, $attrs, array(), '' ),
$start_offset,
$token_length
);
$this->offset = $start_offset + $token_length;
return true;
case 'block-opener':
// track all newly-opened blocks on the stack
array_push( $this->stack, new WP_Block_Parser_Frame(
new WP_Block_Parser_Block( $block_name, $attrs, array(), '' ),
$start_offset,
$token_length,
$start_offset + $token_length,
$leading_html_start
) );
$this->offset = $start_offset + $token_length;
return true;
case 'block-opener':
// track all newly-opened blocks on the stack
array_push( $this->stack, new WP_Block_Parser_Frame(
new WP_Block_Parser_Block( $block_name, $attrs, array(), '' ),
$start_offset,
$token_length,
$start_offset + $token_length,
$leading_html_start
) );
$this->offset = $start_offset + $token_length;
return true;
case 'block-closer':
/*
* if we're missing an opener we're in trouble
* This is an error
*/
if ( 0 === $stack_depth ) {
/*
* we have options
* - assume an implicit opener
* - assume _this_ is the opener
* - give up and close out the document
*/
$this->add_freeform();
return false;
}
case 'block-closer':
/*
* if we're missing an opener we're in trouble
* This is an error
*/
if ( 0 === $stack_depth ) {
/*
* we have options
* - assume an implicit opener
* - assume _this_ is the opener
* - give up and close out the document
*/
$this->add_freeform();
return false;
}
// if we're not nesting then this is easy - close the block
if ( 1 === $stack_depth ) {
$this->add_block_from_stack( $start_offset );
$this->offset = $start_offset + $token_length;
return true;
}
// if we're not nesting then this is easy - close the block
if ( 1 === $stack_depth ) {
$this->add_block_from_stack( $start_offset );
$this->offset = $start_offset + $token_length;
return true;
}
/*
* otherwise we're nested and we have to close out the current
* block and add it as a new innerBlock to the parent
*/
$stack_top = array_pop( $this->stack );
$stack_top->block->innerHTML .= substr( $this->document, $stack_top->prev_offset, $start_offset - $stack_top->prev_offset );
$stack_top->prev_offset = $start_offset + $token_length;
/*
* otherwise we're nested and we have to close out the current
* block and add it as a new innerBlock to the parent
*/
$stack_top = array_pop( $this->stack );
$stack_top->block->innerHTML .= substr( $this->document, $stack_top->prev_offset, $start_offset - $stack_top->prev_offset );
$stack_top->prev_offset = $start_offset + $token_length;
$this->add_inner_block(
$stack_top->block,
$stack_top->token_start,
$stack_top->token_length,
$start_offset + $token_length
);
$this->offset = $start_offset + $token_length;
return true;
$this->add_inner_block(
$stack_top->block,
$stack_top->token_start,
$stack_top->token_length,
$start_offset + $token_length
);
$this->offset = $start_offset + $token_length;
return true;
default:
// This is an error
$this->add_freeform();
return false;
}
}
default:
// This is an error
$this->add_freeform();
return false;
}
}

@@ -356,57 +354,77 @@ /**

*/
function next_token() {
$matches = null;
function next_token() {
$matches = null;
/*
* aye the magic
* we're using a single RegExp to tokenize the block comment delimiters
* we're also using a trick here because the only difference between a
* block opener and a block closer is the leading `/` before `wp:` (and
* a closer has no attributes). we can trap them both and process the
* match back in PHP to see which one it was.
*/
$has_match = preg_match(
'/<!--\s+(?<closer>\/)?wp:(?<namespace>[a-z][a-z0-9_-]*\/)?(?<name>[a-z][a-z0-9_-]*)\s+(?<attrs>{(?:(?!}\s+-->).)+?}\s+)?(?<void>\/)?-->/s',
$this->document,
$matches,
PREG_OFFSET_CAPTURE,
$this->offset
);
/*
* aye the magic
* we're using a single RegExp to tokenize the block comment delimiters
* we're also using a trick here because the only difference between a
* block opener and a block closer is the leading `/` before `wp:` (and
* a closer has no attributes). we can trap them both and process the
* match back in PHP to see which one it was.
*/
$has_match = preg_match(
'/<!--\s+(?<closer>\/)?wp:(?<namespace>[a-z][a-z0-9_-]*\/)?(?<name>[a-z][a-z0-9_-]*)\s+(?<attrs>{(?:(?!}\s+-->).)+?}\s+)?(?<void>\/)?-->/s',
$this->document,
$matches,
PREG_OFFSET_CAPTURE,
$this->offset
);
// we have no more tokens
if ( 0 === $has_match ) {
return array( 'no-more-tokens', null, null, null, null );
}
// we have no more tokens
if ( 0 === $has_match ) {
return array( 'no-more-tokens', null, null, null, null );
}
list( $match, $started_at ) = $matches[ 0 ];
list( $match, $started_at ) = $matches[ 0 ];
$length = strlen( $match );
$is_closer = isset( $matches[ 'closer' ] ) && -1 !== $matches[ 'closer' ][ 1 ];
$is_void = isset( $matches[ 'void' ] ) && -1 !== $matches[ 'void' ][ 1 ];
$namespace = $matches[ 'namespace' ];
$namespace = ( isset( $namespace ) && -1 !== $namespace[ 1 ] ) ? $namespace[ 0 ] : 'core/';
$name = $namespace . $matches[ 'name' ][ 0 ];
$has_attrs = isset( $matches[ 'attrs' ] ) && -1 !== $matches[ 'attrs' ][ 1 ];
$attrs = $has_attrs ? json_decode( $matches[ 'attrs' ][ 0 ] ) : null;
$length = strlen( $match );
$is_closer = isset( $matches[ 'closer' ] ) && -1 !== $matches[ 'closer' ][ 1 ];
$is_void = isset( $matches[ 'void' ] ) && -1 !== $matches[ 'void' ][ 1 ];
$namespace = $matches[ 'namespace' ];
$namespace = ( isset( $namespace ) && -1 !== $namespace[ 1 ] ) ? $namespace[ 0 ] : 'core/';
$name = $namespace . $matches[ 'name' ][ 0 ];
$has_attrs = isset( $matches[ 'attrs' ] ) && -1 !== $matches[ 'attrs' ][ 1 ];
/*
* This state isn't allowed
* This is an error
*/
if ( $is_closer && ( $is_void || $has_attrs ) ) {
// we can ignore them since they don't hurt anything
}
/*
* Fun fact! It's not trivial in PHP to create "an empty associative array" since all arrays
* are associative arrays. If we use `array()` we get a JSON `[]`
*/
$attrs = $has_attrs
? json_decode( $matches[ 'attrs' ][ 0 ], /* as-associative */ true )
: json_decode( '{}', /* don't ask why, just verify in PHP */ false );
if ( $is_void ) {
return array( 'void-block', $name, $attrs, $started_at, $length );
}
/*
* This state isn't allowed
* This is an error
*/
if ( $is_closer && ( $is_void || $has_attrs ) ) {
// we can ignore them since they don't hurt anything
}
if ( $is_closer ) {
return array( 'block-closer', $name, null, $started_at, $length );
}
if ( $is_void ) {
return array( 'void-block', $name, $attrs, $started_at, $length );
}
return array( 'block-opener', $name, $attrs, $started_at, $length );
}
if ( $is_closer ) {
return array( 'block-closer', $name, null, $started_at, $length );
}
return array( 'block-opener', $name, $attrs, $started_at, $length );
}
/**
* Returns a new block object for freeform HTML
*
* @internal
* @since 3.9.0
*
* @param string $innerHTML HTML content of block
* @return WP_Block_Parser_Block freeform block object
*/
static function freeform( $innerHTML ) {
return new WP_Block_Parser_Block( null, array(), array(), $innerHTML );
}
/**
* Pushes a length of text from the input document

@@ -419,14 +437,11 @@ * to the output list as a freeform block

*/
function add_freeform( $length = null ) {
$length = $length ? $length : strlen( $this->document ) - $this->offset;
function add_freeform( $length = null ) {
$length = $length ? $length : strlen( $this->document ) - $this->offset;
if ( 0 === $length ) {
return;
}
if ( 0 === $length ) {
return;
}
$this->output[] = array(
'attrs' => new stdClass(),
'innerHTML' => substr( $this->document, $this->offset, $length ),
);
}
$this->output[] = (array) self::freeform( substr( $this->document, $this->offset, $length ) );
}

@@ -444,8 +459,8 @@ /**

*/
function add_inner_block(WP_Block_Parser_Block $block, $token_start, $token_length, $last_offset = null ) {
$parent = $this->stack[ count( $this->stack ) - 1 ];
$parent->block->innerBlocks[] = $block;
$parent->block->innerHTML .= substr( $this->document, $parent->prev_offset, $token_start - $parent->prev_offset );
$parent->prev_offset = $last_offset ? $last_offset : $token_start + $token_length;
}
function add_inner_block( WP_Block_Parser_Block $block, $token_start, $token_length, $last_offset = null ) {
$parent = $this->stack[ count( $this->stack ) - 1 ];
$parent->block->innerBlocks[] = $block;
$parent->block->innerHTML .= substr( $this->document, $parent->prev_offset, $token_start - $parent->prev_offset );
$parent->prev_offset = $last_offset ? $last_offset : $token_start + $token_length;
}

@@ -459,23 +474,20 @@ /**

*/
function add_block_from_stack( $end_offset = null ) {
$stack_top = array_pop( $this->stack );
$prev_offset = $stack_top->prev_offset;
function add_block_from_stack( $end_offset = null ) {
$stack_top = array_pop( $this->stack );
$prev_offset = $stack_top->prev_offset;
$stack_top->block->innerHTML .= isset( $end_offset )
? substr( $this->document, $prev_offset, $end_offset - $prev_offset )
: substr( $this->document, $prev_offset );
$stack_top->block->innerHTML .= isset( $end_offset )
? substr( $this->document, $prev_offset, $end_offset - $prev_offset )
: substr( $this->document, $prev_offset );
if ( isset( $stack_top->leading_html_start ) ) {
$this->output[] = array(
'attrs' => array(),
'innerHTML' => substr(
$this->document,
$stack_top->leading_html_start,
$stack_top->token_start - $stack_top->leading_html_start
),
);
}
if ( isset( $stack_top->leading_html_start ) ) {
$this->output[] = (array) self::freeform( substr(
$this->document,
$stack_top->leading_html_start,
$stack_top->token_start - $stack_top->leading_html_start
) );
}
$this->output[] = $stack_top->block;
}
$this->output[] = (array) $stack_top->block;
}
}

@@ -16,2 +16,6 @@ let document;

function Freeform( innerHTML ) {
return Block( null, {}, [], innerHTML );
}
function Frame( block, tokenStart, tokenLength, prevOffset, leadingHtmlStart ) {

@@ -82,6 +86,3 @@ return {

if ( null !== leadingHtmlStart ) {
output.push( {
attrs: {},
innerHTML: document.substr( leadingHtmlStart, startOffset - leadingHtmlStart ),
} );
output.push( Freeform( document.substr( leadingHtmlStart, startOffset - leadingHtmlStart ) ) );
}

@@ -201,3 +202,3 @@ output.push( Block( blockName, attrs, [], '' ) );

const hasAttrs = !! attrsMatch;
const attrs = hasAttrs ? parseJSON( attrsMatch ) : null;
const attrs = hasAttrs ? parseJSON( attrsMatch ) : {};

@@ -229,10 +230,3 @@ // This state isn't allowed

// why is this not a Frame? it's because the current grammar
// specifies an object that's different. we can update the
// specification and change here if we want to but for now we
// want this parser to be spec-compliant
output.push( {
attrs: {},
innerHTML: document.substr( offset, length ),
} );
output.push( Freeform( document.substr( offset, length ) ) );
}

@@ -260,6 +254,3 @@

if ( null !== leadingHtmlStart ) {
output.push( {
attrs: {},
innerHTML: document.substr( leadingHtmlStart, tokenStart - leadingHtmlStart ),
} );
output.push( Freeform( document.substr( leadingHtmlStart, tokenStart - leadingHtmlStart ) ) );
}

@@ -266,0 +257,0 @@