Skip to content

Commit af0125b

Browse files
authored
Merge pull request #1484 from rust-lang/compare-page-url
Store compare page UI filters into URL
2 parents 5905b73 + e88a8fe commit af0125b

File tree

1 file changed

+103
-26
lines changed

1 file changed

+103
-26
lines changed

site/static/compare/script.js

Lines changed: 103 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1+
function getQueryParams() {
2+
return new URLSearchParams(window.location.search);
3+
}
4+
15
function findQueryParam(name) {
2-
let urlParams = window.location.search?.substring(1).split("&").map(x => x.split("="));
3-
let pair = urlParams?.find(x => x[0] === name)
4-
if (pair) {
5-
return unescape(pair[1]);
6-
}
6+
const params = getQueryParams();
7+
return params.get(name);
78
}
89

910
function createDefaultFilter() {
@@ -29,6 +30,81 @@ function createDefaultFilter() {
2930
};
3031
}
3132

33+
/**
34+
* Loads the initial state of UI filters from URL parameters.
35+
* Keep in sync with `storeFilterToUrl` and `createDefaultFilter`!
36+
*/
37+
function initializeFilterFromUrl() {
38+
const defaultFilter = createDefaultFilter();
39+
const params = getQueryParams();
40+
41+
function getBoolOrDefault(name, defaultValue) {
42+
const urlValue = params.get(name);
43+
if (urlValue !== null) {
44+
return urlValue === "true";
45+
}
46+
return defaultValue;
47+
}
48+
49+
return {
50+
name: params.get("name"),
51+
nonRelevant: getBoolOrDefault("nonRelevant", defaultFilter.nonRelevant),
52+
profile: {
53+
check: getBoolOrDefault("check", defaultFilter.profile.check),
54+
debug: getBoolOrDefault("debug", defaultFilter.profile.debug),
55+
opt: getBoolOrDefault("opt", defaultFilter.profile.opt),
56+
doc: getBoolOrDefault("doc", defaultFilter.profile.doc)
57+
},
58+
scenario: {
59+
full: getBoolOrDefault("full", defaultFilter.scenario.full),
60+
incrFull: getBoolOrDefault("incrFull", defaultFilter.scenario.incrFull),
61+
incrUnchanged: getBoolOrDefault("incrUnchanged", defaultFilter.scenario.incrUnchanged),
62+
incrPatched: getBoolOrDefault("incrPatched", defaultFilter.scenario.incrPatched)
63+
},
64+
category: {
65+
primary: getBoolOrDefault("primary", defaultFilter.category.primary),
66+
secondary: getBoolOrDefault("secondary", defaultFilter.category.secondary)
67+
}
68+
};
69+
}
70+
71+
/**
72+
* Stores the given filter parameters into URL, so that the current "view" can be shared with
73+
* others easily.
74+
*/
75+
function storeFilterToUrl(filter) {
76+
const defaultFilter = createDefaultFilter();
77+
const params = getQueryParams();
78+
79+
function storeOrReset(name, value, defaultValue) {
80+
if (value === defaultValue) {
81+
if (params.has(name)) {
82+
params.delete(name);
83+
}
84+
} else {
85+
params.set(name, value);
86+
}
87+
}
88+
89+
storeOrReset("name", filter.name || null, defaultFilter.name);
90+
storeOrReset("nonRelevant", filter.nonRelevant, defaultFilter.nonRelevant);
91+
storeOrReset("check", filter.profile.check, defaultFilter.profile.check);
92+
storeOrReset("debug", filter.profile.debug, defaultFilter.profile.debug);
93+
storeOrReset("opt", filter.profile.opt, defaultFilter.profile.opt);
94+
storeOrReset("doc", filter.profile.doc, defaultFilter.profile.doc);
95+
storeOrReset("full", filter.scenario.full, defaultFilter.scenario.full);
96+
storeOrReset("incrFull", filter.scenario.incrFull, defaultFilter.scenario.incrFull);
97+
storeOrReset("incrUnchanged", filter.scenario.incrUnchanged, defaultFilter.scenario.incrUnchanged);
98+
storeOrReset("incrPatched", filter.scenario.incrPatched, defaultFilter.scenario.incrPatched);
99+
storeOrReset("primary", filter.category.primary, defaultFilter.category.primary);
100+
storeOrReset("secondary", filter.category.secondary, defaultFilter.category.secondary);
101+
102+
// Change URL without creating a history entry
103+
if (history.replaceState) {
104+
history.replaceState({}, null, createUrlFromParams(params));
105+
}
106+
}
107+
32108
const app = Vue.createApp({
33109
mounted() {
34110
const app = this;
@@ -46,12 +122,21 @@ const app = Vue.createApp({
46122
},
47123
data() {
48124
return {
49-
filter: createDefaultFilter(),
125+
filter: initializeFilterFromUrl(),
50126
showRawData: false,
51127
data: null,
52128
dataLoading: false
53129
}
54130
},
131+
watch: {
132+
// Every time the filter changes, update URL
133+
filter: {
134+
handler(newValue, oldValue) {
135+
storeFilterToUrl(newValue);
136+
},
137+
deep: true
138+
}
139+
},
55140
computed: {
56141
notContinuous() {
57142
return !this.data.is_contiguous;
@@ -281,10 +366,9 @@ const app = Vue.createApp({
281366
return result;
282367
},
283368
createUrlForMetric(metric) {
284-
let start = findQueryParam("start");
285-
let end = findQueryParam("end");
286-
287-
return createUrlFromParams(createSearchParamsForMetric(metric, start, end));
369+
const params = getQueryParams();
370+
params.set("stat", metric);
371+
return createUrlFromParams(params);
288372
},
289373
resetFilter() {
290374
this.filter = createDefaultFilter();
@@ -696,29 +780,22 @@ function makeData(state, app) {
696780
});
697781
}
698782

699-
function createSearchParamsForMetric(stat, start, end) {
700-
let params = new URLSearchParams();
701-
if (start !== undefined) {
702-
params.append("start", start);
703-
}
704-
if (end !== undefined) {
705-
params.append("end", end);
706-
}
707-
if (stat !== undefined) {
708-
params.append("stat", stat);
709-
}
710-
return params.toString();
711-
}
712-
713783
function createUrlFromParams(params) {
714-
return window.location.protocol + "//" + window.location.host + window.location.pathname + "?" + params;
784+
const url = new URL(window.location);
785+
url.search = params;
786+
return url.toString();
715787
}
716788

717789
function submitSettings() {
718790
let stat = getSelected("stats");
719791
let start = document.getElementById("start-bound").value;
720792
let end = document.getElementById("end-bound").value;
721-
let params = createSearchParamsForMetric(stat, start, end);
793+
794+
const params = getQueryParams();
795+
params.set("stat", stat);
796+
params.set("start", start);
797+
params.set("end", end);
798+
722799
window.location.search = params.toString();
723800
}
724801

0 commit comments

Comments
 (0)