package-helpers-cmxsl/helpers/DATA/firefox/onboarding/onboarding.js

344 lines
12 KiB
JavaScript

/* 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/. */
// Based on the original onboarding code with deep changes from Ruben Rodriguez
// Copyright (C) 2018 Ruben Rodriguez <ruben@gnu.org>
/* eslint-env mozilla/frame-script */
"use strict";
const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
Cu.import("resource://gre/modules/Services.jsm");
const ABOUT_HOME_URL = "about:home";
const ABOUT_NEWTAB_URL = "about:newtab";
/**
* @param {String} action the action to ask the chrome to do
* @param {Array | Object} params the parameters for the action
*/
function sendMessageToChrome(action, params) {
sendAsyncMessage("Onboarding:OnContentMessage", {
action, params
});
}
/**
* The script won't be initialized if we turned off onboarding by
* setting "browser.onboarding.enabled" to false.
*/
class Onboarding {
constructor(contentWindow) {
this.init(contentWindow);
this._bundle = Services.strings.createBundle("chrome://onboarding/locale/onboarding.properties");
this.keylist = {
"javascript.enabled": {
type: "boolean",
name: "javascript.enabled",
label: this._bundle.GetStringFromName("onboarding.disable-javascript.title"),
description: this._bundle.GetStringFromName("onboarding.disable-javascript.description"),
defaultvalue: true,
onvalue: false,
offvalue: true,
},
"browser.display.use_document_fonts": {
type: "integer",
name: "browser.display.use_document_fonts",
label: this._bundle.GetStringFromName("onboarding.custom-fonts.title"),
description: this._bundle.GetStringFromName("onboarding.custom-fonts.description"),
defaultvalue: 1,
onvalue: 0,
offvalue: 1,
},
"browser.safebrowsing.provider.mozilla.updateURL": {
type: "string",
name: "browser.safebrowsing.provider.mozilla.updateURL",
label: this._bundle.GetStringFromName("onboarding.tracking-protection.title"),
description: this._bundle.GetStringFromName("onboarding.tracking-protection.description"),
defaultvalue: "",
onvalue: "https://shavar.services.mozilla.com/downloads?client=SAFEBROWSING_ID&appver=%MAJOR_VERSION%&pver=2.2",
offvalue: "",
},
"privacy.firstparty.isolate": {
type: "boolean",
name: "privacy.firstparty.isolate",
label: this._bundle.GetStringFromName("onboarding.isolate-request-first-party.title"),
description: this._bundle.GetStringFromName("onboarding.isolate-request-first-party.description"),
defaultvalue: false,
onvalue: true,
offvalue: false,
},
"extensions.update.enabled": {
type: "boolean",
name: "extensions.update.enabled",
label: this._bundle.GetStringFromName("onboarding.auto-update-extensions.title"),
description: this._bundle.GetStringFromName("onboarding.auto-update-extensions.description"),
defaultvalue: false,
onvalue: true,
offvalue: false,
},
"network.http.referer.spoofSource": {
type: "boolean",
name: "network.http.referer.spoofSource",
label: this._bundle.GetStringFromName("onboarding.spoof-referers.title"),
description: this._bundle.GetStringFromName("onboarding.spoof-referers.description"),
defaultvalue: true,
onvalue: true,
offvalue: false,
},
"captivedetect.canonicalURL": {
type: "string",
name: "captivedetect.canonicalURL",
label: this._bundle.GetStringFromName("onboarding.detect-captative-portal.title"),
description: this._bundle.GetStringFromName("onboarding.detect-captative-portal.description"),
defaultvalue: "",
onvalue: "http://detectportal.firefox.com/success.txt",
offvalue: "",
},
"browser.search.geoip.url": {
type: "string",
name: "browser.search.geoip.url",
label: this._bundle.GetStringFromName("onboarding.geolocation.title"),
description: this._bundle.GetStringFromName("onboarding.geolocation.description"),
defaultvalue: "",
onvalue: "https://location.services.mozilla.com/v1/country?key=%MOZILLA_API_KEY%",
offvalue: ""
},
"webgl.disabled": {
type: "boolean",
name: "webgl.disabled",
label: this._bundle.GetStringFromName("onboarding.webgl.title"),
description: this._bundle.GetStringFromName("onboarding.webgl.description"),
defaultvalue: true,
onvalue: false,
offvalue: true
}
}
}
async init(contentWindow) {
this._window = contentWindow;
// Destroy on unloading. This is to ensure we remove all the stuff we left.
// No any leak out there.
this._window.addEventListener("unload", () => this.destroy());
this.uiInitialized = false;
this._window.requestIdleCallback(() => this._initUI());
}
getPref(type, key, def){
switch (type){
case "integer":
return Services.prefs.getIntPref(key, def);
break;
case "string":
return Services.prefs.getStringPref(key, def);
break;
case "boolean":
return Services.prefs.getBoolPref(key, def);
break;
}
}
_callback(id, val){
this._window.document.getElementById(id).checked= (val==this.keylist[id].onvalue);
}
newcheckbox(kind, type, name, label, description, defaultvalue, onvalue, offvalue){
let content = this._window.document.createElement("div");
content.style="border-top: 1px solid #DDDDDD; padding-top:10px";
if (kind == "addon")
sendMessageToChrome("check-addon", [{
name: name,
}]);
else
Services.prefs.addObserver(name, () => {this._callback(name, this.getPref(type, name, defaultvalue));});
content.appendChild(this._window.document.createElement("input"));
content.appendChild(this._window.document.createElement("label"));
content.appendChild(this._window.document.createElement("p"));
content.children[0].id=name;
content.children[0].name=name;
content.children[0].className=kind;
content.children[0].type="checkbox";
content.children[0].style="position:relative; top:2px;";
content.children[0].checked=this.getPref(type, name, defaultvalue)==onvalue;
content.children[0].addEventListener("click", this);
content.children[0].addEventListener("keypress", this);
content.children[1].for=name;
content.children[1].innerHTML=label;
content.children[1].style="font-size:15px";
if (description != ""){
content.children[2].innerHTML=description;
content.children[2].style="padding-left:35px; font-size: small; color:#999; margin-top:5px";
}
return content;
}
_initUI() {
if (this.uiInitialized) {
return;
}
this.uiInitialized = true;
let { body } = this._window.document;
let main = this._window.document.getElementsByTagName("main")[0];
let settingsblock = this._window.document.createElement("div");
settingsblock.style=`border:1px solid #D7D7DB;
border-radius:3px;
margin-bottom:40px;
padding:0 15px 10px 15px;
color:#4A4A4F;
`;
let title = this._window.document.createElement("div");
title.innerHTML=`<h2 style="margin:10px 0 5px; font-size:20px">` + this._bundle.GetStringFromName("onboarding.privacy-settings.title") + `</h2> <p style="font-size:14px">` + this._bundle.GetStringFromName("onboarding.privacy-settings.description") + `</p>`;
main.insertBefore(settingsblock, main.childNodes[0]);
settingsblock.appendChild(title);
for ( var key in this.keylist){
key = this.keylist[key];
settingsblock.appendChild(this.newcheckbox("key", key.type, key.name, key.label, key.description, key.defaultvalue, key.onvalue, key.offvalue));
}
settingsblock.appendChild(this.newcheckbox("addon", null, "uBlock0@raymondhill.net", "uBlock Origin", "Block ads and other intrusing trackers."));
settingsblock.appendChild(this.newcheckbox("addon", null, "jid1-KtlZuoiikVfFew@jetpack", "GNU LibreJs", "Block nonfree <a href=\"https://www.gnu.org/software/librejs/\">JavaScript</a>."));
}
_clearPrefObserver() {
for ( var key in this.keylist){
key = this.keylist[key];
Services.prefs.removeObserver(key.name, () => {this._callbacktest(key.name, this.getPref(key.type, key.name, key.defaultvalue));});
}
}
handleClick(target) {
switch (target.className){
case "addon":
sendMessageToChrome("flip-addon", [{
name: target.name
}]);
return;
break;
case "key":
let value
if (target.checked)
value = this.keylist[target.name].onvalue
else
value = this.keylist[target.name].offvalue
if (target.name == "captivedetect.canonicalURL" && value != "")
this._window.alert("You need to restart the browser to apply this change.\n\nWhen this feature is enabled the browser will automatically\ntry to connect to detectportal.firefox.com at the beginning of each browsing session.");
sendMessageToChrome("set-prefs", [{
type: this.keylist[target.name].type,
name: target.name,
value: value
}]);
return;
break
}
}
/**
* Wrap keyboard focus within the dialog.
* When moving forward, focus on the first element when the current focused
* element is the last one.
* When moving backward, focus on the last element when the current focused
* element is the first one.
* Do nothing if focus is moving in the middle of the list of dialog's focusable
* elements.
*
* @param {DOMNode} current currently focused element
* @param {Boolean} back direction
* @return {DOMNode} newly focused element if any
*/
wrapMoveFocus(current, back) {
let elms = [...this._dialog.querySelectorAll(
`button, input[type="checkbox"], input[type="email"], [tabindex="0"]`)];
let next;
if (back) {
if (elms.indexOf(current) === 0) {
next = elms[elms.length - 1];
next.focus();
}
} else if (elms.indexOf(current) === elms.length - 1) {
next = elms[0];
next.focus();
}
return next;
}
handleKeypress(event) {
let { target, key, shiftKey } = event;
if ([" ", "Enter"].includes(key)) {
this.handleClick(target);
event.preventDefault();
}
return;
}
handleEvent(evt) {
switch (evt.type) {
case "keypress":
this.handleKeypress(evt);
break;
case "click":
this.handleClick(evt.target);
break;
default:
break;
}
}
destroy() {
if (!this.uiInitialized) {
return;
}
this.uiInitialized = false;
this._clearPrefObserver();
}
}
addEventListener("load", function onLoad(evt) {
if (!content || evt.target != content.document) {
return;
}
var window = evt.target.defaultView;
// Set the checked value of addons
function handleMessageFromChrome(message) {
if (! window) return;
var payload = message.data;
var cb = window.document.getElementById(payload.id);
if (cb == null) return;
cb.checked=payload.active;
cb.parentNode.hidden = ! payload.installed;
}
function needsrestart(){
window.alert("This change will be applied when you restart the browser");
}
addMessageListener("Onboarding:message-from-chrome", handleMessageFromChrome);
addMessageListener("Onboarding:needsrestart", needsrestart);
let location = window.location.href;
if (location == ABOUT_NEWTAB_URL || location == ABOUT_HOME_URL) {
// We just want to run tests as quickly as possible
// so in the automation test, we don't do `requestIdleCallback`.
if (Cu.isInAutomation) {
new Onboarding(window);
return;
}
window.requestIdleCallback(() => {
new Onboarding(window);
});
}
}, true);