2019-02-27 23:49:00 +01:00
|
|
|
/* 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/. */
|
2020-01-25 01:03:05 +01:00
|
|
|
(async function(){
|
2019-02-27 23:49:00 +01:00
|
|
|
"use strict";
|
|
|
|
|
2019-04-09 08:29:52 +02:00
|
|
|
const extension = require("../lib/extension");
|
2019-04-08 00:02:29 +02:00
|
|
|
const settings = require("../lib/settings");
|
|
|
|
const navigator = require("../lib/navigator");
|
2019-05-02 00:30:30 +02:00
|
|
|
require("../lib/theme").init();
|
2019-02-27 23:49:00 +01:00
|
|
|
|
|
|
|
const title = document.createElement("h1");
|
|
|
|
title.className = "title";
|
2019-04-09 08:29:52 +02:00
|
|
|
title.textContent = extension.getTranslation("navigatorSettings_title");
|
2019-02-27 23:49:00 +01:00
|
|
|
document.body.appendChild(title);
|
|
|
|
|
|
|
|
document.querySelector("head title").textContent = title.textContent;
|
|
|
|
|
|
|
|
const description = document.createElement("div");
|
|
|
|
description.className = "description";
|
2019-04-09 08:29:52 +02:00
|
|
|
description.textContent = extension.getTranslation("navigatorSettings_description");
|
2019-02-27 23:49:00 +01:00
|
|
|
document.body.appendChild(description);
|
|
|
|
|
2019-05-12 00:55:31 +02:00
|
|
|
const disclaimer = document.createElement("div");
|
|
|
|
disclaimer.className = "disclaimer";
|
|
|
|
disclaimer.textContent = extension.getTranslation("navigatorSettings_disclaimer");
|
|
|
|
document.body.appendChild(disclaimer);
|
|
|
|
|
2020-01-25 01:03:05 +01:00
|
|
|
const navigatorDetails = await async function(){
|
|
|
|
let cookieStoreId = "";
|
|
|
|
if (browser.contextualIdentities){
|
|
|
|
const contextualIdentities = await browser.contextualIdentities.query({});
|
|
|
|
if (contextualIdentities.length){
|
|
|
|
const containerLabel = document.createElement("label");
|
|
|
|
containerLabel.className = "contextualIdentities";
|
|
|
|
containerLabel.appendChild(extension.parseTranslation(
|
|
|
|
extension.getTranslation("navigatorSettings_contextualIdentities"),
|
|
|
|
{
|
|
|
|
select: function(){
|
|
|
|
const contextualIdentitiesSelect = document.createElement("select");
|
|
|
|
contextualIdentitiesSelect.appendChild(new Option("", ""));
|
|
|
|
contextualIdentities.forEach(function(contextualIdentity){
|
|
|
|
contextualIdentitiesSelect.appendChild(new Option(
|
|
|
|
contextualIdentity.name,
|
|
|
|
contextualIdentity.cookieStoreId
|
|
|
|
));
|
|
|
|
});
|
|
|
|
window.addEventListener("load", function(){
|
|
|
|
cookieStoreId = contextualIdentitiesSelect.value;
|
|
|
|
emitUpdate();
|
|
|
|
});
|
|
|
|
contextualIdentitiesSelect.addEventListener("change", function(){
|
|
|
|
cookieStoreId = this.value;
|
|
|
|
emitUpdate();
|
|
|
|
});
|
|
|
|
return contextualIdentitiesSelect;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
));
|
|
|
|
document.body.appendChild(containerLabel);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const callbacks = [];
|
|
|
|
let baseStorage;
|
|
|
|
let loaded = false;
|
|
|
|
|
|
|
|
function getKeys(object){
|
|
|
|
return Object.keys(object).filter(function(key){
|
|
|
|
return key !== "contextualIdentities";
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function storageEqual(storage1, storage2){
|
|
|
|
const keys1 = getKeys(storage1);
|
|
|
|
const keys2 = getKeys(storage2);
|
|
|
|
return keys1.length === keys2.length && keys1.every(function(key){
|
|
|
|
return storage1[key] === storage2[key];
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function copyData(from, to = {}){
|
|
|
|
getKeys(from).forEach(function(key){
|
|
|
|
to[key] = from[key];
|
|
|
|
});
|
|
|
|
return to;
|
|
|
|
}
|
|
|
|
|
|
|
|
function getStorage(){
|
|
|
|
if (cookieStoreId === ""){
|
|
|
|
return baseStorage;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (!baseStorage.contextualIdentities){
|
|
|
|
baseStorage.contextualIdentities = {};
|
|
|
|
}
|
|
|
|
if (!baseStorage.contextualIdentities[cookieStoreId]){
|
|
|
|
baseStorage.contextualIdentities[cookieStoreId] = copyData(baseStorage);
|
|
|
|
}
|
|
|
|
return baseStorage.contextualIdentities[cookieStoreId];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
settings.on("navigatorDetails", function({newValue}){
|
|
|
|
baseStorage = newValue;
|
|
|
|
emitUpdate();
|
|
|
|
});
|
|
|
|
settings.onloaded(function(){
|
|
|
|
loaded = true;
|
|
|
|
baseStorage = settings.navigatorDetails;
|
|
|
|
emitUpdate();
|
|
|
|
});
|
|
|
|
function emitUpdate(){
|
|
|
|
if (!loaded){
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
const storage = getStorage();
|
|
|
|
callbacks.forEach(async function(callback){
|
|
|
|
callback(storage);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
const api = {
|
|
|
|
get: getStorage,
|
|
|
|
getComputedValue: function getComputedValue(property){
|
|
|
|
return navigator.getNavigatorValue(property, function(){
|
|
|
|
return cookieStoreId;
|
|
|
|
});
|
|
|
|
},
|
|
|
|
onUpdate: function onUpdate(callback){
|
|
|
|
callbacks.push(callback);
|
|
|
|
if (loaded){
|
|
|
|
callback(getStorage());
|
|
|
|
}
|
|
|
|
},
|
|
|
|
save: function save(){
|
|
|
|
if (!loaded){
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (baseStorage.contextualIdentities){
|
|
|
|
if (Object.keys(baseStorage.contextualIdentities).reduce(function(lastValue, contextualIdentity){
|
|
|
|
if (storageEqual(baseStorage.contextualIdentities[contextualIdentity], baseStorage)){
|
|
|
|
delete baseStorage.contextualIdentities[contextualIdentity];
|
|
|
|
return lastValue;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}, true)){
|
|
|
|
delete baseStorage.contextualIdentities;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
settings.navigatorDetails = baseStorage;
|
|
|
|
},
|
|
|
|
reset: function reset(){
|
|
|
|
if (cookieStoreId === ""){
|
|
|
|
baseStorage = baseStorage.contextualIdentities? {
|
|
|
|
contextualIdentities: baseStorage.contextualIdentities
|
|
|
|
}: {};
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
baseStorage.contextualIdentities[cookieStoreId] = {};
|
|
|
|
}
|
|
|
|
api.save();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
return api;
|
|
|
|
}();
|
|
|
|
|
2019-02-27 23:49:00 +01:00
|
|
|
function presetSection(title, presets){
|
|
|
|
const container = document.createElement("div");
|
|
|
|
container.className = "presetSection";
|
|
|
|
|
|
|
|
const titleNode = document.createElement("h2");
|
|
|
|
titleNode.className = "title";
|
2019-04-09 08:29:52 +02:00
|
|
|
titleNode.textContent = extension.getTranslation("navigatorSettings_presetSection." + title);
|
2019-02-27 23:49:00 +01:00
|
|
|
container.appendChild(titleNode);
|
|
|
|
|
|
|
|
const presetsList = document.createElement("ul");
|
|
|
|
presetsList.className = "presets";
|
|
|
|
container.appendChild(presetsList);
|
|
|
|
|
|
|
|
Object.keys(presets).forEach(function(presetName){
|
|
|
|
const li = document.createElement("li");
|
|
|
|
li.className = "preset " + presetName;
|
|
|
|
presetsList.appendChild(li);
|
|
|
|
|
|
|
|
const button = document.createElement("button");
|
|
|
|
button.className = "button";
|
|
|
|
button.textContent = presetName;
|
|
|
|
li.appendChild(button);
|
|
|
|
|
|
|
|
const presetProperties = presets[presetName];
|
|
|
|
function checkActive(currentProperties){
|
|
|
|
if (Object.keys(presetProperties).every(function(property){
|
2019-12-01 01:27:29 +01:00
|
|
|
let value = presetProperties[property];
|
|
|
|
if ((typeof value) === "function"){
|
|
|
|
value = value(currentProperties);
|
|
|
|
}
|
|
|
|
return value === currentProperties[property];
|
2019-02-27 23:49:00 +01:00
|
|
|
})){
|
|
|
|
li.classList.add("active");
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
li.classList.remove("active");
|
|
|
|
}
|
|
|
|
}
|
2020-01-25 01:03:05 +01:00
|
|
|
navigatorDetails.onUpdate(checkActive);
|
2019-02-27 23:49:00 +01:00
|
|
|
|
|
|
|
button.addEventListener("click", function(){
|
2020-01-25 01:03:05 +01:00
|
|
|
const data = navigatorDetails.get();
|
2019-02-27 23:49:00 +01:00
|
|
|
Object.keys(presetProperties).forEach(function(property){
|
|
|
|
if (presetProperties[property] === undefined){
|
|
|
|
delete data[property];
|
|
|
|
}
|
|
|
|
else {
|
2019-12-01 01:27:29 +01:00
|
|
|
let value = presetProperties[property];
|
|
|
|
if ((typeof value) === "function"){
|
|
|
|
value = value(data);
|
|
|
|
}
|
|
|
|
data[property] = value;
|
2019-02-27 23:49:00 +01:00
|
|
|
}
|
|
|
|
});
|
2020-01-25 01:03:05 +01:00
|
|
|
navigatorDetails.save();
|
2019-02-27 23:49:00 +01:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
return container;
|
|
|
|
}
|
|
|
|
|
2019-12-01 01:27:29 +01:00
|
|
|
const firefoxOscpu = {
|
|
|
|
Windows: "{platformDetails}",
|
|
|
|
Linux: "{platform}",
|
|
|
|
"Mac OS X": "Intel Mac OS X 10.14.3",
|
|
|
|
"": "{original value}"
|
|
|
|
};
|
2019-02-27 23:49:00 +01:00
|
|
|
|
|
|
|
const osPresets = {
|
|
|
|
Windows: {
|
2019-12-01 01:27:29 +01:00
|
|
|
osPreset: "Windows",
|
2019-02-27 23:49:00 +01:00
|
|
|
windowManager: "Windows",
|
|
|
|
platform: "Win32",
|
|
|
|
platformDetails: "Windows NT 10.0; Win64; x64",
|
2019-12-01 01:27:29 +01:00
|
|
|
oscpu: function(currentProperties){
|
|
|
|
if (currentProperties.browserPreset === "Firefox"){
|
|
|
|
return firefoxOscpu.Windows;
|
|
|
|
}
|
|
|
|
return "{undefined}";
|
|
|
|
}
|
2019-02-27 23:49:00 +01:00
|
|
|
},
|
|
|
|
Linux: {
|
2019-12-01 01:27:29 +01:00
|
|
|
osPreset: "Linux",
|
2019-02-27 23:49:00 +01:00
|
|
|
windowManager: "X11",
|
|
|
|
platform: "Linux x86_64",
|
|
|
|
platformDetails: "X11; Linux x86_64",
|
2019-12-01 01:27:29 +01:00
|
|
|
oscpu: function(currentProperties){
|
|
|
|
if (currentProperties.browserPreset === "Firefox"){
|
|
|
|
return firefoxOscpu.Linux;
|
|
|
|
}
|
|
|
|
return "{undefined}";
|
|
|
|
}
|
2019-02-27 23:49:00 +01:00
|
|
|
},
|
|
|
|
"Mac OS X": {
|
2019-12-01 01:27:29 +01:00
|
|
|
osPreset: "Mac OS X",
|
2019-02-27 23:49:00 +01:00
|
|
|
windowManager: "Macintosh",
|
|
|
|
platform: "MacIntel",
|
2019-12-01 01:27:29 +01:00
|
|
|
platformDetails: "Macintosh; Intel Mac OS X 10.14.3",
|
|
|
|
oscpu: function(currentProperties){
|
|
|
|
if (currentProperties.browserPreset === "Firefox"){
|
|
|
|
return firefoxOscpu["Mac OS X"];
|
|
|
|
}
|
|
|
|
return "{undefined}";
|
|
|
|
}
|
2019-02-27 23:49:00 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
const browserPresets = {
|
|
|
|
Edge: {
|
2019-12-01 01:27:29 +01:00
|
|
|
browserPreset: "Edge",
|
2023-03-18 14:45:32 +01:00
|
|
|
chromeVersion: "111.0.0.0",
|
|
|
|
edgeVersion: "111.0.1661.41",
|
2019-02-27 23:49:00 +01:00
|
|
|
firefoxVersion: undefined,
|
2023-03-25 11:36:01 +01:00
|
|
|
firefoxVersionRV: undefined,
|
2019-02-27 23:49:00 +01:00
|
|
|
operaVersion: undefined,
|
|
|
|
safariVersion: undefined,
|
|
|
|
|
|
|
|
appVersion: "5.0 ({platformDetails}) AppleWebKit/537.36 (KHTML, like Gecko) " +
|
|
|
|
"Chrome/{chromeVersion} Safari/537.36 Edge/{edgeVersion}",
|
2019-12-01 01:27:29 +01:00
|
|
|
buildID: "{undefined}",
|
|
|
|
oscpu: "{undefined}",
|
2019-02-27 23:49:00 +01:00
|
|
|
productSub: "20030107",
|
|
|
|
userAgent: "Mozilla/{appVersion}",
|
|
|
|
vendor: undefined,
|
|
|
|
},
|
|
|
|
Opera: {
|
2019-12-01 01:27:29 +01:00
|
|
|
browserPreset: "Opera",
|
2023-03-18 14:45:32 +01:00
|
|
|
chromeVersion: "109.0.0.0",
|
2019-02-27 23:49:00 +01:00
|
|
|
edgeVersion: undefined,
|
|
|
|
firefoxVersion: undefined,
|
2023-03-25 11:36:01 +01:00
|
|
|
firefoxVersionRV: undefined,
|
2023-03-18 14:45:32 +01:00
|
|
|
operaVersion: "95.0.0.0",
|
2019-02-27 23:49:00 +01:00
|
|
|
safariVersion: undefined,
|
|
|
|
|
|
|
|
appVersion: "5.0 ({platformDetails}) AppleWebKit/537.36 (KHTML, like Gecko) " +
|
|
|
|
"Chrome/{chromeVersion} Safari/537.36 OPR/{operaVersion}",
|
2019-12-01 01:27:29 +01:00
|
|
|
buildID: "{undefined}",
|
|
|
|
oscpu: "{undefined}",
|
2019-02-27 23:49:00 +01:00
|
|
|
productSub: "20030107",
|
|
|
|
userAgent: "Mozilla/{appVersion}",
|
|
|
|
vendor: "Google Inc.",
|
|
|
|
},
|
|
|
|
Chrome: {
|
2019-12-01 01:27:29 +01:00
|
|
|
browserPreset: "Chrome",
|
2023-03-18 14:45:32 +01:00
|
|
|
chromeVersion: "111.0.0.0",
|
2019-02-27 23:49:00 +01:00
|
|
|
edgeVersion: undefined,
|
|
|
|
firefoxVersion: undefined,
|
2023-03-25 11:36:01 +01:00
|
|
|
firefoxVersionRV: undefined,
|
2019-02-27 23:49:00 +01:00
|
|
|
operaVersion: undefined,
|
|
|
|
safariVersion: undefined,
|
|
|
|
|
|
|
|
appVersion: "5.0 ({platformDetails}) AppleWebKit/537.36 (KHTML, like Gecko) " +
|
|
|
|
"Chrome/{chromeVersion} Safari/537.36",
|
2019-12-01 01:27:29 +01:00
|
|
|
buildID: "{undefined}",
|
|
|
|
oscpu: "{undefined}",
|
2019-02-27 23:49:00 +01:00
|
|
|
productSub: "20030107",
|
|
|
|
userAgent: "Mozilla/{appVersion}",
|
|
|
|
vendor: "Google Inc.",
|
|
|
|
},
|
|
|
|
Safari: {
|
2019-12-01 01:27:29 +01:00
|
|
|
browserPreset: "Safari",
|
2019-02-27 23:49:00 +01:00
|
|
|
chromeVersion: undefined,
|
|
|
|
edgeVersion: undefined,
|
|
|
|
firefoxVersion: undefined,
|
2023-03-25 11:36:01 +01:00
|
|
|
firefoxVersionRV: undefined,
|
2019-02-27 23:49:00 +01:00
|
|
|
operaVersion: undefined,
|
2023-03-18 14:45:32 +01:00
|
|
|
safariVersion: "16.3",
|
2019-02-27 23:49:00 +01:00
|
|
|
|
|
|
|
appVersion: "5.0 ({platformDetails}) AppleWebKit/605.1.15 (KHTML, like Gecko) " +
|
|
|
|
"Version/{safariVersion} Safari/605.1.15",
|
2019-12-01 01:27:29 +01:00
|
|
|
buildID: "{undefined}",
|
|
|
|
oscpu: "{undefined}",
|
2019-02-27 23:49:00 +01:00
|
|
|
productSub: "20030107",
|
|
|
|
userAgent: "Mozilla/{appVersion}",
|
|
|
|
vendor: "Apple Computer, Inc.",
|
|
|
|
},
|
|
|
|
Firefox: {
|
2019-12-01 01:27:29 +01:00
|
|
|
browserPreset: "Firefox",
|
2019-02-27 23:49:00 +01:00
|
|
|
chromeVersion: undefined,
|
|
|
|
edgeVersion: undefined,
|
|
|
|
firefoxVersion: "{real Firefox version}",
|
2023-03-18 14:44:44 +01:00
|
|
|
firefoxVersionRV: "{real Firefox version - rv}",
|
2019-02-27 23:49:00 +01:00
|
|
|
operaVersion: undefined,
|
|
|
|
safariVersion: undefined,
|
|
|
|
|
|
|
|
appVersion: "5.0 ({windowManager})",
|
|
|
|
buildID: "20181001000000",
|
2019-12-01 01:27:29 +01:00
|
|
|
oscpu: function(currentProperties){
|
|
|
|
return firefoxOscpu[currentProperties.osPreset || ""] || "{original value}";
|
|
|
|
},
|
2019-02-27 23:49:00 +01:00
|
|
|
productSub: "20100101",
|
2023-03-18 14:44:44 +01:00
|
|
|
userAgent: "Mozilla/5.0 ({platformDetails}; rv:{firefoxVersionRV}) Gecko/20100101 Firefox/{firefoxVersion}",
|
2019-02-27 23:49:00 +01:00
|
|
|
vendor: undefined,
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
document.body.appendChild(presetSection("os", osPresets));
|
|
|
|
document.body.appendChild(presetSection("browser", browserPresets));
|
|
|
|
|
|
|
|
const valueTitle = document.createElement("h2");
|
2019-04-09 08:29:52 +02:00
|
|
|
valueTitle.textContent = extension.getTranslation("navigatorSettings_values");
|
2019-02-27 23:49:00 +01:00
|
|
|
document.body.appendChild(valueTitle);
|
|
|
|
|
|
|
|
const valueSection = document.createElement("table");
|
|
|
|
valueSection.className = "values";
|
|
|
|
document.body.appendChild(valueSection);
|
|
|
|
|
|
|
|
function updateValueSection(currentProperties){
|
|
|
|
function createPropertyRow(section, property){
|
|
|
|
const row = document.createElement("tr");
|
|
|
|
|
|
|
|
const name = document.createElement("td");
|
|
|
|
name.textContent = property;
|
|
|
|
row.appendChild(name);
|
|
|
|
|
|
|
|
const value = document.createElement("td");
|
|
|
|
row.appendChild(value);
|
|
|
|
|
|
|
|
const input = document.createElement("input");
|
|
|
|
value.appendChild(input);
|
|
|
|
input.value = currentProperties.hasOwnProperty(property)? currentProperties[property]: "{original value}";
|
|
|
|
input.addEventListener("change", function(){
|
|
|
|
currentProperties[property] = this.value;
|
2020-01-25 01:03:05 +01:00
|
|
|
navigatorDetails.save();
|
2019-02-27 23:49:00 +01:00
|
|
|
});
|
|
|
|
|
|
|
|
const computedValue = document.createElement("td");
|
2020-01-25 01:03:05 +01:00
|
|
|
computedValue.textContent = navigatorDetails.getComputedValue(property);
|
2019-02-27 23:49:00 +01:00
|
|
|
row.appendChild(computedValue);
|
|
|
|
|
|
|
|
section.appendChild(row);
|
|
|
|
}
|
|
|
|
|
|
|
|
valueSection.innerHTML = "";
|
|
|
|
let section = document.createElement("tbody");
|
|
|
|
section.className = "helperValues";
|
|
|
|
valueSection.appendChild(section);
|
|
|
|
|
|
|
|
Object.keys(currentProperties).filter(function(property){
|
2020-01-25 01:03:05 +01:00
|
|
|
return property !== "contextualIdentities" &&
|
|
|
|
navigator.allProperties.indexOf(property) === -1;
|
2019-02-27 23:49:00 +01:00
|
|
|
}).sort().forEach(createPropertyRow.bind(undefined, section));
|
|
|
|
|
|
|
|
section = document.createElement("tbody");
|
|
|
|
section.className = "realValues";
|
|
|
|
valueSection.appendChild(section);
|
|
|
|
|
|
|
|
navigator.allProperties.forEach(createPropertyRow.bind(undefined, section));
|
|
|
|
}
|
2020-01-25 01:03:05 +01:00
|
|
|
navigatorDetails.onUpdate(updateValueSection);
|
2019-02-27 23:49:00 +01:00
|
|
|
|
|
|
|
const resetButton = document.createElement("button");
|
|
|
|
resetButton.className = "button";
|
2019-04-09 08:29:52 +02:00
|
|
|
resetButton.textContent = extension.getTranslation("navigatorSettings_reset");
|
2020-01-25 01:03:05 +01:00
|
|
|
resetButton.addEventListener("click", navigatorDetails.reset);
|
2019-02-27 23:49:00 +01:00
|
|
|
document.body.appendChild(resetButton);
|
|
|
|
}());
|