@wordpress/block-serialization-default-parser
Advanced tools
@@ -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":";AAAA,IAAIA,QAAJ;AACA,IAAIC,MAAJ;AACA,IAAIC,MAAJ;AACA,IAAIC,KAAJ;AACA,IAAMC,SAAS,GAAG,gGAAlB;;AAEA,SAASC,KAAT,CAAgBC,SAAhB,EAA2BC,KAA3B,EAAkCC,WAAlC,EAA+CC,SAA/C,EAA2D;AAC1D,SAAO;AACNH,IAAAA,SAAS,EAATA,SADM;AAENC,IAAAA,KAAK,EAALA,KAFM;AAGNC,IAAAA,WAAW,EAAXA,WAHM;AAINC,IAAAA,SAAS,EAATA;AAJM,GAAP;AAMA;;AAED,SAASC,KAAT,CAAgBC,KAAhB,EAAuBC,UAAvB,EAAmCC,WAAnC,EAAgDC,UAAhD,EAA4DC,gBAA5D,EAA+E;AAC9E,SAAO;AACNJ,IAAAA,KAAK,EAALA,KADM;AAENC,IAAAA,UAAU,EAAVA,UAFM;AAGNC,IAAAA,WAAW,EAAXA,WAHM;AAINC,IAAAA,UAAU,EAAEA,UAAU,IAAIF,UAAU,GAAGC,WAJjC;AAKNE,IAAAA,gBAAgB,EAAhBA;AALM,GAAP;AAOA;;AAED,OAAO,IAAMC,KAAK,GAAG,SAARA,KAAQ,CAAEC,GAAF,EAAW;AAC/BjB,EAAAA,QAAQ,GAAGiB,GAAX;AACAhB,EAAAA,MAAM,GAAG,CAAT;AACAC,EAAAA,MAAM,GAAG,EAAT;AACAC,EAAAA,KAAK,GAAG,EAAR;AACAC,EAAAA,SAAS,CAACc,SAAV,GAAsB,CAAtB;;AAEA,KAAG,CACF;AACA,GAFD,QAEUC,OAAO,EAFjB;;AAIA,SAAOjB,MAAP;AACA,CAZM;;AAcP,SAASiB,OAAT,GAAmB;AAClB,MAAMC,IAAI,GAAGC,SAAS,EAAtB;;AADkB,6BAEgDD,IAFhD;AAAA,MAEVE,SAFU;AAAA,MAEChB,SAFD;AAAA,MAEYC,KAFZ;AAAA,MAEmBgB,WAFnB;AAAA,MAEgCV,WAFhC;;AAGlB,MAAMW,UAAU,GAAGrB,KAAK,CAACsB,MAAzB,CAHkB,CAKlB;;AACA,MAAMV,gBAAgB,GAAKQ,WAAW,GAAGtB,MAAhB,GAA2BA,MAA3B,GAAoC,IAA7D;;AAEA,UAASqB,SAAT;AACC,SAAK,gBAAL;AACC;AACA,UAAK,MAAME,UAAX,EAAwB;AACvBE,QAAAA,WAAW;AACX,eAAO,KAAP;AACA,OALF,CAOC;AACA;AACA;AACA;AACA;AAEA;;;AACA,UAAK,MAAMF,UAAX,EAAwB;AACvBG,QAAAA,iBAAiB;AACjB,eAAO,KAAP;AACA,OAjBF,CAmBC;AACA;AACA;;;AACA,aAAQ,IAAIxB,KAAK,CAACsB,MAAlB,EAA2B;AAC1BE,QAAAA,iBAAiB;AACjB;;AACD,aAAO,KAAP;;AAED,SAAK,YAAL;AACC;AACA;AACA,UAAK,MAAMH,UAAX,EAAwB;AACvB,YAAK,SAAST,gBAAd,EAAiC;AAChCb,UAAAA,MAAM,CAAC0B,IAAP,CAAa;AACZrB,YAAAA,KAAK,EAAE,EADK;AAEZE,YAAAA,SAAS,EAAET,QAAQ,CAAC6B,MAAT,CAAiBd,gBAAjB,EAAmCQ,WAAW,GAAGR,gBAAjD;AAFC,WAAb;AAIA;;AACDb,QAAAA,MAAM,CAAC0B,IAAP,CAAavB,KAAK,CAAEC,SAAF,EAAaC,KAAb,EAAoB,EAApB,EAAwB,EAAxB,CAAlB;AACAN,QAAAA,MAAM,GAAGsB,WAAW,GAAGV,WAAvB;AACA,eAAO,IAAP;AACA,OAbF,CAeC;;;AACAiB,MAAAA,aAAa,CACZzB,KAAK,CAAEC,SAAF,EAAaC,KAAb,EAAoB,EAApB,EAAwB,EAAxB,CADO,EAEZgB,WAFY,EAGZV,WAHY,CAAb;AAKAZ,MAAAA,MAAM,GAAGsB,WAAW,GAAGV,WAAvB;AACA,aAAO,IAAP;;AAED,SAAK,cAAL;AACC;AACAV,MAAAA,KAAK,CAACyB,IAAN,CACClB,KAAK,CACJL,KAAK,CAAEC,SAAF,EAAaC,KAAb,EAAoB,EAApB,EAAwB,EAAxB,CADD,EAEJgB,WAFI,EAGJV,WAHI,EAIJU,WAAW,GAAGV,WAJV,EAKJE,gBALI,CADN;AASAd,MAAAA,MAAM,GAAGsB,WAAW,GAAGV,WAAvB;AACA,aAAO,IAAP;;AAED,SAAK,cAAL;AACC;AACA;AACA,UAAK,MAAMW,UAAX,EAAwB;AACvB;AACA;AACA;AACA;AACAE,QAAAA,WAAW;AACX,eAAO,KAAP;AACA,OAVF,CAYC;;;AACA,UAAK,MAAMF,UAAX,EAAwB;AACvBG,QAAAA,iBAAiB,CAAEJ,WAAF,CAAjB;AACAtB,QAAAA,MAAM,GAAGsB,WAAW,GAAGV,WAAvB;AACA,eAAO,IAAP;AACA,OAjBF,CAmBC;AACA;;;AACA,UAAMkB,QAAQ,GAAG5B,KAAK,CAAC6B,GAAN,EAAjB;AACAD,MAAAA,QAAQ,CAACpB,KAAT,CAAeF,SAAf,IAA4BT,QAAQ,CAAC6B,MAAT,CAC3BE,QAAQ,CAACjB,UADkB,EAE3BS,WAAW,GAAGQ,QAAQ,CAACjB,UAFI,CAA5B;AAIAiB,MAAAA,QAAQ,CAACjB,UAAT,GAAsBS,WAAW,GAAGV,WAApC;AAEAiB,MAAAA,aAAa,CACZC,QAAQ,CAACpB,KADG,EAEZoB,QAAQ,CAACnB,UAFG,EAGZmB,QAAQ,CAAClB,WAHG,EAIZU,WAAW,GAAGV,WAJF,CAAb;AAMAZ,MAAAA,MAAM,GAAGsB,WAAW,GAAGV,WAAvB;AACA,aAAO,IAAP;;AAED;AACC;AACAa,MAAAA,WAAW;AACX,aAAO,KAAP;AA1GF;AA4GA;AAED;;;;;;;;;;;;AAUA,SAASO,SAAT,CAAoBC,KAApB,EAA4B;AAC3B,MAAI;AACH,WAAOC,IAAI,CAACnB,KAAL,CAAYkB,KAAZ,CAAP;AACA,GAFD,CAEE,OAAQE,CAAR,EAAY;AACb,WAAO,IAAP;AACA;AACD;;AAED,SAASf,SAAT,GAAqB;AACpB;AACA;AACA;AACA;AACA;AACA;AACA,MAAMgB,OAAO,GAAGjC,SAAS,CAACkC,IAAV,CAAgBtC,QAAhB,CAAhB,CAPoB,CASpB;;AACA,MAAK,SAASqC,OAAd,EAAwB;AACvB,WAAO,CAAE,gBAAF,CAAP;AACA;;AAED,MAAME,SAAS,GAAGF,OAAO,CAACG,KAA1B;;AAdoB,gCAe6DH,OAf7D;AAAA,MAeZI,KAfY;AAAA,MAeLC,WAfK;AAAA,MAeQC,cAfR;AAAA,MAewBC,SAfxB;AAAA,MAemCC,UAfnC;AAAA,MAe+CC,SAf/C;;AAiBpB,MAAMrB,MAAM,GAAGgB,KAAK,CAAChB,MAArB;AACA,MAAMsB,QAAQ,GAAG,CAAC,CAAEL,WAApB;AACA,MAAMM,MAAM,GAAG,CAAC,CAAEF,SAAlB;AACA,MAAMG,SAAS,GAAGN,cAAc,IAAI,OAApC;AACA,MAAMO,IAAI,GAAGD,SAAS,GAAGL,SAAzB;AACA,MAAMO,QAAQ,GAAG,CAAC,CAAEN,UAApB;AACA,MAAMtC,KAAK,GAAG4C,QAAQ,GAAGlB,SAAS,CAAEY,UAAF,CAAZ,GAA6B,IAAnD,CAvBoB,CAyBpB;AACA;;AACA,MAAKE,QAAQ,KAAMC,MAAM,IAAIG,QAAhB,CAAb,EAA0C,CACzC;AACA;AACA;;AAED,MAAKH,MAAL,EAAc;AACb,WAAO,CAAE,YAAF,EAAgBE,IAAhB,EAAsB3C,KAAtB,EAA6BgC,SAA7B,EAAwCd,MAAxC,CAAP;AACA;;AAED,MAAKsB,QAAL,EAAgB;AACf,WAAO,CAAE,cAAF,EAAkBG,IAAlB,EAAwB,IAAxB,EAA8BX,SAA9B,EAAyCd,MAAzC,CAAP;AACA;;AAED,SAAO,CAAE,cAAF,EAAkByB,IAAlB,EAAwB3C,KAAxB,EAA+BgC,SAA/B,EAA0Cd,MAA1C,CAAP;AACA;;AAED,SAASC,WAAT,CAAsB0B,SAAtB,EAAkC;AACjC,MAAM3B,MAAM,GAAG2B,SAAS,GAAGA,SAAH,GAAepD,QAAQ,CAACyB,MAAT,GAAkBxB,MAAzD;;AAEA,MAAK,MAAMwB,MAAX,EAAoB;AACnB;AACA,GALgC,CAOjC;AACA;AACA;AACA;;;AACAvB,EAAAA,MAAM,CAAC0B,IAAP,CAAa;AACZrB,IAAAA,KAAK,EAAE,EADK;AAEZE,IAAAA,SAAS,EAAET,QAAQ,CAAC6B,MAAT,CAAiB5B,MAAjB,EAAyBwB,MAAzB;AAFC,GAAb;AAIA;;AAED,SAASK,aAAT,CAAwBnB,KAAxB,EAA+BC,UAA/B,EAA2CC,WAA3C,EAAwDwC,UAAxD,EAAqE;AACpE,MAAMC,MAAM,GAAGnD,KAAK,CAAEA,KAAK,CAACsB,MAAN,GAAe,CAAjB,CAApB;AACA6B,EAAAA,MAAM,CAAC3C,KAAP,CAAaH,WAAb,CAAyBoB,IAAzB,CAA+BjB,KAA/B;AACA2C,EAAAA,MAAM,CAAC3C,KAAP,CAAaF,SAAb,IAA0BT,QAAQ,CAAC6B,MAAT,CACzByB,MAAM,CAACxC,UADkB,EAEzBF,UAAU,GAAG0C,MAAM,CAACxC,UAFK,CAA1B;AAIAwC,EAAAA,MAAM,CAACxC,UAAP,GAAoBuC,UAAU,GAAGA,UAAH,GAAgBzC,UAAU,GAAGC,WAA3D;AACA;;AAED,SAASc,iBAAT,CAA4B4B,SAA5B,EAAwC;AAAA,mBACqBpD,KAAK,CAAC6B,GAAN,EADrB;AAAA,MAC/BrB,KAD+B,cAC/BA,KAD+B;AAAA,MACxBI,gBADwB,cACxBA,gBADwB;AAAA,MACND,UADM,cACNA,UADM;AAAA,MACMF,UADN,cACMA,UADN;;AAGvC,MAAK2C,SAAL,EAAiB;AAChB5C,IAAAA,KAAK,CAACF,SAAN,IAAmBT,QAAQ,CAAC6B,MAAT,CAAiBf,UAAjB,EAA6ByC,SAAS,GAAGzC,UAAzC,CAAnB;AACA,GAFD,MAEO;AACNH,IAAAA,KAAK,CAACF,SAAN,IAAmBT,QAAQ,CAAC6B,MAAT,CAAiBf,UAAjB,CAAnB;AACA;;AAED,MAAK,SAASC,gBAAd,EAAiC;AAChCb,IAAAA,MAAM,CAAC0B,IAAP,CAAa;AACZrB,MAAAA,KAAK,EAAE,EADK;AAEZE,MAAAA,SAAS,EAAET,QAAQ,CAAC6B,MAAT,CAAiBd,gBAAjB,EAAmCH,UAAU,GAAGG,gBAAhD;AAFC,KAAb;AAIA;;AAEDb,EAAAA,MAAM,CAAC0B,IAAP,CAAajB,KAAb;AACA","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"]} |
+9
-18
@@ -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":";;;;;;;;;;;AAAA,IAAIA,QAAJ;AACA,IAAIC,MAAJ;AACA,IAAIC,MAAJ;AACA,IAAIC,KAAJ;AACA,IAAMC,SAAS,GAAG,gGAAlB;;AAEA,SAASC,KAAT,CAAgBC,SAAhB,EAA2BC,KAA3B,EAAkCC,WAAlC,EAA+CC,SAA/C,EAA2D;AAC1D,SAAO;AACNH,IAAAA,SAAS,EAATA,SADM;AAENC,IAAAA,KAAK,EAALA,KAFM;AAGNC,IAAAA,WAAW,EAAXA,WAHM;AAINC,IAAAA,SAAS,EAATA;AAJM,GAAP;AAMA;;AAED,SAASC,QAAT,CAAmBD,SAAnB,EAA+B;AAC9B,SAAOJ,KAAK,CAAE,IAAF,EAAQ,EAAR,EAAY,EAAZ,EAAgBI,SAAhB,CAAZ;AACA;;AAED,SAASE,KAAT,CAAgBC,KAAhB,EAAuBC,UAAvB,EAAmCC,WAAnC,EAAgDC,UAAhD,EAA4DC,gBAA5D,EAA+E;AAC9E,SAAO;AACNJ,IAAAA,KAAK,EAALA,KADM;AAENC,IAAAA,UAAU,EAAVA,UAFM;AAGNC,IAAAA,WAAW,EAAXA,WAHM;AAINC,IAAAA,UAAU,EAAEA,UAAU,IAAIF,UAAU,GAAGC,WAJjC;AAKNE,IAAAA,gBAAgB,EAAhBA;AALM,GAAP;AAOA;;AAEM,IAAMC,KAAK,GAAG,SAARA,KAAQ,CAAEC,GAAF,EAAW;AAC/BlB,EAAAA,QAAQ,GAAGkB,GAAX;AACAjB,EAAAA,MAAM,GAAG,CAAT;AACAC,EAAAA,MAAM,GAAG,EAAT;AACAC,EAAAA,KAAK,GAAG,EAAR;AACAC,EAAAA,SAAS,CAACe,SAAV,GAAsB,CAAtB;;AAEA,KAAG,CACF;AACA,GAFD,QAEUC,OAAO,EAFjB;;AAIA,SAAOlB,MAAP;AACA,CAZM;;;;AAcP,SAASkB,OAAT,GAAmB;AAClB,MAAMC,IAAI,GAAGC,SAAS,EAAtB;;AADkB,2CAEgDD,IAFhD;AAAA,MAEVE,SAFU;AAAA,MAECjB,SAFD;AAAA,MAEYC,KAFZ;AAAA,MAEmBiB,WAFnB;AAAA,MAEgCV,WAFhC;;AAGlB,MAAMW,UAAU,GAAGtB,KAAK,CAACuB,MAAzB,CAHkB,CAKlB;;AACA,MAAMV,gBAAgB,GAAKQ,WAAW,GAAGvB,MAAhB,GAA2BA,MAA3B,GAAoC,IAA7D;;AAEA,UAASsB,SAAT;AACC,SAAK,gBAAL;AACC;AACA,UAAK,MAAME,UAAX,EAAwB;AACvBE,QAAAA,WAAW;AACX,eAAO,KAAP;AACA,OALF,CAOC;AACA;AACA;AACA;AACA;AAEA;;;AACA,UAAK,MAAMF,UAAX,EAAwB;AACvBG,QAAAA,iBAAiB;AACjB,eAAO,KAAP;AACA,OAjBF,CAmBC;AACA;AACA;;;AACA,aAAQ,IAAIzB,KAAK,CAACuB,MAAlB,EAA2B;AAC1BE,QAAAA,iBAAiB;AACjB;;AACD,aAAO,KAAP;;AAED,SAAK,YAAL;AACC;AACA;AACA,UAAK,MAAMH,UAAX,EAAwB;AACvB,YAAK,SAAST,gBAAd,EAAiC;AAChCd,UAAAA,MAAM,CAAC2B,IAAP,CAAanB,QAAQ,CAAEV,QAAQ,CAAC8B,MAAT,CAAiBd,gBAAjB,EAAmCQ,WAAW,GAAGR,gBAAjD,CAAF,CAArB;AACA;;AACDd,QAAAA,MAAM,CAAC2B,IAAP,CAAaxB,KAAK,CAAEC,SAAF,EAAaC,KAAb,EAAoB,EAApB,EAAwB,EAAxB,CAAlB;AACAN,QAAAA,MAAM,GAAGuB,WAAW,GAAGV,WAAvB;AACA,eAAO,IAAP;AACA,OAVF,CAYC;;;AACAiB,MAAAA,aAAa,CACZ1B,KAAK,CAAEC,SAAF,EAAaC,KAAb,EAAoB,EAApB,EAAwB,EAAxB,CADO,EAEZiB,WAFY,EAGZV,WAHY,CAAb;AAKAb,MAAAA,MAAM,GAAGuB,WAAW,GAAGV,WAAvB;AACA,aAAO,IAAP;;AAED,SAAK,cAAL;AACC;AACAX,MAAAA,KAAK,CAAC0B,IAAN,CACClB,KAAK,CACJN,KAAK,CAAEC,SAAF,EAAaC,KAAb,EAAoB,EAApB,EAAwB,EAAxB,CADD,EAEJiB,WAFI,EAGJV,WAHI,EAIJU,WAAW,GAAGV,WAJV,EAKJE,gBALI,CADN;AASAf,MAAAA,MAAM,GAAGuB,WAAW,GAAGV,WAAvB;AACA,aAAO,IAAP;;AAED,SAAK,cAAL;AACC;AACA;AACA,UAAK,MAAMW,UAAX,EAAwB;AACvB;AACA;AACA;AACA;AACAE,QAAAA,WAAW;AACX,eAAO,KAAP;AACA,OAVF,CAYC;;;AACA,UAAK,MAAMF,UAAX,EAAwB;AACvBG,QAAAA,iBAAiB,CAAEJ,WAAF,CAAjB;AACAvB,QAAAA,MAAM,GAAGuB,WAAW,GAAGV,WAAvB;AACA,eAAO,IAAP;AACA,OAjBF,CAmBC;AACA;;;AACA,UAAMkB,QAAQ,GAAG7B,KAAK,CAAC8B,GAAN,EAAjB;AACAD,MAAAA,QAAQ,CAACpB,KAAT,CAAeH,SAAf,IAA4BT,QAAQ,CAAC8B,MAAT,CAC3BE,QAAQ,CAACjB,UADkB,EAE3BS,WAAW,GAAGQ,QAAQ,CAACjB,UAFI,CAA5B;AAIAiB,MAAAA,QAAQ,CAACjB,UAAT,GAAsBS,WAAW,GAAGV,WAApC;AAEAiB,MAAAA,aAAa,CACZC,QAAQ,CAACpB,KADG,EAEZoB,QAAQ,CAACnB,UAFG,EAGZmB,QAAQ,CAAClB,WAHG,EAIZU,WAAW,GAAGV,WAJF,CAAb;AAMAb,MAAAA,MAAM,GAAGuB,WAAW,GAAGV,WAAvB;AACA,aAAO,IAAP;;AAED;AACC;AACAa,MAAAA,WAAW;AACX,aAAO,KAAP;AAvGF;AAyGA;AAED;;;;;;;;;;;;AAUA,SAASO,SAAT,CAAoBC,KAApB,EAA4B;AAC3B,MAAI;AACH,WAAOC,IAAI,CAACnB,KAAL,CAAYkB,KAAZ,CAAP;AACA,GAFD,CAEE,OAAQE,CAAR,EAAY;AACb,WAAO,IAAP;AACA;AACD;;AAED,SAASf,SAAT,GAAqB;AACpB;AACA;AACA;AACA;AACA;AACA;AACA,MAAMgB,OAAO,GAAGlC,SAAS,CAACmC,IAAV,CAAgBvC,QAAhB,CAAhB,CAPoB,CASpB;;AACA,MAAK,SAASsC,OAAd,EAAwB;AACvB,WAAO,CAAE,gBAAF,CAAP;AACA;;AAED,MAAME,SAAS,GAAGF,OAAO,CAACG,KAA1B;;AAdoB,8CAe6DH,OAf7D;AAAA,MAeZI,KAfY;AAAA,MAeLC,WAfK;AAAA,MAeQC,cAfR;AAAA,MAewBC,SAfxB;AAAA,MAemCC,UAfnC;AAAA,MAe+CC,SAf/C;;AAiBpB,MAAMrB,MAAM,GAAGgB,KAAK,CAAChB,MAArB;AACA,MAAMsB,QAAQ,GAAG,CAAC,CAAEL,WAApB;AACA,MAAMM,MAAM,GAAG,CAAC,CAAEF,SAAlB;AACA,MAAMG,SAAS,GAAGN,cAAc,IAAI,OAApC;AACA,MAAMO,IAAI,GAAGD,SAAS,GAAGL,SAAzB;AACA,MAAMO,QAAQ,GAAG,CAAC,CAAEN,UAApB;AACA,MAAMvC,KAAK,GAAG6C,QAAQ,GAAGlB,SAAS,CAAEY,UAAF,CAAZ,GAA6B,EAAnD,CAvBoB,CAyBpB;AACA;;AACA,MAAKE,QAAQ,KAAMC,MAAM,IAAIG,QAAhB,CAAb,EAA0C,CACzC;AACA;AACA;;AAED,MAAKH,MAAL,EAAc;AACb,WAAO,CAAE,YAAF,EAAgBE,IAAhB,EAAsB5C,KAAtB,EAA6BiC,SAA7B,EAAwCd,MAAxC,CAAP;AACA;;AAED,MAAKsB,QAAL,EAAgB;AACf,WAAO,CAAE,cAAF,EAAkBG,IAAlB,EAAwB,IAAxB,EAA8BX,SAA9B,EAAyCd,MAAzC,CAAP;AACA;;AAED,SAAO,CAAE,cAAF,EAAkByB,IAAlB,EAAwB5C,KAAxB,EAA+BiC,SAA/B,EAA0Cd,MAA1C,CAAP;AACA;;AAED,SAASC,WAAT,CAAsB0B,SAAtB,EAAkC;AACjC,MAAM3B,MAAM,GAAG2B,SAAS,GAAGA,SAAH,GAAerD,QAAQ,CAAC0B,MAAT,GAAkBzB,MAAzD;;AAEA,MAAK,MAAMyB,MAAX,EAAoB;AACnB;AACA;;AAEDxB,EAAAA,MAAM,CAAC2B,IAAP,CAAanB,QAAQ,CAAEV,QAAQ,CAAC8B,MAAT,CAAiB7B,MAAjB,EAAyByB,MAAzB,CAAF,CAArB;AACA;;AAED,SAASK,aAAT,CAAwBnB,KAAxB,EAA+BC,UAA/B,EAA2CC,WAA3C,EAAwDwC,UAAxD,EAAqE;AACpE,MAAMC,MAAM,GAAGpD,KAAK,CAAEA,KAAK,CAACuB,MAAN,GAAe,CAAjB,CAApB;AACA6B,EAAAA,MAAM,CAAC3C,KAAP,CAAaJ,WAAb,CAAyBqB,IAAzB,CAA+BjB,KAA/B;AACA2C,EAAAA,MAAM,CAAC3C,KAAP,CAAaH,SAAb,IAA0BT,QAAQ,CAAC8B,MAAT,CACzByB,MAAM,CAACxC,UADkB,EAEzBF,UAAU,GAAG0C,MAAM,CAACxC,UAFK,CAA1B;AAIAwC,EAAAA,MAAM,CAACxC,UAAP,GAAoBuC,UAAU,GAAGA,UAAH,GAAgBzC,UAAU,GAAGC,WAA3D;AACA;;AAED,SAASc,iBAAT,CAA4B4B,SAA5B,EAAwC;AAAA,mBACqBrD,KAAK,CAAC8B,GAAN,EADrB;AAAA,MAC/BrB,KAD+B,cAC/BA,KAD+B;AAAA,MACxBI,gBADwB,cACxBA,gBADwB;AAAA,MACND,UADM,cACNA,UADM;AAAA,MACMF,UADN,cACMA,UADN;;AAGvC,MAAK2C,SAAL,EAAiB;AAChB5C,IAAAA,KAAK,CAACH,SAAN,IAAmBT,QAAQ,CAAC8B,MAAT,CAAiBf,UAAjB,EAA6ByC,SAAS,GAAGzC,UAAzC,CAAnB;AACA,GAFD,MAEO;AACNH,IAAAA,KAAK,CAACH,SAAN,IAAmBT,QAAQ,CAAC8B,MAAT,CAAiBf,UAAjB,CAAnB;AACA;;AAED,MAAK,SAASC,gBAAd,EAAiC;AAChCd,IAAAA,MAAM,CAAC2B,IAAP,CAAanB,QAAQ,CAAEV,QAAQ,CAAC8B,MAAT,CAAiBd,gBAAjB,EAAmCH,UAAU,GAAGG,gBAAhD,CAAF,CAArB;AACA;;AAEDd,EAAAA,MAAM,CAAC2B,IAAP,CAAajB,KAAb;AACA","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
-4
@@ -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. |
+2
-2
| { | ||
| "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; | ||
| } | ||
| } |
+8
-17
@@ -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 @@ |
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
89844
-3.23%690
-3.9%1
Infinity%