mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 21:31:04 +00:00
Backed out changeset 8dab8ca19839 (bug 1665957) for bc failures on browser_ion_ui.js . CLOSED TREE
This commit is contained in:
parent
035c84a10b
commit
99412cbf35
@ -57,7 +57,7 @@ var gIdentityHandler = {
|
|||||||
* RegExp used to decide if an about url should be shown as being part of
|
* RegExp used to decide if an about url should be shown as being part of
|
||||||
* the browser UI.
|
* the browser UI.
|
||||||
*/
|
*/
|
||||||
_secureInternalPages: /^(?:accounts|addons|cache|certificate|config|crashes|downloads|license|logins|preferences|protections|rights|sessionrestore|support|welcomeback|ion)(?:[?#]|$)/i,
|
_secureInternalPages: /^(?:accounts|addons|cache|certificate|config|crashes|downloads|license|logins|preferences|protections|rights|sessionrestore|support|welcomeback|pioneer)(?:[?#]|$)/i,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether the established HTTPS connection is considered "broken".
|
* Whether the established HTTPS connection is considered "broken".
|
||||||
|
@ -277,7 +277,7 @@ toolbar[customizing] > .overflow-button {
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
toolbar[customizing] #ion-button,
|
toolbar[customizing] #pioneer-button,
|
||||||
toolbar[customizing] #whats-new-menu-button {
|
toolbar[customizing] #whats-new-menu-button {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
@ -2001,12 +2001,12 @@
|
|||||||
|
|
||||||
<toolbaritem id="PanelUI-button"
|
<toolbaritem id="PanelUI-button"
|
||||||
removable="false">
|
removable="false">
|
||||||
<toolbarbutton id="ion-button"
|
<toolbarbutton id="pioneer-button"
|
||||||
class="toolbarbutton-1"
|
class="toolbarbutton-1"
|
||||||
hidden="true"
|
hidden="true"
|
||||||
badged="true"
|
badged="true"
|
||||||
onmousedown="switchToTabHavingURI('about:ion', true);"
|
onmousedown="switchToTabHavingURI('about:pioneer', true);"
|
||||||
onkeypress="switchToTabHavingURI('about:ion', true);"/>
|
onkeypress="switchToTabHavingURI('about:pioneer', true);"/>
|
||||||
<toolbarbutton id="whats-new-menu-button"
|
<toolbarbutton id="whats-new-menu-button"
|
||||||
class="toolbarbutton-1"
|
class="toolbarbutton-1"
|
||||||
hidden="true"
|
hidden="true"
|
||||||
|
@ -2193,14 +2193,14 @@ BrowserGlue.prototype = {
|
|||||||
_checkHTTPSOnlyPBMPref();
|
_checkHTTPSOnlyPBMPref();
|
||||||
},
|
},
|
||||||
|
|
||||||
_monitorIonPref() {
|
_monitorPioneerPref() {
|
||||||
const PREF_ION_ID = "toolkit.telemetry.pioneerId";
|
const PREF_PIONEER_ID = "toolkit.telemetry.pioneerId";
|
||||||
|
|
||||||
const _checkIonPref = async () => {
|
const _checkPioneerPref = async () => {
|
||||||
for (let win of Services.wm.getEnumerator("navigator:browser")) {
|
for (let win of Services.wm.getEnumerator("navigator:browser")) {
|
||||||
win.document.getElementById(
|
win.document.getElementById(
|
||||||
"ion-button"
|
"pioneer-button"
|
||||||
).hidden = !Services.prefs.getStringPref(PREF_ION_ID, null);
|
).hidden = !Services.prefs.getStringPref(PREF_PIONEER_ID, null);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2208,29 +2208,32 @@ BrowserGlue.prototype = {
|
|||||||
onOpenWindow(xulWindow) {
|
onOpenWindow(xulWindow) {
|
||||||
const win = xulWindow.docShell.domWindow;
|
const win = xulWindow.docShell.domWindow;
|
||||||
win.addEventListener("load", () => {
|
win.addEventListener("load", () => {
|
||||||
const ionButton = win.document.getElementById("ion-button");
|
const pioneerButton = win.document.getElementById("pioneer-button");
|
||||||
if (ionButton) {
|
if (pioneerButton) {
|
||||||
ionButton.hidden = !Services.prefs.getStringPref(PREF_ION_ID, null);
|
pioneerButton.hidden = !Services.prefs.getStringPref(
|
||||||
|
PREF_PIONEER_ID,
|
||||||
|
null
|
||||||
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
onCloseWindow() {},
|
onCloseWindow() {},
|
||||||
};
|
};
|
||||||
|
|
||||||
Services.prefs.addObserver(PREF_ION_ID, _checkIonPref);
|
Services.prefs.addObserver(PREF_PIONEER_ID, _checkPioneerPref);
|
||||||
Services.wm.addListener(windowListener);
|
Services.wm.addListener(windowListener);
|
||||||
_checkIonPref();
|
_checkPioneerPref();
|
||||||
},
|
},
|
||||||
|
|
||||||
_monitorIonStudies() {
|
_monitorPioneerStudies() {
|
||||||
const STUDY_ADDON_COLLECTION_KEY = "pioneer-study-addons-v1";
|
const STUDY_ADDON_COLLECTION_KEY = "pioneer-study-addons-v1";
|
||||||
const PREF_ION_NEW_STUDIES_AVAILABLE =
|
const PREF_PIONEER_NEW_STUDIES_AVAILABLE =
|
||||||
"toolkit.telemetry.pioneer-new-studies-available";
|
"toolkit.telemetry.pioneer-new-studies-available";
|
||||||
|
|
||||||
const _badgeIcon = async () => {
|
const _badgeIcon = async () => {
|
||||||
for (let win of Services.wm.getEnumerator("navigator:browser")) {
|
for (let win of Services.wm.getEnumerator("navigator:browser")) {
|
||||||
win.document
|
win.document
|
||||||
.getElementById("ion-button")
|
.getElementById("pioneer-button")
|
||||||
.querySelector(".toolbarbutton-badge")
|
.querySelector(".toolbarbutton-badge")
|
||||||
.classList.add("feature-callout");
|
.classList.add("feature-callout");
|
||||||
}
|
}
|
||||||
@ -2240,11 +2243,14 @@ BrowserGlue.prototype = {
|
|||||||
onOpenWindow(xulWindow) {
|
onOpenWindow(xulWindow) {
|
||||||
const win = xulWindow.docShell.domWindow;
|
const win = xulWindow.docShell.domWindow;
|
||||||
win.addEventListener("load", () => {
|
win.addEventListener("load", () => {
|
||||||
const ionButton = win.document.getElementById("ion-button");
|
const pioneerButton = win.document.getElementById("pioneer-button");
|
||||||
if (ionButton) {
|
if (pioneerButton) {
|
||||||
const badge = ionButton.querySelector(".toolbarbutton-badge");
|
const badge = pioneerButton.querySelector(".toolbarbutton-badge");
|
||||||
if (
|
if (
|
||||||
Services.prefs.getBoolPref(PREF_ION_NEW_STUDIES_AVAILABLE, false)
|
Services.prefs.getBoolPref(
|
||||||
|
PREF_PIONEER_NEW_STUDIES_AVAILABLE,
|
||||||
|
false
|
||||||
|
)
|
||||||
) {
|
) {
|
||||||
badge.classList.add("feature-callout");
|
badge.classList.add("feature-callout");
|
||||||
} else {
|
} else {
|
||||||
@ -2257,15 +2263,15 @@ BrowserGlue.prototype = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Update all open windows if the pref changes.
|
// Update all open windows if the pref changes.
|
||||||
Services.prefs.addObserver(PREF_ION_NEW_STUDIES_AVAILABLE, _badgeIcon);
|
Services.prefs.addObserver(PREF_PIONEER_NEW_STUDIES_AVAILABLE, _badgeIcon);
|
||||||
|
|
||||||
// Badge any currently-open windows.
|
// Badge any currently-open windows.
|
||||||
if (Services.prefs.getBoolPref(PREF_ION_NEW_STUDIES_AVAILABLE, false)) {
|
if (Services.prefs.getBoolPref(PREF_PIONEER_NEW_STUDIES_AVAILABLE, false)) {
|
||||||
_badgeIcon();
|
_badgeIcon();
|
||||||
}
|
}
|
||||||
|
|
||||||
RemoteSettings(STUDY_ADDON_COLLECTION_KEY).on("sync", async event => {
|
RemoteSettings(STUDY_ADDON_COLLECTION_KEY).on("sync", async event => {
|
||||||
Services.prefs.setBoolPref(PREF_ION_NEW_STUDIES_AVAILABLE, true);
|
Services.prefs.setBoolPref(PREF_PIONEER_NEW_STUDIES_AVAILABLE, true);
|
||||||
});
|
});
|
||||||
|
|
||||||
// When a new window opens, check if we need to badge the icon.
|
// When a new window opens, check if we need to badge the icon.
|
||||||
@ -2362,8 +2368,8 @@ BrowserGlue.prototype = {
|
|||||||
this._monitorScreenshotsPref();
|
this._monitorScreenshotsPref();
|
||||||
this._monitorWebcompatReporterPref();
|
this._monitorWebcompatReporterPref();
|
||||||
this._monitorHTTPSOnlyPref();
|
this._monitorHTTPSOnlyPref();
|
||||||
this._monitorIonPref();
|
this._monitorPioneerPref();
|
||||||
this._monitorIonStudies();
|
this._monitorPioneerStudies();
|
||||||
|
|
||||||
let pService = Cc["@mozilla.org/toolkit/profile-service;1"].getService(
|
let pService = Cc["@mozilla.org/toolkit/profile-service;1"].getService(
|
||||||
Ci.nsIToolkitProfileService
|
Ci.nsIToolkitProfileService
|
||||||
|
@ -118,7 +118,7 @@ static const RedirEntry kRedirMap[] = {
|
|||||||
nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT |
|
nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT |
|
||||||
nsIAboutModule::URI_MUST_LOAD_IN_CHILD | nsIAboutModule::ALLOW_SCRIPT |
|
nsIAboutModule::URI_MUST_LOAD_IN_CHILD | nsIAboutModule::ALLOW_SCRIPT |
|
||||||
nsIAboutModule::URI_CAN_LOAD_IN_PRIVILEGEDABOUT_PROCESS},
|
nsIAboutModule::URI_CAN_LOAD_IN_PRIVILEGEDABOUT_PROCESS},
|
||||||
{"ion", "chrome://browser/content/ion.html",
|
{"pioneer", "chrome://browser/content/pioneer.html",
|
||||||
nsIAboutModule::ALLOW_SCRIPT | nsIAboutModule::HIDE_FROM_ABOUTABOUT},
|
nsIAboutModule::ALLOW_SCRIPT | nsIAboutModule::HIDE_FROM_ABOUTABOUT},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ pages = [
|
|||||||
'logins',
|
'logins',
|
||||||
'newinstall',
|
'newinstall',
|
||||||
'newtab',
|
'newtab',
|
||||||
'ion',
|
'pioneer',
|
||||||
'pocket-saved',
|
'pocket-saved',
|
||||||
'pocket-signup',
|
'pocket-signup',
|
||||||
'policies',
|
'policies',
|
||||||
|
@ -1,76 +0,0 @@
|
|||||||
# 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/.
|
|
||||||
|
|
||||||
### This file is not in a locales directory to prevent it from
|
|
||||||
### being translated as the feature is still in heavy development
|
|
||||||
### and strings are likely to change often.
|
|
||||||
|
|
||||||
-ion-brand-short-name = Ion
|
|
||||||
ion = { -ion-brand-short-name }
|
|
||||||
ion-document-title = Put your data to work for a better internet
|
|
||||||
ion-summary = { -ion-brand-short-name } puts your data to work to address some of today’s most pressing technology concerns, like misinformation, data privacy, and ethical AI. The data you agree to share with Mozilla (the makers of Firefox) helps create tools for better internet transparency and design products that give control back to the people who use them. As a { -ion-brand-short-name } participant, you’ll also have the option to contribute your data to studies sponsored by research institutions and other organizations.
|
|
||||||
ion-study-prompt = Join to enroll
|
|
||||||
ion-join-study = Join Study
|
|
||||||
ion-leave-study = Leave Study
|
|
||||||
ion-enrollment-button = Join { -ion-brand-short-name }
|
|
||||||
ion-unenrollment-button = Leave { -ion-brand-short-name }
|
|
||||||
ion-current-studies = Current Studies
|
|
||||||
ion-no-current-studies = No current studies, please check back later.
|
|
||||||
ion-end-study = End Study
|
|
||||||
ion-ended-study = Study Ended
|
|
||||||
ion-accept-participate = Accept and Participate
|
|
||||||
ion-accept-leave = Accept and Leave
|
|
||||||
ion-cancel = Cancel
|
|
||||||
ion-consent-notice = { -ion-brand-short-name } Privacy Notice
|
|
||||||
ion-consent-study-notice = { -ion-brand-short-name } Study Privacy Consent Notice
|
|
||||||
ion-leave = Leaving { -ion-brand-short-name }
|
|
||||||
ion-consent-study-title = Leaving Study
|
|
||||||
ion-consent-study-join = Accept and Join Study
|
|
||||||
ion-consent-study-leave = Accept and Leave Study
|
|
||||||
|
|
||||||
ion-program-consent-intro = When you enroll in { -ion-brand-short-name }, you are sharing personal information. Keeping that information safe is important to us and to the integrity of { -ion-brand-short-name }. Here is how we safeguard your data and protect your identity.
|
|
||||||
|
|
||||||
ion-program-study-intro = When you enroll in this study, you are sharing personal information. Keeping that information safe is important to us and to the integrity of { -ion-brand-short-name }. Here is how we safeguard your data and protect your identity.
|
|
||||||
|
|
||||||
|
|
||||||
ion-works-title = How it works:
|
|
||||||
ion-works-bullet-get-started-title = Get started.
|
|
||||||
ion-works-bullet-get-started-content = Select the { ion-enrollment-button } button, review and agree to our Privacy Notice, and answer a few (optional) demographic questions. Note that { -ion-brand-short-name } is currently open to participants in the US who are 19 or older.
|
|
||||||
ion-works-bullet-enroll-title = Enroll in studies.
|
|
||||||
ion-works-bullet-enroll-content = Share your data with studies run by { -vendor-short-name } and our { -ion-brand-short-name } research partners. You’ll have the opportunity to learn about a study’s goals, the data it collects, and its research team before you enroll.
|
|
||||||
ion-works-bullet-control-title = Stay in control.
|
|
||||||
ion-works-bullet-control-content = The { -ion-brand-short-name } icon will appear on the { -brand-product-name } toolbar. Select the icon any time you want to return to this page to update your settings, enroll in a study, or leave a study or the { -ion-brand-short-name } program.
|
|
||||||
|
|
||||||
ion-your-data-title = Your data: why it matters and how we protect it
|
|
||||||
ion-your-data-summary = { -ion-brand-short-name } puts your data to work for a better internet. Our goal is to better understand topics like internet usage, online privacy, algorithmic bias, discrimination, and misinformation. This in turn can lead to new products that fundamentally change the tech landscape and hand more power and control back to users.
|
|
||||||
|
|
||||||
ion-your-data-bullet-know = You’ll know the information we plan to collect before we collect it. We publish our data collection documentation, so you can confirm this for yourself. Read each privacy notice for detailed information.
|
|
||||||
ion-your-data-bullet-lengths = We prioritize securing your data and protecting your privacy.
|
|
||||||
ion-your-data-bullet-leave = You can leave the { -ion-brand-short-name } program at any time, and we’ll stop collecting data when you do.
|
|
||||||
ion-your-data-learn-more = Learn more about <a data-l10n-name="privacy-policy">managing the data you share</a> with { -ion-brand-short-name }.
|
|
||||||
|
|
||||||
ion-us-only = Sorry, { -ion-brand-short-name } is currently only open to participants in the US.
|
|
||||||
|
|
||||||
ion-enroll-effective-date = Effective September 1, 2020
|
|
||||||
ion-enroll-summary = { -ion-brand-short-name } is an experimental initiative led by Mozilla to better understand how our users use and navigate the internet. { -ion-brand-short-name } is available to Firefox users in the United States who are 19 or older.
|
|
||||||
ion-enroll-demographic = When you join { -ion-brand-short-name }, we’ll ask you to provide optional demographic data. We’ll also collect basic technical and interaction data as long as you’re participating in { -ion-brand-short-name }. Once you’ve enrolled, you’ll have the opportunity to join available studies—each study will have a specific research purpose and unique privacy notice for you to review before you join it.
|
|
||||||
ion-enroll-privacy-notice = In this Privacy Notice, we detail what data the { -ion-brand-short-name } program collects and discloses, and why. Read each study’s privacy notice for information about how data is collected and handled in that particular study. We also adhere to the <a data-l10n-name="privacy-notice">Mozilla Privacy Policy</a> for how we receive, handle, and share information.
|
|
||||||
ion-enroll-data-disclosure = To see a full list of the data we collect, click <a data-l10n-name="privacy-policy">here</a>.
|
|
||||||
ion-enroll-what-we-collect = What Information We Collect:
|
|
||||||
ion-enroll-collect-demographic = <strong>Demographic data:</strong> We collect optional, self-reported demographic data from { -ion-brand-short-name } participants, including their age, gender, race/ethnicity, education level, household income, and zip code.
|
|
||||||
ion-enroll-technical-data = <strong>Technical data:</strong> We collect basic information about your device’s operating system. When Firefox sends data to us, your IP address is temporarily collected as part of our server logs.
|
|
||||||
ion-enroll-interaction-data = <strong>Interaction data:</strong> We collect data about your interactions with Firefox, like number and type of installed Firefox Add-ons and your active browsing session duration.
|
|
||||||
ion-enroll-location-data = <strong>Location data:</strong> We will use your IP address to approximate your country location, in addition to collecting your self-reported zip code (if you provide it).
|
|
||||||
ion-enroll-how-we-use = How We Use Your Information:
|
|
||||||
ion-enroll-r-and-d = We use the information we collect for for <strong>research and development</strong>, including:
|
|
||||||
ion-enroll-bullet-criteria = To determine which participants meet the criteria to be available to participate in particular research studies
|
|
||||||
ion-enroll-bullet-representative = To ensure our data sets are representative of the many users of Firefox
|
|
||||||
ion-enroll-bullet-improve-existing = To improve our existing products and services
|
|
||||||
ion-enroll-bullet-create = To create and develop new products
|
|
||||||
ion-enroll-who-we-disclose-to = Who We May Disclose Information To:
|
|
||||||
ion-enroll-who-we-disclose-bullet-gcp = <strong>Google Cloud Platform (GCP):</strong> We use GCP as our cloud-storage service. Mozilla has contracted with GCP requiring them to handle the data in ways that are approved by us.
|
|
||||||
ion-enroll-who-we-disclose-bullet-third-party = <strong>Third-party researchers:</strong> As part of being part of the { -ion-brand-short-name } program, we will offer you the ability to join studies. If necessary for the study, we may ask you to share all or some of the data collected under this Privacy Notice with the third party researcher(s) administering a study. Mozilla will contractually obligate the third party researchers to ensure that your data is handled in ways that are approved by us.
|
|
||||||
ion-enroll-who-we-disclose-bullet-public = <strong>General public:</strong> To advance our <a data-l10n-name="mozilla-manifesto">mission of being open</a>, we may release data sets to the general public. When we do so, we will aggregate the data and remove identifying information, so the data won’t reveal the behaviors or characteristics of individual users.
|
|
||||||
ion-enroll-data-management = Data Management:
|
|
||||||
ion-enroll-data-management-learn-more = You can learn more about managing your { -ion-brand-short-name } and individual study data <a data-l10n-name="privacy-policy">here</a>. If you have any other questions regarding our privacy practices, please contact us at <a data-l10n-name="compliance-email">compliance@mozilla.com</a>.
|
|
@ -1,119 +0,0 @@
|
|||||||
<!-- 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/. -->
|
|
||||||
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta http-equiv="Content-Security-Policy" content="default-src chrome: blob:; img-src https:; object-src 'none'">
|
|
||||||
<link rel="localization" href="browser/branding/brandings.ftl">
|
|
||||||
<link rel="localization" href="branding/brand.ftl">
|
|
||||||
<!-- Temporary "en-US"-only l10n strings -->
|
|
||||||
<link rel="localization" href="preview/ion.ftl">
|
|
||||||
<link rel="stylesheet" href="chrome://global/skin/in-content/common.css">
|
|
||||||
<link rel="stylesheet" href="chrome://browser/content/ion.css">
|
|
||||||
<script src="chrome://browser/content/ion.js"></script>
|
|
||||||
<link rel="icon" href="chrome://browser/skin/ion.svg">
|
|
||||||
<title data-l10n-id="ion"></title>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<div id="locale-notification" data-l10n-id="ion-us-only"></div>
|
|
||||||
<div id="report-content">
|
|
||||||
<header>
|
|
||||||
<h1 id="title" data-l10n-id="ion-document-title"></h1>
|
|
||||||
<button id="enrollment-button" class="primary"></button>
|
|
||||||
</header>
|
|
||||||
<div id="summary" data-l10n-id="ion-summary"></div>
|
|
||||||
<div id="details">
|
|
||||||
<h2 data-l10n-id="ion-works-title"></h2>
|
|
||||||
<p><strong data-l10n-id="ion-works-bullet-get-started-title" ></strong> <span data-l10n-id="ion-works-bullet-get-started-content"></span></p>
|
|
||||||
<p><strong data-l10n-id="ion-works-bullet-enroll-title" ></strong> <span data-l10n-id="ion-works-bullet-enroll-content"></span></p>
|
|
||||||
<p><strong data-l10n-id="ion-works-bullet-control-title" ></strong> <span data-l10n-id="ion-works-bullet-control-content"></span></p>
|
|
||||||
</div>
|
|
||||||
<div id="data">
|
|
||||||
<h2 data-l10n-id="ion-your-data-title"></h2>
|
|
||||||
<p data-l10n-id="ion-your-data-summary"></p>
|
|
||||||
<ul>
|
|
||||||
<li data-l10n-id="ion-your-data-bullet-know"></li>
|
|
||||||
<li data-l10n-id="ion-your-data-bullet-lengths"></li>
|
|
||||||
<li data-l10n-id="ion-your-data-bullet-leave"></li>
|
|
||||||
</ul>
|
|
||||||
<p data-l10n-id="ion-your-data-learn-more">
|
|
||||||
<a data-l10n-name="privacy-policy" class="privacy-policy" href="https://support.mozilla.org/1/firefox/%VERSION%/%OS%/%LOCALE%/pioneer-managing-account-data" target="_blank"></a>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<h2 id="header-available-studies"></h2>
|
|
||||||
<div id="available-studies"></div>
|
|
||||||
<dialog id="join-ion-consent-dialog" class="modal" is="trapped-dialog">
|
|
||||||
<h3 data-l10n-id="ion-consent-notice"></h3>
|
|
||||||
<p data-l10n-id="ion-program-consent-intro"></p>
|
|
||||||
<ul id="join-ion-consent" class="consent-list">
|
|
||||||
<p data-l10n-id="ion-enroll-effective-date"></p>
|
|
||||||
<p data-l10n-id="ion-enroll-summary"></p>
|
|
||||||
<p data-l10n-id="ion-enroll-demographic"></p>
|
|
||||||
<p data-l10n-id="ion-enroll-privacy-notice">
|
|
||||||
<a data-l10n-name="privacy-notice" class="privacy-notice" href="https://www.mozilla.org/%LOCALE%/privacy/" target="_blank"></a>
|
|
||||||
</p>
|
|
||||||
<h2 data-l10n-id="ion-enroll-what-we-collect"></h2>
|
|
||||||
<p data-l10n-id="ion-enroll-collect-demographic"></p>
|
|
||||||
<p data-l10n-id="ion-enroll-technical-data"></p>
|
|
||||||
<p data-l10n-id="ion-enroll-interaction-data"></p>
|
|
||||||
<p data-l10n-id="ion-enroll-location-data"></p>
|
|
||||||
<p data-l10n-id="ion-enroll-data-disclosure">
|
|
||||||
<a data-l10n-name="privacy-policy" class="privacy-policy" href="https://support.mozilla.org/1/firefox/%VERSION%/%OS%/%LOCALE%/pioneer-managing-account-data" target="_blank"></a>
|
|
||||||
</p>
|
|
||||||
<h2 data-l10n-id="ion-enroll-how-we-use"></h2>
|
|
||||||
<p data-l10n-id="ion-enroll-r-and-d"></p>
|
|
||||||
<ul>
|
|
||||||
<li data-l10n-id="ion-enroll-bullet-criteria"></li>
|
|
||||||
<li data-l10n-id="ion-enroll-bullet-representative"></li>
|
|
||||||
<li data-l10n-id="ion-enroll-bullet-improve-existing"></li>
|
|
||||||
<li data-l10n-id="ion-enroll-bullet-create"></li>
|
|
||||||
</ul>
|
|
||||||
<h2 data-l10n-id="ion-enroll-who-we-disclose-to"></h2>
|
|
||||||
<p data-l10n-id="ion-enroll-who-we-disclose-bullet-gcp"></p>
|
|
||||||
<p data-l10n-id="ion-enroll-who-we-disclose-bullet-third-party"></p>
|
|
||||||
<p data-l10n-id="ion-enroll-who-we-disclose-bullet-public">
|
|
||||||
<a data-l10n-name="mozilla-manifesto" href="https://www.mozilla.org/about/manifesto/" target="_blank"></a>
|
|
||||||
</p>
|
|
||||||
<h2 data-l10n-id="ion-enroll-data-management"></h2>
|
|
||||||
<p data-l10n-id="ion-enroll-data-management-learn-more">
|
|
||||||
<a data-l10n-name="privacy-policy" class="privacy-policy" href="https://support.mozilla.org/1/firefox/%VERSION%/%OS%/%LOCALE%/pioneer-managing-account-data" target="_blank"></a>
|
|
||||||
<a data-l10n-name="compliance-email" href="mailto:compliance@mozilla.com"></a>
|
|
||||||
</p>
|
|
||||||
</ul>
|
|
||||||
<footer>
|
|
||||||
<button id="join-ion-accept-dialog-button" class="primary" data-l10n-id="ion-accept-participate" ></button>
|
|
||||||
<button id="join-ion-cancel-dialog-button" data-l10n-id="ion-cancel" ></button>
|
|
||||||
</footer>
|
|
||||||
</dialog>
|
|
||||||
<dialog id="leave-ion-consent-dialog" class="modal" is="trapped-dialog">
|
|
||||||
<h3 data-l10n-id="ion-leave"></h3>
|
|
||||||
<ul id="leave-ion-consent" class="consent-list"></ul>
|
|
||||||
<footer>
|
|
||||||
<button id="leave-ion-cancel-dialog-button" class="primary" data-l10n-id="ion-cancel"></button>
|
|
||||||
<button id="leave-ion-accept-dialog-button" data-l10n-id="ion-accept-leave" ></button>
|
|
||||||
</footer>
|
|
||||||
</dialog>
|
|
||||||
<dialog id="join-study-consent-dialog" class="modal" is="trapped-dialog">
|
|
||||||
<h3 data-l10n-id="ion-consent-study-notice"></h3>
|
|
||||||
<p data-l10n-id="ion-program-study-intro"></p>
|
|
||||||
<ul id="join-study-consent" class="consent-list"></ul>
|
|
||||||
<footer>
|
|
||||||
<button id="join-study-accept-dialog-button" class="primary" data-l10n-id="ion-consent-study-join"></button>
|
|
||||||
<button id="join-study-cancel-dialog-button" data-l10n-id="ion-cancel" ></button>
|
|
||||||
</footer>
|
|
||||||
</dialog>
|
|
||||||
<dialog id="leave-study-consent-dialog" class="modal" is="trapped-dialog">
|
|
||||||
<h3 data-l10n-id="ion-consent-study-title"></h3>
|
|
||||||
<ul id="leave-study-consent" class="consent-list"></ul>
|
|
||||||
<footer>
|
|
||||||
<button id="leave-study-cancel-dialog-button" class="primary" data-l10n-id="ion-cancel" ></button>
|
|
||||||
<button id="leave-study-accept-dialog-button" data-l10n-id="ion-consent-study-leave"></button>
|
|
||||||
</footer>
|
|
||||||
</dialog>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,8 +0,0 @@
|
|||||||
# 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/.
|
|
||||||
|
|
||||||
browser.jar:
|
|
||||||
content/browser/ion.html (content/ion.html)
|
|
||||||
content/browser/ion.css (content/ion.css)
|
|
||||||
content/browser/ion.js (content/ion.js)
|
|
@ -1,3 +0,0 @@
|
|||||||
[DEFAULT]
|
|
||||||
|
|
||||||
[browser_ion_ui.js]
|
|
@ -41,7 +41,7 @@ DIRS += [
|
|||||||
'migration',
|
'migration',
|
||||||
'newtab',
|
'newtab',
|
||||||
'originattributes',
|
'originattributes',
|
||||||
'ion',
|
'pioneer',
|
||||||
'places',
|
'places',
|
||||||
'pocket',
|
'pocket',
|
||||||
'preferences',
|
'preferences',
|
||||||
|
@ -143,7 +143,7 @@ details > summary {
|
|||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ion-icon {
|
#pioneer-icon {
|
||||||
-moz-context-properties: fill;
|
-moz-context-properties: fill;
|
||||||
fill: currentColor;
|
fill: currentColor;
|
||||||
}
|
}
|
76
browser/components/pioneer/content/pioneer.ftl
Normal file
76
browser/components/pioneer/content/pioneer.ftl
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
# 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/.
|
||||||
|
|
||||||
|
### This file is not in a locales directory to prevent it from
|
||||||
|
### being translated as the feature is still in heavy development
|
||||||
|
### and strings are likely to change often.
|
||||||
|
|
||||||
|
-pioneer-brand-short-name = Pioneer
|
||||||
|
pioneer = { -pioneer-brand-short-name }
|
||||||
|
pioneer-document-title = Put your data to work for a better internet
|
||||||
|
pioneer-summary = { -pioneer-brand-short-name } puts your data to work to address some of today’s most pressing technology concerns, like misinformation, data privacy, and ethical AI. The data you agree to share with Mozilla (the makers of Firefox) helps create tools for better internet transparency and design products that give control back to the people who use them. As a { -pioneer-brand-short-name } participant, you’ll also have the option to contribute your data to studies sponsored by research institutions and other organizations.
|
||||||
|
pioneer-study-prompt = Join to enroll
|
||||||
|
pioneer-join-study = Join Study
|
||||||
|
pioneer-leave-study = Leave Study
|
||||||
|
pioneer-enrollment-button = Join { -pioneer-brand-short-name }
|
||||||
|
pioneer-unenrollment-button = Leave { -pioneer-brand-short-name }
|
||||||
|
pioneer-current-studies = Current Studies
|
||||||
|
pioneer-no-current-studies = No current studies, please check back later.
|
||||||
|
pioneer-end-study = End Study
|
||||||
|
pioneer-ended-study = Study Ended
|
||||||
|
pioneer-accept-participate = Accept and Participate
|
||||||
|
pioneer-accept-leave = Accept and Leave
|
||||||
|
pioneer-cancel = Cancel
|
||||||
|
pioneer-consent-notice = { -pioneer-brand-short-name } Privacy Notice
|
||||||
|
pioneer-consent-study-notice = { -pioneer-brand-short-name } Study Privacy Consent Notice
|
||||||
|
pioneer-leave = Leaving { -pioneer-brand-short-name }
|
||||||
|
pioneer-consent-study-title = Leaving Study
|
||||||
|
pioneer-consent-study-join = Accept and Join Study
|
||||||
|
pioneer-consent-study-leave = Accept and Leave Study
|
||||||
|
|
||||||
|
pioneer-program-consent-intro = When you enroll in { -pioneer-brand-short-name }, you are sharing personal information. Keeping that information safe is important to us and to the integrity of { -pioneer-brand-short-name }. Here is how we safeguard your data and protect your identity.
|
||||||
|
|
||||||
|
pioneer-program-study-intro = When you enroll in this study, you are sharing personal information. Keeping that information safe is important to us and to the integrity of { -pioneer-brand-short-name }. Here is how we safeguard your data and protect your identity.
|
||||||
|
|
||||||
|
|
||||||
|
pioneer-works-title = How it works:
|
||||||
|
pioneer-works-bullet-get-started-title = Get started.
|
||||||
|
pioneer-works-bullet-get-started-content = Select the { pioneer-enrollment-button } button, review and agree to our Privacy Notice, and answer a few (optional) demographic questions. Note that { -pioneer-brand-short-name } is currently open to participants in the US who are 19 or older.
|
||||||
|
pioneer-works-bullet-enroll-title = Enroll in studies.
|
||||||
|
pioneer-works-bullet-enroll-content = Share your data with studies run by { -vendor-short-name } and our { -pioneer-brand-short-name } research partners. You’ll have the opportunity to learn about a study’s goals, the data it collects, and its research team before you enroll.
|
||||||
|
pioneer-works-bullet-control-title = Stay in control.
|
||||||
|
pioneer-works-bullet-control-content = The { -pioneer-brand-short-name } icon will appear on the { -brand-product-name } toolbar. Select the icon any time you want to return to this page to update your settings, enroll in a study, or leave a study or the { -pioneer-brand-short-name } program.
|
||||||
|
|
||||||
|
pioneer-your-data-title = Your data: why it matters and how we protect it
|
||||||
|
pioneer-your-data-summary = { -pioneer-brand-short-name } puts your data to work for a better internet. Our goal is to better understand topics like internet usage, online privacy, algorithmic bias, discrimination, and misinformation. This in turn can lead to new products that fundamentally change the tech landscape and hand more power and control back to users.
|
||||||
|
|
||||||
|
pioneer-your-data-bullet-know = You’ll know the information we plan to collect before we collect it. We publish our data collection documentation, so you can confirm this for yourself. Read each privacy notice for detailed information.
|
||||||
|
pioneer-your-data-bullet-lengths = We prioritize securing your data and protecting your privacy.
|
||||||
|
pioneer-your-data-bullet-leave = You can leave the { -pioneer-brand-short-name } program at any time, and we’ll stop collecting data when you do.
|
||||||
|
pioneer-your-data-learn-more = Learn more about <a data-l10n-name="privacy-policy">managing the data you share</a> with { -pioneer-brand-short-name }.
|
||||||
|
|
||||||
|
pioneer-us-only = Sorry, { -pioneer-brand-short-name } is currently only open to participants in the US.
|
||||||
|
|
||||||
|
pioneer-enroll-effective-date = Effective September 1, 2020
|
||||||
|
pioneer-enroll-summary = { -pioneer-brand-short-name } is an experimental initiative led by Mozilla to better understand how our users use and navigate the internet. { -pioneer-brand-short-name } is available to Firefox users in the United States who are 19 or older.
|
||||||
|
pioneer-enroll-demographic = When you join { -pioneer-brand-short-name }, we’ll ask you to provide optional demographic data. We’ll also collect basic technical and interaction data as long as you’re participating in { -pioneer-brand-short-name }. Once you’ve enrolled, you’ll have the opportunity to join available studies—each study will have a specific research purpose and unique privacy notice for you to review before you join it.
|
||||||
|
pioneer-enroll-privacy-notice = In this Privacy Notice, we detail what data the { -pioneer-brand-short-name } program collects and discloses, and why. Read each study’s privacy notice for information about how data is collected and handled in that particular study. We also adhere to the <a data-l10n-name="privacy-notice">Mozilla Privacy Policy</a> for how we receive, handle, and share information.
|
||||||
|
pioneer-enroll-data-disclosure = To see a full list of the data we collect, click <a data-l10n-name="privacy-policy">here</a>.
|
||||||
|
pioneer-enroll-what-we-collect = What Information We Collect:
|
||||||
|
pioneer-enroll-collect-demographic = <strong>Demographic data:</strong> We collect optional, self-reported demographic data from { -pioneer-brand-short-name } participants, including their age, gender, race/ethnicity, education level, household income, and zip code.
|
||||||
|
pioneer-enroll-technical-data = <strong>Technical data:</strong> We collect basic information about your device’s operating system. When Firefox sends data to us, your IP address is temporarily collected as part of our server logs.
|
||||||
|
pioneer-enroll-interaction-data = <strong>Interaction data:</strong> We collect data about your interactions with Firefox, like number and type of installed Firefox Add-ons and your active browsing session duration.
|
||||||
|
pioneer-enroll-location-data = <strong>Location data:</strong> We will use your IP address to approximate your country location, in addition to collecting your self-reported zip code (if you provide it).
|
||||||
|
pioneer-enroll-how-we-use = How We Use Your Information:
|
||||||
|
pioneer-enroll-r-and-d = We use the information we collect for for <strong>research and development</strong>, including:
|
||||||
|
pioneer-enroll-bullet-criteria = To determine which participants meet the criteria to be available to participate in particular research studies
|
||||||
|
pioneer-enroll-bullet-representative = To ensure our data sets are representative of the many users of Firefox
|
||||||
|
pioneer-enroll-bullet-improve-existing = To improve our existing products and services
|
||||||
|
pioneer-enroll-bullet-create = To create and develop new products
|
||||||
|
pioneer-enroll-who-we-disclose-to = Who We May Disclose Information To:
|
||||||
|
pioneer-enroll-who-we-disclose-bullet-gcp = <strong>Google Cloud Platform (GCP):</strong> We use GCP as our cloud-storage service. Mozilla has contracted with GCP requiring them to handle the data in ways that are approved by us.
|
||||||
|
pioneer-enroll-who-we-disclose-bullet-third-party = <strong>Third-party researchers:</strong> As part of being part of the { -pioneer-brand-short-name } program, we will offer you the ability to join studies. If necessary for the study, we may ask you to share all or some of the data collected under this Privacy Notice with the third party researcher(s) administering a study. Mozilla will contractually obligate the third party researchers to ensure that your data is handled in ways that are approved by us.
|
||||||
|
pioneer-enroll-who-we-disclose-bullet-public = <strong>General public:</strong> To advance our <a data-l10n-name="mozilla-manifesto">mission of being open</a>, we may release data sets to the general public. When we do so, we will aggregate the data and remove identifying information, so the data won’t reveal the behaviors or characteristics of individual users.
|
||||||
|
pioneer-enroll-data-management = Data Management:
|
||||||
|
pioneer-enroll-data-management-learn-more = You can learn more about managing your { -pioneer-brand-short-name } and individual study data <a data-l10n-name="privacy-policy">here</a>. If you have any other questions regarding our privacy practices, please contact us at <a data-l10n-name="compliance-email">compliance@mozilla.com</a>.
|
119
browser/components/pioneer/content/pioneer.html
Normal file
119
browser/components/pioneer/content/pioneer.html
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
<!-- 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/. -->
|
||||||
|
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="Content-Security-Policy" content="default-src chrome: blob:; img-src https:; object-src 'none'">
|
||||||
|
<link rel="localization" href="browser/branding/brandings.ftl">
|
||||||
|
<link rel="localization" href="branding/brand.ftl">
|
||||||
|
<!-- Temporary "en-US"-only l10n strings -->
|
||||||
|
<link rel="localization" href="preview/pioneer.ftl">
|
||||||
|
<link rel="stylesheet" href="chrome://global/skin/in-content/common.css">
|
||||||
|
<link rel="stylesheet" href="chrome://browser/content/pioneer.css">
|
||||||
|
<script src="chrome://browser/content/pioneer.js"></script>
|
||||||
|
<link rel="icon" href="chrome://browser/skin/pioneer.svg">
|
||||||
|
<title data-l10n-id="pioneer"></title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div id="locale-notification" data-l10n-id="pioneer-us-only"></div>
|
||||||
|
<div id="report-content">
|
||||||
|
<header>
|
||||||
|
<h1 id="title" data-l10n-id="pioneer-document-title"></h1>
|
||||||
|
<button id="enrollment-button" class="primary"></button>
|
||||||
|
</header>
|
||||||
|
<div id="summary" data-l10n-id="pioneer-summary"></div>
|
||||||
|
<div id="details">
|
||||||
|
<h2 data-l10n-id="pioneer-works-title"></h2>
|
||||||
|
<p><strong data-l10n-id="pioneer-works-bullet-get-started-title" ></strong> <span data-l10n-id="pioneer-works-bullet-get-started-content"></span></p>
|
||||||
|
<p><strong data-l10n-id="pioneer-works-bullet-enroll-title" ></strong> <span data-l10n-id="pioneer-works-bullet-enroll-content"></span></p>
|
||||||
|
<p><strong data-l10n-id="pioneer-works-bullet-control-title" ></strong> <span data-l10n-id="pioneer-works-bullet-control-content"></span></p>
|
||||||
|
</div>
|
||||||
|
<div id="data">
|
||||||
|
<h2 data-l10n-id="pioneer-your-data-title"></h2>
|
||||||
|
<p data-l10n-id="pioneer-your-data-summary"></p>
|
||||||
|
<ul>
|
||||||
|
<li data-l10n-id="pioneer-your-data-bullet-know"></li>
|
||||||
|
<li data-l10n-id="pioneer-your-data-bullet-lengths"></li>
|
||||||
|
<li data-l10n-id="pioneer-your-data-bullet-leave"></li>
|
||||||
|
</ul>
|
||||||
|
<p data-l10n-id="pioneer-your-data-learn-more">
|
||||||
|
<a data-l10n-name="privacy-policy" class="privacy-policy" href="https://support.mozilla.org/1/firefox/%VERSION%/%OS%/%LOCALE%/pioneer-managing-account-data" target="_blank"></a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<h2 id="header-available-studies"></h2>
|
||||||
|
<div id="available-studies"></div>
|
||||||
|
<dialog id="join-pioneer-consent-dialog" class="modal" is="trapped-dialog">
|
||||||
|
<h3 data-l10n-id="pioneer-consent-notice"></h3>
|
||||||
|
<p data-l10n-id="pioneer-program-consent-intro"></p>
|
||||||
|
<ul id="join-pioneer-consent" class="consent-list">
|
||||||
|
<p data-l10n-id="pioneer-enroll-effective-date"></p>
|
||||||
|
<p data-l10n-id="pioneer-enroll-summary"></p>
|
||||||
|
<p data-l10n-id="pioneer-enroll-demographic"></p>
|
||||||
|
<p data-l10n-id="pioneer-enroll-privacy-notice">
|
||||||
|
<a data-l10n-name="privacy-notice" class="privacy-notice" href="https://www.mozilla.org/%LOCALE%/privacy/" target="_blank"></a>
|
||||||
|
</p>
|
||||||
|
<h2 data-l10n-id="pioneer-enroll-what-we-collect"></h2>
|
||||||
|
<p data-l10n-id="pioneer-enroll-collect-demographic"></p>
|
||||||
|
<p data-l10n-id="pioneer-enroll-technical-data"></p>
|
||||||
|
<p data-l10n-id="pioneer-enroll-interaction-data"></p>
|
||||||
|
<p data-l10n-id="pioneer-enroll-location-data"></p>
|
||||||
|
<p data-l10n-id="pioneer-enroll-data-disclosure">
|
||||||
|
<a data-l10n-name="privacy-policy" class="privacy-policy" href="https://support.mozilla.org/1/firefox/%VERSION%/%OS%/%LOCALE%/pioneer-managing-account-data" target="_blank"></a>
|
||||||
|
</p>
|
||||||
|
<h2 data-l10n-id="pioneer-enroll-how-we-use"></h2>
|
||||||
|
<p data-l10n-id="pioneer-enroll-r-and-d"></p>
|
||||||
|
<ul>
|
||||||
|
<li data-l10n-id="pioneer-enroll-bullet-criteria"></li>
|
||||||
|
<li data-l10n-id="pioneer-enroll-bullet-representative"></li>
|
||||||
|
<li data-l10n-id="pioneer-enroll-bullet-improve-existing"></li>
|
||||||
|
<li data-l10n-id="pioneer-enroll-bullet-create"></li>
|
||||||
|
</ul>
|
||||||
|
<h2 data-l10n-id="pioneer-enroll-who-we-disclose-to"></h2>
|
||||||
|
<p data-l10n-id="pioneer-enroll-who-we-disclose-bullet-gcp"></p>
|
||||||
|
<p data-l10n-id="pioneer-enroll-who-we-disclose-bullet-third-party"></p>
|
||||||
|
<p data-l10n-id="pioneer-enroll-who-we-disclose-bullet-public">
|
||||||
|
<a data-l10n-name="mozilla-manifesto" href="https://www.mozilla.org/about/manifesto/" target="_blank"></a>
|
||||||
|
</p>
|
||||||
|
<h2 data-l10n-id="pioneer-enroll-data-management"></h2>
|
||||||
|
<p data-l10n-id="pioneer-enroll-data-management-learn-more">
|
||||||
|
<a data-l10n-name="privacy-policy" class="privacy-policy" href="https://support.mozilla.org/1/firefox/%VERSION%/%OS%/%LOCALE%/pioneer-managing-account-data" target="_blank"></a>
|
||||||
|
<a data-l10n-name="compliance-email" href="mailto:compliance@mozilla.com"></a>
|
||||||
|
</p>
|
||||||
|
</ul>
|
||||||
|
<footer>
|
||||||
|
<button id="join-pioneer-accept-dialog-button" class="primary" data-l10n-id="pioneer-accept-participate" ></button>
|
||||||
|
<button id="join-pioneer-cancel-dialog-button" data-l10n-id="pioneer-cancel" ></button>
|
||||||
|
</footer>
|
||||||
|
</dialog>
|
||||||
|
<dialog id="leave-pioneer-consent-dialog" class="modal" is="trapped-dialog">
|
||||||
|
<h3 data-l10n-id="pioneer-leave"></h3>
|
||||||
|
<ul id="leave-pioneer-consent" class="consent-list"></ul>
|
||||||
|
<footer>
|
||||||
|
<button id="leave-pioneer-cancel-dialog-button" class="primary" data-l10n-id="pioneer-cancel"></button>
|
||||||
|
<button id="leave-pioneer-accept-dialog-button" data-l10n-id="pioneer-accept-leave" ></button>
|
||||||
|
</footer>
|
||||||
|
</dialog>
|
||||||
|
<dialog id="join-study-consent-dialog" class="modal" is="trapped-dialog">
|
||||||
|
<h3 data-l10n-id="pioneer-consent-study-notice"></h3>
|
||||||
|
<p data-l10n-id="pioneer-program-study-intro"></p>
|
||||||
|
<ul id="join-study-consent" class="consent-list"></ul>
|
||||||
|
<footer>
|
||||||
|
<button id="join-study-accept-dialog-button" class="primary" data-l10n-id="pioneer-consent-study-join"></button>
|
||||||
|
<button id="join-study-cancel-dialog-button" data-l10n-id="pioneer-cancel" ></button>
|
||||||
|
</footer>
|
||||||
|
</dialog>
|
||||||
|
<dialog id="leave-study-consent-dialog" class="modal" is="trapped-dialog">
|
||||||
|
<h3 data-l10n-id="pioneer-consent-study-title"></h3>
|
||||||
|
<ul id="leave-study-consent" class="consent-list"></ul>
|
||||||
|
<footer>
|
||||||
|
<button id="leave-study-cancel-dialog-button" class="primary" data-l10n-id="pioneer-cancel" ></button>
|
||||||
|
<button id="leave-study-accept-dialog-button" data-l10n-id="pioneer-consent-study-leave"></button>
|
||||||
|
</footer>
|
||||||
|
</dialog>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -2,15 +2,6 @@
|
|||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* 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/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
/**
|
|
||||||
* Control panel for the Ion project, formerly known as Pioneer.
|
|
||||||
* This lives in `about:ion` and provides a UI for users to un/enroll in the
|
|
||||||
* overall program, and to un/enroll from individual studies.
|
|
||||||
*
|
|
||||||
* NOTE - prefs and Telemetry both still mention Pioneer for backwards-compatibility,
|
|
||||||
* this may change in the future.
|
|
||||||
*/
|
|
||||||
|
|
||||||
const { AddonManager } = ChromeUtils.import(
|
const { AddonManager } = ChromeUtils.import(
|
||||||
"resource://gre/modules/AddonManager.jsm"
|
"resource://gre/modules/AddonManager.jsm"
|
||||||
);
|
);
|
||||||
@ -25,10 +16,10 @@ const { TelemetryController } = ChromeUtils.import(
|
|||||||
|
|
||||||
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||||
|
|
||||||
const PREF_ION_ID = "toolkit.telemetry.pioneerId";
|
const PREF_PIONEER_ID = "toolkit.telemetry.pioneerId";
|
||||||
const PREF_ION_NEW_STUDIES_AVAILABLE =
|
const PREF_PIONEER_NEW_STUDIES_AVAILABLE =
|
||||||
"toolkit.telemetry.pioneer-new-studies-available";
|
"toolkit.telemetry.pioneer-new-studies-available";
|
||||||
const PREF_ION_COMPLETED_STUDIES =
|
const PREF_PIONEER_COMPLETED_STUDIES =
|
||||||
"toolkit.telemetry.pioneer-completed-studies";
|
"toolkit.telemetry.pioneer-completed-studies";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -47,15 +38,15 @@ const PREF_TEST_CACHED_ADDONS = "toolkit.pioneer.testCachedAddons";
|
|||||||
const PREF_TEST_ADDONS = "toolkit.pioneer.testAddons";
|
const PREF_TEST_ADDONS = "toolkit.pioneer.testAddons";
|
||||||
|
|
||||||
function showEnrollmentStatus() {
|
function showEnrollmentStatus() {
|
||||||
const ionId = Services.prefs.getStringPref(PREF_ION_ID, null);
|
const pioneerId = Services.prefs.getStringPref(PREF_PIONEER_ID, null);
|
||||||
|
|
||||||
const enrollmentButton = document.getElementById("enrollment-button");
|
const enrollmentButton = document.getElementById("enrollment-button");
|
||||||
|
|
||||||
document.l10n.setAttributes(
|
document.l10n.setAttributes(
|
||||||
enrollmentButton,
|
enrollmentButton,
|
||||||
`ion-${ionId ? "un" : ""}enrollment-button`
|
`pioneer-${pioneerId ? "un" : ""}enrollment-button`
|
||||||
);
|
);
|
||||||
enrollmentButton.classList.toggle("primary", !ionId);
|
enrollmentButton.classList.toggle("primary", !pioneerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleContentBasedOnLocale() {
|
function toggleContentBasedOnLocale() {
|
||||||
@ -111,7 +102,7 @@ async function toggleEnrolled(studyAddonId, cachedAddons) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const completedStudies = Services.prefs.getStringPref(
|
const completedStudies = Services.prefs.getStringPref(
|
||||||
PREF_ION_COMPLETED_STUDIES,
|
PREF_PIONEER_COMPLETED_STUDIES,
|
||||||
"{}"
|
"{}"
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -123,7 +114,7 @@ async function toggleEnrolled(studyAddonId, cachedAddons) {
|
|||||||
await addon.uninstall();
|
await addon.uninstall();
|
||||||
await sendDeletionPing(studyAddonId);
|
await sendDeletionPing(studyAddonId);
|
||||||
|
|
||||||
document.l10n.setAttributes(joinBtn, "ion-join-study");
|
document.l10n.setAttributes(joinBtn, "pioneer-join-study");
|
||||||
joinBtn.disabled = false;
|
joinBtn.disabled = false;
|
||||||
|
|
||||||
// Record that the user abandoned this study, since it may not be re-join-able.
|
// Record that the user abandoned this study, since it may not be re-join-able.
|
||||||
@ -131,7 +122,7 @@ async function toggleEnrolled(studyAddonId, cachedAddons) {
|
|||||||
const studies = JSON.parse(completedStudies);
|
const studies = JSON.parse(completedStudies);
|
||||||
studies[studyAddonId] = STUDY_LEAVE_REASONS.USER_ABANDONED;
|
studies[studyAddonId] = STUDY_LEAVE_REASONS.USER_ABANDONED;
|
||||||
Services.prefs.setStringPref(
|
Services.prefs.setStringPref(
|
||||||
PREF_ION_COMPLETED_STUDIES,
|
PREF_PIONEER_COMPLETED_STUDIES,
|
||||||
JSON.stringify(studies)
|
JSON.stringify(studies)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -151,7 +142,7 @@ async function toggleEnrolled(studyAddonId, cachedAddons) {
|
|||||||
}
|
}
|
||||||
joinBtn.disabled = true;
|
joinBtn.disabled = true;
|
||||||
await install.install();
|
await install.install();
|
||||||
document.l10n.setAttributes(joinBtn, "ion-leave-study");
|
document.l10n.setAttributes(joinBtn, "pioneer-leave-study");
|
||||||
joinBtn.disabled = false;
|
joinBtn.disabled = false;
|
||||||
|
|
||||||
// Send an enrollment ping for this study. Note that this could be sent again
|
// Send an enrollment ping for this study. Note that this could be sent again
|
||||||
@ -163,9 +154,9 @@ async function toggleEnrolled(studyAddonId, cachedAddons) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function showAvailableStudies(cachedAddons) {
|
async function showAvailableStudies(cachedAddons) {
|
||||||
const ionId = Services.prefs.getStringPref(PREF_ION_ID, null);
|
const pioneerId = Services.prefs.getStringPref(PREF_PIONEER_ID, null);
|
||||||
const defaultAddons = cachedAddons.filter(a => a.isDefault);
|
const defaultAddons = cachedAddons.filter(a => a.isDefault);
|
||||||
if (ionId) {
|
if (pioneerId) {
|
||||||
for (const defaultAddon of defaultAddons) {
|
for (const defaultAddon of defaultAddons) {
|
||||||
let addon;
|
let addon;
|
||||||
let install;
|
let install;
|
||||||
@ -174,7 +165,8 @@ async function showAvailableStudies(cachedAddons) {
|
|||||||
install = {
|
install = {
|
||||||
install: async () => {
|
install: async () => {
|
||||||
if (
|
if (
|
||||||
defaultAddon.addon_id == "ion-v2-bad-default-example@mozilla.org"
|
defaultAddon.addon_id ==
|
||||||
|
"pioneer-v2-bad-default-example@mozilla.org"
|
||||||
) {
|
) {
|
||||||
throw new Error("Bad test default add-on");
|
throw new Error("Bad test default add-on");
|
||||||
}
|
}
|
||||||
@ -198,7 +190,7 @@ async function showAvailableStudies(cachedAddons) {
|
|||||||
for (const cachedAddon of studyAddons) {
|
for (const cachedAddon of studyAddons) {
|
||||||
if (!cachedAddon) {
|
if (!cachedAddon) {
|
||||||
console.error(
|
console.error(
|
||||||
`about:ion - Study addon ID not found in cache: ${studyAddonId}`
|
`about:pioneer - Study addon ID not found in cache: ${studyAddonId}`
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -238,7 +230,7 @@ async function showAvailableStudies(cachedAddons) {
|
|||||||
joinBtn.setAttribute("id", `${studyAddonId}-join-button`);
|
joinBtn.setAttribute("id", `${studyAddonId}-join-button`);
|
||||||
joinBtn.classList.add("primary");
|
joinBtn.classList.add("primary");
|
||||||
joinBtn.classList.add("join-button");
|
joinBtn.classList.add("join-button");
|
||||||
document.l10n.setAttributes(joinBtn, "ion-join-study");
|
document.l10n.setAttributes(joinBtn, "pioneer-join-study");
|
||||||
|
|
||||||
joinBtn.addEventListener("click", async () => {
|
joinBtn.addEventListener("click", async () => {
|
||||||
let addon;
|
let addon;
|
||||||
@ -327,7 +319,7 @@ async function showAvailableStudies(cachedAddons) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const availableStudies = document.getElementById("header-available-studies");
|
const availableStudies = document.getElementById("header-available-studies");
|
||||||
document.l10n.setAttributes(availableStudies, "ion-current-studies");
|
document.l10n.setAttributes(availableStudies, "pioneer-current-studies");
|
||||||
}
|
}
|
||||||
|
|
||||||
async function updateStudy(studyAddonId) {
|
async function updateStudy(studyAddonId) {
|
||||||
@ -349,10 +341,10 @@ async function updateStudy(studyAddonId) {
|
|||||||
|
|
||||||
const joinBtn = study.querySelector(".join-button");
|
const joinBtn = study.querySelector(".join-button");
|
||||||
|
|
||||||
const ionId = Services.prefs.getStringPref(PREF_ION_ID, null);
|
const pioneerId = Services.prefs.getStringPref(PREF_PIONEER_ID, null);
|
||||||
|
|
||||||
const completedStudies = Services.prefs.getStringPref(
|
const completedStudies = Services.prefs.getStringPref(
|
||||||
PREF_ION_COMPLETED_STUDIES,
|
PREF_PIONEER_COMPLETED_STUDIES,
|
||||||
"{}"
|
"{}"
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -360,21 +352,21 @@ async function updateStudy(studyAddonId) {
|
|||||||
if (studyAddonId in studies) {
|
if (studyAddonId in studies) {
|
||||||
study.style.opacity = 0.5;
|
study.style.opacity = 0.5;
|
||||||
joinBtn.disabled = true;
|
joinBtn.disabled = true;
|
||||||
document.l10n.setAttributes(joinBtn, "ion-ended-study");
|
document.l10n.setAttributes(joinBtn, "pioneer-ended-study");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ionId) {
|
if (pioneerId) {
|
||||||
study.style.opacity = 1;
|
study.style.opacity = 1;
|
||||||
joinBtn.disabled = false;
|
joinBtn.disabled = false;
|
||||||
|
|
||||||
if (addon) {
|
if (addon) {
|
||||||
document.l10n.setAttributes(joinBtn, "ion-leave-study");
|
document.l10n.setAttributes(joinBtn, "pioneer-leave-study");
|
||||||
} else {
|
} else {
|
||||||
document.l10n.setAttributes(joinBtn, "ion-join-study");
|
document.l10n.setAttributes(joinBtn, "pioneer-join-study");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
document.l10n.setAttributes(joinBtn, "ion-study-prompt");
|
document.l10n.setAttributes(joinBtn, "pioneer-study-prompt");
|
||||||
study.style.opacity = 0.5;
|
study.style.opacity = 0.5;
|
||||||
joinBtn.disabled = true;
|
joinBtn.disabled = true;
|
||||||
}
|
}
|
||||||
@ -394,28 +386,28 @@ async function setup(cachedAddons) {
|
|||||||
document
|
document
|
||||||
.getElementById("enrollment-button")
|
.getElementById("enrollment-button")
|
||||||
.addEventListener("click", async () => {
|
.addEventListener("click", async () => {
|
||||||
const ionId = Services.prefs.getStringPref(PREF_ION_ID, null);
|
const pioneerId = Services.prefs.getStringPref(PREF_PIONEER_ID, null);
|
||||||
|
|
||||||
if (ionId) {
|
if (pioneerId) {
|
||||||
let dialog = document.getElementById("leave-ion-consent-dialog");
|
let dialog = document.getElementById("leave-pioneer-consent-dialog");
|
||||||
dialog.showModal();
|
dialog.showModal();
|
||||||
dialog.scrollTop = 0;
|
dialog.scrollTop = 0;
|
||||||
} else {
|
} else {
|
||||||
let dialog = document.getElementById("join-ion-consent-dialog");
|
let dialog = document.getElementById("join-pioneer-consent-dialog");
|
||||||
dialog.showModal();
|
dialog.showModal();
|
||||||
dialog.scrollTop = 0;
|
dialog.scrollTop = 0;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
document
|
document
|
||||||
.getElementById("join-ion-cancel-dialog-button")
|
.getElementById("join-pioneer-cancel-dialog-button")
|
||||||
.addEventListener("click", () =>
|
.addEventListener("click", () =>
|
||||||
document.getElementById("join-ion-consent-dialog").close()
|
document.getElementById("join-pioneer-consent-dialog").close()
|
||||||
);
|
);
|
||||||
document
|
document
|
||||||
.getElementById("leave-ion-cancel-dialog-button")
|
.getElementById("leave-pioneer-cancel-dialog-button")
|
||||||
.addEventListener("click", () =>
|
.addEventListener("click", () =>
|
||||||
document.getElementById("leave-ion-consent-dialog").close()
|
document.getElementById("leave-pioneer-consent-dialog").close()
|
||||||
);
|
);
|
||||||
document
|
document
|
||||||
.getElementById("join-study-cancel-dialog-button")
|
.getElementById("join-study-cancel-dialog-button")
|
||||||
@ -429,13 +421,13 @@ async function setup(cachedAddons) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
document
|
document
|
||||||
.getElementById("join-ion-accept-dialog-button")
|
.getElementById("join-pioneer-accept-dialog-button")
|
||||||
.addEventListener("click", async event => {
|
.addEventListener("click", async event => {
|
||||||
const ionId = Services.prefs.getStringPref(PREF_ION_ID, null);
|
const pioneerId = Services.prefs.getStringPref(PREF_PIONEER_ID, null);
|
||||||
|
|
||||||
if (!ionId) {
|
if (!pioneerId) {
|
||||||
let uuid = generateUUID();
|
let uuid = generateUUID();
|
||||||
Services.prefs.setStringPref(PREF_ION_ID, uuid);
|
Services.prefs.setStringPref(PREF_PIONEER_ID, uuid);
|
||||||
for (const cachedAddon of cachedAddons) {
|
for (const cachedAddon of cachedAddons) {
|
||||||
if (cachedAddon.isDefault) {
|
if (cachedAddon.isDefault) {
|
||||||
let install;
|
let install;
|
||||||
@ -444,7 +436,7 @@ async function setup(cachedAddons) {
|
|||||||
install: async () => {
|
install: async () => {
|
||||||
if (
|
if (
|
||||||
cachedAddon.addon_id ==
|
cachedAddon.addon_id ==
|
||||||
"ion-v2-bad-default-example@mozilla.org"
|
"pioneer-v2-bad-default-example@mozilla.org"
|
||||||
) {
|
) {
|
||||||
throw new Error("Bad test default add-on");
|
throw new Error("Bad test default add-on");
|
||||||
}
|
}
|
||||||
@ -468,7 +460,7 @@ async function setup(cachedAddons) {
|
|||||||
);
|
);
|
||||||
document.l10n.setAttributes(
|
document.l10n.setAttributes(
|
||||||
availableStudies,
|
availableStudies,
|
||||||
"ion-no-current-studies"
|
"pioneer-no-current-studies"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -479,7 +471,7 @@ async function setup(cachedAddons) {
|
|||||||
}
|
}
|
||||||
document.querySelector("dialog").close();
|
document.querySelector("dialog").close();
|
||||||
}
|
}
|
||||||
// A this point we should have a valid ion id, so we should be able to send
|
// A this point we should have a valid pioneer id, so we should be able to send
|
||||||
// the enrollment ping.
|
// the enrollment ping.
|
||||||
await sendEnrollmentPing();
|
await sendEnrollmentPing();
|
||||||
|
|
||||||
@ -487,10 +479,10 @@ async function setup(cachedAddons) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
document
|
document
|
||||||
.getElementById("leave-ion-accept-dialog-button")
|
.getElementById("leave-pioneer-accept-dialog-button")
|
||||||
.addEventListener("click", async event => {
|
.addEventListener("click", async event => {
|
||||||
const completedStudies = Services.prefs.getStringPref(
|
const completedStudies = Services.prefs.getStringPref(
|
||||||
PREF_ION_COMPLETED_STUDIES,
|
PREF_PIONEER_COMPLETED_STUDIES,
|
||||||
"{}"
|
"{}"
|
||||||
);
|
);
|
||||||
const studies = JSON.parse(completedStudies);
|
const studies = JSON.parse(completedStudies);
|
||||||
@ -500,7 +492,7 @@ async function setup(cachedAddons) {
|
|||||||
await sendDeletionPing(studyAddonId);
|
await sendDeletionPing(studyAddonId);
|
||||||
}
|
}
|
||||||
|
|
||||||
Services.prefs.clearUserPref(PREF_ION_COMPLETED_STUDIES);
|
Services.prefs.clearUserPref(PREF_PIONEER_COMPLETED_STUDIES);
|
||||||
|
|
||||||
for (const cachedAddon of cachedAddons) {
|
for (const cachedAddon of cachedAddons) {
|
||||||
// Record any studies that have been marked as concluded on the server, in case they re-enroll.
|
// Record any studies that have been marked as concluded on the server, in case they re-enroll.
|
||||||
@ -508,7 +500,7 @@ async function setup(cachedAddons) {
|
|||||||
studies[cachedAddon.addon_id] = STUDY_LEAVE_REASONS.STUDY_ENDED;
|
studies[cachedAddon.addon_id] = STUDY_LEAVE_REASONS.STUDY_ENDED;
|
||||||
|
|
||||||
Services.prefs.setStringPref(
|
Services.prefs.setStringPref(
|
||||||
PREF_ION_COMPLETED_STUDIES,
|
PREF_PIONEER_COMPLETED_STUDIES,
|
||||||
JSON.stringify(studies)
|
JSON.stringify(studies)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -540,7 +532,7 @@ async function setup(cachedAddons) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Services.prefs.clearUserPref(PREF_ION_ID);
|
Services.prefs.clearUserPref(PREF_PIONEER_ID);
|
||||||
for (const cachedAddon of cachedAddons) {
|
for (const cachedAddon of cachedAddons) {
|
||||||
const study = document.getElementById(cachedAddon.addon_id);
|
const study = document.getElementById(cachedAddon.addon_id);
|
||||||
if (study) {
|
if (study) {
|
||||||
@ -548,7 +540,7 @@ async function setup(cachedAddons) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
document.getElementById("leave-ion-consent-dialog").close();
|
document.getElementById("leave-pioneer-consent-dialog").close();
|
||||||
showEnrollmentStatus();
|
showEnrollmentStatus();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -590,19 +582,23 @@ async function setup(cachedAddons) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function removeBadge() {
|
function removeBadge() {
|
||||||
Services.prefs.setBoolPref(PREF_ION_NEW_STUDIES_AVAILABLE, false);
|
Services.prefs.setBoolPref(PREF_PIONEER_NEW_STUDIES_AVAILABLE, false);
|
||||||
|
|
||||||
for (let win of Services.wm.getEnumerator("navigator:browser")) {
|
for (let win of Services.wm.getEnumerator("navigator:browser")) {
|
||||||
const badge = win.document
|
const badge = win.document
|
||||||
.getElementById("ion-button")
|
.getElementById("pioneer-button")
|
||||||
.querySelector(".toolbarbutton-badge");
|
.querySelector(".toolbarbutton-badge");
|
||||||
badge.classList.remove("feature-callout");
|
badge.classList.remove("feature-callout");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Updates Ion HTML page contents from RemoteSettings.
|
// Updates Pioneer HTML page contents from RemoteSettings.
|
||||||
function updateContents(contents) {
|
function updateContents(contents) {
|
||||||
for (const section of ["title", "joinIonConsent", "leaveIonConsent"]) {
|
for (const section of [
|
||||||
|
"title",
|
||||||
|
"joinPioneerConsent",
|
||||||
|
"leavePioneerConsent",
|
||||||
|
]) {
|
||||||
if (contents && section in contents) {
|
if (contents && section in contents) {
|
||||||
// Generate a corresponding dom-id style ID for a camel-case domId style JS attribute.
|
// Generate a corresponding dom-id style ID for a camel-case domId style JS attribute.
|
||||||
// Dynamically set the tag type based on which section is getting updated.
|
// Dynamically set the tag type based on which section is getting updated.
|
||||||
@ -688,14 +684,14 @@ document.addEventListener("DOMContentLoaded", async domEvent => {
|
|||||||
// Record any studies that have been marked as concluded on the server.
|
// Record any studies that have been marked as concluded on the server.
|
||||||
if ("studyEnded" in cachedAddon && cachedAddon.studyEnded === true) {
|
if ("studyEnded" in cachedAddon && cachedAddon.studyEnded === true) {
|
||||||
const completedStudies = Services.prefs.getStringPref(
|
const completedStudies = Services.prefs.getStringPref(
|
||||||
PREF_ION_COMPLETED_STUDIES,
|
PREF_PIONEER_COMPLETED_STUDIES,
|
||||||
"{}"
|
"{}"
|
||||||
);
|
);
|
||||||
const studies = JSON.parse(completedStudies);
|
const studies = JSON.parse(completedStudies);
|
||||||
studies[cachedAddon.addon_id] = STUDY_LEAVE_REASONS.STUDY_ENDED;
|
studies[cachedAddon.addon_id] = STUDY_LEAVE_REASONS.STUDY_ENDED;
|
||||||
|
|
||||||
Services.prefs.setStringPref(
|
Services.prefs.setStringPref(
|
||||||
PREF_ION_COMPLETED_STUDIES,
|
PREF_PIONEER_COMPLETED_STUDIES,
|
||||||
JSON.stringify(studies)
|
JSON.stringify(studies)
|
||||||
);
|
);
|
||||||
}
|
}
|
8
browser/components/pioneer/jar.mn
Normal file
8
browser/components/pioneer/jar.mn
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# 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/.
|
||||||
|
|
||||||
|
browser.jar:
|
||||||
|
content/browser/pioneer.html (content/pioneer.html)
|
||||||
|
content/browser/pioneer.css (content/pioneer.css)
|
||||||
|
content/browser/pioneer.js (content/pioneer.js)
|
@ -12,6 +12,6 @@ with Files('**'):
|
|||||||
BUG_COMPONENT = ('Firefox', 'General')
|
BUG_COMPONENT = ('Firefox', 'General')
|
||||||
|
|
||||||
TESTING_JS_MODULES += [
|
TESTING_JS_MODULES += [
|
||||||
'schemas/IonContentSchema.json',
|
'schemas/PioneerContentSchema.json',
|
||||||
'schemas/IonStudyAddonsSchema.json',
|
'schemas/PioneerStudyAddonsSchema.json',
|
||||||
]
|
]
|
@ -6,8 +6,8 @@
|
|||||||
"title",
|
"title",
|
||||||
"summary",
|
"summary",
|
||||||
"details",
|
"details",
|
||||||
"joinIonConsent",
|
"joinPioneerConsent",
|
||||||
"leaveIonConsent",
|
"leavePioneerConsent",
|
||||||
"privacyPolicy"
|
"privacyPolicy"
|
||||||
],
|
],
|
||||||
"properties": {
|
"properties": {
|
||||||
@ -26,14 +26,14 @@
|
|||||||
"title": "Details",
|
"title": "Details",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"joinIonConsent": {
|
"joinPioneerConsent": {
|
||||||
"$id": "#root/joinIonConsent",
|
"$id": "#root/joinPioneerConsent",
|
||||||
"title": "JoinIonconsent",
|
"title": "Joinpioneerconsent",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"leaveIonConsent": {
|
"leavePioneerConsent": {
|
||||||
"$id": "#root/leaveIonConsent",
|
"$id": "#root/leavePioneerConsent",
|
||||||
"title": "LeaveIonconsent",
|
"title": "Leavepioneerconsent",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"privacyPolicy": {
|
"privacyPolicy": {
|
3
browser/components/pioneer/test/browser/browser.ini
Normal file
3
browser/components/pioneer/test/browser/browser.ini
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
[DEFAULT]
|
||||||
|
|
||||||
|
[browser_pioneer_ui.js]
|
@ -21,10 +21,10 @@ const { TelemetryStorage } = ChromeUtils.import(
|
|||||||
const ORIG_AVAILABLE_LOCALES = Services.locale.availableLocales;
|
const ORIG_AVAILABLE_LOCALES = Services.locale.availableLocales;
|
||||||
const ORIG_REQUESTED_LOCALES = Services.locale.requestedLocales;
|
const ORIG_REQUESTED_LOCALES = Services.locale.requestedLocales;
|
||||||
|
|
||||||
const PREF_ION_ID = "toolkit.telemetry.pioneerId";
|
const PREF_PIONEER_ID = "toolkit.telemetry.pioneerId";
|
||||||
const PREF_ION_NEW_STUDIES_AVAILABLE =
|
const PREF_PIONEER_NEW_STUDIES_AVAILABLE =
|
||||||
"toolkit.telemetry.pioneer-new-studies-available";
|
"toolkit.telemetry.pioneer-new-studies-available";
|
||||||
const PREF_ION_COMPLETED_STUDIES =
|
const PREF_PIONEER_COMPLETED_STUDIES =
|
||||||
"toolkit.telemetry.pioneer-completed-studies";
|
"toolkit.telemetry.pioneer-completed-studies";
|
||||||
|
|
||||||
const PREF_TEST_CACHED_CONTENT = "toolkit.pioneer.testCachedContent";
|
const PREF_TEST_CACHED_CONTENT = "toolkit.pioneer.testCachedContent";
|
||||||
@ -36,15 +36,15 @@ const CACHED_CONTENT = [
|
|||||||
title: "test title\ntest title line 2",
|
title: "test title\ntest title line 2",
|
||||||
summary: "test summary\ntest summary line 2",
|
summary: "test summary\ntest summary line 2",
|
||||||
details: "1. test details\n2. test details line 2\n3. test details line 3",
|
details: "1. test details\n2. test details line 2\n3. test details line 3",
|
||||||
joinIonConsent: "test join consent\njoin consent line 2",
|
joinPioneerConsent: "test join consent\njoin consent line 2",
|
||||||
leaveIonConsent: "test leave consent\ntest leave consent line 2",
|
leavePioneerConsent: "test leave consent\ntest leave consent line 2",
|
||||||
privacyPolicy: "http://localhost",
|
privacyPolicy: "http://localhost",
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const CACHED_ADDONS = [
|
const CACHED_ADDONS = [
|
||||||
{
|
{
|
||||||
addon_id: "ion-v2-example@mozilla.org",
|
addon_id: "pioneer-v2-example@mozilla.org",
|
||||||
icons: {
|
icons: {
|
||||||
"32":
|
"32":
|
||||||
"https://localhost/user-media/addon_icons/2644/2644632-32.png?modified=4a64e2bc",
|
"https://localhost/user-media/addon_icons/2644/2644632-32.png?modified=4a64e2bc",
|
||||||
@ -58,13 +58,13 @@ const CACHED_ADDONS = [
|
|||||||
sourceURI: {
|
sourceURI: {
|
||||||
spec: "https://localhost",
|
spec: "https://localhost",
|
||||||
},
|
},
|
||||||
description: "Study purpose: Testing Ion.",
|
description: "Study purpose: Testing Pioneer.",
|
||||||
privacyPolicy: {
|
privacyPolicy: {
|
||||||
spec: "http://localhost",
|
spec: "http://localhost",
|
||||||
},
|
},
|
||||||
studyType: "extension",
|
studyType: "extension",
|
||||||
authors: {
|
authors: {
|
||||||
name: "Ion Developers",
|
name: "Pioneer Developers",
|
||||||
url: "https://addons.mozilla.org/en-US/firefox/user/6510522/",
|
url: "https://addons.mozilla.org/en-US/firefox/user/6510522/",
|
||||||
},
|
},
|
||||||
dataCollectionDetails: ["test123", "test345"],
|
dataCollectionDetails: ["test123", "test345"],
|
||||||
@ -77,7 +77,7 @@ const CACHED_ADDONS = [
|
|||||||
leaveStudyConsent: "test345",
|
leaveStudyConsent: "test345",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
addon_id: "ion-v2-default-example@mozilla.org",
|
addon_id: "pioneer-v2-default-example@mozilla.org",
|
||||||
icons: {
|
icons: {
|
||||||
"32":
|
"32":
|
||||||
"https://localhost/user-media/addon_icons/2644/2644632-32.png?modified=4a64e2bc",
|
"https://localhost/user-media/addon_icons/2644/2644632-32.png?modified=4a64e2bc",
|
||||||
@ -91,13 +91,13 @@ const CACHED_ADDONS = [
|
|||||||
sourceURI: {
|
sourceURI: {
|
||||||
spec: "https://localhost",
|
spec: "https://localhost",
|
||||||
},
|
},
|
||||||
description: "Study purpose: Testing Ion.",
|
description: "Study purpose: Testing Pioneer.",
|
||||||
privacyPolicy: {
|
privacyPolicy: {
|
||||||
spec: "http://localhost",
|
spec: "http://localhost",
|
||||||
},
|
},
|
||||||
studyType: "extension",
|
studyType: "extension",
|
||||||
authors: {
|
authors: {
|
||||||
name: "Ion Developers",
|
name: "Pioneer Developers",
|
||||||
url: "https://addons.mozilla.org/en-US/firefox/user/6510522/",
|
url: "https://addons.mozilla.org/en-US/firefox/user/6510522/",
|
||||||
},
|
},
|
||||||
dataCollectionDetails: ["test123", "test345"],
|
dataCollectionDetails: ["test123", "test345"],
|
||||||
@ -124,7 +124,7 @@ const CACHED_ADDONS = [
|
|||||||
sourceURI: {
|
sourceURI: {
|
||||||
spec: "https://localhost",
|
spec: "https://localhost",
|
||||||
},
|
},
|
||||||
description: "Study purpose: Testing Ion.",
|
description: "Study purpose: Testing Pioneer.",
|
||||||
privacyPolicy: {
|
privacyPolicy: {
|
||||||
spec: "http://localhost",
|
spec: "http://localhost",
|
||||||
},
|
},
|
||||||
@ -157,7 +157,7 @@ const CACHED_ADDONS = [
|
|||||||
sourceURI: {
|
sourceURI: {
|
||||||
spec: "https://localhost",
|
spec: "https://localhost",
|
||||||
},
|
},
|
||||||
description: "Study purpose: Testing Ion.",
|
description: "Study purpose: Testing Pioneer.",
|
||||||
privacyPolicy: {
|
privacyPolicy: {
|
||||||
spec: "http://localhost",
|
spec: "http://localhost",
|
||||||
},
|
},
|
||||||
@ -179,7 +179,7 @@ const CACHED_ADDONS = [
|
|||||||
|
|
||||||
const CACHED_ADDONS_BAD_DEFAULT = [
|
const CACHED_ADDONS_BAD_DEFAULT = [
|
||||||
{
|
{
|
||||||
addon_id: "ion-v2-bad-default-example@mozilla.org",
|
addon_id: "pioneer-v2-bad-default-example@mozilla.org",
|
||||||
icons: {
|
icons: {
|
||||||
"32":
|
"32":
|
||||||
"https://localhost/user-media/addon_icons/2644/2644632-32.png?modified=4a64e2bc",
|
"https://localhost/user-media/addon_icons/2644/2644632-32.png?modified=4a64e2bc",
|
||||||
@ -193,13 +193,13 @@ const CACHED_ADDONS_BAD_DEFAULT = [
|
|||||||
sourceURI: {
|
sourceURI: {
|
||||||
spec: "https://localhost",
|
spec: "https://localhost",
|
||||||
},
|
},
|
||||||
description: "Study purpose: Testing Ion.",
|
description: "Study purpose: Testing Pioneer.",
|
||||||
privacyPolicy: {
|
privacyPolicy: {
|
||||||
spec: "http://localhost",
|
spec: "http://localhost",
|
||||||
},
|
},
|
||||||
studyType: "extension",
|
studyType: "extension",
|
||||||
authors: {
|
authors: {
|
||||||
name: "Ion Developers",
|
name: "Pioneer Developers",
|
||||||
url: "https://addons.mozilla.org/en-US/firefox/user/6510522/",
|
url: "https://addons.mozilla.org/en-US/firefox/user/6510522/",
|
||||||
},
|
},
|
||||||
dataCollectionDetails: ["test123", "test345"],
|
dataCollectionDetails: ["test123", "test345"],
|
||||||
@ -226,7 +226,7 @@ const CACHED_ADDONS_BAD_DEFAULT = [
|
|||||||
sourceURI: {
|
sourceURI: {
|
||||||
spec: "https://localhost",
|
spec: "https://localhost",
|
||||||
},
|
},
|
||||||
description: "Study purpose: Testing Ion.",
|
description: "Study purpose: Testing Pioneer.",
|
||||||
privacyPolicy: {
|
privacyPolicy: {
|
||||||
spec: "http://localhost",
|
spec: "http://localhost",
|
||||||
},
|
},
|
||||||
@ -259,7 +259,7 @@ const CACHED_ADDONS_BAD_DEFAULT = [
|
|||||||
sourceURI: {
|
sourceURI: {
|
||||||
spec: "https://localhost",
|
spec: "https://localhost",
|
||||||
},
|
},
|
||||||
description: "Study purpose: Testing Ion.",
|
description: "Study purpose: Testing Pioneer.",
|
||||||
privacyPolicy: {
|
privacyPolicy: {
|
||||||
spec: "http://localhost",
|
spec: "http://localhost",
|
||||||
},
|
},
|
||||||
@ -280,8 +280,8 @@ const CACHED_ADDONS_BAD_DEFAULT = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
const TEST_ADDONS = [
|
const TEST_ADDONS = [
|
||||||
{ id: "ion-v2-example@ion.mozilla.org" },
|
{ id: "pioneer-v2-example@pioneer.mozilla.org" },
|
||||||
{ id: "ion-v2-default-example@mozilla.org" },
|
{ id: "pioneer-v2-default-example@mozilla.org" },
|
||||||
{ id: "study@partner" },
|
{ id: "study@partner" },
|
||||||
{ id: "second-study@parnter" },
|
{ id: "second-study@parnter" },
|
||||||
];
|
];
|
||||||
@ -298,8 +298,8 @@ const clearLocale = async () => {
|
|||||||
|
|
||||||
add_task(async function testMockSchema() {
|
add_task(async function testMockSchema() {
|
||||||
for (const [schemaName, values] of [
|
for (const [schemaName, values] of [
|
||||||
["IonContentSchema", CACHED_CONTENT],
|
["PioneerContentSchema", CACHED_CONTENT],
|
||||||
["IonStudyAddonsSchema", CACHED_ADDONS],
|
["PioneerStudyAddonsSchema", CACHED_ADDONS],
|
||||||
]) {
|
]) {
|
||||||
const response = await fetch(
|
const response = await fetch(
|
||||||
`resource://testing-common/${schemaName}.json`
|
`resource://testing-common/${schemaName}.json`
|
||||||
@ -333,25 +333,27 @@ add_task(async function testBadDefaultAddon() {
|
|||||||
[PREF_TEST_ADDONS, "[]"],
|
[PREF_TEST_ADDONS, "[]"],
|
||||||
],
|
],
|
||||||
clear: [
|
clear: [
|
||||||
[PREF_ION_ID, ""],
|
[PREF_PIONEER_ID, ""],
|
||||||
[PREF_ION_COMPLETED_STUDIES, "[]"],
|
[PREF_PIONEER_COMPLETED_STUDIES, "[]"],
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
await BrowserTestUtils.withNewTab(
|
await BrowserTestUtils.withNewTab(
|
||||||
{
|
{
|
||||||
url: "about:ion",
|
url: "about:pioneer",
|
||||||
gBrowser,
|
gBrowser,
|
||||||
},
|
},
|
||||||
async function taskFn(browser) {
|
async function taskFn(browser) {
|
||||||
const beforePref = Services.prefs.getStringPref(PREF_ION_ID, null);
|
const beforePref = Services.prefs.getStringPref(PREF_PIONEER_ID, null);
|
||||||
ok(beforePref === null, "before enrollment, Ion pref is null.");
|
ok(beforePref === null, "before enrollment, Pioneer pref is null.");
|
||||||
const enrollmentButton = content.document.getElementById(
|
const enrollmentButton = content.document.getElementById(
|
||||||
"enrollment-button"
|
"enrollment-button"
|
||||||
);
|
);
|
||||||
enrollmentButton.click();
|
enrollmentButton.click();
|
||||||
|
|
||||||
const dialog = content.document.getElementById("join-ion-consent-dialog");
|
const dialog = content.document.getElementById(
|
||||||
|
"join-pioneer-consent-dialog"
|
||||||
|
);
|
||||||
ok(dialog.open, "after clicking enrollment, consent dialog is open.");
|
ok(dialog.open, "after clicking enrollment, consent dialog is open.");
|
||||||
|
|
||||||
// When a modal dialog is cancelled, the inertness for other elements
|
// When a modal dialog is cancelled, the inertness for other elements
|
||||||
@ -365,7 +367,7 @@ add_task(async function testBadDefaultAddon() {
|
|||||||
ok(dialog.open, "after retrying enrollment, consent dialog is open.");
|
ok(dialog.open, "after retrying enrollment, consent dialog is open.");
|
||||||
|
|
||||||
const acceptDialogButton = content.document.getElementById(
|
const acceptDialogButton = content.document.getElementById(
|
||||||
"join-ion-accept-dialog-button"
|
"join-pioneer-accept-dialog-button"
|
||||||
);
|
);
|
||||||
// Wait for the enrollment button to change its label to "leave", meaning
|
// Wait for the enrollment button to change its label to "leave", meaning
|
||||||
// that the policy was accepted.
|
// that the policy was accepted.
|
||||||
@ -375,14 +377,17 @@ add_task(async function testBadDefaultAddon() {
|
|||||||
);
|
);
|
||||||
acceptDialogButton.click();
|
acceptDialogButton.click();
|
||||||
|
|
||||||
const ionEnrolled = Services.prefs.getStringPref(PREF_ION_ID, null);
|
const pioneerEnrolled = Services.prefs.getStringPref(
|
||||||
ok(ionEnrolled, "after enrollment, Ion pref is set.");
|
PREF_PIONEER_ID,
|
||||||
|
null
|
||||||
|
);
|
||||||
|
ok(pioneerEnrolled, "after enrollment, Pioneer pref is set.");
|
||||||
|
|
||||||
await promiseDialogAccepted;
|
await promiseDialogAccepted;
|
||||||
ok(
|
ok(
|
||||||
document.l10n.getAttributes(enrollmentButton).id ==
|
document.l10n.getAttributes(enrollmentButton).id ==
|
||||||
"ion-unenrollment-button",
|
"pioneer-unenrollment-button",
|
||||||
"After Ion enrollment, join button is now leave button"
|
"After Pioneer enrollment, join button is now leave button"
|
||||||
);
|
);
|
||||||
|
|
||||||
const availableStudies = content.document.getElementById(
|
const availableStudies = content.document.getElementById(
|
||||||
@ -390,7 +395,7 @@ add_task(async function testBadDefaultAddon() {
|
|||||||
);
|
);
|
||||||
ok(
|
ok(
|
||||||
document.l10n.getAttributes(availableStudies).id ==
|
document.l10n.getAttributes(availableStudies).id ==
|
||||||
"ion-no-current-studies",
|
"pioneer-no-current-studies",
|
||||||
"No studies are available if default add-on install fails."
|
"No studies are available if default add-on install fails."
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -408,24 +413,24 @@ add_task(async function testAboutPage() {
|
|||||||
[PREF_TEST_ADDONS, "[]"],
|
[PREF_TEST_ADDONS, "[]"],
|
||||||
],
|
],
|
||||||
clear: [
|
clear: [
|
||||||
[PREF_ION_ID, ""],
|
[PREF_PIONEER_ID, ""],
|
||||||
[PREF_ION_COMPLETED_STUDIES, "[]"],
|
[PREF_PIONEER_COMPLETED_STUDIES, "[]"],
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
await BrowserTestUtils.withNewTab(
|
await BrowserTestUtils.withNewTab(
|
||||||
{
|
{
|
||||||
url: "about:ion",
|
url: "about:pioneer",
|
||||||
gBrowser,
|
gBrowser,
|
||||||
},
|
},
|
||||||
async function taskFn(browser) {
|
async function taskFn(browser) {
|
||||||
const beforePref = Services.prefs.getStringPref(PREF_ION_ID, null);
|
const beforePref = Services.prefs.getStringPref(PREF_PIONEER_ID, null);
|
||||||
ok(beforePref === null, "before enrollment, Ion pref is null.");
|
ok(beforePref === null, "before enrollment, Pioneer pref is null.");
|
||||||
|
|
||||||
const beforeToolbarButton = document.getElementById("ion-button");
|
const beforeToolbarButton = document.getElementById("pioneer-button");
|
||||||
ok(
|
ok(
|
||||||
beforeToolbarButton.hidden,
|
beforeToolbarButton.hidden,
|
||||||
"before enrollment, Ion toolbar button is hidden."
|
"before enrollment, Pioneer toolbar button is hidden."
|
||||||
);
|
);
|
||||||
|
|
||||||
const enrollmentButton = content.document.getElementById(
|
const enrollmentButton = content.document.getElementById(
|
||||||
@ -433,11 +438,13 @@ add_task(async function testAboutPage() {
|
|||||||
);
|
);
|
||||||
enrollmentButton.click();
|
enrollmentButton.click();
|
||||||
|
|
||||||
const dialog = content.document.getElementById("join-ion-consent-dialog");
|
const dialog = content.document.getElementById(
|
||||||
|
"join-pioneer-consent-dialog"
|
||||||
|
);
|
||||||
ok(dialog.open, "after clicking enrollment, consent dialog is open.");
|
ok(dialog.open, "after clicking enrollment, consent dialog is open.");
|
||||||
|
|
||||||
const cancelDialogButton = content.document.getElementById(
|
const cancelDialogButton = content.document.getElementById(
|
||||||
"join-ion-cancel-dialog-button"
|
"join-pioneer-cancel-dialog-button"
|
||||||
);
|
);
|
||||||
cancelDialogButton.click();
|
cancelDialogButton.click();
|
||||||
|
|
||||||
@ -447,13 +454,13 @@ add_task(async function testAboutPage() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const canceledEnrollment = Services.prefs.getStringPref(
|
const canceledEnrollment = Services.prefs.getStringPref(
|
||||||
PREF_ION_ID,
|
PREF_PIONEER_ID,
|
||||||
null
|
null
|
||||||
);
|
);
|
||||||
|
|
||||||
ok(
|
ok(
|
||||||
!canceledEnrollment,
|
!canceledEnrollment,
|
||||||
"after cancelling enrollment, Ion is not enrolled."
|
"after cancelling enrollment, Pioneer is not enrolled."
|
||||||
);
|
);
|
||||||
|
|
||||||
// When a modal dialog is cancelled, the inertness for other elements
|
// When a modal dialog is cancelled, the inertness for other elements
|
||||||
@ -467,7 +474,7 @@ add_task(async function testAboutPage() {
|
|||||||
ok(dialog.open, "after retrying enrollment, consent dialog is open.");
|
ok(dialog.open, "after retrying enrollment, consent dialog is open.");
|
||||||
|
|
||||||
const acceptDialogButton = content.document.getElementById(
|
const acceptDialogButton = content.document.getElementById(
|
||||||
"join-ion-accept-dialog-button"
|
"join-pioneer-accept-dialog-button"
|
||||||
);
|
);
|
||||||
// Wait for the enrollment button to change its label to "leave", meaning
|
// Wait for the enrollment button to change its label to "leave", meaning
|
||||||
// that the policy was accepted.
|
// that the policy was accepted.
|
||||||
@ -477,20 +484,23 @@ add_task(async function testAboutPage() {
|
|||||||
);
|
);
|
||||||
acceptDialogButton.click();
|
acceptDialogButton.click();
|
||||||
|
|
||||||
const ionEnrolled = Services.prefs.getStringPref(PREF_ION_ID, null);
|
const pioneerEnrolled = Services.prefs.getStringPref(
|
||||||
ok(ionEnrolled, "after enrollment, Ion pref is set.");
|
PREF_PIONEER_ID,
|
||||||
|
null
|
||||||
|
);
|
||||||
|
ok(pioneerEnrolled, "after enrollment, Pioneer pref is set.");
|
||||||
|
|
||||||
await promiseDialogAccepted;
|
await promiseDialogAccepted;
|
||||||
ok(
|
ok(
|
||||||
document.l10n.getAttributes(enrollmentButton).id ==
|
document.l10n.getAttributes(enrollmentButton).id ==
|
||||||
"ion-unenrollment-button",
|
"pioneer-unenrollment-button",
|
||||||
"After Ion enrollment, join button is now leave button"
|
"After Pioneer enrollment, join button is now leave button"
|
||||||
);
|
);
|
||||||
|
|
||||||
const enrolledToolbarButton = document.getElementById("ion-button");
|
const enrolledToolbarButton = document.getElementById("pioneer-button");
|
||||||
ok(
|
ok(
|
||||||
!enrolledToolbarButton.hidden,
|
!enrolledToolbarButton.hidden,
|
||||||
"after enrollment, Ion toolbar button is not hidden."
|
"after enrollment, Pioneer toolbar button is not hidden."
|
||||||
);
|
);
|
||||||
|
|
||||||
for (const cachedAddon of CACHED_ADDONS) {
|
for (const cachedAddon of CACHED_ADDONS) {
|
||||||
@ -505,7 +515,7 @@ add_task(async function testAboutPage() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const completedStudies = Services.prefs.getStringPref(
|
const completedStudies = Services.prefs.getStringPref(
|
||||||
PREF_ION_COMPLETED_STUDIES,
|
PREF_PIONEER_COMPLETED_STUDIES,
|
||||||
"{}"
|
"{}"
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -587,7 +597,7 @@ add_task(async function testAboutPage() {
|
|||||||
await promiseJoinTurnsToLeave;
|
await promiseJoinTurnsToLeave;
|
||||||
|
|
||||||
ok(
|
ok(
|
||||||
document.l10n.getAttributes(joinButton).id == "ion-leave-study",
|
document.l10n.getAttributes(joinButton).id == "pioneer-leave-study",
|
||||||
"After study enrollment, join button is now leave button"
|
"After study enrollment, join button is now leave button"
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -667,49 +677,58 @@ add_task(async function testAboutPage() {
|
|||||||
enrollmentButton.click();
|
enrollmentButton.click();
|
||||||
|
|
||||||
const cancelUnenrollmentDialogButton = content.document.getElementById(
|
const cancelUnenrollmentDialogButton = content.document.getElementById(
|
||||||
"leave-ion-cancel-dialog-button"
|
"leave-pioneer-cancel-dialog-button"
|
||||||
);
|
);
|
||||||
cancelUnenrollmentDialogButton.click();
|
cancelUnenrollmentDialogButton.click();
|
||||||
|
|
||||||
const ionStillEnrolled = Services.prefs.getStringPref(PREF_ION_ID, null);
|
const pioneerStillEnrolled = Services.prefs.getStringPref(
|
||||||
|
PREF_PIONEER_ID,
|
||||||
|
null
|
||||||
|
);
|
||||||
|
|
||||||
ok(
|
ok(
|
||||||
ionStillEnrolled,
|
pioneerStillEnrolled,
|
||||||
"after canceling unenrollment, Ion pref is still set."
|
"after canceling unenrollment, Pioneer pref is still set."
|
||||||
);
|
);
|
||||||
|
|
||||||
enrollmentButton.click();
|
enrollmentButton.click();
|
||||||
|
|
||||||
const acceptUnenrollmentDialogButton = content.document.getElementById(
|
const acceptUnenrollmentDialogButton = content.document.getElementById(
|
||||||
"leave-ion-accept-dialog-button"
|
"leave-pioneer-accept-dialog-button"
|
||||||
);
|
);
|
||||||
|
|
||||||
acceptUnenrollmentDialogButton.click();
|
acceptUnenrollmentDialogButton.click();
|
||||||
|
|
||||||
// Wait for deletion ping, uninstalls, and UI updates...
|
// Wait for deletion ping, uninstalls, and UI updates...
|
||||||
const ionUnenrolled = await new Promise((resolve, reject) => {
|
const pioneerUnenrolled = await new Promise((resolve, reject) => {
|
||||||
Services.prefs.addObserver(PREF_ION_ID, function observer(
|
Services.prefs.addObserver(PREF_PIONEER_ID, function observer(
|
||||||
subject,
|
subject,
|
||||||
topic,
|
topic,
|
||||||
data
|
data
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
const prefValue = Services.prefs.getStringPref(PREF_ION_ID, null);
|
const prefValue = Services.prefs.getStringPref(
|
||||||
Services.prefs.removeObserver(PREF_ION_ID, observer);
|
PREF_PIONEER_ID,
|
||||||
|
null
|
||||||
|
);
|
||||||
|
Services.prefs.removeObserver(PREF_PIONEER_ID, observer);
|
||||||
resolve(prefValue);
|
resolve(prefValue);
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
Services.prefs.removeObserver(PREF_ION_ID, observer);
|
Services.prefs.removeObserver(PREF_PIONEER_ID, observer);
|
||||||
reject(ex);
|
reject(ex);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
ok(!ionUnenrolled, "after accepting unenrollment, Ion pref is null.");
|
ok(
|
||||||
|
!pioneerUnenrolled,
|
||||||
|
"after accepting unenrollment, Pioneer pref is null."
|
||||||
|
);
|
||||||
|
|
||||||
const unenrolledToolbarButton = document.getElementById("ion-button");
|
const unenrolledToolbarButton = document.getElementById("pioneer-button");
|
||||||
ok(
|
ok(
|
||||||
unenrolledToolbarButton.hidden,
|
unenrolledToolbarButton.hidden,
|
||||||
"after unenrollment, Ion toolbar button is hidden."
|
"after unenrollment, Pioneer toolbar button is hidden."
|
||||||
);
|
);
|
||||||
|
|
||||||
await TelemetryStorage.testClearPendingPings();
|
await TelemetryStorage.testClearPendingPings();
|
||||||
@ -764,8 +783,8 @@ add_task(async function testEnrollmentPings() {
|
|||||||
[PREF_TEST_ADDONS, "[]"],
|
[PREF_TEST_ADDONS, "[]"],
|
||||||
],
|
],
|
||||||
clear: [
|
clear: [
|
||||||
[PREF_ION_ID, ""],
|
[PREF_PIONEER_ID, ""],
|
||||||
[PREF_ION_COMPLETED_STUDIES, "[]"],
|
[PREF_PIONEER_COMPLETED_STUDIES, "[]"],
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -774,21 +793,21 @@ add_task(async function testEnrollmentPings() {
|
|||||||
|
|
||||||
await BrowserTestUtils.withNewTab(
|
await BrowserTestUtils.withNewTab(
|
||||||
{
|
{
|
||||||
url: "about:ion",
|
url: "about:pioneer",
|
||||||
gBrowser,
|
gBrowser,
|
||||||
},
|
},
|
||||||
async function taskFn(browser) {
|
async function taskFn(browser) {
|
||||||
const beforePref = Services.prefs.getStringPref(PREF_ION_ID, null);
|
const beforePref = Services.prefs.getStringPref(PREF_PIONEER_ID, null);
|
||||||
ok(beforePref === null, "before enrollment, Ion pref is null.");
|
ok(beforePref === null, "before enrollment, Pioneer pref is null.");
|
||||||
|
|
||||||
// Enroll in ion.
|
// Enroll in pioneer.
|
||||||
const enrollmentButton = content.document.getElementById(
|
const enrollmentButton = content.document.getElementById(
|
||||||
"enrollment-button"
|
"enrollment-button"
|
||||||
);
|
);
|
||||||
enrollmentButton.click();
|
enrollmentButton.click();
|
||||||
|
|
||||||
const acceptDialogButton = content.document.getElementById(
|
const acceptDialogButton = content.document.getElementById(
|
||||||
"join-ion-accept-dialog-button"
|
"join-pioneer-accept-dialog-button"
|
||||||
);
|
);
|
||||||
let promiseDialogAccepted = BrowserTestUtils.waitForAttribute(
|
let promiseDialogAccepted = BrowserTestUtils.waitForAttribute(
|
||||||
"data-l10n-id",
|
"data-l10n-id",
|
||||||
@ -796,8 +815,8 @@ add_task(async function testEnrollmentPings() {
|
|||||||
);
|
);
|
||||||
acceptDialogButton.click();
|
acceptDialogButton.click();
|
||||||
|
|
||||||
const ionId = Services.prefs.getStringPref(PREF_ION_ID, null);
|
const pioneerId = Services.prefs.getStringPref(PREF_PIONEER_ID, null);
|
||||||
ok(ionId, "after enrollment, Ion pref is set.");
|
ok(pioneerId, "after enrollment, Pioneer pref is set.");
|
||||||
|
|
||||||
await promiseDialogAccepted;
|
await promiseDialogAccepted;
|
||||||
|
|
||||||
@ -847,17 +866,17 @@ add_task(async function testEnrollmentPings() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// We expect 1 ping with just the ion id (ion consent) and another
|
// We expect 1 ping with just the pioneer id (pioneer consent) and another
|
||||||
// with both the ion id and the study id (study consent).
|
// with both the pioneer id and the study id (study consent).
|
||||||
ok(
|
ok(
|
||||||
pingDetails.find(
|
pingDetails.find(
|
||||||
p =>
|
p =>
|
||||||
p.schemaName == "pioneer-enrollment" &&
|
p.schemaName == "pioneer-enrollment" &&
|
||||||
p.schemaNamespace == "pioneer-meta" &&
|
p.schemaNamespace == "pioneer-meta" &&
|
||||||
p.pioneerId == ionId &&
|
p.pioneerId == pioneerId &&
|
||||||
p.studyName == "pioneer-meta"
|
p.studyName == "pioneer-meta"
|
||||||
),
|
),
|
||||||
"We expect the Ion program consent to be present"
|
"We expect the Pioneer program consent to be present"
|
||||||
);
|
);
|
||||||
|
|
||||||
ok(
|
ok(
|
||||||
@ -865,7 +884,7 @@ add_task(async function testEnrollmentPings() {
|
|||||||
p =>
|
p =>
|
||||||
p.schemaName == "pioneer-enrollment" &&
|
p.schemaName == "pioneer-enrollment" &&
|
||||||
p.schemaNamespace == CACHED_TEST_ADDON.addon_id &&
|
p.schemaNamespace == CACHED_TEST_ADDON.addon_id &&
|
||||||
p.pioneerId == ionId &&
|
p.pioneerId == pioneerId &&
|
||||||
p.studyName == CACHED_TEST_ADDON.addon_id
|
p.studyName == CACHED_TEST_ADDON.addon_id
|
||||||
),
|
),
|
||||||
"We expect the study consent to be present"
|
"We expect the study consent to be present"
|
||||||
@ -874,17 +893,17 @@ add_task(async function testEnrollmentPings() {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
add_task(async function testIonBadge() {
|
add_task(async function testPioneerBadge() {
|
||||||
await SpecialPowers.pushPrefEnv({
|
await SpecialPowers.pushPrefEnv({
|
||||||
set: [[PREF_ION_NEW_STUDIES_AVAILABLE, true]],
|
set: [[PREF_PIONEER_NEW_STUDIES_AVAILABLE, true]],
|
||||||
clear: [
|
clear: [
|
||||||
[PREF_ION_NEW_STUDIES_AVAILABLE, false],
|
[PREF_PIONEER_NEW_STUDIES_AVAILABLE, false],
|
||||||
[PREF_ION_ID, ""],
|
[PREF_PIONEER_ID, ""],
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
let ionTab = await BrowserTestUtils.openNewForegroundTab({
|
let pioneerTab = await BrowserTestUtils.openNewForegroundTab({
|
||||||
url: "about:ion",
|
url: "about:pioneer",
|
||||||
gBrowser,
|
gBrowser,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -896,37 +915,37 @@ add_task(async function testIonBadge() {
|
|||||||
gBrowser,
|
gBrowser,
|
||||||
});
|
});
|
||||||
|
|
||||||
Services.prefs.setBoolPref(PREF_ION_NEW_STUDIES_AVAILABLE, true);
|
Services.prefs.setBoolPref(PREF_PIONEER_NEW_STUDIES_AVAILABLE, true);
|
||||||
|
|
||||||
const toolbarButton = document.getElementById("ion-button");
|
const toolbarButton = document.getElementById("pioneer-button");
|
||||||
const toolbarBadge = toolbarButton.querySelector(".toolbarbutton-badge");
|
const toolbarBadge = toolbarButton.querySelector(".toolbarbutton-badge");
|
||||||
|
|
||||||
ok(
|
ok(
|
||||||
toolbarBadge.classList.contains("feature-callout"),
|
toolbarBadge.classList.contains("feature-callout"),
|
||||||
"When pref is true, Ion toolbar button is called out in the current window."
|
"When pref is true, Pioneer toolbar button is called out in the current window."
|
||||||
);
|
);
|
||||||
|
|
||||||
toolbarButton.click();
|
toolbarButton.click();
|
||||||
|
|
||||||
await ionTab;
|
await pioneerTab;
|
||||||
|
|
||||||
ok(
|
ok(
|
||||||
!toolbarBadge.classList.contains("feature-callout"),
|
!toolbarBadge.classList.contains("feature-callout"),
|
||||||
"When about:ion toolbar button is pressed, call-out is removed."
|
"When about:pioneer toolbar button is pressed, call-out is removed."
|
||||||
);
|
);
|
||||||
|
|
||||||
Services.prefs.setBoolPref(PREF_ION_NEW_STUDIES_AVAILABLE, true);
|
Services.prefs.setBoolPref(PREF_PIONEER_NEW_STUDIES_AVAILABLE, true);
|
||||||
|
|
||||||
const newWin = await BrowserTestUtils.openNewBrowserWindow();
|
const newWin = await BrowserTestUtils.openNewBrowserWindow();
|
||||||
const newToolbarBadge = toolbarButton.querySelector(".toolbarbutton-badge");
|
const newToolbarBadge = toolbarButton.querySelector(".toolbarbutton-badge");
|
||||||
|
|
||||||
ok(
|
ok(
|
||||||
newToolbarBadge.classList.contains("feature-callout"),
|
newToolbarBadge.classList.contains("feature-callout"),
|
||||||
"When pref is true, Ion toolbar button is called out in a new window."
|
"When pref is true, Pioneer toolbar button is called out in a new window."
|
||||||
);
|
);
|
||||||
|
|
||||||
await BrowserTestUtils.closeWindow(newWin);
|
await BrowserTestUtils.closeWindow(newWin);
|
||||||
await BrowserTestUtils.removeTab(ionTab);
|
await BrowserTestUtils.removeTab(pioneerTab);
|
||||||
await BrowserTestUtils.removeTab(blankTab);
|
await BrowserTestUtils.removeTab(blankTab);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -938,12 +957,12 @@ add_task(async function testContentReplacement() {
|
|||||||
[PREF_TEST_CACHED_CONTENT, cachedContent],
|
[PREF_TEST_CACHED_CONTENT, cachedContent],
|
||||||
[PREF_TEST_ADDONS, "[]"],
|
[PREF_TEST_ADDONS, "[]"],
|
||||||
],
|
],
|
||||||
clear: [[PREF_ION_ID, ""]],
|
clear: [[PREF_PIONEER_ID, ""]],
|
||||||
});
|
});
|
||||||
|
|
||||||
await BrowserTestUtils.withNewTab(
|
await BrowserTestUtils.withNewTab(
|
||||||
{
|
{
|
||||||
url: "about:ion",
|
url: "about:pioneer",
|
||||||
gBrowser,
|
gBrowser,
|
||||||
},
|
},
|
||||||
async function taskFn(browser) {
|
async function taskFn(browser) {
|
||||||
@ -968,8 +987,8 @@ add_task(async function testLocaleGating() {
|
|||||||
[PREF_TEST_ADDONS, "[]"],
|
[PREF_TEST_ADDONS, "[]"],
|
||||||
],
|
],
|
||||||
clear: [
|
clear: [
|
||||||
[PREF_ION_ID, ""],
|
[PREF_PIONEER_ID, ""],
|
||||||
[PREF_ION_COMPLETED_STUDIES, "[]"],
|
[PREF_PIONEER_COMPLETED_STUDIES, "[]"],
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -977,7 +996,7 @@ add_task(async function testLocaleGating() {
|
|||||||
|
|
||||||
await BrowserTestUtils.withNewTab(
|
await BrowserTestUtils.withNewTab(
|
||||||
{
|
{
|
||||||
url: "about:ion",
|
url: "about:pioneer",
|
||||||
gBrowser,
|
gBrowser,
|
||||||
},
|
},
|
||||||
async function taskFn(browser) {
|
async function taskFn(browser) {
|
||||||
@ -1003,7 +1022,7 @@ add_task(async function testLocaleGating() {
|
|||||||
|
|
||||||
await BrowserTestUtils.withNewTab(
|
await BrowserTestUtils.withNewTab(
|
||||||
{
|
{
|
||||||
url: "about:ion",
|
url: "about:pioneer",
|
||||||
gBrowser,
|
gBrowser,
|
||||||
},
|
},
|
||||||
async function taskFn(browser) {
|
async function taskFn(browser) {
|
@ -8,7 +8,7 @@
|
|||||||
# having to create the same entry for each locale.
|
# having to create the same entry for each locale.
|
||||||
|
|
||||||
[localization] @AB_CD@.jar:
|
[localization] @AB_CD@.jar:
|
||||||
preview/ion.ftl (../components/ion/content/ion.ftl)
|
preview/pioneer.ftl (../components/pioneer/content/pioneer.ftl)
|
||||||
preview/protections.ftl (../components/protections/content/protections.ftl)
|
preview/protections.ftl (../components/protections/content/protections.ftl)
|
||||||
preview/interventions.ftl (../components/urlbar/content/interventions.ftl)
|
preview/interventions.ftl (../components/urlbar/content/interventions.ftl)
|
||||||
browser (%browser/**/*.ftl)
|
browser (%browser/**/*.ftl)
|
||||||
|
Before Width: | Height: | Size: 845 B After Width: | Height: | Size: 845 B |
@ -246,7 +246,7 @@
|
|||||||
skin/classic/browser/window.svg (../shared/icons/window.svg)
|
skin/classic/browser/window.svg (../shared/icons/window.svg)
|
||||||
skin/classic/browser/zoom-in.svg (../shared/icons/zoom-in.svg)
|
skin/classic/browser/zoom-in.svg (../shared/icons/zoom-in.svg)
|
||||||
skin/classic/browser/zoom-out.svg (../shared/icons/zoom-out.svg)
|
skin/classic/browser/zoom-out.svg (../shared/icons/zoom-out.svg)
|
||||||
skin/classic/browser/ion.svg (../shared/icons/ion.svg)
|
skin/classic/browser/pioneer.svg (../shared/icons/pioneer.svg)
|
||||||
|
|
||||||
|
|
||||||
skin/classic/browser/search-engine-placeholder.png (../shared/search/search-engine-placeholder.png)
|
skin/classic/browser/search-engine-placeholder.png (../shared/search/search-engine-placeholder.png)
|
||||||
|
@ -633,6 +633,6 @@ toolbarbutton.bookmark-item {
|
|||||||
#whats-new-menu-button {
|
#whats-new-menu-button {
|
||||||
list-style-image: url("chrome://browser/skin/whatsnew.svg");
|
list-style-image: url("chrome://browser/skin/whatsnew.svg");
|
||||||
}
|
}
|
||||||
#ion-button {
|
#pioneer-button {
|
||||||
list-style-image: url("chrome://browser/skin/ion.svg");
|
list-style-image: url("chrome://browser/skin/pioneer.svg");
|
||||||
}
|
}
|
||||||
|
@ -893,7 +893,7 @@ void nsContentSecurityUtils::AssertAboutPageHasCSP(Document* aDocument) {
|
|||||||
MOZ_ASSERT(!foundWorkerSrc,
|
MOZ_ASSERT(!foundWorkerSrc,
|
||||||
"about: page must not contain a CSP including worker-src");
|
"about: page must not contain a CSP including worker-src");
|
||||||
|
|
||||||
// addons, preferences, debugging, newinstall, ion, devtools all have
|
// addons, preferences, debugging, newinstall, pioneer, devtools all have
|
||||||
// to allow some remote web resources
|
// to allow some remote web resources
|
||||||
MOZ_ASSERT(!foundWebScheme ||
|
MOZ_ASSERT(!foundWebScheme ||
|
||||||
StringBeginsWith(aboutSpec, "about:preferences"_ns) ||
|
StringBeginsWith(aboutSpec, "about:preferences"_ns) ||
|
||||||
@ -901,7 +901,7 @@ void nsContentSecurityUtils::AssertAboutPageHasCSP(Document* aDocument) {
|
|||||||
StringBeginsWith(aboutSpec, "about:newtab"_ns) ||
|
StringBeginsWith(aboutSpec, "about:newtab"_ns) ||
|
||||||
StringBeginsWith(aboutSpec, "about:debugging"_ns) ||
|
StringBeginsWith(aboutSpec, "about:debugging"_ns) ||
|
||||||
StringBeginsWith(aboutSpec, "about:newinstall"_ns) ||
|
StringBeginsWith(aboutSpec, "about:newinstall"_ns) ||
|
||||||
StringBeginsWith(aboutSpec, "about:ion"_ns) ||
|
StringBeginsWith(aboutSpec, "about:pioneer"_ns) ||
|
||||||
StringBeginsWith(aboutSpec, "about:compat"_ns) ||
|
StringBeginsWith(aboutSpec, "about:compat"_ns) ||
|
||||||
StringBeginsWith(aboutSpec, "about:logins"_ns) ||
|
StringBeginsWith(aboutSpec, "about:logins"_ns) ||
|
||||||
StringBeginsWith(aboutSpec, "about:home"_ns) ||
|
StringBeginsWith(aboutSpec, "about:home"_ns) ||
|
||||||
|
@ -160,7 +160,7 @@
|
|||||||
"browser/components/newtab/test/browser/abouthomecache/browser.ini": 10.59,
|
"browser/components/newtab/test/browser/abouthomecache/browser.ini": 10.59,
|
||||||
"browser/components/newtab/test/browser/browser.ini": 74.49,
|
"browser/components/newtab/test/browser/browser.ini": 74.49,
|
||||||
"browser/components/originattributes/test/browser/browser.ini": 116.79,
|
"browser/components/originattributes/test/browser/browser.ini": 116.79,
|
||||||
"browser/components/ion/test/browser/browser.ini": 0.49,
|
"browser/components/pioneer/test/browser/browser.ini": 0.49,
|
||||||
"browser/components/places/tests/browser/browser.ini": 145.76,
|
"browser/components/places/tests/browser/browser.ini": 145.76,
|
||||||
"browser/components/pocket/test/browser.ini": 5.1,
|
"browser/components/pocket/test/browser.ini": 5.1,
|
||||||
"browser/components/preferences/tests/browser.ini": 459.56,
|
"browser/components/preferences/tests/browser.ini": 459.56,
|
||||||
|
@ -159,7 +159,7 @@
|
|||||||
"browser/components/newtab/test/browser/abouthomecache/browser.ini": 10.38,
|
"browser/components/newtab/test/browser/abouthomecache/browser.ini": 10.38,
|
||||||
"browser/components/newtab/test/browser/browser.ini": 52.48,
|
"browser/components/newtab/test/browser/browser.ini": 52.48,
|
||||||
"browser/components/originattributes/test/browser/browser.ini": 58.43,
|
"browser/components/originattributes/test/browser/browser.ini": 58.43,
|
||||||
"browser/components/ion/test/browser/browser.ini": 1.63,
|
"browser/components/pioneer/test/browser/browser.ini": 1.63,
|
||||||
"browser/components/places/tests/browser/browser.ini": 106.52,
|
"browser/components/places/tests/browser/browser.ini": 106.52,
|
||||||
"browser/components/pocket/test/browser.ini": 3.48,
|
"browser/components/pocket/test/browser.ini": 3.48,
|
||||||
"browser/components/preferences/tests/browser.ini": 295.7,
|
"browser/components/preferences/tests/browser.ini": 295.7,
|
||||||
|
@ -50,7 +50,7 @@ avoid-blacklist-and-whitelist:
|
|||||||
- browser/components/migration/ChromeMigrationUtils.jsm
|
- browser/components/migration/ChromeMigrationUtils.jsm
|
||||||
- browser/components/migration/ChromeProfileMigrator.jsm
|
- browser/components/migration/ChromeProfileMigrator.jsm
|
||||||
- browser/components/newtab/data/content/activity-stream.bundle.js
|
- browser/components/newtab/data/content/activity-stream.bundle.js
|
||||||
- browser/components/ion/content/ion.js
|
- browser/components/pioneer/content/pioneer.js
|
||||||
- browser/components/preferences/privacy.inc.xhtml
|
- browser/components/preferences/privacy.inc.xhtml
|
||||||
- browser/components/preferences/privacy.js
|
- browser/components/preferences/privacy.js
|
||||||
- browser/components/resistfingerprinting/test/mochitest/test_bug1354633_media_error.html
|
- browser/components/resistfingerprinting/test/mochitest/test_bug1354633_media_error.html
|
||||||
|
Loading…
Reference in New Issue
Block a user