mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-10 11:55:49 +00:00
Bug 1078539 - Add a doorhanger widget for the developer edition notification to browser console, developer tools, webide and responsive design mode. r=jryans
This commit is contained in:
parent
7880585d9d
commit
a181e76100
@ -1306,6 +1306,17 @@ pref("browser.devedition.theme.enabled", false);
|
||||
pref("browser.devedition.theme.showCustomizeButton", false);
|
||||
#endif
|
||||
|
||||
// Developer edition promo preferences
|
||||
pref("devtools.devedition.promo.shown", false);
|
||||
pref("devtools.devedition.promo.url", "https://mozilla.org/firefox/developer");
|
||||
|
||||
// Only potentially show in beta release
|
||||
#ifdef MOZ_UPDATE_CHANNEL == beta
|
||||
pref("devtools.devedition.promo.enabled", true);
|
||||
#else
|
||||
pref("devtools.devedition.promo.enabled", false);
|
||||
#endif
|
||||
|
||||
// Disable the error console
|
||||
pref("devtools.errorconsole.enabled", false);
|
||||
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 6.6 KiB |
@ -0,0 +1,74 @@
|
||||
/* 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/. */
|
||||
|
||||
#doorhanger-container {
|
||||
width: 450px;
|
||||
}
|
||||
|
||||
#top-panel {
|
||||
padding: 20px;
|
||||
background: #343c45; /* toolbars */
|
||||
color: #8fa1b2; /* body text */
|
||||
font-size: 15px;
|
||||
line-height: 19px;
|
||||
min-height: 100px;
|
||||
}
|
||||
|
||||
#top-panel h1 {
|
||||
font-weight: bold;
|
||||
font-family: Open Sans, sans-serif;
|
||||
font-size: 1.1em;
|
||||
}
|
||||
|
||||
#top-panel p {
|
||||
font-family: Open Sans, sans-serif;
|
||||
font-size: 0.9em;
|
||||
width: 300px;
|
||||
display: block;
|
||||
margin: 5px 0px 0px 0px;
|
||||
}
|
||||
|
||||
#icon {
|
||||
background-image: url("chrome://browser/content/devtools/framework/dev-edition-logo.png");
|
||||
background-size: 64px 64px;
|
||||
background-repeat: no-repeat;
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
#lower-panel {
|
||||
padding: 20px;
|
||||
background-color: #252c33; /* tab toolbars */
|
||||
min-height: 75px;
|
||||
border-top: 1px solid #292e33; /* text high contrast (light) */
|
||||
}
|
||||
|
||||
#button-container {
|
||||
margin: auto 20px;
|
||||
}
|
||||
|
||||
#button-container button {
|
||||
font: message-box !important;
|
||||
font-size: 16px !important;
|
||||
cursor: pointer;
|
||||
width: 125px;
|
||||
opacity: 1;
|
||||
position: static;
|
||||
-moz-appearance: none;
|
||||
border-radius: 5px;
|
||||
height: 30px;
|
||||
width: 450px;
|
||||
}
|
||||
|
||||
#close {
|
||||
background-color: transparent;
|
||||
color: #8fa1b2; /* body text */
|
||||
}
|
||||
|
||||
#go {
|
||||
margin-left: 100px;
|
||||
background-color: #70bf53; /* green */
|
||||
color: #f5f7fa; /* selection text color */
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
<?xml version="1.0" encoding="utf-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/. -->
|
||||
<!DOCTYPE window [
|
||||
<!ENTITY % toolboxDTD SYSTEM "chrome://browser/locale/devtools/toolbox.dtd" >
|
||||
%toolboxDTD;
|
||||
]>
|
||||
<?xml-stylesheet href="chrome://browser/skin/" type="text/css"?>
|
||||
<?xml-stylesheet rel="stylesheet" href="chrome://browser/content/devtools/framework/dev-edition-promo.css" type="text/css"?>
|
||||
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" id="dev-edition-promo">
|
||||
<vbox id="doorhanger-container">
|
||||
<hbox flex="1" id="top-panel">
|
||||
<image id="icon" />
|
||||
<vbox id="info">
|
||||
<h1>Using Developer Tools in your browser?</h1>
|
||||
<p>Download Firefox Developer Edition, our first browser made just for you.</p>
|
||||
</vbox>
|
||||
</hbox>
|
||||
<hbox id="lower-panel" flex="1">
|
||||
<hbox id="button-container" flex="1">
|
||||
<button id="close"
|
||||
flex="1"
|
||||
standalone="true"
|
||||
label="No thanks">
|
||||
</button>
|
||||
<button id="go"
|
||||
flex="1"
|
||||
standalone="true"
|
||||
label="Learn more »">
|
||||
</button>
|
||||
</hbox>
|
||||
</hbox>
|
||||
</vbox>
|
||||
</window>
|
@ -17,6 +17,7 @@ let EventEmitter = require("devtools/toolkit/event-emitter");
|
||||
let Telemetry = require("devtools/shared/telemetry");
|
||||
let {getHighlighterUtils} = require("devtools/framework/toolbox-highlighter-utils");
|
||||
let HUDService = require("devtools/webconsole/hudservice");
|
||||
let {showDoorhanger} = require("devtools/shared/doorhanger");
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
@ -100,6 +101,7 @@ function Toolbox(target, selectedTool, hostType, hostOptions) {
|
||||
this._prefChanged = this._prefChanged.bind(this);
|
||||
this._saveSplitConsoleHeight = this._saveSplitConsoleHeight.bind(this);
|
||||
this._onFocus = this._onFocus.bind(this);
|
||||
this._showDevEditionPromo = this._showDevEditionPromo.bind(this);
|
||||
|
||||
this._target.on("close", this.destroy);
|
||||
|
||||
@ -124,6 +126,8 @@ function Toolbox(target, selectedTool, hostType, hostOptions) {
|
||||
this.on("host-changed", this._refreshHostTitle);
|
||||
this.on("select", this._refreshHostTitle);
|
||||
|
||||
this.on("ready", this._showDevEditionPromo);
|
||||
|
||||
gDevTools.on("tool-registered", this._toolRegistered);
|
||||
gDevTools.on("tool-unregistered", this._toolUnregistered);
|
||||
}
|
||||
@ -1649,5 +1653,18 @@ Toolbox.prototype = {
|
||||
|
||||
_highlighterHidden: function() {
|
||||
this.emit("highlighter-hide");
|
||||
},
|
||||
|
||||
/**
|
||||
* For displaying the promotional Doorhanger on first opening of
|
||||
* the developer tools, promoting the Developer Edition.
|
||||
*/
|
||||
_showDevEditionPromo: function() {
|
||||
// Do not display in browser toolbox
|
||||
if (this.target.chrome) {
|
||||
return;
|
||||
}
|
||||
let window = this.frame.contentWindow;
|
||||
showDoorhanger({ window, type: "deveditionpromo" });
|
||||
}
|
||||
};
|
||||
|
@ -103,6 +103,9 @@ browser.jar:
|
||||
content/browser/devtools/framework/options-panel.css (framework/options-panel.css)
|
||||
content/browser/devtools/framework/toolbox-process-window.xul (framework/toolbox-process-window.xul)
|
||||
content/browser/devtools/framework/toolbox-process-window.js (framework/toolbox-process-window.js)
|
||||
content/browser/devtools/framework/dev-edition-promo.xul (framework/dev-edition-promo/dev-edition-promo.xul)
|
||||
content/browser/devtools/framework/dev-edition-promo.css (framework/dev-edition-promo/dev-edition-promo.css)
|
||||
content/browser/devtools/framework/dev-edition-logo.png (framework/dev-edition-promo/dev-edition-logo.png)
|
||||
content/browser/devtools/inspector/inspector.xul (inspector/inspector.xul)
|
||||
content/browser/devtools/inspector/inspector.css (inspector/inspector.css)
|
||||
content/browser/devtools/connect.xhtml (framework/connect/connect.xhtml)
|
||||
|
@ -17,6 +17,7 @@ XPCOMUtils.defineLazyModuleGetter(this, "SystemAppProxy",
|
||||
|
||||
var require = Cu.import("resource://gre/modules/devtools/Loader.jsm", {}).devtools.require;
|
||||
let Telemetry = require("devtools/shared/telemetry");
|
||||
let {showDoorhanger} = require("devtools/shared/doorhanger");
|
||||
let {TouchEventHandler} = require("devtools/touch-events");
|
||||
|
||||
this.EXPORTED_SYMBOLS = ["ResponsiveUIManager"];
|
||||
@ -217,6 +218,13 @@ function ResponsiveUI(aWindow, aTab)
|
||||
|
||||
// E10S: We should be using target here. See bug 1028234
|
||||
ResponsiveUIManager.emit("on", { tab: this.tab });
|
||||
|
||||
// Hook to display promotional Developer Edition doorhanger. Only displayed once.
|
||||
showDoorhanger({
|
||||
window: this.mainWindow,
|
||||
type: "deveditionpromo",
|
||||
anchor: this.chromeDoc.querySelector("#content")
|
||||
});
|
||||
}
|
||||
|
||||
ResponsiveUI.prototype = {
|
||||
|
144
browser/devtools/shared/doorhanger.js
Normal file
144
browser/devtools/shared/doorhanger.js
Normal file
@ -0,0 +1,144 @@
|
||||
/* 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("resource://gre/modules/Services.jsm");
|
||||
const { DOMHelpers } = require("resource:///modules/devtools/DOMHelpers.jsm");
|
||||
const { Task } = require("resource://gre/modules/Task.jsm");
|
||||
const { Promise } = require("resource://gre/modules/Promise.jsm");
|
||||
const { getMostRecentBrowserWindow } = require("sdk/window/utils");
|
||||
|
||||
const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
const DEV_EDITION_PROMO_URL = "chrome://browser/content/devtools/framework/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";
|
||||
}
|
||||
|
||||
let 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: () => 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
|
||||
}
|
||||
};
|
||||
|
||||
let 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;
|
||||
}
|
||||
|
||||
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();
|
||||
});
|
||||
}
|
||||
|
||||
// Call success function to set preferences, etc.
|
||||
success();
|
||||
});
|
||||
|
||||
function setDoorhangerStyle (panel, frame) {
|
||||
Object.keys(panelAttrs).forEach(prop => panel.setAttribute(prop, panelAttrs[prop]));
|
||||
panel.style.margin = "20px";
|
||||
panel.style.borderRadius = "5px";
|
||||
frame.style.borderRadius = "5px";
|
||||
frame.setAttribute("flex", "1");
|
||||
frame.setAttribute("width", "450");
|
||||
frame.setAttribute("height", "179");
|
||||
}
|
||||
|
||||
function onFrameLoad (frame) {
|
||||
let { resolve, promise } = 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;
|
||||
}
|
@ -33,6 +33,7 @@ EXTRA_JS_MODULES.devtools += [
|
||||
EXTRA_JS_MODULES.devtools.shared += [
|
||||
'autocomplete-popup.js',
|
||||
'd3.js',
|
||||
'doorhanger.js',
|
||||
'frame-script-utils.js',
|
||||
'inplace-editor.js',
|
||||
'observable-object.js',
|
||||
|
@ -19,6 +19,7 @@ loader.lazyImporter(this, "devtools", "resource://gre/modules/devtools/Loader.js
|
||||
loader.lazyImporter(this, "Services", "resource://gre/modules/Services.jsm");
|
||||
loader.lazyImporter(this, "DebuggerServer", "resource://gre/modules/devtools/dbg-server.jsm");
|
||||
loader.lazyImporter(this, "DebuggerClient", "resource://gre/modules/devtools/dbg-client.jsm");
|
||||
loader.lazyGetter(this, "showDoorhanger", () => require("devtools/shared/doorhanger").showDoorhanger);
|
||||
|
||||
const STRINGS_URI = "chrome://browser/locale/devtools/webconsole.properties";
|
||||
let l10n = new WebConsoleUtils.l10n(STRINGS_URI);
|
||||
@ -713,6 +714,9 @@ BrowserConsole.prototype = Heritage.extend(WebConsole.prototype,
|
||||
|
||||
this._telemetry.toolOpened("browserconsole");
|
||||
|
||||
// Hook to display promotional Developer Edition doorhanger. Only displayed once.
|
||||
showDoorhanger({ window, type: "deveditionpromo" });
|
||||
|
||||
this._bc_init = this.$init();
|
||||
return this._bc_init;
|
||||
},
|
||||
|
@ -23,6 +23,7 @@ const {GetTemplatesJSON, GetAddonsJSON} = require("devtools/webide/remote-resour
|
||||
const utils = require("devtools/webide/utils");
|
||||
const Telemetry = require("devtools/shared/telemetry");
|
||||
const {RuntimeScanners, WiFiScanner} = require("devtools/webide/runtimes");
|
||||
const {showDoorhanger} = require("devtools/shared/doorhanger");
|
||||
|
||||
const Strings = Services.strings.createBundle("chrome://browser/locale/devtools/webide.properties");
|
||||
|
||||
@ -96,6 +97,9 @@ let UI = {
|
||||
}
|
||||
|
||||
this.setupDeck();
|
||||
|
||||
// Hook to display promotional Developer Edition doorhanger. Only displayed once.
|
||||
showDoorhanger({ window, type: "deveditionpromo", anchor: document.querySelector("#deck") });
|
||||
},
|
||||
|
||||
uninit: function() {
|
||||
|
Loading…
Reference in New Issue
Block a user