Files
tubestation/browser/extensions/shield-recipe-client/content/shield-content-frame.js
Michael Kelly dfeb1fb501 Bug 1397415: Sync shield-recipe-client v73 from GitHub (commit e96eea7) r=Gijs
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
2017-09-06 12:50:43 -07:00

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);