summaryrefslogtreecommitdiffstats
path: root/devtools/client/shared/doorhanger.js
diff options
context:
space:
mode:
authorMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
committerMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
commit5f8de423f190bbb79a62f804151bc24824fa32d8 (patch)
tree10027f336435511475e392454359edea8e25895d /devtools/client/shared/doorhanger.js
parent49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff)
downloadUXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip
Add m-esr52 at 52.6.0
Diffstat (limited to 'devtools/client/shared/doorhanger.js')
-rw-r--r--devtools/client/shared/doorhanger.js164
1 files changed, 164 insertions, 0 deletions
diff --git a/devtools/client/shared/doorhanger.js b/devtools/client/shared/doorhanger.js
new file mode 100644
index 000000000..fc2767966
--- /dev/null
+++ b/devtools/client/shared/doorhanger.js
@@ -0,0 +1,164 @@
+/* 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";
+
+const { Ci, Cc } = require("chrome");
+const Services = require("Services");
+const { DOMHelpers } = require("resource://devtools/client/shared/DOMHelpers.jsm");
+const { Task } = require("devtools/shared/task");
+const defer = require("devtools/shared/defer");
+const { getMostRecentBrowserWindow } = require("sdk/window/utils");
+
+const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
+const DEV_EDITION_PROMO_URL = "chrome://devtools/content/framework/dev-edition-promo/dev-edition-promo.xul";
+const DEV_EDITION_PROMO_ENABLED_PREF = "devtools.devedition.promo.enabled";
+const DEV_EDITION_PROMO_SHOWN_PREF = "devtools.devedition.promo.shown";
+const DEV_EDITION_PROMO_URL_PREF = "devtools.devedition.promo.url";
+const LOCALE = Cc["@mozilla.org/chrome/chrome-registry;1"]
+ .getService(Ci.nsIXULChromeRegistry)
+ .getSelectedLocale("global");
+
+/**
+ * Only show Dev Edition promo if it's enabled (beta channel),
+ * if it has not been shown before, and it's a locale build
+ * for `en-US`
+ */
+function shouldDevEditionPromoShow() {
+ return Services.prefs.getBoolPref(DEV_EDITION_PROMO_ENABLED_PREF) &&
+ !Services.prefs.getBoolPref(DEV_EDITION_PROMO_SHOWN_PREF) &&
+ LOCALE === "en-US";
+}
+
+var TYPES = {
+ // The Developer Edition promo doorhanger, called by
+ // opening the toolbox, browser console, WebIDE, or responsive design mode
+ // in Beta releases. Only displayed once per profile.
+ deveditionpromo: {
+ predicate: shouldDevEditionPromoShow,
+ success: () => {
+ return Services.prefs.setBoolPref(DEV_EDITION_PROMO_SHOWN_PREF, true);
+ },
+ action: () => {
+ let url = Services.prefs.getCharPref(DEV_EDITION_PROMO_URL_PREF);
+ getGBrowser().selectedTab = getGBrowser().addTab(url);
+ },
+ url: DEV_EDITION_PROMO_URL
+ }
+};
+
+var panelAttrs = {
+ orient: "vertical",
+ hidden: "false",
+ consumeoutsideclicks: "true",
+ noautofocus: "true",
+ align: "start",
+ role: "alert"
+};
+
+/**
+ * Helper to call a doorhanger, defined in `TYPES`, with defined conditions,
+ * success handlers and loads its own XUL in a frame. Takes an object with
+ * several properties:
+ *
+ * @param {XULWindow} window
+ * The window that should house the doorhanger.
+ * @param {String} type
+ * The type of doorhanger to be displayed is, using the `TYPES`
+ * definition.
+ * @param {String} selector
+ * The selector that the doorhanger should be appended to within
+ * `window`. Defaults to a XUL Document's `window` element.
+ */
+exports.showDoorhanger = Task.async(function* ({ window, type, anchor }) {
+ let { predicate, success, url, action } = TYPES[type];
+ // Abort if predicate fails
+ if (!predicate()) {
+ return;
+ }
+
+ // Call success function to set preferences/cleanup immediately,
+ // so if triggered multiple times, only happens once (Windows/Linux)
+ success();
+
+ // Wait 200ms to prevent flickering where the popup is displayed
+ // before the underlying window (Windows 7, 64bit)
+ yield wait(200);
+
+ let document = window.document;
+
+ let panel = document.createElementNS(XULNS, "panel");
+ let frame = document.createElementNS(XULNS, "iframe");
+ let parentEl = document.querySelector("window");
+
+ frame.setAttribute("src", url);
+ let close = () => parentEl.removeChild(panel);
+
+ setDoorhangerStyle(panel, frame);
+
+ panel.appendChild(frame);
+ parentEl.appendChild(panel);
+
+ yield onFrameLoad(frame);
+
+ panel.openPopup(anchor);
+
+ let closeBtn = frame.contentDocument.querySelector("#close");
+ if (closeBtn) {
+ closeBtn.addEventListener("click", close);
+ }
+
+ let goBtn = frame.contentDocument.querySelector("#go");
+ if (goBtn) {
+ goBtn.addEventListener("click", () => {
+ if (action) {
+ action();
+ }
+ close();
+ });
+ }
+});
+
+function setDoorhangerStyle(panel, frame) {
+ Object.keys(panelAttrs).forEach(prop => {
+ return panel.setAttribute(prop, panelAttrs[prop]);
+ });
+ panel.style.margin = "20px";
+ panel.style.borderRadius = "5px";
+ panel.style.border = "none";
+ panel.style.MozAppearance = "none";
+ panel.style.backgroundColor = "transparent";
+
+ frame.style.borderRadius = "5px";
+ frame.setAttribute("flex", "1");
+ frame.setAttribute("width", "450");
+ frame.setAttribute("height", "179");
+}
+
+function onFrameLoad(frame) {
+ let { resolve, promise } = defer();
+
+ if (frame.contentWindow) {
+ let domHelper = new DOMHelpers(frame.contentWindow);
+ domHelper.onceDOMReady(resolve);
+ } else {
+ let callback = () => {
+ frame.removeEventListener("DOMContentLoaded", callback);
+ resolve();
+ };
+ frame.addEventListener("DOMContentLoaded", callback);
+ }
+
+ return promise;
+}
+
+function getGBrowser() {
+ return getMostRecentBrowserWindow().gBrowser;
+}
+
+function wait(n) {
+ let { resolve, promise } = defer();
+ setTimeout(resolve, n);
+ return promise;
+}