PageSourceSearch

https://www.browserling.com/js/dropdown.js?v=2f10da

js browserling.com collected 2026-10-01 08:59:59 UTC 2,873 bytes, 106 lines download raw bytes

1// @ts-check
2
3/**
4 * @constructor
5 * @template {{text: string, icon?: string, selected?: boolean}} T
6 * @param {"platform"|"browser"|"version"} kind
7 * @param {T[]} data
8 * @param {(e: T, i: number)=>void} onSelect
9 */
10function Dropdown(kind, data, onSelect) {
11    var self = this;
12
13    /** @param {string} cl */
14    function mkDiv(cl) {
15        var e = document.createElement("div");
16        e.className = cl;
17        return e;
18    }
19    /** @param {Element} e
20     * @param {string} k */
21    function toggleAttr(e, k) {
22        var x = e.hasAttribute(k);
23        if (x) { e.removeAttribute(k); }
24        else { e.setAttribute(k, "true"); }
25        return !x;
26    }
27
28    var dd = mkDiv("dropdown kind-" + kind);
29
30    /** @type {(open: boolean) => void} */
31    self.onToggle = function(){};
32
33    var ddSel = mkDiv("dropdown-selected");
34    ddSel.addEventListener("click", function() {
35        var open = toggleAttr(dd, "data-open");
36        self.onToggle(open);
37    });
38    dd.appendChild(ddSel);
39
40    var ddItems = mkDiv("dropdown-slider");
41    ddItems.addEventListener("click", function(e) {
42        if (!e.target) { return; }
43        var dataI = /** @type {Element} */(e.target).getAttribute("data-i");
44        if (!dataI) { return; }
45        var i = parseInt(dataI);
46        setSel(i);
47        onSelect(self.selectedItem, self.selectedIndex);
48        dd.removeAttribute("data-open");
49        self.onToggle(false);
50    });
51    dd.appendChild(ddItems);
52
53    /** @type {T[]} */
54    self.data = data;
55    /** @type {number} */
56    self.selectedIndex = -1;
57    /** @type {T} */
58    self.selectedItem = data[0];
59
60    /** @type {(i: number) => void} */
61    function setSel(i) {
62        self.selectedIndex = i;
63        self.selectedItem = self.data[i];
64        ddSel.innerHTML = "";
65        ddSel.appendChild(ddItems.children[i].cloneNode(true));
66    }
67
68    /** @type {(x: T, i: number) => void} */
69    function addItem(x, i) {
70        var item = mkDiv("item");
71        item.setAttribute("data-i", i+"");
72        if (x.icon) {
73            var icon = mkDiv("icon");
74            var img = document.createElement("img");
75            img.src = x.icon;
76            icon.appendChild(img);
77            item.appendChild(icon);
78        }
79        var text = mkDiv("text");
80        text.textContent = x.text;
81        item.appendChild(text);
82        ddItems.appendChild(item);
83        if (x.selected) {
84            setSel(i);
85        }
86    }
87
88    /** @type {(data: T[]) => void} */
89    self.update = function(data) {
90        self.data = data;
91        ddItems.innerHTML = "";
92        ddSel.innerHTML = "";
93        self.selectedIndex = -1;
94
95        for (var i = 0; i < self.data.length; i++) {
96            addItem(self.data[i], i);
97        }
98
99        if (self.selectedIndex == -1) {
100            setSel(0);
101        }
102    }
103    self.update(data);
104
105    self.create = function() { return dd };
106}

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.