This commit is contained in:
2025-11-30 16:24:02 +01:00
parent 9a1feb2912
commit 15bda4545e
20 changed files with 921 additions and 270 deletions

View File

@@ -12,6 +12,12 @@ export type ExportedElement = {
d?: string;
r?: string;
h?: string;
c?: number;
samples?: {
t?: string[];
l?: string[];
p?: string[];
};
};
export const extractDom = (): ExportedElement[] => {
@@ -142,41 +148,17 @@ export const extractDom = (): ExportedElement[] => {
};
const items: ExportedElement[] = [];
const seenStructure = new Set<string>();
const seen = new Map<string, number>();
const addItem = (o: ExportedElement & { keyPath: string }) => {
const structureKey = o.el + "|" + o.keyPath;
if (seenStructure.has(structureKey)) return;
seenStructure.add(structureKey);
const keyParts = [o.el, o.x];
if (o.t) keyParts.push("t=" + o.t);
if (o.l) keyParts.push("l=" + o.l);
if (o.p) keyParts.push("p=" + o.p);
if (o.n) keyParts.push("n=" + o.n);
if (o.i) keyParts.push("i=" + o.i);
if (o.d) keyParts.push("d=" + o.d);
if (o.r) keyParts.push("r=" + o.r);
const key = keyParts.join("|");
const prev = seen.get(key) || 0;
if (prev > 0) {
let hVal = 0;
const str = key + "#" + prev;
for (let i = 0; i < str.length; i++) {
hVal = (hVal * 31 + str.charCodeAt(i)) >>> 0;
}
const hex = (hVal & 0xfff).toString(16).padStart(3, "0");
o.h = hex;
}
seen.set(key, prev + 1);
const { keyPath, ...rest } = o;
items.push(rest);
type Group = {
element: ExportedElement & { keyPath: string };
count: number;
t: Set<string>;
l: Set<string>;
p: Set<string>;
};
const groups = new Map<string, Group>();
const elements = Array.from(
document.querySelectorAll<HTMLElement>("button,a,input,select,textarea")
);
@@ -195,21 +177,63 @@ export const extractDom = (): ExportedElement[] => {
if (!(t || l || p || n || !stableId || d || r)) continue;
const { full, key } = getPaths(e);
const o: ExportedElement & { keyPath: string } = {
const base: ExportedElement & { keyPath: string } = {
el: shortTag(e.tagName),
x: full,
keyPath: key,
};
if (t) o.t = t;
if (l && l !== t) o.l = l;
if (p && p !== t && p !== l) o.p = p;
if (n) o.n = n;
if (!stableId && id) o.i = id;
if (d) o.d = d;
if (r) o.r = r;
if (t) base.t = t;
if (l && l !== t) base.l = l;
if (p && p !== t && p !== l) base.p = p;
if (n) base.n = n;
if (!stableId && id) base.i = id;
if (d) base.d = d;
if (r) base.r = r;
addItem(o);
const structureKey = base.el + "|" + base.keyPath;
let group = groups.get(structureKey);
if (!group) {
group = {
element: base,
count: 0,
t: new Set<string>(),
l: new Set<string>(),
p: new Set<string>(),
};
groups.set(structureKey, group);
}
group.count += 1;
if (base.t) group.t.add(base.t);
if (base.l) group.l.add(base.l);
if (base.p) group.p.add(base.p);
}
const MAX_SAMPLES = 5;
for (const group of groups.values()) {
const { keyPath, ...rest } = group.element;
const out: ExportedElement = { ...rest };
if (group.count > 1) {
out.c = group.count;
}
const samples: { t?: string[]; l?: string[]; p?: string[] } = {};
const tSamples = Array.from(group.t).slice(0, MAX_SAMPLES);
const lSamples = Array.from(group.l).slice(0, MAX_SAMPLES);
const pSamples = Array.from(group.p).slice(0, MAX_SAMPLES);
if (group.count > 1 && tSamples.length > 1) samples.t = tSamples;
if (group.count > 1 && lSamples.length > 1) samples.l = lSamples;
if (group.count > 1 && pSamples.length > 1) samples.p = pSamples;
if (Object.keys(samples).length > 0) {
out.samples = samples;
}
items.push(out);
}
return items;