MCPcopy Index your code
hub / github.com/hoothin/UserScripts / parseHTMLToFragment

Function parseHTMLToFragment

Picviewer CE+/Picviewer CE+.user.js:12830–12893  ·  view source on GitHub ↗
(html, fragment, doc)

Source from the content-addressed store, hash-verified

12828 });
12829 }
12830 function parseHTMLToFragment(html, fragment, doc){
12831 const stack = [fragment];
12832 const tokenRe = /<!--[\s\S]*?-->|<!doctype[^>]*>|<\/?[a-zA-Z][^>]*>|[^<]+/gi;
12833 let match;
12834 while ((match = tokenRe.exec(html))) {
12835 const token = match[0];
12836 if (token[0] !== '<') {
12837 const text = decodeEntities(token);
12838 if (text) stack[stack.length - 1].appendChild(doc.createTextNode(text));
12839 continue;
12840 }
12841 if (token.indexOf('<!--') === 0) {
12842 continue;
12843 }
12844 if (/^<!doctype/i.test(token)) {
12845 continue;
12846 }
12847 if (token[1] === '/') {
12848 const tag = token.slice(2, -1).trim().toLowerCase();
12849 for (let i = stack.length - 1; i > 0; i--) {
12850 const node = stack[i];
12851 if (node.nodeType === 1 && node.nodeName.toLowerCase() === tag) {
12852 stack.length = i;
12853 break;
12854 }
12855 }
12856 continue;
12857 }
12858 const tagMatch = /^<\s*([^\s/>]+)/.exec(token);
12859 if (!tagMatch) continue;
12860 const rawName = tagMatch[1];
12861 const tagName = rawName.toLowerCase();
12862 const parent = stack[stack.length - 1];
12863 const parentIsSvg = parent.nodeType === 1 && parent.namespaceURI === SVG_NS;
12864 const isSvg = parentIsSvg || tagName === 'svg';
12865 const el = isSvg ? doc.createElementNS(SVG_NS, rawName) : doc.createElement(tagName);
12866 const attrPart = token.replace(/^<\s*[^\s/>]+/, '').replace(/\/?>$/, '');
12867 if (attrPart) {
12868 const attrRe = /([^\s=]+)(?:\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s"'=<>`]+)))?/g;
12869 let attrMatch;
12870 while ((attrMatch = attrRe.exec(attrPart))) {
12871 const name = attrMatch[1];
12872 const value = decodeEntities(attrMatch[2] || attrMatch[3] || attrMatch[4] || '');
12873 el.setAttribute(name, value);
12874 }
12875 }
12876 parent.appendChild(el);
12877 const selfClosing = token.endsWith('/>');
12878 if (!selfClosing && !VOID_TAGS[tagName]) {
12879 stack.push(el);
12880 if (RAW_TEXT_TAGS[tagName]) {
12881 const closeRe = new RegExp('<\\/\\s*' + tagName + '\\s*>', 'ig');
12882 closeRe.lastIndex = tokenRe.lastIndex;
12883 const closeMatch = closeRe.exec(html);
12884 if (closeMatch) {
12885 const rawText = html.slice(tokenRe.lastIndex, closeMatch.index);
12886 if (rawText) el.appendChild(doc.createTextNode(rawText));
12887 tokenRe.lastIndex = closeMatch.index + closeMatch[0].length;

Callers 1

createHTMLFunction · 0.70

Calls 1

decodeEntitiesFunction · 0.70

Tested by

no test coverage detected