PRs included in this patch: - #1002: Fix bug 1393257: Stop in-progress studies when opt-out pref changes. https://github.com/mozilla/normandy/pull/1002 - #1010: Bug 1392738: Update how we open the new preferences UI. https://github.com/mozilla/normandy/pull/1010 - #1024: Bug 1371350: Delay almost all startup tasks until after sessionstore-windows-restored https://github.com/mozilla/normandy/pull/1024 - #1029: Fix #856: Add type parameter to preference experiment annotations. https://github.com/mozilla/normandy/pull/1029 MozReview-Commit-ID: 7T3MgLMMsiE
116 lines
3.6 KiB
JavaScript
116 lines
3.6 KiB
JavaScript
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
"use strict";
|
|
|
|
/**
|
|
* Listen for DOM events bubbling up from the about:studies page, and perform
|
|
* privileged actions in response to them. If we need to do anything that the
|
|
* content process can't handle (such as reading IndexedDB), we send a message
|
|
* to the parent process and handle it there.
|
|
*
|
|
* This file is loaded as a frame script. It will be loaded once per tab that
|
|
* is opened.
|
|
*/
|
|
|
|
/* global content addMessageListener removeMessageListener sendAsyncMessage */
|
|
|
|
const { utils: Cu } = Components;
|
|
Cu.import("resource://gre/modules/Services.jsm");
|
|
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
|
|
|
const frameGlobal = {};
|
|
XPCOMUtils.defineLazyModuleGetter(
|
|
frameGlobal, "AboutPages", "resource://shield-recipe-client-content/AboutPages.jsm",
|
|
);
|
|
|
|
/**
|
|
* Handles incoming events from the parent process and about:studies.
|
|
* @implements nsIMessageListener
|
|
* @implements EventListener
|
|
*/
|
|
class ShieldFrameListener {
|
|
handleEvent(event) {
|
|
// Abort if the current page isn't about:studies.
|
|
if (!this.ensureTrustedOrigin()) {
|
|
return;
|
|
}
|
|
|
|
// We waited until after we received an event to register message listeners
|
|
// in order to save resources for tabs that don't ever load about:studies.
|
|
addMessageListener("Shield:ShuttingDown", this);
|
|
addMessageListener("Shield:ReceiveStudyList", this);
|
|
|
|
switch (event.detail.action) {
|
|
// Actions that require the parent process
|
|
case "GetRemoteValue:StudyList":
|
|
sendAsyncMessage("Shield:GetStudyList");
|
|
break;
|
|
case "RemoveStudy":
|
|
sendAsyncMessage("Shield:RemoveStudy", event.detail.data);
|
|
break;
|
|
// Actions that can be performed in the content process
|
|
case "GetRemoteValue:ShieldLearnMoreHref":
|
|
this.triggerPageCallback(
|
|
"ReceiveRemoteValue:ShieldLearnMoreHref",
|
|
frameGlobal.AboutPages.aboutStudies.getShieldLearnMoreHref()
|
|
);
|
|
break;
|
|
case "NavigateToDataPreferences":
|
|
sendAsyncMessage("Shield:OpenDataPreferences");
|
|
break;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Check that the current webpage's origin is about:studies.
|
|
* @return {Boolean}
|
|
*/
|
|
ensureTrustedOrigin() {
|
|
return content.document.documentURI.startsWith("about:studies");
|
|
}
|
|
|
|
/**
|
|
* Handle messages from the parent process.
|
|
* @param {Object} message
|
|
* See the nsIMessageListener docs.
|
|
*/
|
|
receiveMessage(message) {
|
|
switch (message.name) {
|
|
case "Shield:ReceiveStudyList":
|
|
this.triggerPageCallback("ReceiveRemoteValue:StudyList", message.data.studies);
|
|
break;
|
|
case "Shield:ShuttingDown":
|
|
this.onShutdown();
|
|
break;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Trigger an event to communicate with the unprivileged about: page.
|
|
* @param {String} type
|
|
* @param {Object} detail
|
|
*/
|
|
triggerPageCallback(type, detail) {
|
|
// Do not communicate with untrusted pages.
|
|
if (!this.ensureTrustedOrigin()) {
|
|
return;
|
|
}
|
|
|
|
// Clone details and use the event class from the unprivileged context.
|
|
const event = new content.document.defaultView.CustomEvent(type, {
|
|
bubbles: true,
|
|
detail: Cu.cloneInto(detail, content.document.defaultView),
|
|
});
|
|
content.document.dispatchEvent(event);
|
|
}
|
|
|
|
onShutdown() {
|
|
removeMessageListener("Shield:SendStudyList", this);
|
|
removeMessageListener("Shield:ShuttingDown", this);
|
|
removeEventListener("Shield", this);
|
|
}
|
|
}
|
|
|
|
addEventListener("ShieldPageEvent", new ShieldFrameListener(), false, true);
|