diff options
Diffstat (limited to 'devtools/shared/compatibility/compatibility-user-settings.js')
-rw-r--r-- | devtools/shared/compatibility/compatibility-user-settings.js | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/devtools/shared/compatibility/compatibility-user-settings.js b/devtools/shared/compatibility/compatibility-user-settings.js new file mode 100644 index 0000000000..cfd0552968 --- /dev/null +++ b/devtools/shared/compatibility/compatibility-user-settings.js @@ -0,0 +1,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, +}; |