Runner: Analyse-Einsetzen ignoriert Kommentare/Skripte (Fix Runde 1)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
ClaudeandClaude Sonnet 5.5 committed 2026-10-01 10:05:08 +00:00
1 parent 18d37d1e01
commit 9fa05e23d1
4 files changed
+79 -16

No files matched your search

+38 -11
View File
@@ -17,20 +17,47 @@ export function scriptTag(analytics, baseUrl) {
return `<script data-wk-analytics src="${baseUrl}w.js" data-site="${analytics.siteKey}" data-color="${analytics.color}" defer></script>`;
}
// Spannen, in denen Marker nichts zu suchen haben: Kommentare, script, style, textarea, template (ohne Verschachtelungs-Logik).
function findSpans(s) {
const spans = [];
const re = /<!--|<(script|style|textarea|template)\b/gi;
let m;
while ((m = re.exec(s))) {
let end;
let kind = 'raw';
if (m[0] === '<!--') {
const e = s.indexOf('-->', m.index + 4);
end = e < 0 ? s.length : e + 3;
kind = 'comment';
} else {
const close = new RegExp(`</${m[1]}\\s*>`, 'ig');
close.lastIndex = m.index + m[0].length;
const c = close.exec(s);
end = c ? c.index + c[0].length : s.length;
if (m[1].toLowerCase() === 'script') kind = 'script';
}
spans.push({ start: m.index, end, kind });
re.lastIndex = end;
}
return spans;
}
// Arbeitet auf latin1-Zeichenketten (1 Byte = 1 Zeichen), damit beliebige Kodierungen byte-genau erhalten bleiben.
export function injectIntoHtml(buf, tag) {
let s = buf.toString('latin1');
const old = /<script\b[^>]*\bdata-wk-analytics\b[^>]*>\s*<\/script\s*>/gi;
if (old.test(s)) {
let first = true;
s = s.replace(old, () => (first ? ((first = false), tag) : ''));
} else {
const head = s.search(/<\/head\s*>/i);
if (head >= 0) s = s.slice(0, head) + tag + s.slice(head);
else {
const m = /<body\b[^>]*>/i.exec(s);
if (m) { const at = m.index + m[0].length; s = s.slice(0, at) + tag + s.slice(at); } else s = tag + s;
}
const spans = findSpans(s);
const olds = spans.filter((x) => x.kind === 'script' && /\bdata-wk-analytics\b/i.test(s.slice(x.start, s.indexOf('>', x.start) + 1)));
if (olds.length) {
for (let i = olds.length - 1; i >= 0; i--) s = s.slice(0, olds[i].start) + (i === 0 ? tag : '') + s.slice(olds[i].end);
return Buffer.from(s, 'latin1');
}
let masked = s;
for (const x of spans) masked = masked.slice(0, x.start) + ' '.repeat(x.end - x.start) + masked.slice(x.end);
const head = masked.search(/<\/head\s*>/i);
if (head >= 0) s = s.slice(0, head) + tag + s.slice(head);
else {
const m = /<body\b[^>]*>/i.exec(masked);
if (m) { const at = m.index + m[0].length; s = s.slice(0, at) + tag + s.slice(at); } else s = tag + s;
}
return Buffer.from(s, 'latin1');
}