1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const { RemoteSettings } = ChromeUtils.importESModule(
"resource://services-settings/remote-settings.sys.mjs"
);
loader.lazyRequireGetter(
this,
["TARGET_BROWSER_ID", "TARGET_BROWSER_STATUS", "TARGET_BROWSER_PREF"],
"resource://devtools/shared/compatibility/constants.js",
true
);
/**
* Returns the full list of browsers in the RemoteSetting devtools-compatibility-browsers
* collection (which is a flat copy of MDN compat data), sorted by browser and version.
*
* @returns Promise<Array<Object>> : Objects in the array have the following shape:
* - {string} id: The browser id (e.g. `firefox`,`safari_ios`). Should be one of TARGET_BROWSER_ID
* - {string} name: The browser display name (e.g. `Firefox`,`Safari for IOS`, …)
* - {string} version: The browser version (e.g. `99`,`15.3`, `1.0.4`, …)
* - {string} status: The browser status (e.g. `current`,`beta`, …). Should be one of TARGET_BROWSER_STATUS
*/
async function getBrowsersList() {
const records = await RemoteSettings("devtools-compatibility-browsers", {
filterFunc: record => {
if (
!TARGET_BROWSER_ID.includes(record.browserid) ||
!TARGET_BROWSER_STATUS.includes(record.status)
) {
return null;
}
return {
id: record.browserid,
name: record.name,
version: record.version,
status: record.status,
};
},
}).get();
const numericCollator = new Intl.Collator([], { numeric: true });
records.sort((a, b) => {
if (a.id == b.id) {
return numericCollator.compare(a.version, b.version);
}
return a.id > b.id ? 1 : -1;
});
// MDN compat data might have browser data that have the same id and status.
// e.g. https://github.com/mdn/browser-compat-data/commit/53453400ecb2a85e7750d99e2e0a1611648d1d56#diff-31a16f09157f13354db27821261604aa
// In this case, only keep the newer version to keep uniqueness by id and status.
// This needs to be done after sorting since we rely on the order of the records.
return records.filter((record, index, arr) => {
const nextRecord = arr[index + 1];
// If the next record in the array is the same browser and has the same status, filter
// out this one since it's a lower version.
if (
nextRecord &&
record.id === nextRecord.id &&
record.status === nextRecord.status
) {
return false;
}
return true;
});
}
/**
* Returns the list of browsers for which we should check compatibility issues.
*
* @returns Promise<Array<Object>> : Objects in the array have the following shape:
* - {string} id: The browser id (e.g. `firefox`,`safari_ios`). Should be one of TARGET_BROWSER_ID
* - {string} name: The browser display name (e.g. `Firefox`,`Safari for IOS`, …)
* - {string} version: The browser version (e.g. `99`,`15.3`, `1.0.4`, …)
* - {string} status: The browser status (e.g. `current`,`beta`, …). Should be one of TARGET_BROWSER_STATUS
*/
async function getTargetBrowsers() {
const targetsString = Services.prefs.getCharPref(TARGET_BROWSER_PREF, "");
const browsers = await getBrowsersList();
// If not value are stored in the pref, it means the user did not chose specific browsers,
// so we need to return the full list.
if (!targetsString) {
return browsers;
}
const selectedBrowsersAndStatuses = JSON.parse(targetsString);
return browsers.filter(
browser =>
!!selectedBrowsersAndStatuses.find(
({ id, status }) => browser.id == id && browser.status == status
)
);
}
/**
* Store the list of browser id and status that should be used for checking compatibility
* issues.
*
* @param {Object[]} browsers
* @param {string} browsers[].id: The browser id. Should be one of TARGET_BROWSER_ID
* @param {string} browsers[].status: The browser status. Should be one of TARGET_BROWSER_STATUS
*/
function setTargetBrowsers(browsers) {
Services.prefs.setCharPref(
TARGET_BROWSER_PREF,
JSON.stringify(
// Only store the id and the status
browsers.map(browser => ({
id: browser.id,
status: browser.status,
}))
)
);
}
module.exports = {
getBrowsersList,
getTargetBrowsers,
setTargetBrowsers,
};
|