in src/helper/merge-html-plugin.ts [73:126]
function mergeStreams (original: Event[], highlighted: Event[], value: string): string {
let processed = 0;
let result = '';
const nodeStack = [];
function selectStream (): Event[] {
if ((original.length === 0) || (highlighted.length === 0)) {
return (original.length > 0) ? original : highlighted;
}
if (original[0].offset !== highlighted[0].offset) {
return (original[0].offset < highlighted[0].offset) ? original : highlighted;
}
return highlighted[0].event === 'start' ? original : highlighted;
}
function open (node: Node): void {
function attributeString (attr: Attr): string {
return ' ' + attr.nodeName + '="' + escapeHTML(attr.value) + '"';
}
// @ts-expect-error
result += '<' + tag(node) + [].map.call(node.attributes, attributeString).join('') + '>';
}
function close (node: Node): void {
result += '</' + tag(node) + '>';
}
function render (event: Event): void {
(event.event === 'start' ? open : close)(event.node);
}
while ((original.length > 0) || (highlighted.length > 0)) {
let stream = selectStream();
result += escapeHTML(value.substring(processed, stream[0].offset));
processed = stream[0].offset;
if (stream === original) {
nodeStack.reverse().forEach(close);
do {
render(stream.splice(0, 1)[0]);
stream = selectStream();
} while (stream === original && (stream.length > 0) && stream[0].offset === processed);
nodeStack.reverse().forEach(open);
} else {
if (stream[0].event === 'start') {
nodeStack.push(stream[0].node);
} else {
nodeStack.pop();
}
render(stream.splice(0, 1)[0]);
}
}
return result + escapeHTML(value.substr(processed));
}