PageSourceSearch

https://browserbench.org/Speedometer3.1/resources/developer-mode.mjs

js browserbench.org collected 2026-10-01 12:29:35 UTC 9,355 bytes, 288 lines download raw bytes

1import { Suites, Tags } from "./tests.mjs";
2import { params, defaultParams } from "./params.mjs";
3
4export function createDeveloperModeContainer() {
5    const container = document.createElement("div");
6    container.className = "developer-mode";
7
8    const details = document.createElement("details");
9    const summary = document.createElement("summary");
10    summary.textContent = "Developer Mode";
11    details.append(summary);
12
13    const content = document.createElement("div");
14    content.className = "developer-mode-content";
15
16    content.append(createUIForSuites());
17
18    const settings = document.createElement("div");
19    settings.className = "settings";
20    settings.append(createUIForIterationCount());
21    settings.append(createUIForMeasurementMethod());
22    settings.append(createUIForWarmupSuite());
23    settings.append(createUIForWarmupBeforeSync());
24    settings.append(createUIForSyncStepDelay());
25
26    content.append(document.createElement("hr"));
27    content.append(settings);
28
29    content.append(document.createElement("hr"));
30    content.append(createUIForRun());
31
32    details.append(content);
33    container.append(details);
34    return container;
35}
36
37function span(text) {
38    const span = document.createElement("span");
39    span.textContent = text;
40    return span;
41}
42
43function createUIForMeasurementMethod() {
44    let check = document.createElement("input");
45    check.type = "checkbox";
46    check.id = "measurement-method";
47    check.checked = params.measurementMethod === "raf";
48
49    check.onchange = () => {
50        params.measurementMethod = check.checked ? "raf" : "timer";
51        updateURL();
52    };
53
54    let label = document.createElement("label");
55    label.append(check, " ", span("rAF timing"));
56
57    return label;
58}
59
60function createUIForWarmupSuite() {
61    let check = document.createElement("input");
62    check.type = "checkbox";
63    check.id = "warmup-suite";
64    check.checked = !!params.useWarmupSuite;
65
66    check.onchange = () => {
67        params.useWarmupSuite = check.checked;
68        updateURL();
69    };
70
71    let label = document.createElement("label");
72    label.append(check, " ", span("Use Warmup Suite"));
73
74    return label;
75}
76
77function createUIForIterationCount() {
78    const { range, label } = createTimeRangeUI("Iterations: ", params.iterationCount, "#", 1, 200);
79    range.onchange = () => {
80        params.iterationCount = parseInt(range.value);
81        updateURL();
82    };
83    return label;
84}
85
86function createUIForWarmupBeforeSync() {
87    const { range, label } = createTimeRangeUI("Warmup time: ", params.warmupBeforeSync);
88    range.onchange = () => {
89        params.warmupBeforeSync = parseInt(range.value);
90        updateURL();
91    };
92    return label;
93}
94
95function createUIForSyncStepDelay() {
96    const { range, label } = createTimeRangeUI("Sync step delay: ", params.waitBeforeSync);
97    range.onchange = () => {
98        params.waitBeforeSync = parseInt(range.value);
99        updateURL();
100    };
101    return label;
102}
103
104function createTimeRangeUI(labelText, initialValue, unit = "ms", min = 0, max = 1000) {
105    const range = document.createElement("input");
106    range.type = "range";
107    range.min = min;
108    range.max = max;
109    range.value = initialValue;
110
111    const rangeValueAndUnit = document.createElement("span");
112    rangeValueAndUnit.className = "range-label-data";
113
114    const rangeValue = document.createElement("span");
115    rangeValue.textContent = initialValue;
116    rangeValueAndUnit.append(rangeValue, " ", unit);
117
118    const label = document.createElement("label");
119    label.append(span(labelText), range, rangeValueAndUnit);
120
121    range.oninput = () => {
122        rangeValue.textContent = range.value;
123    };
124
125    return { range, label };
126}
127
128function createUIForSuites() {
129    const control = document.createElement("nav");
130    control.className = "suites";
131    const ol = document.createElement("ol");
132    const checkboxes = [];
133    const setSuiteEnabled = (suiteIndex, enabled) => {
134        Suites[suiteIndex].disabled = !enabled;
135        checkboxes[suiteIndex].checked = enabled;
136    };
137
138    for (const suite of Suites) {
139        const li = document.createElement("li");
140        const checkbox = document.createElement("input");
141        checkbox.id = suite.name;
142        checkbox.type = "checkbox";
143        checkbox.checked = !suite.disabled;
144        checkbox.onchange = () => {
145            suite.disabled = !checkbox.checked;
146            updateURL();
147        };
148        checkboxes.push(checkbox);
149
150        const label = document.createElement("label");
151        label.append(checkbox, " ", suite.name);
152        li.appendChild(label);
153        label.onclick = (event) => {
154            if (event?.ctrlKey || event?.metaKey) {
155                for (let suiteIndex = 0; suiteIndex < Suites.length; suiteIndex++) {
156                    if (Suites[suiteIndex] !== suite)
157                        setSuiteEnabled(suiteIndex, false);
158                    else
159                        setSuiteEnabled(suiteIndex, true);
160                }
161            }
162        };
163
164        ol.appendChild(li);
165    }
166    control.appendChild(ol);
167    let buttons = control.appendChild(document.createElement("div"));
168    buttons.className = "button-bar";
169
170    let button = document.createElement("button");
171    button.textContent = "Select all";
172    button.onclick = () => {
173        for (let suiteIndex = 0; suiteIndex < Suites.length; suiteIndex++)
174            setSuiteEnabled(suiteIndex, true);
175
176        updateURL();
177    };
178    buttons.appendChild(button);
179
180    button = document.createElement("button");
181    button.textContent = "Unselect all";
182    button.onclick = () => {
183        for (let suiteIndex = 0; suiteIndex < Suites.length; suiteIndex++)
184            setSuiteEnabled(suiteIndex, false);
185
186        updateURL();
187    };
188    buttons.appendChild(button);
189
190    let i = 0;
191    const kTagsPerLine = 3;
192    for (const tag of Tags) {
193        if (tag === "all")
194            continue;
195        if (!(i % kTagsPerLine)) {
196            buttons = control.appendChild(document.createElement("div"));
197            buttons.className = "button-bar";
198        }
199        i++;
200        button = document.createElement("button");
201        button.className = "tag";
202        button.textContent = `#${tag}`;
203        button.dataTag = tag;
204        button.onclick = (event) => {
205            const extendSelection = event?.shiftKey;
206            const invertSelection = event?.ctrlKey || event?.metaKey;
207            const selectedTag = event.target.dataTag;
208            for (let suiteIndex = 0; suiteIndex < Suites.length; suiteIndex++) {
209                let enabled = Suites[suiteIndex].tags.includes(selectedTag);
210                if (invertSelection)
211                    enabled = !enabled;
212                if (extendSelection && !enabled)
213                    continue;
214                setSuiteEnabled(suiteIndex, enabled);
215            }
216            updateURL();
217        };
218        buttons.appendChild(button);
219    }
220
221    return control;
222}
223
224function createUIForRun() {
225    let button = document.createElement("button");
226    button.textContent = "Start Test";
227    button.onclick = (event) => {
228        globalThis.benchmarkClient.start();
229    };
230    let buttons = document.createElement("div");
231    buttons.className = "button-bar";
232    buttons.appendChild(button);
233    return buttons;
234}
235
236function updateURL() {
237    const url = new URL(window.location.href);
238
239    // If less than all suites are selected then change the URL "Suites" GET parameter
240    // to comma separate only the selected
241    const selectedSuites = Suites.filter((suite) => !suite.disabled);
242
243    if (!selectedSuites.length) {
244        url.searchParams.delete("tags");
245        url.searchParams.delete("suites");
246        url.searchParams.delete("suite");
247    } else {
248        url.searchParams.delete("tags");
249        url.searchParams.delete("suite");
250        // Try finding common tags that would result in the current suite selection.
251        let commonTags = new Set(selectedSuites[0].tags);
252        for (const suite of Suites) {
253            if (suite.disabled)
254                suite.tags.forEach((tag) => commonTags.delete(tag));
255            else
256                commonTags = new Set(suite.tags.filter((tag) => commonTags.has(tag)));
257        }
258        if (commonTags.size) {
259            const tags = [...commonTags][0];
260            if (tags === "default")
261                url.searchParams.delete("tags");
262            else
263                url.searchParams.set("tags", tags);
264            url.searchParams.delete("suites");
265        } else {
266            url.searchParams.delete("tags");
267            url.searchParams.set("suites", selectedSuites.map((suite) => suite.name).join(","));
268        }
269    }
270
271    if (params.measurementMethod !== "raf")
272        url.searchParams.set("measurementMethod", "timer");
273    else
274        url.searchParams.delete("measurementMethod");
275
276    const boolParamKeys = ["iterationCount", "useWarmupSuite", "warmupBeforeSync", "waitBeforeSync"];
277    for (const paramKey of boolParamKeys) {
278        if (params[paramKey] !== defaultParams[paramKey])
279            url.searchParams.set(paramKey, params[paramKey]);
280        else
281            url.searchParams.delete(paramKey);
282    }
283
284    // Only push state if changed
285    url.search = decodeURIComponent(url.search);
286    if (url.href !== window.location.href)
287        window.history.pushState({}, "", url);
288}

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.