PageSourceSearch

https://html.spec.whatwg.org/var-click-highlighting.js

js whatwg.org collected 2026-10-01 06:16:09 UTC 2,731 bytes, 83 lines download raw bytes

1// Derived from https://github.com/speced/bikeshed/blob/3a2640eecd45fd5d8abe5d37b5adaf23cc945b88/bikeshed/stylescript/var-click-highlighting.js with an addition for var-scope.
2/*
3Color-choosing design:
4
5* Colors are ordered by goodness.
6* On clicking a var, give it the earliest color
7    with the lowest usage in the algorithm.
8* On re-clicking, re-use the var's most recent color
9    if that's not currently being used elsewhere.
10*/
11
12const COLOR_COUNT = 7;
13
14document.addEventListener("click", e=>{
15    if(e.target.nodeName == "VAR") {
16        highlightSameAlgoVars(e.target);
17    }
18});
19
20function highlightSameAlgoVars(v) {
21    // Find the algorithm container.
22    let algoContainer = findAlgoContainer(v);
23
24    // Not highlighting document-global vars,
25    // too likely to be unrelated.
26    if(algoContainer == null) return;
27
28    const varName = nameFromVar(v);
29    if(!v.hasAttribute("data-var-color")) {
30        const newColor = chooseHighlightColor(algoContainer, v);
31        for(const el of algoContainer.querySelectorAll("var")) {
32            if(nameFromVar(el) == varName) {
33                el.setAttribute("data-var-color", newColor);
34                el.setAttribute("data-var-last-color", newColor);
35            }
36        }
37    } else {
38        for(const el of algoContainer.querySelectorAll("var")) {
39            if(nameFromVar(el) == varName) {
40                el.removeAttribute("data-var-color");
41            }
42        }
43    }
44}
45function findAlgoContainer(el) {
46    while(el != document.body) {
47        if(el.hasAttribute("data-algorithm") || el.hasAttribute("data-var-scope")) return el;
48        el = el.parentNode;
49    }
50    return null;
51}
52function nameFromVar(el) {
53    return el.textContent.replace(/(\s|\xa0)+/g, " ").trim();
54}
55function colorCountsFromContainer(container) {
56    const namesFromColor = Array.from({length:COLOR_COUNT}, x=>new Set());
57    for(let v of container.querySelectorAll("var[data-var-color]")) {
58        let color = +v.getAttribute("data-var-color");
59        namesFromColor[color].add(nameFromVar(v));
60    }
61
62    return namesFromColor.map(x=>x.size);
63}
64function leastUsedColor(colors) {
65    // Find the earliest color with the lowest count.
66    let minCount = Infinity;
67    let minColor = null;
68    for(var i = 0; i < colors.length; i++) {
69        if(colors[i] < minCount) {
70            minColor = i;
71            minCount = colors[i];
72        }
73    }
74    return minColor;
75}
76function chooseHighlightColor(container, v) {
77    const colorCounts = colorCountsFromContainer(container);
78    if(v.hasAttribute("data-var-last-color")) {
79        let color = +v.getAttribute("data-var-last-color");
80        if(colorCounts[color] == 0) return color;
81    }
82    return leastUsedColor(colorCounts);
83}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.