(html, fragment, doc)
| 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; |
no test coverage detected