New:Socket for Asana Is Now Available.Learn more
Get Started

html-parse-stringify

Package Overview
Dependencies
Maintainers
5
Versions
15
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

html-parse-stringify - npm Package Compare versions

Comparing version
3.0.1
to
3.1.0
+43
html-parse-stringify.d.ts
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;
}
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
-1

@@ -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":"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"}

@@ -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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"}
{
"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",

# 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!