html-parse-stringify
Advanced tools
| declare module 'html-parse-stringify' { | ||
| namespace HTML { | ||
| interface TagNode { | ||
| type: 'tag'; | ||
| name: string; | ||
| voidElement: boolean; | ||
| attrs: Record<string, string | undefined>; | ||
| children: Node[]; | ||
| } | ||
| interface TextNode { | ||
| type: 'text'; | ||
| content: string; | ||
| } | ||
| interface CommentNode { | ||
| type: 'comment'; | ||
| comment: string; | ||
| } | ||
| interface ComponentNode { | ||
| type: 'component'; | ||
| name: string; | ||
| attrs: Record<string, string | undefined>; | ||
| voidElement: boolean; | ||
| children: []; | ||
| } | ||
| type Node = TagNode | TextNode | CommentNode | ComponentNode; | ||
| interface ParseOptions { | ||
| components?: Record<string, boolean>; | ||
| } | ||
| function parse(html: string, options?: ParseOptions): Node[]; | ||
| function stringify(doc: Node[]): string; | ||
| } | ||
| // the CommonJS build assigns `module.exports = { parse, stringify }` with | ||
| // no `default` property, so `export =` is the only declaration shape that | ||
| // is correct both with and without esModuleInterop | ||
| export = HTML; | ||
| } |
+21
| MIT License | ||
| Copyright (c) 2025 Henrik Joreteg <henrik@joreteg.com> | ||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| of this software and associated documentation files (the "Software"), to deal | ||
| in the Software without restriction, including without limitation the rights | ||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| copies of the Software, and to permit persons to whom the Software is | ||
| furnished to do so, subject to the following conditions: | ||
| The above copyright notice and this permission notice shall be included in all | ||
| copies or substantial portions of the Software. | ||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| SOFTWARE. |
@@ -1,2 +0,2 @@ | ||
| var e,t=(e=require("void-elements"))&&"object"==typeof e&&"default"in e?e.default:e,n=/\s([^'"/\s><]+?)[\s/>]|([^\s=]+)=\s?(".*?"|'.*?')/g;function r(e){var r={type:"tag",name:"",voidElement:!1,attrs:{},children:[]},i=e.match(/<\/?([^\s]+?)[/\s>]/);if(i&&(r.name=i[1],(t[i[1]]||"/"===e.charAt(e.length-2))&&(r.voidElement=!0),r.name.startsWith("!--"))){var s=e.indexOf("--\x3e");return{type:"comment",comment:-1!==s?e.slice(4,s):""}}for(var c=new RegExp(n),a=null;null!==(a=c.exec(e));)if(a[0].trim())if(a[1]){var o=a[1].trim(),u=[o,""];o.indexOf("=")>-1&&(u=o.split("=")),r.attrs[u[0]]=u[1],c.lastIndex--}else a[2]&&(r.attrs[a[2]]=a[3].trim().substring(1,a[3].length-1));return r}var i=/<[a-zA-Z0-9\-\!\/](?:"[^"]*"|'[^']*'|[^'">])*>/g,s=/^\s*$/,c=Object.create(null);function a(e,t){switch(t.type){case"text":return e+t.content;case"tag":return e+="<"+t.name+(t.attrs?function(e){var t=[];for(var n in e)t.push(n+'="'+e[n]+'"');return t.length?" "+t.join(" "):""}(t.attrs):"")+(t.voidElement?"/>":">"),t.voidElement?e:e+t.children.reduce(a,"")+"</"+t.name+">";case"comment":return e+"\x3c!--"+t.comment+"--\x3e"}}module.exports={parse:function(e,t){t||(t={}),t.components||(t.components=c);var n,a=[],o=[],u=-1,l=!1;if(0!==e.indexOf("<")){var m=e.indexOf("<");a.push({type:"text",content:-1===m?e:e.substring(0,m)})}return e.replace(i,function(i,c){if(l){if(i!=="</"+n.name+">")return;l=!1}var m,d="/"!==i.charAt(1),f=i.startsWith("\x3c!--"),h=c+i.length,p=e.charAt(h);if(f){var v=r(i);return u<0?(a.push(v),a):((m=o[u]).children.push(v),a)}if(d&&(u++,"tag"===(n=r(i)).type&&t.components[n.name]&&(n.type="component",l=!0),n.voidElement||l||!p||"<"===p||n.children.push({type:"text",content:e.slice(h,e.indexOf("<",h))}),0===u&&a.push(n),(m=o[u-1])&&m.children.push(n),o[u]=n),(!d||n.voidElement)&&(u>-1&&(n.voidElement||n.name===i.slice(2,-1))&&(u--,n=-1===u?a:o[u]),!l&&"<"!==p&&p)){m=-1===u?a:o[u].children;var x=e.indexOf("<",h),g=e.slice(h,-1===x?void 0:x);s.test(g)&&(g=" "),(x>-1&&u+m.length>=0||" "!==g)&&m.push({type:"text",content:g})}}),a},stringify:function(e){return e.reduce(function(e,t){return e+a("",t)},"")}}; | ||
| var e,t=(e=require("void-elements"))&&"object"==typeof e&&"default"in e?e.default:e,n=/\s([^'"/\s><]+?)[\s/>]|([^\s=]+)=\s?("[^"]*"|'[^']*')/g;function r(e){var r={type:"tag",name:"",voidElement:!1,attrs:{},children:[]},i=e.match(/<\/?([^\s]+?)[/\s>]/);if(i&&(r.name=i[1],(t[i[1]]||"/"===e.charAt(e.length-2))&&(r.voidElement=!0),r.name.startsWith("!--"))){var s=e.indexOf("--\x3e");return{type:"comment",comment:-1!==s?e.slice(4,s):""}}for(var a=new RegExp(n),c=null;null!==(c=a.exec(e));)if(c[0].trim())if(c[1]){var l=c[1].trim(),o=[l,""];l.indexOf("=")>-1&&(o=l.split("=")),r.attrs[o[0]]=o[1],a.lastIndex--}else c[2]&&(r.attrs[c[2]]=c[3].trim().substring(1,c[3].length-1));return r}var i=/<[a-zA-Z0-9\-\!\/](?:"[^"]*"|'[^']*'|[^'">])*>/g,s=/^\s*$/,a=Object.create(null);function c(e,t){switch(t.type){case"text":return e+t.content;case"tag":return e+="<"+t.name+(t.attrs?function(e){var t=[];for(var n in e)t.push(n+'="'+e[n]+'"');return t.length?" "+t.join(" "):""}(t.attrs):"")+(t.voidElement?"/>":">"),t.voidElement?e:e+t.children.reduce(c,"")+"</"+t.name+">";case"comment":return e+"\x3c!--"+t.comment+"--\x3e"}}module.exports={parse:function(e,t){t||(t={}),t.components||(t.components=a);var n,c=[],l=[],o=-1,u=!1;if(0!==e.indexOf("<")){var h=e.indexOf("<");c.push({type:"text",content:-1===h?e:e.substring(0,h)})}for(var f,d=[];f=i.exec(e);)d.push(f);return d.forEach(function(e,t){var n=e[0];if(n&&!n.startsWith("\x3c!--")){for(var r=0,i=0,s=-1,a=null,c=0;c<n.length;c++){var l=n.charAt(c);a?l===a&&(a=null):'"'===l||"'"===l?a=l:"<"===l?2==++r&&(s=c):">"===l&&i++}var o=s>-1&&/[a-zA-Z0-9\-!/]/.test(n.charAt(s+1));if(r>i&&o){var u=n.substring(0,s),h=n.substring(u.length);d[t][0]=h,d[t].index+=u.length}}}),d.forEach(function(i,a){var h=i[0];if(h){var f=i.index;if(u){if(h!=="</"+n.name+">")return;u=!1}var v,m,p="/"!==h.charAt(1),x=h.startsWith("\x3c!--"),g=f+h.length,y=e.charAt(g),E=d[a+1];if("<"===y&&E){var b=e.substring(g,E.index);v=b.split("<").length>b.split(">").length}if(x){var A=r(h);if(o<0)return c.push(A),c;(m=l[o]).children.push(A);var O=e.slice(g,E?E.index:void 0);return O.length>0&&m.children.push({type:"text",content:O}),c}if(p&&(o++,"tag"===(n=r(h)).type&&t.components[n.name]&&(n.type="component",u=!0),n.voidElement||u||!y||"<"===y||n.children.push({type:"text",content:e.slice(g,E?E.index:void 0)}),0===o&&c.push(n),(m=l[o-1])&&m.children.push(n),l[o]=n),(!p||n.voidElement)&&(o>-1&&(n.voidElement||n.name===h.slice(2,-1))&&(o--,n=-1===o?c:l[o]),!u&&("<"!==y||v)&&y)){m=-1===o?c:l[o].children;var j=E?E.index:-1,W=e.slice(g,-1===j?void 0:j);s.test(W)&&(W=" "),(j>-1&&o+m.length>=0||" "!==W)&&m.push({type:"text",content:W})}}}),c},stringify:function(e){return e.reduce(function(e,t){return e+c("",t)},"")}}; | ||
| //# sourceMappingURL=html-parse-stringify.js.map |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"html-parse-stringify.js","sources":["../src/parse-tag.js","../src/parse.js","../src/stringify.js","../src/index.js"],"sourcesContent":["import lookup from 'void-elements'\nconst attrRE = /\\s([^'\"/\\s><]+?)[\\s/>]|([^\\s=]+)=\\s?(\".*?\"|'.*?')/g\n\nexport default function stringify(tag) {\n const res = {\n type: 'tag',\n name: '',\n voidElement: false,\n attrs: {},\n children: [],\n }\n\n const tagMatch = tag.match(/<\\/?([^\\s]+?)[/\\s>]/)\n if (tagMatch) {\n res.name = tagMatch[1]\n if (\n lookup[tagMatch[1]] ||\n tag.charAt(tag.length - 2) === '/'\n ) {\n res.voidElement = true\n }\n\n // handle comment tag\n if (res.name.startsWith('!--')) {\n const endIndex = tag.indexOf('-->')\n return {\n type: 'comment',\n comment: endIndex !== -1 ? tag.slice(4, endIndex) : '',\n }\n }\n }\n\n const reg = new RegExp(attrRE)\n let result = null\n for (;;) {\n result = reg.exec(tag)\n\n if (result === null) {\n break\n }\n\n if (!result[0].trim()) {\n continue\n }\n\n if (result[1]) {\n const attr = result[1].trim()\n let arr = [attr, '']\n\n if (attr.indexOf('=') > -1) {\n arr = attr.split('=')\n }\n\n res.attrs[arr[0]] = arr[1]\n reg.lastIndex--\n } else if (result[2]) {\n res.attrs[result[2]] = result[3].trim().substring(1, result[3].length - 1)\n }\n }\n\n return res\n}\n","import parseTag from './parse-tag'\n\nconst tagRE = /<[a-zA-Z0-9\\-\\!\\/](?:\"[^\"]*\"|'[^']*'|[^'\">])*>/g\nconst whitespaceRE = /^\\s*$/\n\n// re-used obj for quick lookups of components\nconst empty = Object.create(null)\n\nexport default function parse(html, options) {\n options || (options = {})\n options.components || (options.components = empty)\n const result = []\n const arr = []\n let current\n let level = -1\n let inComponent = false\n\n // handle text at top level\n if (html.indexOf('<') !== 0) {\n var end = html.indexOf('<')\n result.push({\n type: 'text',\n content: end === -1 ? html : html.substring(0, end),\n })\n }\n\n html.replace(tagRE, function (tag, index) {\n if (inComponent) {\n if (tag !== '</' + current.name + '>') {\n return\n } else {\n inComponent = false\n }\n }\n const isOpen = tag.charAt(1) !== '/'\n const isComment = tag.startsWith('<!--')\n const start = index + tag.length\n const nextChar = html.charAt(start)\n let parent\n\n if (isComment) {\n const comment = parseTag(tag)\n\n // if we're at root, push new base node\n if (level < 0) {\n result.push(comment)\n return result\n }\n parent = arr[level]\n parent.children.push(comment)\n return result\n }\n\n if (isOpen) {\n level++\n\n current = parseTag(tag)\n if (current.type === 'tag' && options.components[current.name]) {\n current.type = 'component'\n inComponent = true\n }\n\n if (\n !current.voidElement &&\n !inComponent &&\n nextChar &&\n nextChar !== '<'\n ) {\n current.children.push({\n type: 'text',\n content: html.slice(start, html.indexOf('<', start)),\n })\n }\n\n // if we're at root, push new base node\n if (level === 0) {\n result.push(current)\n }\n\n parent = arr[level - 1]\n\n if (parent) {\n parent.children.push(current)\n }\n\n arr[level] = current\n }\n\n if (!isOpen || current.voidElement) {\n if (\n level > -1 &&\n (current.voidElement || current.name === tag.slice(2, -1))\n ) {\n level--\n // move current up a level to match the end tag\n current = level === -1 ? result : arr[level]\n }\n if (!inComponent && nextChar !== '<' && nextChar) {\n // trailing text node\n // if we're at the root, push a base text node. otherwise add as\n // a child to the current node.\n parent = level === -1 ? result : arr[level].children\n\n // calculate correct end of the content slice in case there's\n // no tag after the text node.\n const end = html.indexOf('<', start)\n let content = html.slice(start, end === -1 ? undefined : end)\n // if a node is nothing but whitespace, collapse it as the spec states:\n // https://www.w3.org/TR/html4/struct/text.html#h-9.1\n if (whitespaceRE.test(content)) {\n content = ' '\n }\n // don't add whitespace-only text nodes if they would be trailing text nodes\n // or if they would be leading whitespace-only text nodes:\n // * end > -1 indicates this is not a trailing text node\n // * leading node is when level is -1 and parent has length 0\n if ((end > -1 && level + parent.length >= 0) || content !== ' ') {\n parent.push({\n type: 'text',\n content: content,\n })\n }\n }\n }\n })\n\n return result\n}\n","function attrString(attrs) {\n const buff = []\n for (let key in attrs) {\n buff.push(key + '=\"' + attrs[key] + '\"')\n }\n if (!buff.length) {\n return ''\n }\n return ' ' + buff.join(' ')\n}\n\nfunction stringify(buff, doc) {\n switch (doc.type) {\n case 'text':\n return buff + doc.content\n case 'tag':\n buff +=\n '<' +\n doc.name +\n (doc.attrs ? attrString(doc.attrs) : '') +\n (doc.voidElement ? '/>' : '>')\n if (doc.voidElement) {\n return buff\n }\n return buff + doc.children.reduce(stringify, '') + '</' + doc.name + '>'\n case 'comment':\n buff += '<!--' + doc.comment + '-->'\n return buff\n }\n}\n\nexport default function (doc) {\n return doc.reduce(function (token, rootEl) {\n return token + stringify('', rootEl)\n }, '')\n}\n","import parse from './parse'\nimport stringify from './stringify'\n\nexport default {\n parse,\n stringify,\n}\n"],"names":["attrRE","stringify","tag","res","type","name","voidElement","attrs","children","tagMatch","match","lookup","charAt","length","startsWith","endIndex","indexOf","comment","slice","reg","RegExp","result","exec","trim","attr","arr","split","lastIndex","substring","tagRE","whitespaceRE","empty","Object","create","buff","doc","content","key","push","join","attrString","reduce","parse","html","options","components","current","level","inComponent","end","replace","index","parent","isOpen","isComment","start","nextChar","parseTag","undefined","test","token","rootEl"],"mappings":"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"} | ||
| {"version":3,"file":"html-parse-stringify.js","sources":["../src/parse-tag.js","../src/parse.js","../src/stringify.js","../src/index.js"],"sourcesContent":["import lookup from 'void-elements'\nconst attrRE = /\\s([^'\"/\\s><]+?)[\\s/>]|([^\\s=]+)=\\s?(\"[^\"]*\"|'[^']*')/g\n\nexport default function stringify(tag) {\n const res = {\n type: 'tag',\n name: '',\n voidElement: false,\n attrs: {},\n children: [],\n }\n\n const tagMatch = tag.match(/<\\/?([^\\s]+?)[/\\s>]/)\n if (tagMatch) {\n res.name = tagMatch[1]\n if (lookup[tagMatch[1]] || tag.charAt(tag.length - 2) === '/') {\n res.voidElement = true\n }\n\n // handle comment tag\n if (res.name.startsWith('!--')) {\n const endIndex = tag.indexOf('-->')\n return {\n type: 'comment',\n comment: endIndex !== -1 ? tag.slice(4, endIndex) : '',\n }\n }\n }\n\n const reg = new RegExp(attrRE)\n let result = null\n for (;;) {\n result = reg.exec(tag)\n\n if (result === null) {\n break\n }\n\n if (!result[0].trim()) {\n continue\n }\n\n if (result[1]) {\n const attr = result[1].trim()\n let arr = [attr, '']\n\n if (attr.indexOf('=') > -1) {\n arr = attr.split('=')\n }\n\n res.attrs[arr[0]] = arr[1]\n reg.lastIndex--\n } else if (result[2]) {\n res.attrs[result[2]] = result[3].trim().substring(1, result[3].length - 1)\n }\n }\n\n return res\n}\n","import parseTag from './parse-tag'\n\nconst tagRE = /<[a-zA-Z0-9\\-\\!\\/](?:\"[^\"]*\"|'[^']*'|[^'\">])*>/g\nconst whitespaceRE = /^\\s*$/\n\n// re-used obj for quick lookups of components\nconst empty = Object.create(null)\n\nexport default function parse(html, options) {\n options || (options = {})\n options.components || (options.components = empty)\n const result = []\n const arr = []\n let current\n let level = -1\n let inComponent = false\n\n // handle text at top level\n if (html.indexOf('<') !== 0) {\n var end = html.indexOf('<')\n result.push({\n type: 'text',\n content: end === -1 ? html : html.substring(0, end),\n })\n }\n\n // collect matches with an exec loop instead of matchAll to keep ES5 API compat\n const matches = []\n let m\n while ((m = tagRE.exec(html))) {\n matches.push(m)\n }\n matches.forEach(function (match, i) {\n const tag = match[0]\n if (!tag) return\n // comments are handled by parseTag as a whole\n if (tag.startsWith('<!--')) return\n // count brackets outside quoted attribute values, so `<` inside an\n // attribute (e.g. title=\"1 < 2\") can't trigger a bogus split\n let lts = 0\n let gts = 0\n let secondLt = -1\n let quote = null\n for (let j = 0; j < tag.length; j++) {\n const c = tag.charAt(j)\n if (quote) {\n if (c === quote) quote = null\n } else if (c === '\"' || c === \"'\") {\n quote = c\n } else if (c === '<') {\n lts++\n if (lts === 2) secondLt = j\n } else if (c === '>') {\n gts++\n }\n }\n // only split when the remainder is itself a valid tag start; otherwise\n // a fragment like `< <!-->` desyncs the string-level isComment check\n // from parseTag's name-based comment detection and crashes the walker\n const validSplit =\n secondLt > -1 && /[a-zA-Z0-9\\-!/]/.test(tag.charAt(secondLt + 1))\n if (lts > gts && validSplit) {\n const firstPart = tag.substring(0, secondLt)\n const secondPart = tag.substring(firstPart.length)\n matches[i][0] = secondPart\n matches[i].index += firstPart.length\n }\n })\n matches.forEach(function (match, i) {\n const tag = match[0]\n if (!tag) return\n const index = match.index\n if (inComponent) {\n if (tag !== '</' + current.name + '>') {\n return\n } else {\n inComponent = false\n }\n }\n const isOpen = tag.charAt(1) !== '/'\n const isComment = tag.startsWith('<!--')\n const start = index + tag.length\n const nextChar = html.charAt(start)\n const nextMatch = matches[i + 1]\n let isText\n if (nextChar === '<' && nextMatch) {\n const nextTag = html.substring(start, nextMatch.index)\n isText = nextTag.split('<').length > nextTag.split('>').length\n }\n\n let parent\n\n if (isComment) {\n const comment = parseTag(tag)\n\n // if we're at root, push new base node\n if (level < 0) {\n result.push(comment)\n return result\n }\n parent = arr[level]\n parent.children.push(comment)\n\n const text = html.slice(start, nextMatch ? nextMatch.index : undefined)\n if (text.length > 0) {\n parent.children.push({\n type: 'text',\n content: text,\n })\n }\n return result\n }\n\n if (isOpen) {\n level++\n\n current = parseTag(tag)\n if (current.type === 'tag' && options.components[current.name]) {\n current.type = 'component'\n inComponent = true\n }\n\n if (\n !current.voidElement &&\n !inComponent &&\n nextChar &&\n nextChar !== '<'\n ) {\n // text content runs to the next actual tag match; stray `<`\n // characters in between are part of the text\n current.children.push({\n type: 'text',\n content: html.slice(start, nextMatch ? nextMatch.index : undefined),\n })\n }\n\n // if we're at root, push new base node\n if (level === 0) {\n result.push(current)\n }\n\n parent = arr[level - 1]\n\n if (parent) {\n parent.children.push(current)\n }\n\n arr[level] = current\n }\n\n if (!isOpen || current.voidElement) {\n if (\n level > -1 &&\n (current.voidElement || current.name === tag.slice(2, -1))\n ) {\n level--\n // move current up a level to match the end tag\n current = level === -1 ? result : arr[level]\n }\n if (!inComponent && (nextChar !== '<' || isText) && nextChar) {\n // trailing text node\n // if we're at the root, push a base text node. otherwise add as\n // a child to the current node.\n parent = level === -1 ? result : arr[level].children\n\n // the text node runs to the next actual tag match; -1 means\n // there's no tag after it (trailing text)\n const end = nextMatch ? nextMatch.index : -1\n let content = html.slice(start, end === -1 ? undefined : end)\n // if a node is nothing but whitespace, collapse it as the spec states:\n // https://www.w3.org/TR/html4/struct/text.html#h-9.1\n if (whitespaceRE.test(content)) {\n content = ' '\n }\n // don't add whitespace-only text nodes if they would be trailing text nodes\n // or if they would be leading whitespace-only text nodes:\n // * end > -1 indicates this is not a trailing text node\n // * leading node is when level is -1 and parent has length 0\n if ((end > -1 && level + parent.length >= 0) || content !== ' ') {\n parent.push({\n type: 'text',\n content: content,\n })\n }\n }\n }\n })\n\n return result\n}\n","function attrString(attrs) {\n const buff = []\n for (let key in attrs) {\n buff.push(key + '=\"' + attrs[key] + '\"')\n }\n if (!buff.length) {\n return ''\n }\n return ' ' + buff.join(' ')\n}\n\nfunction stringify(buff, doc) {\n switch (doc.type) {\n case 'text':\n return buff + doc.content\n case 'tag':\n buff +=\n '<' +\n doc.name +\n (doc.attrs ? attrString(doc.attrs) : '') +\n (doc.voidElement ? '/>' : '>')\n if (doc.voidElement) {\n return buff\n }\n return buff + doc.children.reduce(stringify, '') + '</' + doc.name + '>'\n case 'comment':\n buff += '<!--' + doc.comment + '-->'\n return buff\n }\n}\n\nexport default function (doc) {\n return doc.reduce(function (token, rootEl) {\n return token + stringify('', rootEl)\n }, '')\n}\n","import parse from './parse'\nimport stringify from './stringify'\n\nexport default {\n parse,\n stringify,\n}\n"],"names":["attrRE","stringify","tag","res","type","name","voidElement","attrs","children","tagMatch","match","lookup","charAt","length","startsWith","endIndex","indexOf","comment","slice","reg","RegExp","result","exec","trim","attr","arr","split","lastIndex","substring","tagRE","whitespaceRE","empty","Object","create","buff","doc","content","key","push","join","attrString","reduce","parse","html","options","components","current","level","inComponent","end","m","matches","forEach","i","lts","gts","secondLt","quote","j","c","validSplit","test","firstPart","secondPart","index","isText","parent","isOpen","isComment","start","nextChar","nextMatch","nextTag","parseTag","text","undefined","token","rootEl"],"mappings":"oFACMA,EAAS,kEAESC,EAAUC,GAChC,IAAMC,EAAM,CACVC,KAAM,MACNC,KAAM,GACNC,aAAa,EACbC,MAAO,GACPC,SAAU,IAGNC,EAAWP,EAAIQ,MAAM,uBAC3B,GAAID,IACFN,EAAIE,KAAOI,EAAS,IAChBE,EAAOF,EAAS,KAAsC,MAA/BP,EAAIU,OAAOV,EAAIW,OAAS,MACjDV,EAAIG,aAAc,GAIhBH,EAAIE,KAAKS,WAAW,QAAQ,CAC9B,IAAMC,EAAWb,EAAIc,QAAQ,UAC7B,MAAO,CACLZ,KAAM,UACNa,SAAuB,IAAdF,EAAkBb,EAAIgB,MAAM,EAAGH,GAAY,IAO1D,IAFA,IAAMI,EAAM,IAAIC,OAAOpB,GACnBqB,EAAS,KAII,QAFfA,EAASF,EAAIG,KAAKpB,KAMlB,GAAKmB,EAAO,GAAGE,OAIf,GAAIF,EAAO,GAAI,CACb,IAAMG,EAAOH,EAAO,GAAGE,OACnBE,EAAM,CAACD,EAAM,IAEbA,EAAKR,QAAQ,MAAQ,IACvBS,EAAMD,EAAKE,MAAM,MAGnBvB,EAAII,MAAMkB,EAAI,IAAMA,EAAI,GACxBN,EAAIQ,iBACKN,EAAO,KAChBlB,EAAII,MAAMc,EAAO,IAAMA,EAAO,GAAGE,OAAOK,UAAU,EAAGP,EAAO,GAAGR,OAAS,IAI5E,OAAOV,ECvDT,IAAM0B,EAAQ,kDACRC,EAAe,QAGfC,EAAQC,OAAOC,OAAO,MCK5B,SAAShC,EAAUiC,EAAMC,GACvB,OAAQA,EAAI/B,MACV,IAAK,OACH,OAAO8B,EAAOC,EAAIC,QACpB,IAAK,MAMH,OALAF,GACE,IACAC,EAAI9B,MACH8B,EAAI5B,MAnBb,SAAoBA,GAClB,IAAM2B,EAAO,GACb,IAAK,IAAIG,KAAO9B,EACd2B,EAAKI,KAAKD,EAAM,KAAO9B,EAAM8B,GAAO,KAEtC,OAAKH,EAAKrB,OAGH,IAAMqB,EAAKK,KAAK,KAFd,GAaUC,CAAWL,EAAI5B,OAAS,KACpC4B,EAAI7B,YAAc,KAAO,KACxB6B,EAAI7B,YACC4B,EAEFA,EAAOC,EAAI3B,SAASiC,OAAOxC,EAAW,IAAM,KAAOkC,EAAI9B,KAAO,IACvE,IAAK,UAEH,OADA6B,EAAQ,UAASC,EAAIlB,QAAU,yBCvBtB,CACbyB,MFIF,SAA8BC,EAAMC,GAClCA,IAAYA,EAAU,IACtBA,EAAQC,aAAeD,EAAQC,WAAad,GAC5C,IAEIe,EAFEzB,EAAS,GACTI,EAAM,GAERsB,GAAS,EACTC,GAAc,EAGlB,GAA0B,IAAtBL,EAAK3B,QAAQ,KAAY,CAC3B,IAAIiC,EAAMN,EAAK3B,QAAQ,KACvBK,EAAOiB,KAAK,CACVlC,KAAM,OACNgC,SAAkB,IAATa,EAAaN,EAAOA,EAAKf,UAAU,EAAGqB,KAOnD,IAFA,IACIC,EADEC,EAAU,GAERD,EAAIrB,EAAMP,KAAKqB,IACrBQ,EAAQb,KAAKY,GA8Jf,OA5JAC,EAAQC,QAAQ,SAAU1C,EAAO2C,GAC/B,IAAMnD,EAAMQ,EAAM,GAClB,GAAKR,IAEDA,EAAIY,WAAW,WAAnB,CAOA,IAJA,IAAIwC,EAAM,EACNC,EAAM,EACNC,GAAY,EACZC,EAAQ,KACHC,EAAI,EAAGA,EAAIxD,EAAIW,OAAQ6C,IAAK,CACnC,IAAMC,EAAIzD,EAAIU,OAAO8C,GACjBD,EACEE,IAAMF,IAAOA,EAAQ,MACV,MAANE,GAAmB,MAANA,EACtBF,EAAQE,EACO,MAANA,EAEG,KADZL,IACeE,EAAWE,GACX,MAANC,GACTJ,IAMJ,IAAMK,EACJJ,GAAY,GAAK,kBAAkBK,KAAK3D,EAAIU,OAAO4C,EAAW,IAChE,GAAIF,EAAMC,GAAOK,EAAY,CAC3B,IAAME,EAAY5D,EAAI0B,UAAU,EAAG4B,GAC7BO,EAAa7D,EAAI0B,UAAUkC,EAAUjD,QAC3CsC,EAAQE,GAAG,GAAKU,EAChBZ,EAAQE,GAAGW,OAASF,EAAUjD,WAGlCsC,EAAQC,QAAQ,SAAU1C,EAAO2C,GAC/B,IAAMnD,EAAMQ,EAAM,GAClB,GAAKR,EAAL,CACA,IAAM8D,EAAQtD,EAAMsD,MACpB,GAAIhB,EAAa,CACf,GAAI9C,IAAQ,KAAO4C,EAAQzC,KAAO,IAChC,OAEA2C,GAAc,EAGlB,IAKIiB,EAMAC,EAXEC,EAA2B,MAAlBjE,EAAIU,OAAO,GACpBwD,EAAYlE,EAAIY,WAAW,WAC3BuD,EAAQL,EAAQ9D,EAAIW,OACpByD,EAAW3B,EAAK/B,OAAOyD,GACvBE,EAAYpB,EAAQE,EAAI,GAE9B,GAAiB,MAAbiB,GAAoBC,EAAW,CACjC,IAAMC,EAAU7B,EAAKf,UAAUyC,EAAOE,EAAUP,OAChDC,EAASO,EAAQ9C,MAAM,KAAKb,OAAS2D,EAAQ9C,MAAM,KAAKb,OAK1D,GAAIuD,EAAW,CACb,IAAMnD,EAAUwD,EAASvE,GAGzB,GAAI6C,EAAQ,EAEV,OADA1B,EAAOiB,KAAKrB,GACLI,GAET6C,EAASzC,EAAIsB,IACNvC,SAAS8B,KAAKrB,GAErB,IAAMyD,EAAO/B,EAAKzB,MAAMmD,EAAOE,EAAYA,EAAUP,WAAQW,GAO7D,OANID,EAAK7D,OAAS,GAChBqD,EAAO1D,SAAS8B,KAAK,CACnBlC,KAAM,OACNgC,QAASsC,IAGNrD,EAwCT,GArCI8C,IACFpB,IAGqB,SADrBD,EAAU2B,EAASvE,IACPE,MAAkBwC,EAAQC,WAAWC,EAAQzC,QACvDyC,EAAQ1C,KAAO,YACf4C,GAAc,GAIbF,EAAQxC,aACR0C,IACDsB,GACa,MAAbA,GAIAxB,EAAQtC,SAAS8B,KAAK,CACpBlC,KAAM,OACNgC,QAASO,EAAKzB,MAAMmD,EAAOE,EAAYA,EAAUP,WAAQW,KAK/C,IAAV5B,GACF1B,EAAOiB,KAAKQ,IAGdoB,EAASzC,EAAIsB,EAAQ,KAGnBmB,EAAO1D,SAAS8B,KAAKQ,GAGvBrB,EAAIsB,GAASD,KAGVqB,GAAUrB,EAAQxC,eAEnByC,GAAS,IACRD,EAAQxC,aAAewC,EAAQzC,OAASH,EAAIgB,MAAM,GAAI,MAEvD6B,IAEAD,GAAqB,IAAXC,EAAe1B,EAASI,EAAIsB,KAEnCC,IAA6B,MAAbsB,GAAoBL,IAAWK,GAAU,CAI5DJ,GAAoB,IAAXnB,EAAe1B,EAASI,EAAIsB,GAAOvC,SAI5C,IAAMyC,EAAMsB,EAAYA,EAAUP,OAAS,EACvC5B,EAAUO,EAAKzB,MAAMmD,GAAgB,IAATpB,OAAa0B,EAAY1B,GAGrDnB,EAAa+B,KAAKzB,KACpBA,EAAU,MAMPa,GAAO,GAAKF,EAAQmB,EAAOrD,QAAU,GAAkB,MAAZuB,IAC9C8B,EAAO5B,KAAK,CACVlC,KAAM,OACNgC,QAASA,QAOZf,GEvLPpB,mBD0BuBkC,GACvB,OAAOA,EAAIM,OAAO,SAAUmC,EAAOC,GACjC,OAAOD,EAAQ3E,EAAU,GAAI4E,IAC5B"} |
@@ -1,2 +0,2 @@ | ||
| import t from"void-elements";const e=/\s([^'"/\s><]+?)[\s/>]|([^\s=]+)=\s?(".*?"|'.*?')/g;function n(n){const s={type:"tag",name:"",voidElement:!1,attrs:{},children:[]},c=n.match(/<\/?([^\s]+?)[/\s>]/);if(c&&(s.name=c[1],(t[c[1]]||"/"===n.charAt(n.length-2))&&(s.voidElement=!0),s.name.startsWith("!--"))){const t=n.indexOf("--\x3e");return{type:"comment",comment:-1!==t?n.slice(4,t):""}}const r=new RegExp(e);let i=null;for(;i=r.exec(n),null!==i;)if(i[0].trim())if(i[1]){const t=i[1].trim();let e=[t,""];t.indexOf("=")>-1&&(e=t.split("=")),s.attrs[e[0]]=e[1],r.lastIndex--}else i[2]&&(s.attrs[i[2]]=i[3].trim().substring(1,i[3].length-1));return s}const s=/<[a-zA-Z0-9\-\!\/](?:"[^"]*"|'[^']*'|[^'">])*>/g,c=/^\s*$/,r=Object.create(null);function i(t,e){switch(e.type){case"text":return t+e.content;case"tag":return t+="<"+e.name+(e.attrs?function(t){const e=[];for(let n in t)e.push(n+'="'+t[n]+'"');return e.length?" "+e.join(" "):""}(e.attrs):"")+(e.voidElement?"/>":">"),e.voidElement?t:t+e.children.reduce(i,"")+"</"+e.name+">";case"comment":return t+"\x3c!--"+e.comment+"--\x3e"}}var o={parse:function(t,e){e||(e={}),e.components||(e.components=r);const i=[],o=[];let l,m=-1,u=!1;if(0!==t.indexOf("<")){var a=t.indexOf("<");i.push({type:"text",content:-1===a?t:t.substring(0,a)})}return t.replace(s,function(s,r){if(u){if(s!=="</"+l.name+">")return;u=!1}const a="/"!==s.charAt(1),f=s.startsWith("\x3c!--"),h=r+s.length,p=t.charAt(h);let d;if(f){const t=n(s);return m<0?(i.push(t),i):(d=o[m],d.children.push(t),i)}if(a&&(m++,l=n(s),"tag"===l.type&&e.components[l.name]&&(l.type="component",u=!0),l.voidElement||u||!p||"<"===p||l.children.push({type:"text",content:t.slice(h,t.indexOf("<",h))}),0===m&&i.push(l),d=o[m-1],d&&d.children.push(l),o[m]=l),(!a||l.voidElement)&&(m>-1&&(l.voidElement||l.name===s.slice(2,-1))&&(m--,l=-1===m?i:o[m]),!u&&"<"!==p&&p)){d=-1===m?i:o[m].children;const e=t.indexOf("<",h);let n=t.slice(h,-1===e?void 0:e);c.test(n)&&(n=" "),(e>-1&&m+d.length>=0||" "!==n)&&d.push({type:"text",content:n})}}),i},stringify:function(t){return t.reduce(function(t,e){return t+i("",e)},"")}};export default o; | ||
| import t from"void-elements";const e=/\s([^'"/\s><]+?)[\s/>]|([^\s=]+)=\s?("[^"]*"|'[^']*')/g;function n(n){const s={type:"tag",name:"",voidElement:!1,attrs:{},children:[]},i=n.match(/<\/?([^\s]+?)[/\s>]/);if(i&&(s.name=i[1],(t[i[1]]||"/"===n.charAt(n.length-2))&&(s.voidElement=!0),s.name.startsWith("!--"))){const t=n.indexOf("--\x3e");return{type:"comment",comment:-1!==t?n.slice(4,t):""}}const c=new RegExp(e);let r=null;for(;r=c.exec(n),null!==r;)if(r[0].trim())if(r[1]){const t=r[1].trim();let e=[t,""];t.indexOf("=")>-1&&(e=t.split("=")),s.attrs[e[0]]=e[1],c.lastIndex--}else r[2]&&(s.attrs[r[2]]=r[3].trim().substring(1,r[3].length-1));return s}const s=/<[a-zA-Z0-9\-\!\/](?:"[^"]*"|'[^']*'|[^'">])*>/g,i=/^\s*$/,c=Object.create(null);function r(t,e){switch(e.type){case"text":return t+e.content;case"tag":return t+="<"+e.name+(e.attrs?function(t){const e=[];for(let n in t)e.push(n+'="'+t[n]+'"');return e.length?" "+e.join(" "):""}(e.attrs):"")+(e.voidElement?"/>":">"),e.voidElement?t:t+e.children.reduce(r,"")+"</"+e.name+">";case"comment":return t+"\x3c!--"+e.comment+"--\x3e"}}var o={parse:function(t,e){e||(e={}),e.components||(e.components=c);const r=[],o=[];let l,u=-1,h=!1;if(0!==t.indexOf("<")){var a=t.indexOf("<");r.push({type:"text",content:-1===a?t:t.substring(0,a)})}const f=[];let m;for(;m=s.exec(t);)f.push(m);return f.forEach(function(t,e){const n=t[0];if(!n)return;if(n.startsWith("\x3c!--"))return;let s=0,i=0,c=-1,r=null;for(let t=0;t<n.length;t++){const e=n.charAt(t);r?e===r&&(r=null):'"'===e||"'"===e?r=e:"<"===e?(s++,2===s&&(c=t)):">"===e&&i++}const o=c>-1&&/[a-zA-Z0-9\-!/]/.test(n.charAt(c+1));if(s>i&&o){const t=n.substring(0,c),s=n.substring(t.length);f[e][0]=s,f[e].index+=t.length}}),f.forEach(function(s,c){const a=s[0];if(!a)return;const m=s.index;if(h){if(a!=="</"+l.name+">")return;h=!1}const d="/"!==a.charAt(1),p=a.startsWith("\x3c!--"),x=m+a.length,g=t.charAt(x),v=f[c+1];let y,E;if("<"===g&&v){const e=t.substring(x,v.index);y=e.split("<").length>e.split(">").length}if(p){const e=n(a);if(u<0)return r.push(e),r;E=o[u],E.children.push(e);const s=t.slice(x,v?v.index:void 0);return s.length>0&&E.children.push({type:"text",content:s}),r}if(d&&(u++,l=n(a),"tag"===l.type&&e.components[l.name]&&(l.type="component",h=!0),l.voidElement||h||!g||"<"===g||l.children.push({type:"text",content:t.slice(x,v?v.index:void 0)}),0===u&&r.push(l),E=o[u-1],E&&E.children.push(l),o[u]=l),(!d||l.voidElement)&&(u>-1&&(l.voidElement||l.name===a.slice(2,-1))&&(u--,l=-1===u?r:o[u]),!h&&("<"!==g||y)&&g)){E=-1===u?r:o[u].children;const e=v?v.index:-1;let n=t.slice(x,-1===e?void 0:e);i.test(n)&&(n=" "),(e>-1&&u+E.length>=0||" "!==n)&&E.push({type:"text",content:n})}}),r},stringify:function(t){return t.reduce(function(t,e){return t+r("",e)},"")}};export default o; | ||
| //# sourceMappingURL=html-parse-stringify.modern.js.map |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"html-parse-stringify.modern.js","sources":["../src/parse-tag.js","../src/parse.js","../src/stringify.js","../src/index.js"],"sourcesContent":["import lookup from 'void-elements'\nconst attrRE = /\\s([^'\"/\\s><]+?)[\\s/>]|([^\\s=]+)=\\s?(\".*?\"|'.*?')/g\n\nexport default function stringify(tag) {\n const res = {\n type: 'tag',\n name: '',\n voidElement: false,\n attrs: {},\n children: [],\n }\n\n const tagMatch = tag.match(/<\\/?([^\\s]+?)[/\\s>]/)\n if (tagMatch) {\n res.name = tagMatch[1]\n if (\n lookup[tagMatch[1]] ||\n tag.charAt(tag.length - 2) === '/'\n ) {\n res.voidElement = true\n }\n\n // handle comment tag\n if (res.name.startsWith('!--')) {\n const endIndex = tag.indexOf('-->')\n return {\n type: 'comment',\n comment: endIndex !== -1 ? tag.slice(4, endIndex) : '',\n }\n }\n }\n\n const reg = new RegExp(attrRE)\n let result = null\n for (;;) {\n result = reg.exec(tag)\n\n if (result === null) {\n break\n }\n\n if (!result[0].trim()) {\n continue\n }\n\n if (result[1]) {\n const attr = result[1].trim()\n let arr = [attr, '']\n\n if (attr.indexOf('=') > -1) {\n arr = attr.split('=')\n }\n\n res.attrs[arr[0]] = arr[1]\n reg.lastIndex--\n } else if (result[2]) {\n res.attrs[result[2]] = result[3].trim().substring(1, result[3].length - 1)\n }\n }\n\n return res\n}\n","import parseTag from './parse-tag'\n\nconst tagRE = /<[a-zA-Z0-9\\-\\!\\/](?:\"[^\"]*\"|'[^']*'|[^'\">])*>/g\nconst whitespaceRE = /^\\s*$/\n\n// re-used obj for quick lookups of components\nconst empty = Object.create(null)\n\nexport default function parse(html, options) {\n options || (options = {})\n options.components || (options.components = empty)\n const result = []\n const arr = []\n let current\n let level = -1\n let inComponent = false\n\n // handle text at top level\n if (html.indexOf('<') !== 0) {\n var end = html.indexOf('<')\n result.push({\n type: 'text',\n content: end === -1 ? html : html.substring(0, end),\n })\n }\n\n html.replace(tagRE, function (tag, index) {\n if (inComponent) {\n if (tag !== '</' + current.name + '>') {\n return\n } else {\n inComponent = false\n }\n }\n const isOpen = tag.charAt(1) !== '/'\n const isComment = tag.startsWith('<!--')\n const start = index + tag.length\n const nextChar = html.charAt(start)\n let parent\n\n if (isComment) {\n const comment = parseTag(tag)\n\n // if we're at root, push new base node\n if (level < 0) {\n result.push(comment)\n return result\n }\n parent = arr[level]\n parent.children.push(comment)\n return result\n }\n\n if (isOpen) {\n level++\n\n current = parseTag(tag)\n if (current.type === 'tag' && options.components[current.name]) {\n current.type = 'component'\n inComponent = true\n }\n\n if (\n !current.voidElement &&\n !inComponent &&\n nextChar &&\n nextChar !== '<'\n ) {\n current.children.push({\n type: 'text',\n content: html.slice(start, html.indexOf('<', start)),\n })\n }\n\n // if we're at root, push new base node\n if (level === 0) {\n result.push(current)\n }\n\n parent = arr[level - 1]\n\n if (parent) {\n parent.children.push(current)\n }\n\n arr[level] = current\n }\n\n if (!isOpen || current.voidElement) {\n if (\n level > -1 &&\n (current.voidElement || current.name === tag.slice(2, -1))\n ) {\n level--\n // move current up a level to match the end tag\n current = level === -1 ? result : arr[level]\n }\n if (!inComponent && nextChar !== '<' && nextChar) {\n // trailing text node\n // if we're at the root, push a base text node. otherwise add as\n // a child to the current node.\n parent = level === -1 ? result : arr[level].children\n\n // calculate correct end of the content slice in case there's\n // no tag after the text node.\n const end = html.indexOf('<', start)\n let content = html.slice(start, end === -1 ? undefined : end)\n // if a node is nothing but whitespace, collapse it as the spec states:\n // https://www.w3.org/TR/html4/struct/text.html#h-9.1\n if (whitespaceRE.test(content)) {\n content = ' '\n }\n // don't add whitespace-only text nodes if they would be trailing text nodes\n // or if they would be leading whitespace-only text nodes:\n // * end > -1 indicates this is not a trailing text node\n // * leading node is when level is -1 and parent has length 0\n if ((end > -1 && level + parent.length >= 0) || content !== ' ') {\n parent.push({\n type: 'text',\n content: content,\n })\n }\n }\n }\n })\n\n return result\n}\n","function attrString(attrs) {\n const buff = []\n for (let key in attrs) {\n buff.push(key + '=\"' + attrs[key] + '\"')\n }\n if (!buff.length) {\n return ''\n }\n return ' ' + buff.join(' ')\n}\n\nfunction stringify(buff, doc) {\n switch (doc.type) {\n case 'text':\n return buff + doc.content\n case 'tag':\n buff +=\n '<' +\n doc.name +\n (doc.attrs ? attrString(doc.attrs) : '') +\n (doc.voidElement ? '/>' : '>')\n if (doc.voidElement) {\n return buff\n }\n return buff + doc.children.reduce(stringify, '') + '</' + doc.name + '>'\n case 'comment':\n buff += '<!--' + doc.comment + '-->'\n return buff\n }\n}\n\nexport default function (doc) {\n return doc.reduce(function (token, rootEl) {\n return token + stringify('', rootEl)\n }, '')\n}\n","import parse from './parse'\nimport stringify from './stringify'\n\nexport default {\n parse,\n stringify,\n}\n"],"names":["attrRE","stringify","tag","res","type","name","voidElement","attrs","children","tagMatch","match","lookup","charAt","length","startsWith","endIndex","indexOf","comment","slice","reg","RegExp","result","exec","trim","attr","arr","split","lastIndex","substring","tagRE","whitespaceRE","empty","Object","create","buff","doc","content","key","push","join","attrString","reduce","parse","html","options","components","current","level","inComponent","end","replace","index","isOpen","isComment","start","nextChar","parent","parseTag","undefined","test","token","rootEl"],"mappings":"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"} | ||
| {"version":3,"file":"html-parse-stringify.modern.js","sources":["../src/parse-tag.js","../src/parse.js","../src/stringify.js","../src/index.js"],"sourcesContent":["import lookup from 'void-elements'\nconst attrRE = /\\s([^'\"/\\s><]+?)[\\s/>]|([^\\s=]+)=\\s?(\"[^\"]*\"|'[^']*')/g\n\nexport default function stringify(tag) {\n const res = {\n type: 'tag',\n name: '',\n voidElement: false,\n attrs: {},\n children: [],\n }\n\n const tagMatch = tag.match(/<\\/?([^\\s]+?)[/\\s>]/)\n if (tagMatch) {\n res.name = tagMatch[1]\n if (lookup[tagMatch[1]] || tag.charAt(tag.length - 2) === '/') {\n res.voidElement = true\n }\n\n // handle comment tag\n if (res.name.startsWith('!--')) {\n const endIndex = tag.indexOf('-->')\n return {\n type: 'comment',\n comment: endIndex !== -1 ? tag.slice(4, endIndex) : '',\n }\n }\n }\n\n const reg = new RegExp(attrRE)\n let result = null\n for (;;) {\n result = reg.exec(tag)\n\n if (result === null) {\n break\n }\n\n if (!result[0].trim()) {\n continue\n }\n\n if (result[1]) {\n const attr = result[1].trim()\n let arr = [attr, '']\n\n if (attr.indexOf('=') > -1) {\n arr = attr.split('=')\n }\n\n res.attrs[arr[0]] = arr[1]\n reg.lastIndex--\n } else if (result[2]) {\n res.attrs[result[2]] = result[3].trim().substring(1, result[3].length - 1)\n }\n }\n\n return res\n}\n","import parseTag from './parse-tag'\n\nconst tagRE = /<[a-zA-Z0-9\\-\\!\\/](?:\"[^\"]*\"|'[^']*'|[^'\">])*>/g\nconst whitespaceRE = /^\\s*$/\n\n// re-used obj for quick lookups of components\nconst empty = Object.create(null)\n\nexport default function parse(html, options) {\n options || (options = {})\n options.components || (options.components = empty)\n const result = []\n const arr = []\n let current\n let level = -1\n let inComponent = false\n\n // handle text at top level\n if (html.indexOf('<') !== 0) {\n var end = html.indexOf('<')\n result.push({\n type: 'text',\n content: end === -1 ? html : html.substring(0, end),\n })\n }\n\n // collect matches with an exec loop instead of matchAll to keep ES5 API compat\n const matches = []\n let m\n while ((m = tagRE.exec(html))) {\n matches.push(m)\n }\n matches.forEach(function (match, i) {\n const tag = match[0]\n if (!tag) return\n // comments are handled by parseTag as a whole\n if (tag.startsWith('<!--')) return\n // count brackets outside quoted attribute values, so `<` inside an\n // attribute (e.g. title=\"1 < 2\") can't trigger a bogus split\n let lts = 0\n let gts = 0\n let secondLt = -1\n let quote = null\n for (let j = 0; j < tag.length; j++) {\n const c = tag.charAt(j)\n if (quote) {\n if (c === quote) quote = null\n } else if (c === '\"' || c === \"'\") {\n quote = c\n } else if (c === '<') {\n lts++\n if (lts === 2) secondLt = j\n } else if (c === '>') {\n gts++\n }\n }\n // only split when the remainder is itself a valid tag start; otherwise\n // a fragment like `< <!-->` desyncs the string-level isComment check\n // from parseTag's name-based comment detection and crashes the walker\n const validSplit =\n secondLt > -1 && /[a-zA-Z0-9\\-!/]/.test(tag.charAt(secondLt + 1))\n if (lts > gts && validSplit) {\n const firstPart = tag.substring(0, secondLt)\n const secondPart = tag.substring(firstPart.length)\n matches[i][0] = secondPart\n matches[i].index += firstPart.length\n }\n })\n matches.forEach(function (match, i) {\n const tag = match[0]\n if (!tag) return\n const index = match.index\n if (inComponent) {\n if (tag !== '</' + current.name + '>') {\n return\n } else {\n inComponent = false\n }\n }\n const isOpen = tag.charAt(1) !== '/'\n const isComment = tag.startsWith('<!--')\n const start = index + tag.length\n const nextChar = html.charAt(start)\n const nextMatch = matches[i + 1]\n let isText\n if (nextChar === '<' && nextMatch) {\n const nextTag = html.substring(start, nextMatch.index)\n isText = nextTag.split('<').length > nextTag.split('>').length\n }\n\n let parent\n\n if (isComment) {\n const comment = parseTag(tag)\n\n // if we're at root, push new base node\n if (level < 0) {\n result.push(comment)\n return result\n }\n parent = arr[level]\n parent.children.push(comment)\n\n const text = html.slice(start, nextMatch ? nextMatch.index : undefined)\n if (text.length > 0) {\n parent.children.push({\n type: 'text',\n content: text,\n })\n }\n return result\n }\n\n if (isOpen) {\n level++\n\n current = parseTag(tag)\n if (current.type === 'tag' && options.components[current.name]) {\n current.type = 'component'\n inComponent = true\n }\n\n if (\n !current.voidElement &&\n !inComponent &&\n nextChar &&\n nextChar !== '<'\n ) {\n // text content runs to the next actual tag match; stray `<`\n // characters in between are part of the text\n current.children.push({\n type: 'text',\n content: html.slice(start, nextMatch ? nextMatch.index : undefined),\n })\n }\n\n // if we're at root, push new base node\n if (level === 0) {\n result.push(current)\n }\n\n parent = arr[level - 1]\n\n if (parent) {\n parent.children.push(current)\n }\n\n arr[level] = current\n }\n\n if (!isOpen || current.voidElement) {\n if (\n level > -1 &&\n (current.voidElement || current.name === tag.slice(2, -1))\n ) {\n level--\n // move current up a level to match the end tag\n current = level === -1 ? result : arr[level]\n }\n if (!inComponent && (nextChar !== '<' || isText) && nextChar) {\n // trailing text node\n // if we're at the root, push a base text node. otherwise add as\n // a child to the current node.\n parent = level === -1 ? result : arr[level].children\n\n // the text node runs to the next actual tag match; -1 means\n // there's no tag after it (trailing text)\n const end = nextMatch ? nextMatch.index : -1\n let content = html.slice(start, end === -1 ? undefined : end)\n // if a node is nothing but whitespace, collapse it as the spec states:\n // https://www.w3.org/TR/html4/struct/text.html#h-9.1\n if (whitespaceRE.test(content)) {\n content = ' '\n }\n // don't add whitespace-only text nodes if they would be trailing text nodes\n // or if they would be leading whitespace-only text nodes:\n // * end > -1 indicates this is not a trailing text node\n // * leading node is when level is -1 and parent has length 0\n if ((end > -1 && level + parent.length >= 0) || content !== ' ') {\n parent.push({\n type: 'text',\n content: content,\n })\n }\n }\n }\n })\n\n return result\n}\n","function attrString(attrs) {\n const buff = []\n for (let key in attrs) {\n buff.push(key + '=\"' + attrs[key] + '\"')\n }\n if (!buff.length) {\n return ''\n }\n return ' ' + buff.join(' ')\n}\n\nfunction stringify(buff, doc) {\n switch (doc.type) {\n case 'text':\n return buff + doc.content\n case 'tag':\n buff +=\n '<' +\n doc.name +\n (doc.attrs ? attrString(doc.attrs) : '') +\n (doc.voidElement ? '/>' : '>')\n if (doc.voidElement) {\n return buff\n }\n return buff + doc.children.reduce(stringify, '') + '</' + doc.name + '>'\n case 'comment':\n buff += '<!--' + doc.comment + '-->'\n return buff\n }\n}\n\nexport default function (doc) {\n return doc.reduce(function (token, rootEl) {\n return token + stringify('', rootEl)\n }, '')\n}\n","import parse from './parse'\nimport stringify from './stringify'\n\nexport default {\n parse,\n stringify,\n}\n"],"names":["attrRE","stringify","tag","res","type","name","voidElement","attrs","children","tagMatch","match","lookup","charAt","length","startsWith","endIndex","indexOf","comment","slice","reg","RegExp","result","exec","trim","attr","arr","split","lastIndex","substring","tagRE","whitespaceRE","empty","Object","create","buff","doc","content","key","push","join","attrString","reduce","parse","html","options","components","current","level","inComponent","end","matches","m","forEach","i","lts","gts","secondLt","quote","j","c","validSplit","test","firstPart","secondPart","index","isOpen","isComment","start","nextChar","nextMatch","isText","parent","nextTag","parseTag","text","undefined","token","rootEl"],"mappings":"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"} |
@@ -1,2 +0,2 @@ | ||
| import e from"void-elements";var t=/\s([^'"/\s><]+?)[\s/>]|([^\s=]+)=\s?(".*?"|'.*?')/g;function n(n){var r={type:"tag",name:"",voidElement:!1,attrs:{},children:[]},i=n.match(/<\/?([^\s]+?)[/\s>]/);if(i&&(r.name=i[1],(e[i[1]]||"/"===n.charAt(n.length-2))&&(r.voidElement=!0),r.name.startsWith("!--"))){var s=n.indexOf("--\x3e");return{type:"comment",comment:-1!==s?n.slice(4,s):""}}for(var a=new RegExp(t),c=null;null!==(c=a.exec(n));)if(c[0].trim())if(c[1]){var o=c[1].trim(),l=[o,""];o.indexOf("=")>-1&&(l=o.split("=")),r.attrs[l[0]]=l[1],a.lastIndex--}else c[2]&&(r.attrs[c[2]]=c[3].trim().substring(1,c[3].length-1));return r}var r=/<[a-zA-Z0-9\-\!\/](?:"[^"]*"|'[^']*'|[^'">])*>/g,i=/^\s*$/,s=Object.create(null);function a(e,t){switch(t.type){case"text":return e+t.content;case"tag":return e+="<"+t.name+(t.attrs?function(e){var t=[];for(var n in e)t.push(n+'="'+e[n]+'"');return t.length?" "+t.join(" "):""}(t.attrs):"")+(t.voidElement?"/>":">"),t.voidElement?e:e+t.children.reduce(a,"")+"</"+t.name+">";case"comment":return e+"\x3c!--"+t.comment+"--\x3e"}}var c={parse:function(e,t){t||(t={}),t.components||(t.components=s);var a,c=[],o=[],l=-1,m=!1;if(0!==e.indexOf("<")){var u=e.indexOf("<");c.push({type:"text",content:-1===u?e:e.substring(0,u)})}return e.replace(r,function(r,s){if(m){if(r!=="</"+a.name+">")return;m=!1}var u,f="/"!==r.charAt(1),h=r.startsWith("\x3c!--"),p=s+r.length,d=e.charAt(p);if(h){var v=n(r);return l<0?(c.push(v),c):((u=o[l]).children.push(v),c)}if(f&&(l++,"tag"===(a=n(r)).type&&t.components[a.name]&&(a.type="component",m=!0),a.voidElement||m||!d||"<"===d||a.children.push({type:"text",content:e.slice(p,e.indexOf("<",p))}),0===l&&c.push(a),(u=o[l-1])&&u.children.push(a),o[l]=a),(!f||a.voidElement)&&(l>-1&&(a.voidElement||a.name===r.slice(2,-1))&&(l--,a=-1===l?c:o[l]),!m&&"<"!==d&&d)){u=-1===l?c:o[l].children;var x=e.indexOf("<",p),g=e.slice(p,-1===x?void 0:x);i.test(g)&&(g=" "),(x>-1&&l+u.length>=0||" "!==g)&&u.push({type:"text",content:g})}}),c},stringify:function(e){return e.reduce(function(e,t){return e+a("",t)},"")}};export default c; | ||
| import t from"void-elements";var e=/\s([^'"/\s><]+?)[\s/>]|([^\s=]+)=\s?("[^"]*"|'[^']*')/g;function n(n){var r={type:"tag",name:"",voidElement:!1,attrs:{},children:[]},i=n.match(/<\/?([^\s]+?)[/\s>]/);if(i&&(r.name=i[1],(t[i[1]]||"/"===n.charAt(n.length-2))&&(r.voidElement=!0),r.name.startsWith("!--"))){var s=n.indexOf("--\x3e");return{type:"comment",comment:-1!==s?n.slice(4,s):""}}for(var a=new RegExp(e),c=null;null!==(c=a.exec(n));)if(c[0].trim())if(c[1]){var l=c[1].trim(),o=[l,""];l.indexOf("=")>-1&&(o=l.split("=")),r.attrs[o[0]]=o[1],a.lastIndex--}else c[2]&&(r.attrs[c[2]]=c[3].trim().substring(1,c[3].length-1));return r}var r=/<[a-zA-Z0-9\-\!\/](?:"[^"]*"|'[^']*'|[^'">])*>/g,i=/^\s*$/,s=Object.create(null);function a(t,e){switch(e.type){case"text":return t+e.content;case"tag":return t+="<"+e.name+(e.attrs?function(t){var e=[];for(var n in t)e.push(n+'="'+t[n]+'"');return e.length?" "+e.join(" "):""}(e.attrs):"")+(e.voidElement?"/>":">"),e.voidElement?t:t+e.children.reduce(a,"")+"</"+e.name+">";case"comment":return t+"\x3c!--"+e.comment+"--\x3e"}}var c={parse:function(t,e){e||(e={}),e.components||(e.components=s);var a,c=[],l=[],o=-1,u=!1;if(0!==t.indexOf("<")){var h=t.indexOf("<");c.push({type:"text",content:-1===h?t:t.substring(0,h)})}for(var v,f=[];v=r.exec(t);)f.push(v);return f.forEach(function(t,e){var n=t[0];if(n&&!n.startsWith("\x3c!--")){for(var r=0,i=0,s=-1,a=null,c=0;c<n.length;c++){var l=n.charAt(c);a?l===a&&(a=null):'"'===l||"'"===l?a=l:"<"===l?2==++r&&(s=c):">"===l&&i++}var o=s>-1&&/[a-zA-Z0-9\-!/]/.test(n.charAt(s+1));if(r>i&&o){var u=n.substring(0,s),h=n.substring(u.length);f[e][0]=h,f[e].index+=u.length}}}),f.forEach(function(r,s){var h=r[0];if(h){var v=r.index;if(u){if(h!=="</"+a.name+">")return;u=!1}var m,d,p="/"!==h.charAt(1),x=h.startsWith("\x3c!--"),g=v+h.length,y=t.charAt(g),E=f[s+1];if("<"===y&&E){var A=t.substring(g,E.index);m=A.split("<").length>A.split(">").length}if(x){var b=n(h);if(o<0)return c.push(b),c;(d=l[o]).children.push(b);var O=t.slice(g,E?E.index:void 0);return O.length>0&&d.children.push({type:"text",content:O}),c}if(p&&(o++,"tag"===(a=n(h)).type&&e.components[a.name]&&(a.type="component",u=!0),a.voidElement||u||!y||"<"===y||a.children.push({type:"text",content:t.slice(g,E?E.index:void 0)}),0===o&&c.push(a),(d=l[o-1])&&d.children.push(a),l[o]=a),(!p||a.voidElement)&&(o>-1&&(a.voidElement||a.name===h.slice(2,-1))&&(o--,a=-1===o?c:l[o]),!u&&("<"!==y||m)&&y)){d=-1===o?c:l[o].children;var W=E?E.index:-1,j=t.slice(g,-1===W?void 0:W);i.test(j)&&(j=" "),(W>-1&&o+d.length>=0||" "!==j)&&d.push({type:"text",content:j})}}}),c},stringify:function(t){return t.reduce(function(t,e){return t+a("",e)},"")}};export default c; | ||
| //# sourceMappingURL=html-parse-stringify.module.js.map |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"html-parse-stringify.module.js","sources":["../src/parse-tag.js","../src/parse.js","../src/stringify.js","../src/index.js"],"sourcesContent":["import lookup from 'void-elements'\nconst attrRE = /\\s([^'\"/\\s><]+?)[\\s/>]|([^\\s=]+)=\\s?(\".*?\"|'.*?')/g\n\nexport default function stringify(tag) {\n const res = {\n type: 'tag',\n name: '',\n voidElement: false,\n attrs: {},\n children: [],\n }\n\n const tagMatch = tag.match(/<\\/?([^\\s]+?)[/\\s>]/)\n if (tagMatch) {\n res.name = tagMatch[1]\n if (\n lookup[tagMatch[1]] ||\n tag.charAt(tag.length - 2) === '/'\n ) {\n res.voidElement = true\n }\n\n // handle comment tag\n if (res.name.startsWith('!--')) {\n const endIndex = tag.indexOf('-->')\n return {\n type: 'comment',\n comment: endIndex !== -1 ? tag.slice(4, endIndex) : '',\n }\n }\n }\n\n const reg = new RegExp(attrRE)\n let result = null\n for (;;) {\n result = reg.exec(tag)\n\n if (result === null) {\n break\n }\n\n if (!result[0].trim()) {\n continue\n }\n\n if (result[1]) {\n const attr = result[1].trim()\n let arr = [attr, '']\n\n if (attr.indexOf('=') > -1) {\n arr = attr.split('=')\n }\n\n res.attrs[arr[0]] = arr[1]\n reg.lastIndex--\n } else if (result[2]) {\n res.attrs[result[2]] = result[3].trim().substring(1, result[3].length - 1)\n }\n }\n\n return res\n}\n","import parseTag from './parse-tag'\n\nconst tagRE = /<[a-zA-Z0-9\\-\\!\\/](?:\"[^\"]*\"|'[^']*'|[^'\">])*>/g\nconst whitespaceRE = /^\\s*$/\n\n// re-used obj for quick lookups of components\nconst empty = Object.create(null)\n\nexport default function parse(html, options) {\n options || (options = {})\n options.components || (options.components = empty)\n const result = []\n const arr = []\n let current\n let level = -1\n let inComponent = false\n\n // handle text at top level\n if (html.indexOf('<') !== 0) {\n var end = html.indexOf('<')\n result.push({\n type: 'text',\n content: end === -1 ? html : html.substring(0, end),\n })\n }\n\n html.replace(tagRE, function (tag, index) {\n if (inComponent) {\n if (tag !== '</' + current.name + '>') {\n return\n } else {\n inComponent = false\n }\n }\n const isOpen = tag.charAt(1) !== '/'\n const isComment = tag.startsWith('<!--')\n const start = index + tag.length\n const nextChar = html.charAt(start)\n let parent\n\n if (isComment) {\n const comment = parseTag(tag)\n\n // if we're at root, push new base node\n if (level < 0) {\n result.push(comment)\n return result\n }\n parent = arr[level]\n parent.children.push(comment)\n return result\n }\n\n if (isOpen) {\n level++\n\n current = parseTag(tag)\n if (current.type === 'tag' && options.components[current.name]) {\n current.type = 'component'\n inComponent = true\n }\n\n if (\n !current.voidElement &&\n !inComponent &&\n nextChar &&\n nextChar !== '<'\n ) {\n current.children.push({\n type: 'text',\n content: html.slice(start, html.indexOf('<', start)),\n })\n }\n\n // if we're at root, push new base node\n if (level === 0) {\n result.push(current)\n }\n\n parent = arr[level - 1]\n\n if (parent) {\n parent.children.push(current)\n }\n\n arr[level] = current\n }\n\n if (!isOpen || current.voidElement) {\n if (\n level > -1 &&\n (current.voidElement || current.name === tag.slice(2, -1))\n ) {\n level--\n // move current up a level to match the end tag\n current = level === -1 ? result : arr[level]\n }\n if (!inComponent && nextChar !== '<' && nextChar) {\n // trailing text node\n // if we're at the root, push a base text node. otherwise add as\n // a child to the current node.\n parent = level === -1 ? result : arr[level].children\n\n // calculate correct end of the content slice in case there's\n // no tag after the text node.\n const end = html.indexOf('<', start)\n let content = html.slice(start, end === -1 ? undefined : end)\n // if a node is nothing but whitespace, collapse it as the spec states:\n // https://www.w3.org/TR/html4/struct/text.html#h-9.1\n if (whitespaceRE.test(content)) {\n content = ' '\n }\n // don't add whitespace-only text nodes if they would be trailing text nodes\n // or if they would be leading whitespace-only text nodes:\n // * end > -1 indicates this is not a trailing text node\n // * leading node is when level is -1 and parent has length 0\n if ((end > -1 && level + parent.length >= 0) || content !== ' ') {\n parent.push({\n type: 'text',\n content: content,\n })\n }\n }\n }\n })\n\n return result\n}\n","function attrString(attrs) {\n const buff = []\n for (let key in attrs) {\n buff.push(key + '=\"' + attrs[key] + '\"')\n }\n if (!buff.length) {\n return ''\n }\n return ' ' + buff.join(' ')\n}\n\nfunction stringify(buff, doc) {\n switch (doc.type) {\n case 'text':\n return buff + doc.content\n case 'tag':\n buff +=\n '<' +\n doc.name +\n (doc.attrs ? attrString(doc.attrs) : '') +\n (doc.voidElement ? '/>' : '>')\n if (doc.voidElement) {\n return buff\n }\n return buff + doc.children.reduce(stringify, '') + '</' + doc.name + '>'\n case 'comment':\n buff += '<!--' + doc.comment + '-->'\n return buff\n }\n}\n\nexport default function (doc) {\n return doc.reduce(function (token, rootEl) {\n return token + stringify('', rootEl)\n }, '')\n}\n","import parse from './parse'\nimport stringify from './stringify'\n\nexport default {\n parse,\n stringify,\n}\n"],"names":["attrRE","stringify","tag","res","type","name","voidElement","attrs","children","tagMatch","match","lookup","charAt","length","startsWith","endIndex","indexOf","comment","slice","reg","RegExp","result","exec","trim","attr","arr","split","lastIndex","substring","tagRE","whitespaceRE","empty","Object","create","buff","doc","content","key","push","join","attrString","reduce","parse","html","options","components","current","level","inComponent","end","replace","index","parent","isOpen","isComment","start","nextChar","parseTag","undefined","test","token","rootEl"],"mappings":"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"} | ||
| {"version":3,"file":"html-parse-stringify.module.js","sources":["../src/parse-tag.js","../src/parse.js","../src/stringify.js","../src/index.js"],"sourcesContent":["import lookup from 'void-elements'\nconst attrRE = /\\s([^'\"/\\s><]+?)[\\s/>]|([^\\s=]+)=\\s?(\"[^\"]*\"|'[^']*')/g\n\nexport default function stringify(tag) {\n const res = {\n type: 'tag',\n name: '',\n voidElement: false,\n attrs: {},\n children: [],\n }\n\n const tagMatch = tag.match(/<\\/?([^\\s]+?)[/\\s>]/)\n if (tagMatch) {\n res.name = tagMatch[1]\n if (lookup[tagMatch[1]] || tag.charAt(tag.length - 2) === '/') {\n res.voidElement = true\n }\n\n // handle comment tag\n if (res.name.startsWith('!--')) {\n const endIndex = tag.indexOf('-->')\n return {\n type: 'comment',\n comment: endIndex !== -1 ? tag.slice(4, endIndex) : '',\n }\n }\n }\n\n const reg = new RegExp(attrRE)\n let result = null\n for (;;) {\n result = reg.exec(tag)\n\n if (result === null) {\n break\n }\n\n if (!result[0].trim()) {\n continue\n }\n\n if (result[1]) {\n const attr = result[1].trim()\n let arr = [attr, '']\n\n if (attr.indexOf('=') > -1) {\n arr = attr.split('=')\n }\n\n res.attrs[arr[0]] = arr[1]\n reg.lastIndex--\n } else if (result[2]) {\n res.attrs[result[2]] = result[3].trim().substring(1, result[3].length - 1)\n }\n }\n\n return res\n}\n","import parseTag from './parse-tag'\n\nconst tagRE = /<[a-zA-Z0-9\\-\\!\\/](?:\"[^\"]*\"|'[^']*'|[^'\">])*>/g\nconst whitespaceRE = /^\\s*$/\n\n// re-used obj for quick lookups of components\nconst empty = Object.create(null)\n\nexport default function parse(html, options) {\n options || (options = {})\n options.components || (options.components = empty)\n const result = []\n const arr = []\n let current\n let level = -1\n let inComponent = false\n\n // handle text at top level\n if (html.indexOf('<') !== 0) {\n var end = html.indexOf('<')\n result.push({\n type: 'text',\n content: end === -1 ? html : html.substring(0, end),\n })\n }\n\n // collect matches with an exec loop instead of matchAll to keep ES5 API compat\n const matches = []\n let m\n while ((m = tagRE.exec(html))) {\n matches.push(m)\n }\n matches.forEach(function (match, i) {\n const tag = match[0]\n if (!tag) return\n // comments are handled by parseTag as a whole\n if (tag.startsWith('<!--')) return\n // count brackets outside quoted attribute values, so `<` inside an\n // attribute (e.g. title=\"1 < 2\") can't trigger a bogus split\n let lts = 0\n let gts = 0\n let secondLt = -1\n let quote = null\n for (let j = 0; j < tag.length; j++) {\n const c = tag.charAt(j)\n if (quote) {\n if (c === quote) quote = null\n } else if (c === '\"' || c === \"'\") {\n quote = c\n } else if (c === '<') {\n lts++\n if (lts === 2) secondLt = j\n } else if (c === '>') {\n gts++\n }\n }\n // only split when the remainder is itself a valid tag start; otherwise\n // a fragment like `< <!-->` desyncs the string-level isComment check\n // from parseTag's name-based comment detection and crashes the walker\n const validSplit =\n secondLt > -1 && /[a-zA-Z0-9\\-!/]/.test(tag.charAt(secondLt + 1))\n if (lts > gts && validSplit) {\n const firstPart = tag.substring(0, secondLt)\n const secondPart = tag.substring(firstPart.length)\n matches[i][0] = secondPart\n matches[i].index += firstPart.length\n }\n })\n matches.forEach(function (match, i) {\n const tag = match[0]\n if (!tag) return\n const index = match.index\n if (inComponent) {\n if (tag !== '</' + current.name + '>') {\n return\n } else {\n inComponent = false\n }\n }\n const isOpen = tag.charAt(1) !== '/'\n const isComment = tag.startsWith('<!--')\n const start = index + tag.length\n const nextChar = html.charAt(start)\n const nextMatch = matches[i + 1]\n let isText\n if (nextChar === '<' && nextMatch) {\n const nextTag = html.substring(start, nextMatch.index)\n isText = nextTag.split('<').length > nextTag.split('>').length\n }\n\n let parent\n\n if (isComment) {\n const comment = parseTag(tag)\n\n // if we're at root, push new base node\n if (level < 0) {\n result.push(comment)\n return result\n }\n parent = arr[level]\n parent.children.push(comment)\n\n const text = html.slice(start, nextMatch ? nextMatch.index : undefined)\n if (text.length > 0) {\n parent.children.push({\n type: 'text',\n content: text,\n })\n }\n return result\n }\n\n if (isOpen) {\n level++\n\n current = parseTag(tag)\n if (current.type === 'tag' && options.components[current.name]) {\n current.type = 'component'\n inComponent = true\n }\n\n if (\n !current.voidElement &&\n !inComponent &&\n nextChar &&\n nextChar !== '<'\n ) {\n // text content runs to the next actual tag match; stray `<`\n // characters in between are part of the text\n current.children.push({\n type: 'text',\n content: html.slice(start, nextMatch ? nextMatch.index : undefined),\n })\n }\n\n // if we're at root, push new base node\n if (level === 0) {\n result.push(current)\n }\n\n parent = arr[level - 1]\n\n if (parent) {\n parent.children.push(current)\n }\n\n arr[level] = current\n }\n\n if (!isOpen || current.voidElement) {\n if (\n level > -1 &&\n (current.voidElement || current.name === tag.slice(2, -1))\n ) {\n level--\n // move current up a level to match the end tag\n current = level === -1 ? result : arr[level]\n }\n if (!inComponent && (nextChar !== '<' || isText) && nextChar) {\n // trailing text node\n // if we're at the root, push a base text node. otherwise add as\n // a child to the current node.\n parent = level === -1 ? result : arr[level].children\n\n // the text node runs to the next actual tag match; -1 means\n // there's no tag after it (trailing text)\n const end = nextMatch ? nextMatch.index : -1\n let content = html.slice(start, end === -1 ? undefined : end)\n // if a node is nothing but whitespace, collapse it as the spec states:\n // https://www.w3.org/TR/html4/struct/text.html#h-9.1\n if (whitespaceRE.test(content)) {\n content = ' '\n }\n // don't add whitespace-only text nodes if they would be trailing text nodes\n // or if they would be leading whitespace-only text nodes:\n // * end > -1 indicates this is not a trailing text node\n // * leading node is when level is -1 and parent has length 0\n if ((end > -1 && level + parent.length >= 0) || content !== ' ') {\n parent.push({\n type: 'text',\n content: content,\n })\n }\n }\n }\n })\n\n return result\n}\n","function attrString(attrs) {\n const buff = []\n for (let key in attrs) {\n buff.push(key + '=\"' + attrs[key] + '\"')\n }\n if (!buff.length) {\n return ''\n }\n return ' ' + buff.join(' ')\n}\n\nfunction stringify(buff, doc) {\n switch (doc.type) {\n case 'text':\n return buff + doc.content\n case 'tag':\n buff +=\n '<' +\n doc.name +\n (doc.attrs ? attrString(doc.attrs) : '') +\n (doc.voidElement ? '/>' : '>')\n if (doc.voidElement) {\n return buff\n }\n return buff + doc.children.reduce(stringify, '') + '</' + doc.name + '>'\n case 'comment':\n buff += '<!--' + doc.comment + '-->'\n return buff\n }\n}\n\nexport default function (doc) {\n return doc.reduce(function (token, rootEl) {\n return token + stringify('', rootEl)\n }, '')\n}\n","import parse from './parse'\nimport stringify from './stringify'\n\nexport default {\n parse,\n stringify,\n}\n"],"names":["attrRE","stringify","tag","res","type","name","voidElement","attrs","children","tagMatch","match","lookup","charAt","length","startsWith","endIndex","indexOf","comment","slice","reg","RegExp","result","exec","trim","attr","arr","split","lastIndex","substring","tagRE","whitespaceRE","empty","Object","create","buff","doc","content","key","push","join","attrString","reduce","parse","html","options","components","current","level","inComponent","end","m","matches","forEach","i","lts","gts","secondLt","quote","j","c","validSplit","test","firstPart","secondPart","index","isText","parent","isOpen","isComment","start","nextChar","nextMatch","nextTag","parseTag","text","undefined","token","rootEl"],"mappings":"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"} |
@@ -1,2 +0,2 @@ | ||
| !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("void-elements")):"function"==typeof define&&define.amd?define(["void-elements"],t):(e=e||self).htmlParseStringify=t(e.voidElements)}(this,function(e){e=e&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e;var t=/\s([^'"/\s><]+?)[\s/>]|([^\s=]+)=\s?(".*?"|'.*?')/g;function n(n){var r={type:"tag",name:"",voidElement:!1,attrs:{},children:[]},i=n.match(/<\/?([^\s]+?)[/\s>]/);if(i&&(r.name=i[1],(e[i[1]]||"/"===n.charAt(n.length-2))&&(r.voidElement=!0),r.name.startsWith("!--"))){var s=n.indexOf("--\x3e");return{type:"comment",comment:-1!==s?n.slice(4,s):""}}for(var c=new RegExp(t),o=null;null!==(o=c.exec(n));)if(o[0].trim())if(o[1]){var a=o[1].trim(),l=[a,""];a.indexOf("=")>-1&&(l=a.split("=")),r.attrs[l[0]]=l[1],c.lastIndex--}else o[2]&&(r.attrs[o[2]]=o[3].trim().substring(1,o[3].length-1));return r}var r=/<[a-zA-Z0-9\-\!\/](?:"[^"]*"|'[^']*'|[^'">])*>/g,i=/^\s*$/,s=Object.create(null);function c(e,t){switch(t.type){case"text":return e+t.content;case"tag":return e+="<"+t.name+(t.attrs?function(e){var t=[];for(var n in e)t.push(n+'="'+e[n]+'"');return t.length?" "+t.join(" "):""}(t.attrs):"")+(t.voidElement?"/>":">"),t.voidElement?e:e+t.children.reduce(c,"")+"</"+t.name+">";case"comment":return e+"\x3c!--"+t.comment+"--\x3e"}}return{parse:function(e,t){t||(t={}),t.components||(t.components=s);var c,o=[],a=[],l=-1,u=!1;if(0!==e.indexOf("<")){var f=e.indexOf("<");o.push({type:"text",content:-1===f?e:e.substring(0,f)})}return e.replace(r,function(r,s){if(u){if(r!=="</"+c.name+">")return;u=!1}var f,m="/"!==r.charAt(1),d=r.startsWith("\x3c!--"),p=s+r.length,h=e.charAt(p);if(d){var v=n(r);return l<0?(o.push(v),o):((f=a[l]).children.push(v),o)}if(m&&(l++,"tag"===(c=n(r)).type&&t.components[c.name]&&(c.type="component",u=!0),c.voidElement||u||!h||"<"===h||c.children.push({type:"text",content:e.slice(p,e.indexOf("<",p))}),0===l&&o.push(c),(f=a[l-1])&&f.children.push(c),a[l]=c),(!m||c.voidElement)&&(l>-1&&(c.voidElement||c.name===r.slice(2,-1))&&(l--,c=-1===l?o:a[l]),!u&&"<"!==h&&h)){f=-1===l?o:a[l].children;var x=e.indexOf("<",p),g=e.slice(p,-1===x?void 0:x);i.test(g)&&(g=" "),(x>-1&&l+f.length>=0||" "!==g)&&f.push({type:"text",content:g})}}),o},stringify:function(e){return e.reduce(function(e,t){return e+c("",t)},"")}}}); | ||
| !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("void-elements")):"function"==typeof define&&define.amd?define(["void-elements"],t):(e=e||self).htmlParseStringify=t(e.voidElements)}(this,function(e){e=e&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e;var t=/\s([^'"/\s><]+?)[\s/>]|([^\s=]+)=\s?("[^"]*"|'[^']*')/g;function n(n){var r={type:"tag",name:"",voidElement:!1,attrs:{},children:[]},i=n.match(/<\/?([^\s]+?)[/\s>]/);if(i&&(r.name=i[1],(e[i[1]]||"/"===n.charAt(n.length-2))&&(r.voidElement=!0),r.name.startsWith("!--"))){var s=n.indexOf("--\x3e");return{type:"comment",comment:-1!==s?n.slice(4,s):""}}for(var a=new RegExp(t),c=null;null!==(c=a.exec(n));)if(c[0].trim())if(c[1]){var o=c[1].trim(),l=[o,""];o.indexOf("=")>-1&&(l=o.split("=")),r.attrs[l[0]]=l[1],a.lastIndex--}else c[2]&&(r.attrs[c[2]]=c[3].trim().substring(1,c[3].length-1));return r}var r=/<[a-zA-Z0-9\-\!\/](?:"[^"]*"|'[^']*'|[^'">])*>/g,i=/^\s*$/,s=Object.create(null);function a(e,t){switch(t.type){case"text":return e+t.content;case"tag":return e+="<"+t.name+(t.attrs?function(e){var t=[];for(var n in e)t.push(n+'="'+e[n]+'"');return t.length?" "+t.join(" "):""}(t.attrs):"")+(t.voidElement?"/>":">"),t.voidElement?e:e+t.children.reduce(a,"")+"</"+t.name+">";case"comment":return e+"\x3c!--"+t.comment+"--\x3e"}}return{parse:function(e,t){t||(t={}),t.components||(t.components=s);var a,c=[],o=[],l=-1,u=!1;if(0!==e.indexOf("<")){var f=e.indexOf("<");c.push({type:"text",content:-1===f?e:e.substring(0,f)})}for(var d,h=[];d=r.exec(e);)h.push(d);return h.forEach(function(e,t){var n=e[0];if(n&&!n.startsWith("\x3c!--")){for(var r=0,i=0,s=-1,a=null,c=0;c<n.length;c++){var o=n.charAt(c);a?o===a&&(a=null):'"'===o||"'"===o?a=o:"<"===o?2==++r&&(s=c):">"===o&&i++}var l=s>-1&&/[a-zA-Z0-9\-!/]/.test(n.charAt(s+1));if(r>i&&l){var u=n.substring(0,s),f=n.substring(u.length);h[t][0]=f,h[t].index+=u.length}}}),h.forEach(function(r,s){var f=r[0];if(f){var d=r.index;if(u){if(f!=="</"+a.name+">")return;u=!1}var m,p,v="/"!==f.charAt(1),x=f.startsWith("\x3c!--"),g=d+f.length,y=e.charAt(g),E=h[s+1];if("<"===y&&E){var b=e.substring(g,E.index);m=b.split("<").length>b.split(">").length}if(x){var A=n(f);if(l<0)return c.push(A),c;(p=o[l]).children.push(A);var O=e.slice(g,E?E.index:void 0);return O.length>0&&p.children.push({type:"text",content:O}),c}if(v&&(l++,"tag"===(a=n(f)).type&&t.components[a.name]&&(a.type="component",u=!0),a.voidElement||u||!y||"<"===y||a.children.push({type:"text",content:e.slice(g,E?E.index:void 0)}),0===l&&c.push(a),(p=o[l-1])&&p.children.push(a),o[l]=a),(!v||a.voidElement)&&(l>-1&&(a.voidElement||a.name===f.slice(2,-1))&&(l--,a=-1===l?c:o[l]),!u&&("<"!==y||m)&&y)){p=-1===l?c:o[l].children;var j=E?E.index:-1,w=e.slice(g,-1===j?void 0:j);i.test(w)&&(w=" "),(j>-1&&l+p.length>=0||" "!==w)&&p.push({type:"text",content:w})}}}),c},stringify:function(e){return e.reduce(function(e,t){return e+a("",t)},"")}}}); | ||
| //# sourceMappingURL=html-parse-stringify.umd.js.map |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"html-parse-stringify.umd.js","sources":["../src/parse-tag.js","../src/parse.js","../src/stringify.js","../src/index.js"],"sourcesContent":["import lookup from 'void-elements'\nconst attrRE = /\\s([^'\"/\\s><]+?)[\\s/>]|([^\\s=]+)=\\s?(\".*?\"|'.*?')/g\n\nexport default function stringify(tag) {\n const res = {\n type: 'tag',\n name: '',\n voidElement: false,\n attrs: {},\n children: [],\n }\n\n const tagMatch = tag.match(/<\\/?([^\\s]+?)[/\\s>]/)\n if (tagMatch) {\n res.name = tagMatch[1]\n if (\n lookup[tagMatch[1]] ||\n tag.charAt(tag.length - 2) === '/'\n ) {\n res.voidElement = true\n }\n\n // handle comment tag\n if (res.name.startsWith('!--')) {\n const endIndex = tag.indexOf('-->')\n return {\n type: 'comment',\n comment: endIndex !== -1 ? tag.slice(4, endIndex) : '',\n }\n }\n }\n\n const reg = new RegExp(attrRE)\n let result = null\n for (;;) {\n result = reg.exec(tag)\n\n if (result === null) {\n break\n }\n\n if (!result[0].trim()) {\n continue\n }\n\n if (result[1]) {\n const attr = result[1].trim()\n let arr = [attr, '']\n\n if (attr.indexOf('=') > -1) {\n arr = attr.split('=')\n }\n\n res.attrs[arr[0]] = arr[1]\n reg.lastIndex--\n } else if (result[2]) {\n res.attrs[result[2]] = result[3].trim().substring(1, result[3].length - 1)\n }\n }\n\n return res\n}\n","import parseTag from './parse-tag'\n\nconst tagRE = /<[a-zA-Z0-9\\-\\!\\/](?:\"[^\"]*\"|'[^']*'|[^'\">])*>/g\nconst whitespaceRE = /^\\s*$/\n\n// re-used obj for quick lookups of components\nconst empty = Object.create(null)\n\nexport default function parse(html, options) {\n options || (options = {})\n options.components || (options.components = empty)\n const result = []\n const arr = []\n let current\n let level = -1\n let inComponent = false\n\n // handle text at top level\n if (html.indexOf('<') !== 0) {\n var end = html.indexOf('<')\n result.push({\n type: 'text',\n content: end === -1 ? html : html.substring(0, end),\n })\n }\n\n html.replace(tagRE, function (tag, index) {\n if (inComponent) {\n if (tag !== '</' + current.name + '>') {\n return\n } else {\n inComponent = false\n }\n }\n const isOpen = tag.charAt(1) !== '/'\n const isComment = tag.startsWith('<!--')\n const start = index + tag.length\n const nextChar = html.charAt(start)\n let parent\n\n if (isComment) {\n const comment = parseTag(tag)\n\n // if we're at root, push new base node\n if (level < 0) {\n result.push(comment)\n return result\n }\n parent = arr[level]\n parent.children.push(comment)\n return result\n }\n\n if (isOpen) {\n level++\n\n current = parseTag(tag)\n if (current.type === 'tag' && options.components[current.name]) {\n current.type = 'component'\n inComponent = true\n }\n\n if (\n !current.voidElement &&\n !inComponent &&\n nextChar &&\n nextChar !== '<'\n ) {\n current.children.push({\n type: 'text',\n content: html.slice(start, html.indexOf('<', start)),\n })\n }\n\n // if we're at root, push new base node\n if (level === 0) {\n result.push(current)\n }\n\n parent = arr[level - 1]\n\n if (parent) {\n parent.children.push(current)\n }\n\n arr[level] = current\n }\n\n if (!isOpen || current.voidElement) {\n if (\n level > -1 &&\n (current.voidElement || current.name === tag.slice(2, -1))\n ) {\n level--\n // move current up a level to match the end tag\n current = level === -1 ? result : arr[level]\n }\n if (!inComponent && nextChar !== '<' && nextChar) {\n // trailing text node\n // if we're at the root, push a base text node. otherwise add as\n // a child to the current node.\n parent = level === -1 ? result : arr[level].children\n\n // calculate correct end of the content slice in case there's\n // no tag after the text node.\n const end = html.indexOf('<', start)\n let content = html.slice(start, end === -1 ? undefined : end)\n // if a node is nothing but whitespace, collapse it as the spec states:\n // https://www.w3.org/TR/html4/struct/text.html#h-9.1\n if (whitespaceRE.test(content)) {\n content = ' '\n }\n // don't add whitespace-only text nodes if they would be trailing text nodes\n // or if they would be leading whitespace-only text nodes:\n // * end > -1 indicates this is not a trailing text node\n // * leading node is when level is -1 and parent has length 0\n if ((end > -1 && level + parent.length >= 0) || content !== ' ') {\n parent.push({\n type: 'text',\n content: content,\n })\n }\n }\n }\n })\n\n return result\n}\n","function attrString(attrs) {\n const buff = []\n for (let key in attrs) {\n buff.push(key + '=\"' + attrs[key] + '\"')\n }\n if (!buff.length) {\n return ''\n }\n return ' ' + buff.join(' ')\n}\n\nfunction stringify(buff, doc) {\n switch (doc.type) {\n case 'text':\n return buff + doc.content\n case 'tag':\n buff +=\n '<' +\n doc.name +\n (doc.attrs ? attrString(doc.attrs) : '') +\n (doc.voidElement ? '/>' : '>')\n if (doc.voidElement) {\n return buff\n }\n return buff + doc.children.reduce(stringify, '') + '</' + doc.name + '>'\n case 'comment':\n buff += '<!--' + doc.comment + '-->'\n return buff\n }\n}\n\nexport default function (doc) {\n return doc.reduce(function (token, rootEl) {\n return token + stringify('', rootEl)\n }, '')\n}\n","import parse from './parse'\nimport stringify from './stringify'\n\nexport default {\n parse,\n stringify,\n}\n"],"names":["attrRE","stringify","tag","res","type","name","voidElement","attrs","children","tagMatch","match","lookup","charAt","length","startsWith","endIndex","indexOf","comment","slice","reg","RegExp","result","exec","trim","attr","arr","split","lastIndex","substring","tagRE","whitespaceRE","empty","Object","create","buff","doc","content","key","push","join","attrString","reduce","parse","html","options","components","current","level","inComponent","end","replace","index","parent","isOpen","isComment","start","nextChar","parseTag","undefined","test","token","rootEl"],"mappings":"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"} | ||
| {"version":3,"file":"html-parse-stringify.umd.js","sources":["../src/parse-tag.js","../src/parse.js","../src/stringify.js","../src/index.js"],"sourcesContent":["import lookup from 'void-elements'\nconst attrRE = /\\s([^'\"/\\s><]+?)[\\s/>]|([^\\s=]+)=\\s?(\"[^\"]*\"|'[^']*')/g\n\nexport default function stringify(tag) {\n const res = {\n type: 'tag',\n name: '',\n voidElement: false,\n attrs: {},\n children: [],\n }\n\n const tagMatch = tag.match(/<\\/?([^\\s]+?)[/\\s>]/)\n if (tagMatch) {\n res.name = tagMatch[1]\n if (lookup[tagMatch[1]] || tag.charAt(tag.length - 2) === '/') {\n res.voidElement = true\n }\n\n // handle comment tag\n if (res.name.startsWith('!--')) {\n const endIndex = tag.indexOf('-->')\n return {\n type: 'comment',\n comment: endIndex !== -1 ? tag.slice(4, endIndex) : '',\n }\n }\n }\n\n const reg = new RegExp(attrRE)\n let result = null\n for (;;) {\n result = reg.exec(tag)\n\n if (result === null) {\n break\n }\n\n if (!result[0].trim()) {\n continue\n }\n\n if (result[1]) {\n const attr = result[1].trim()\n let arr = [attr, '']\n\n if (attr.indexOf('=') > -1) {\n arr = attr.split('=')\n }\n\n res.attrs[arr[0]] = arr[1]\n reg.lastIndex--\n } else if (result[2]) {\n res.attrs[result[2]] = result[3].trim().substring(1, result[3].length - 1)\n }\n }\n\n return res\n}\n","import parseTag from './parse-tag'\n\nconst tagRE = /<[a-zA-Z0-9\\-\\!\\/](?:\"[^\"]*\"|'[^']*'|[^'\">])*>/g\nconst whitespaceRE = /^\\s*$/\n\n// re-used obj for quick lookups of components\nconst empty = Object.create(null)\n\nexport default function parse(html, options) {\n options || (options = {})\n options.components || (options.components = empty)\n const result = []\n const arr = []\n let current\n let level = -1\n let inComponent = false\n\n // handle text at top level\n if (html.indexOf('<') !== 0) {\n var end = html.indexOf('<')\n result.push({\n type: 'text',\n content: end === -1 ? html : html.substring(0, end),\n })\n }\n\n // collect matches with an exec loop instead of matchAll to keep ES5 API compat\n const matches = []\n let m\n while ((m = tagRE.exec(html))) {\n matches.push(m)\n }\n matches.forEach(function (match, i) {\n const tag = match[0]\n if (!tag) return\n // comments are handled by parseTag as a whole\n if (tag.startsWith('<!--')) return\n // count brackets outside quoted attribute values, so `<` inside an\n // attribute (e.g. title=\"1 < 2\") can't trigger a bogus split\n let lts = 0\n let gts = 0\n let secondLt = -1\n let quote = null\n for (let j = 0; j < tag.length; j++) {\n const c = tag.charAt(j)\n if (quote) {\n if (c === quote) quote = null\n } else if (c === '\"' || c === \"'\") {\n quote = c\n } else if (c === '<') {\n lts++\n if (lts === 2) secondLt = j\n } else if (c === '>') {\n gts++\n }\n }\n // only split when the remainder is itself a valid tag start; otherwise\n // a fragment like `< <!-->` desyncs the string-level isComment check\n // from parseTag's name-based comment detection and crashes the walker\n const validSplit =\n secondLt > -1 && /[a-zA-Z0-9\\-!/]/.test(tag.charAt(secondLt + 1))\n if (lts > gts && validSplit) {\n const firstPart = tag.substring(0, secondLt)\n const secondPart = tag.substring(firstPart.length)\n matches[i][0] = secondPart\n matches[i].index += firstPart.length\n }\n })\n matches.forEach(function (match, i) {\n const tag = match[0]\n if (!tag) return\n const index = match.index\n if (inComponent) {\n if (tag !== '</' + current.name + '>') {\n return\n } else {\n inComponent = false\n }\n }\n const isOpen = tag.charAt(1) !== '/'\n const isComment = tag.startsWith('<!--')\n const start = index + tag.length\n const nextChar = html.charAt(start)\n const nextMatch = matches[i + 1]\n let isText\n if (nextChar === '<' && nextMatch) {\n const nextTag = html.substring(start, nextMatch.index)\n isText = nextTag.split('<').length > nextTag.split('>').length\n }\n\n let parent\n\n if (isComment) {\n const comment = parseTag(tag)\n\n // if we're at root, push new base node\n if (level < 0) {\n result.push(comment)\n return result\n }\n parent = arr[level]\n parent.children.push(comment)\n\n const text = html.slice(start, nextMatch ? nextMatch.index : undefined)\n if (text.length > 0) {\n parent.children.push({\n type: 'text',\n content: text,\n })\n }\n return result\n }\n\n if (isOpen) {\n level++\n\n current = parseTag(tag)\n if (current.type === 'tag' && options.components[current.name]) {\n current.type = 'component'\n inComponent = true\n }\n\n if (\n !current.voidElement &&\n !inComponent &&\n nextChar &&\n nextChar !== '<'\n ) {\n // text content runs to the next actual tag match; stray `<`\n // characters in between are part of the text\n current.children.push({\n type: 'text',\n content: html.slice(start, nextMatch ? nextMatch.index : undefined),\n })\n }\n\n // if we're at root, push new base node\n if (level === 0) {\n result.push(current)\n }\n\n parent = arr[level - 1]\n\n if (parent) {\n parent.children.push(current)\n }\n\n arr[level] = current\n }\n\n if (!isOpen || current.voidElement) {\n if (\n level > -1 &&\n (current.voidElement || current.name === tag.slice(2, -1))\n ) {\n level--\n // move current up a level to match the end tag\n current = level === -1 ? result : arr[level]\n }\n if (!inComponent && (nextChar !== '<' || isText) && nextChar) {\n // trailing text node\n // if we're at the root, push a base text node. otherwise add as\n // a child to the current node.\n parent = level === -1 ? result : arr[level].children\n\n // the text node runs to the next actual tag match; -1 means\n // there's no tag after it (trailing text)\n const end = nextMatch ? nextMatch.index : -1\n let content = html.slice(start, end === -1 ? undefined : end)\n // if a node is nothing but whitespace, collapse it as the spec states:\n // https://www.w3.org/TR/html4/struct/text.html#h-9.1\n if (whitespaceRE.test(content)) {\n content = ' '\n }\n // don't add whitespace-only text nodes if they would be trailing text nodes\n // or if they would be leading whitespace-only text nodes:\n // * end > -1 indicates this is not a trailing text node\n // * leading node is when level is -1 and parent has length 0\n if ((end > -1 && level + parent.length >= 0) || content !== ' ') {\n parent.push({\n type: 'text',\n content: content,\n })\n }\n }\n }\n })\n\n return result\n}\n","function attrString(attrs) {\n const buff = []\n for (let key in attrs) {\n buff.push(key + '=\"' + attrs[key] + '\"')\n }\n if (!buff.length) {\n return ''\n }\n return ' ' + buff.join(' ')\n}\n\nfunction stringify(buff, doc) {\n switch (doc.type) {\n case 'text':\n return buff + doc.content\n case 'tag':\n buff +=\n '<' +\n doc.name +\n (doc.attrs ? attrString(doc.attrs) : '') +\n (doc.voidElement ? '/>' : '>')\n if (doc.voidElement) {\n return buff\n }\n return buff + doc.children.reduce(stringify, '') + '</' + doc.name + '>'\n case 'comment':\n buff += '<!--' + doc.comment + '-->'\n return buff\n }\n}\n\nexport default function (doc) {\n return doc.reduce(function (token, rootEl) {\n return token + stringify('', rootEl)\n }, '')\n}\n","import parse from './parse'\nimport stringify from './stringify'\n\nexport default {\n parse,\n stringify,\n}\n"],"names":["attrRE","stringify","tag","res","type","name","voidElement","attrs","children","tagMatch","match","lookup","charAt","length","startsWith","endIndex","indexOf","comment","slice","reg","RegExp","result","exec","trim","attr","arr","split","lastIndex","substring","tagRE","whitespaceRE","empty","Object","create","buff","doc","content","key","push","join","attrString","reduce","parse","html","options","components","current","level","inComponent","end","m","matches","forEach","i","lts","gts","secondLt","quote","j","c","validSplit","test","firstPart","secondPart","index","isText","parent","isOpen","isComment","start","nextChar","nextMatch","nextTag","parseTag","text","undefined","token","rootEl"],"mappings":"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"} |
+4
-2
| { | ||
| "name": "html-parse-stringify", | ||
| "description": "Parses well-formed HTML (meaning all tags closed) into an AST and back. quickly.", | ||
| "version": "3.0.1", | ||
| "version": "3.1.0", | ||
| "author": "Henrik Joreteg <henrik@joreteg.com>", | ||
@@ -20,3 +20,4 @@ "bugs": { | ||
| "files": [ | ||
| "dist" | ||
| "dist", | ||
| "html-parse-stringify.d.ts" | ||
| ], | ||
@@ -35,2 +36,3 @@ "homepage": "https://github.com/henrikjoreteg/html-parse-stringify", | ||
| "unpkg": "dist/html-parse-stringify.umd.js", | ||
| "types": "html-parse-stringify.d.ts", | ||
| "prettier": { | ||
@@ -37,0 +39,0 @@ "arrowParens": "avoid", |
+3
-0
| # html-parse-stringify | ||
| > **Note:** development of this package continues at [i18next/html-parse-stringify](https://github.com/i18next/html-parse-stringify), where version 4.x and later are maintained. 3.1.0 is the final release from this repository; the npm package name stays `html-parse-stringify`. See [issue #65](https://github.com/HenrikJoreteg/html-parse-stringify/issues/65) for the background. | ||
| This is an _experimental lightweight approach_ to enable quickly parsing HTML into an AST and stringify'ing it back to the original string. | ||
@@ -138,2 +140,3 @@ | ||
| - `3.1.0` Maintenance release, merging long-standing community PRs: LICENSE file shipped in the npm package (#66 by @monholm, closes #61), text containing `<` no longer truncated (#64, closes #59), multi-line attribute values (#63 by @steffanhalv, closes #62), TypeScript declaration shipped and improved (#51/#52 by @jiangfengming, closes #56), text after comment nodes no longer discarded (#53 by @tohosaku). Development continues at [i18next/html-parse-stringify](https://github.com/i18next/html-parse-stringify). | ||
| - `3.0.1` Merged #47 which makes void elements check case insensitive. Thanks again, [@adrai](https://github.com/adrai) for this contribution! | ||
@@ -140,0 +143,0 @@ - `3.0.0` Merged #46 which fixed an issue with handling of whitespace. Doing major version bump since this changes behavior if you have whitespace only nodes (see merged PR and #45 for more details). Thanks [@adrai](https://github.com/adrai) for this contribution! |
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.
74440
34.07%12
20%85
112.5%158
1.94%1
Infinity%