summaryrefslogtreecommitdiffstats
path: root/browser/components/uitour/content-UITour.js
diff options
context:
space:
mode:
Diffstat (limited to 'browser/components/uitour/content-UITour.js')
-rw-r--r--browser/components/uitour/content-UITour.js103
1 files changed, 103 insertions, 0 deletions
diff --git a/browser/components/uitour/content-UITour.js b/browser/components/uitour/content-UITour.js
new file mode 100644
index 000000000..c33d687e8
--- /dev/null
+++ b/browser/components/uitour/content-UITour.js
@@ -0,0 +1,103 @@
+/* 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/. */
+
+var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
+
+const PREF_TEST_WHITELIST = "browser.uitour.testingOrigins";
+const UITOUR_PERMISSION = "uitour";
+
+var UITourListener = {
+ handleEvent: function (event) {
+ if (!Services.prefs.getBoolPref("browser.uitour.enabled")) {
+ return;
+ }
+ if (!this.ensureTrustedOrigin()) {
+ return;
+ }
+ addMessageListener("UITour:SendPageCallback", this);
+ addMessageListener("UITour:SendPageNotification", this);
+ sendAsyncMessage("UITour:onPageEvent", {
+ detail: event.detail,
+ type: event.type,
+ pageVisibilityState: content.document.visibilityState,
+ });
+ },
+
+ isTestingOrigin: function(aURI) {
+ if (Services.prefs.getPrefType(PREF_TEST_WHITELIST) != Services.prefs.PREF_STRING) {
+ return false;
+ }
+
+ // Add any testing origins (comma-seperated) to the whitelist for the session.
+ for (let origin of Services.prefs.getCharPref(PREF_TEST_WHITELIST).split(",")) {
+ try {
+ let testingURI = Services.io.newURI(origin, null, null);
+ if (aURI.prePath == testingURI.prePath) {
+ return true;
+ }
+ } catch (ex) {
+ Cu.reportError(ex);
+ }
+ }
+ return false;
+ },
+
+ // This function is copied from UITour.jsm.
+ isSafeScheme: function(aURI) {
+ let allowedSchemes = new Set(["https", "about"]);
+ if (!Services.prefs.getBoolPref("browser.uitour.requireSecure"))
+ allowedSchemes.add("http");
+
+ if (!allowedSchemes.has(aURI.scheme))
+ return false;
+
+ return true;
+ },
+
+ ensureTrustedOrigin: function() {
+ if (content.top != content)
+ return false;
+
+ let uri = content.document.documentURIObject;
+
+ if (uri.schemeIs("chrome"))
+ return true;
+
+ if (!this.isSafeScheme(uri))
+ return false;
+
+ let permission = Services.perms.testPermission(uri, UITOUR_PERMISSION);
+ if (permission == Services.perms.ALLOW_ACTION)
+ return true;
+
+ return this.isTestingOrigin(uri);
+ },
+
+ receiveMessage: function(aMessage) {
+ switch (aMessage.name) {
+ case "UITour:SendPageCallback":
+ this.sendPageEvent("Response", aMessage.data);
+ break;
+ case "UITour:SendPageNotification":
+ this.sendPageEvent("Notification", aMessage.data);
+ break;
+ }
+ },
+
+ sendPageEvent: function (type, detail) {
+ if (!this.ensureTrustedOrigin()) {
+ return;
+ }
+
+ let doc = content.document;
+ let eventName = "mozUITour" + type;
+ let event = new doc.defaultView.CustomEvent(eventName, {
+ bubbles: true,
+ detail: Cu.cloneInto(detail, doc.defaultView)
+ });
+ doc.dispatchEvent(event);
+ }
+};
+
+addEventListener("mozUITour", UITourListener, false, true);