mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge mx-team to m-c
This commit is contained in:
commit
92b85e697e
@ -126,6 +126,33 @@ DevTools.prototype = {
|
||||
return tools.sort(this.ordinalSort);
|
||||
},
|
||||
|
||||
/**
|
||||
* Get a tool definition if it exists and is enabled.
|
||||
*
|
||||
* @param {string} toolId
|
||||
* The id of the tool to show
|
||||
*
|
||||
* @return {ToolDefinition|null} tool
|
||||
* The ToolDefinition for the id or null.
|
||||
*/
|
||||
getToolDefinition: function DT_getToolDefinition(toolId) {
|
||||
let tool = this._tools.get(toolId);
|
||||
if (!tool) {
|
||||
return null;
|
||||
} else if (tool.id == "options") {
|
||||
return tool;
|
||||
}
|
||||
|
||||
let enabled;
|
||||
try {
|
||||
enabled = Services.prefs.getBoolPref(tool.visibilityswitch);
|
||||
} catch (e) {
|
||||
enabled = true;
|
||||
}
|
||||
|
||||
return enabled ? tool : null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Allow ToolBoxes to get at the list of tools that they should populate
|
||||
* themselves with.
|
||||
@ -136,19 +163,12 @@ DevTools.prototype = {
|
||||
getToolDefinitionMap: function DT_getToolDefinitionMap() {
|
||||
let tools = new Map();
|
||||
|
||||
for (let [key, value] of this._tools) {
|
||||
let enabled;
|
||||
|
||||
try {
|
||||
enabled = Services.prefs.getBoolPref(value.visibilityswitch);
|
||||
} catch(e) {
|
||||
enabled = true;
|
||||
}
|
||||
|
||||
if (enabled || value.id == "options") {
|
||||
tools.set(key, value);
|
||||
for (let [id, definition] of this._tools) {
|
||||
if (this.getToolDefinition(id)) {
|
||||
tools.set(id, definition);
|
||||
}
|
||||
}
|
||||
|
||||
return tools;
|
||||
},
|
||||
|
||||
@ -162,8 +182,11 @@ DevTools.prototype = {
|
||||
*/
|
||||
getToolDefinitionArray: function DT_getToolDefinitionArray() {
|
||||
let definitions = [];
|
||||
for (let [id, definition] of this.getToolDefinitionMap()) {
|
||||
definitions.push(definition);
|
||||
|
||||
for (let [id, definition] of this._tools) {
|
||||
if (this.getToolDefinition(id)) {
|
||||
definitions.push(definition);
|
||||
}
|
||||
}
|
||||
|
||||
return definitions.sort(this.ordinalSort);
|
||||
@ -415,8 +438,7 @@ let gDevToolsBrowser = {
|
||||
selectToolCommand: function(gBrowser, toolId) {
|
||||
let target = devtools.TargetFactory.forTab(gBrowser.selectedTab);
|
||||
let toolbox = gDevTools.getToolbox(target);
|
||||
let tools = gDevTools.getToolDefinitionMap();
|
||||
let toolDefinition = tools.get(toolId);
|
||||
let toolDefinition = gDevTools.getToolDefinition(toolId);
|
||||
|
||||
if (toolbox && toolbox.currentToolId == toolId) {
|
||||
toolbox.fireCustomKey(toolId);
|
||||
@ -603,13 +625,6 @@ let gDevToolsBrowser = {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Skip if the tool is disabled.
|
||||
try {
|
||||
if (!Services.prefs.getBoolPref(toolDefinition.visibilityswitch)) {
|
||||
continue;
|
||||
}
|
||||
} catch(e) {}
|
||||
|
||||
let elements = gDevToolsBrowser._createToolMenuElements(toolDefinition, doc);
|
||||
|
||||
if (!elements) {
|
||||
|
@ -4,50 +4,44 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
const {Cc, Ci, Cu} = require("chrome");
|
||||
const MAX_ORDINAL = 99;
|
||||
const ZOOM_PREF = "devtools.toolbox.zoomValue";
|
||||
const MIN_ZOOM = 0.5;
|
||||
const MAX_ZOOM = 2;
|
||||
|
||||
let {Cc, Ci, Cu} = require("chrome");
|
||||
let promise = require("sdk/core/promise");
|
||||
let EventEmitter = require("devtools/shared/event-emitter");
|
||||
let Telemetry = require("devtools/shared/telemetry");
|
||||
let HUDService = require("devtools/webconsole/hudservice");
|
||||
|
||||
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource:///modules/devtools/gDevTools.jsm");
|
||||
Cu.import("resource:///modules/devtools/scratchpad-manager.jsm");
|
||||
|
||||
loader.lazyGetter(this, "Hosts", () => require("devtools/framework/toolbox-hosts").Hosts);
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "CommandUtils",
|
||||
"resource:///modules/devtools/DeveloperToolbar.jsm");
|
||||
loader.lazyImporter(this, "CommandUtils", "resource:///modules/devtools/DeveloperToolbar.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "toolboxStrings", function() {
|
||||
loader.lazyGetter(this, "toolboxStrings", () => {
|
||||
let bundle = Services.strings.createBundle("chrome://browser/locale/devtools/toolbox.properties");
|
||||
let l10n = function(aName, ...aArgs) {
|
||||
return (name, ...args) => {
|
||||
try {
|
||||
if (aArgs.length == 0) {
|
||||
return bundle.GetStringFromName(aName);
|
||||
} else {
|
||||
return bundle.formatStringFromName(aName, aArgs, aArgs.length);
|
||||
if (!args.length) {
|
||||
return bundle.GetStringFromName(name);
|
||||
}
|
||||
return bundle.formatStringFromName(name, args, args.length);
|
||||
} catch (ex) {
|
||||
Services.console.logStringMessage("Error reading '" + aName + "'");
|
||||
Services.console.logStringMessage("Error reading '" + name + "'");
|
||||
}
|
||||
};
|
||||
return l10n;
|
||||
});
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "Requisition", function() {
|
||||
let scope = {};
|
||||
Cu.import("resource://gre/modules/devtools/Require.jsm", scope);
|
||||
loader.lazyGetter(this, "Requisition", () => {
|
||||
let {require} = Cu.import("resource://gre/modules/devtools/Require.jsm", {});
|
||||
Cu.import("resource://gre/modules/devtools/gcli.jsm", {});
|
||||
|
||||
let req = scope.require;
|
||||
return req('gcli/cli').Requisition;
|
||||
return require("gcli/cli").Requisition;
|
||||
});
|
||||
|
||||
/**
|
||||
@ -69,6 +63,7 @@ function Toolbox(target, selectedTool, hostType) {
|
||||
|
||||
this._toolRegistered = this._toolRegistered.bind(this);
|
||||
this._toolUnregistered = this._toolUnregistered.bind(this);
|
||||
this._refreshHostTitle = this._refreshHostTitle.bind(this);
|
||||
this.destroy = this.destroy.bind(this);
|
||||
|
||||
this._target.on("close", this.destroy);
|
||||
@ -79,8 +74,7 @@ function Toolbox(target, selectedTool, hostType) {
|
||||
if (!selectedTool) {
|
||||
selectedTool = Services.prefs.getCharPref(this._prefs.LAST_TOOL);
|
||||
}
|
||||
let definitions = gDevTools.getToolDefinitionMap();
|
||||
if (!definitions.get(selectedTool) && selectedTool != "options") {
|
||||
if (!gDevTools.getToolDefinition(selectedTool)) {
|
||||
selectedTool = "webconsole";
|
||||
}
|
||||
this._defaultToolId = selectedTool;
|
||||
@ -89,7 +83,6 @@ function Toolbox(target, selectedTool, hostType) {
|
||||
|
||||
EventEmitter.decorate(this);
|
||||
|
||||
this._refreshHostTitle = this._refreshHostTitle.bind(this);
|
||||
this._target.on("navigate", this._refreshHostTitle);
|
||||
this.on("host-changed", this._refreshHostTitle);
|
||||
this.on("select", this._refreshHostTitle);
|
||||
@ -107,7 +100,7 @@ Toolbox.HostType = {
|
||||
BOTTOM: "bottom",
|
||||
SIDE: "side",
|
||||
WINDOW: "window"
|
||||
}
|
||||
};
|
||||
|
||||
Toolbox.prototype = {
|
||||
_URL: "chrome://browser/content/devtools/framework/toolbox.xul",
|
||||
@ -118,7 +111,7 @@ Toolbox.prototype = {
|
||||
SIDE_ENABLED: "devtools.toolbox.sideEnabled"
|
||||
},
|
||||
|
||||
HostType: Toolbox.HostType,
|
||||
currentToolId: null,
|
||||
|
||||
/**
|
||||
* Returns a *copy* of the _toolPanels collection.
|
||||
@ -126,20 +119,15 @@ Toolbox.prototype = {
|
||||
* @return {Map} panels
|
||||
* All the running panels in the toolbox
|
||||
*/
|
||||
getToolPanels: function TB_getToolPanels() {
|
||||
let panels = new Map();
|
||||
|
||||
for (let [key, value] of this._toolPanels) {
|
||||
panels.set(key, value);
|
||||
}
|
||||
return panels;
|
||||
getToolPanels: function() {
|
||||
return new Map(this._toolPanels);
|
||||
},
|
||||
|
||||
/**
|
||||
* Access the panel for a given tool
|
||||
*/
|
||||
getPanel: function TBOX_getPanel(id) {
|
||||
return this.getToolPanels().get(id);
|
||||
getPanel: function(id) {
|
||||
return this._toolPanels.get(id);
|
||||
},
|
||||
|
||||
/**
|
||||
@ -147,8 +135,8 @@ Toolbox.prototype = {
|
||||
* likely that we're going to want to get the panel that we've just made
|
||||
* visible
|
||||
*/
|
||||
getCurrentPanel: function TBOX_getCurrentPanel() {
|
||||
return this.getToolPanels().get(this.currentToolId);
|
||||
getCurrentPanel: function() {
|
||||
return this._toolPanels.get(this.currentToolId);
|
||||
},
|
||||
|
||||
/**
|
||||
@ -168,17 +156,6 @@ Toolbox.prototype = {
|
||||
return this._host.type;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get/alter the currently displayed tool.
|
||||
*/
|
||||
get currentToolId() {
|
||||
return this._currentToolId;
|
||||
},
|
||||
|
||||
set currentToolId(value) {
|
||||
this._currentToolId = value;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the iframe containing the toolbox UI.
|
||||
*/
|
||||
@ -203,10 +180,12 @@ Toolbox.prototype = {
|
||||
/**
|
||||
* Open the toolbox
|
||||
*/
|
||||
open: function TBOX_open() {
|
||||
open: function() {
|
||||
let deferred = promise.defer();
|
||||
|
||||
this._host.create().then(iframe => {
|
||||
return this._host.create().then(iframe => {
|
||||
let deferred = promise.defer();
|
||||
|
||||
let domReady = () => {
|
||||
iframe.removeEventListener("DOMContentLoaded", domReady, true);
|
||||
|
||||
@ -226,27 +205,27 @@ Toolbox.prototype = {
|
||||
|
||||
this._telemetry.toolOpened("toolbox");
|
||||
|
||||
this.selectTool(this._defaultToolId).then(function(panel) {
|
||||
this.selectTool(this._defaultToolId).then(panel => {
|
||||
this.emit("ready");
|
||||
deferred.resolve();
|
||||
}.bind(this));
|
||||
});
|
||||
};
|
||||
|
||||
iframe.addEventListener("DOMContentLoaded", domReady, true);
|
||||
iframe.setAttribute("src", this._URL);
|
||||
|
||||
return deferred.promise;
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
},
|
||||
|
||||
_buildOptions: function TBOX__buildOptions() {
|
||||
_buildOptions: function() {
|
||||
let key = this.doc.getElementById("toolbox-options-key");
|
||||
key.addEventListener("command", function(toolId) {
|
||||
this.selectTool(toolId);
|
||||
}.bind(this, "options"), true);
|
||||
key.addEventListener("command", () => {
|
||||
this.selectTool("options");
|
||||
}, true);
|
||||
},
|
||||
|
||||
_addToolSwitchingKeys: function TBOX__addToolSwitchingKeys() {
|
||||
_addToolSwitchingKeys: function() {
|
||||
let nextKey = this.doc.getElementById("toolbox-next-tool-key");
|
||||
nextKey.addEventListener("command", this.selectNextTool.bind(this), true);
|
||||
let prevKey = this.doc.getElementById("toolbox-previous-tool-key");
|
||||
@ -256,7 +235,7 @@ Toolbox.prototype = {
|
||||
/**
|
||||
* Wire up the listeners for the zoom keys.
|
||||
*/
|
||||
_addZoomKeys: function TBOX__addZoomKeys() {
|
||||
_addZoomKeys: function() {
|
||||
let inKey = this.doc.getElementById("toolbox-zoom-in-key");
|
||||
inKey.addEventListener("command", this.zoomIn.bind(this), true);
|
||||
|
||||
@ -273,28 +252,28 @@ Toolbox.prototype = {
|
||||
/**
|
||||
* Set zoom on toolbox to whatever the last setting was.
|
||||
*/
|
||||
_loadInitialZoom: function TBOX__loadInitialZoom() {
|
||||
_loadInitialZoom: function() {
|
||||
this.setZoom(this.zoomValue);
|
||||
},
|
||||
|
||||
/**
|
||||
* Increase zoom level of toolbox window - make things bigger.
|
||||
*/
|
||||
zoomIn: function TBOX__zoomIn() {
|
||||
zoomIn: function() {
|
||||
this.setZoom(this.zoomValue + 0.1);
|
||||
},
|
||||
|
||||
/**
|
||||
* Decrease zoom level of toolbox window - make things smaller.
|
||||
*/
|
||||
zoomOut: function TBOX__zoomOut() {
|
||||
zoomOut: function() {
|
||||
this.setZoom(this.zoomValue - 0.1);
|
||||
},
|
||||
|
||||
/**
|
||||
* Reset zoom level of the toolbox window.
|
||||
*/
|
||||
zoomReset: function TBOX__zoomReset() {
|
||||
zoomReset: function() {
|
||||
this.setZoom(1);
|
||||
},
|
||||
|
||||
@ -304,7 +283,7 @@ Toolbox.prototype = {
|
||||
* @param {number} zoomValue
|
||||
* Zoom level e.g. 1.2
|
||||
*/
|
||||
setZoom: function TBOX__setZoom(zoomValue) {
|
||||
setZoom: function(zoomValue) {
|
||||
// cap zoom value
|
||||
zoomValue = Math.max(zoomValue, MIN_ZOOM);
|
||||
zoomValue = Math.min(zoomValue, MAX_ZOOM);
|
||||
@ -320,60 +299,47 @@ Toolbox.prototype = {
|
||||
/**
|
||||
* Adds the keys and commands to the Toolbox Window in window mode.
|
||||
*/
|
||||
_addKeysToWindow: function TBOX__addKeysToWindow() {
|
||||
_addKeysToWindow: function() {
|
||||
if (this.hostType != Toolbox.HostType.WINDOW) {
|
||||
return;
|
||||
}
|
||||
|
||||
let doc = this.doc.defaultView.parent.document;
|
||||
|
||||
for (let [id, toolDefinition] of gDevTools.getToolDefinitionMap()) {
|
||||
if (toolDefinition.key) {
|
||||
// Prevent multiple entries for the same tool.
|
||||
if (doc.getElementById("key_" + id)) {
|
||||
continue;
|
||||
}
|
||||
let key = doc.createElement("key");
|
||||
key.id = "key_" + id;
|
||||
|
||||
if (toolDefinition.key.startsWith("VK_")) {
|
||||
key.setAttribute("keycode", toolDefinition.key);
|
||||
} else {
|
||||
key.setAttribute("key", toolDefinition.key);
|
||||
}
|
||||
|
||||
key.setAttribute("modifiers", toolDefinition.modifiers);
|
||||
key.setAttribute("oncommand", "void(0);"); // needed. See bug 371900
|
||||
key.addEventListener("command", function(toolId) {
|
||||
this.selectTool(toolId).then(() => {
|
||||
this.fireCustomKey(toolId);
|
||||
});
|
||||
}.bind(this, id), true);
|
||||
doc.getElementById("toolbox-keyset").appendChild(key);
|
||||
// Prevent multiple entries for the same tool.
|
||||
if (!toolDefinition.key || doc.getElementById("key_" + id)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Add key for opening Scratchpad from the detached window
|
||||
if(doc.getElementById("key_scratchpad") == null) {
|
||||
let toolId = id;
|
||||
let key = doc.createElement("key");
|
||||
key.id = "key_scratchpad";
|
||||
|
||||
key.setAttribute("keycode", toolboxStrings("scratchpad.keycode"));
|
||||
key.setAttribute("modifiers", "shift");
|
||||
key.setAttribute("oncommand", "void(0)"); // needed. See bug 371900
|
||||
key.addEventListener("command", function() {
|
||||
ScratchpadManager.openScratchpad();
|
||||
key.id = "key_" + toolId;
|
||||
|
||||
if (toolDefinition.key.startsWith("VK_")) {
|
||||
key.setAttribute("keycode", toolDefinition.key);
|
||||
} else {
|
||||
key.setAttribute("key", toolDefinition.key);
|
||||
}
|
||||
|
||||
key.setAttribute("modifiers", toolDefinition.modifiers);
|
||||
key.setAttribute("oncommand", "void(0);"); // needed. See bug 371900
|
||||
key.addEventListener("command", () => {
|
||||
this.selectTool(toolId).then(() => this.fireCustomKey(toolId));
|
||||
}, true);
|
||||
doc.getElementById("toolbox-keyset").appendChild(key);
|
||||
}
|
||||
|
||||
// Add key for toggling the browser console from the detached window
|
||||
if(doc.getElementById("key_browserconsole") == null) {
|
||||
if (!doc.getElementById("key_browserconsole")) {
|
||||
let key = doc.createElement("key");
|
||||
key.id = "key_browserconsole";
|
||||
|
||||
key.setAttribute("key", toolboxStrings("browserConsoleCmd.commandkey"));
|
||||
key.setAttribute("modifiers", "accel,shift");
|
||||
key.setAttribute("oncommand", "void(0)"); // needed. See bug 371900
|
||||
key.addEventListener("command", function() {
|
||||
key.addEventListener("command", () => {
|
||||
HUDService.toggleBrowserConsole();
|
||||
}, true);
|
||||
doc.getElementById("toolbox-keyset").appendChild(key);
|
||||
@ -386,12 +352,11 @@ Toolbox.prototype = {
|
||||
* @param {string} toolId
|
||||
* Which tool to run the command on (skip if not current)
|
||||
*/
|
||||
fireCustomKey: function TBOX_fireCustomKey(toolId) {
|
||||
let tools = gDevTools.getToolDefinitionMap();
|
||||
let activeToolDefinition = tools.get(toolId);
|
||||
fireCustomKey: function(toolId) {
|
||||
let toolDefinition = gDevTools.getToolDefinition(toolId);
|
||||
|
||||
if (activeToolDefinition.onkey && this.currentToolId === toolId) {
|
||||
activeToolDefinition.onkey(this.getCurrentPanel());
|
||||
if (toolDefinition.onkey && this.currentToolId === toolId) {
|
||||
toolDefinition.onkey(this.getCurrentPanel());
|
||||
}
|
||||
},
|
||||
|
||||
@ -399,7 +364,7 @@ Toolbox.prototype = {
|
||||
* Build the buttons for changing hosts. Called every time
|
||||
* the host changes.
|
||||
*/
|
||||
_buildDockButtons: function TBOX_createDockButtons() {
|
||||
_buildDockButtons: function() {
|
||||
let dockBox = this.doc.getElementById("toolbox-dock-buttons");
|
||||
|
||||
while (dockBox.firstChild) {
|
||||
@ -411,7 +376,7 @@ Toolbox.prototype = {
|
||||
}
|
||||
|
||||
let closeButton = this.doc.getElementById("toolbox-close");
|
||||
if (this.hostType === this.HostType.WINDOW) {
|
||||
if (this.hostType == Toolbox.HostType.WINDOW) {
|
||||
closeButton.setAttribute("hidden", "true");
|
||||
} else {
|
||||
closeButton.removeAttribute("hidden");
|
||||
@ -419,9 +384,10 @@ Toolbox.prototype = {
|
||||
|
||||
let sideEnabled = Services.prefs.getBoolPref(this._prefs.SIDE_ENABLED);
|
||||
|
||||
for each (let position in this.HostType) {
|
||||
for (let type in Toolbox.HostType) {
|
||||
let position = Toolbox.HostType[type];
|
||||
if (position == this.hostType ||
|
||||
(!sideEnabled && position == this.HostType.SIDE)) {
|
||||
(!sideEnabled && position == Toolbox.HostType.SIDE)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -430,9 +396,9 @@ Toolbox.prototype = {
|
||||
button.className = "toolbox-dock-button";
|
||||
button.setAttribute("tooltiptext", toolboxStrings("toolboxDockButtons." +
|
||||
position + ".tooltip"));
|
||||
button.addEventListener("command", function(position) {
|
||||
button.addEventListener("command", () => {
|
||||
this.switchHost(position);
|
||||
}.bind(this, position));
|
||||
});
|
||||
|
||||
dockBox.appendChild(button);
|
||||
}
|
||||
@ -441,7 +407,7 @@ Toolbox.prototype = {
|
||||
/**
|
||||
* Add tabs to the toolbox UI for registered tools
|
||||
*/
|
||||
_buildTabs: function TBOX_buildTabs() {
|
||||
_buildTabs: function() {
|
||||
for (let definition of gDevTools.getToolDefinitionArray()) {
|
||||
this._buildTabForTool(definition);
|
||||
}
|
||||
@ -450,18 +416,16 @@ Toolbox.prototype = {
|
||||
/**
|
||||
* Add buttons to the UI as specified in the devtools.window.toolbarSpec pref
|
||||
*/
|
||||
_buildButtons: function TBOX_buildButtons() {
|
||||
_buildButtons: function() {
|
||||
if (!this.target.isLocalTab) {
|
||||
return;
|
||||
}
|
||||
|
||||
let toolbarSpec = CommandUtils.getCommandbarSpec("devtools.toolbox.toolbarSpec");
|
||||
let spec = CommandUtils.getCommandbarSpec("devtools.toolbox.toolbarSpec");
|
||||
let env = CommandUtils.createEnvironment(this.target.tab.ownerDocument,
|
||||
this.target.window.document);
|
||||
let requisition = new Requisition(env);
|
||||
|
||||
let buttons = CommandUtils.createButtons(toolbarSpec, this._target, this.doc, requisition);
|
||||
|
||||
let req = new Requisition(env);
|
||||
let buttons = CommandUtils.createButtons(spec, this._target, this.doc, req);
|
||||
let container = this.doc.getElementById("toolbox-buttons");
|
||||
buttons.forEach(container.appendChild.bind(container));
|
||||
},
|
||||
@ -472,7 +436,7 @@ Toolbox.prototype = {
|
||||
* @param {string} toolDefinition
|
||||
* Tool definition of the tool to build a tab for.
|
||||
*/
|
||||
_buildTabForTool: function TBOX_buildTabForTool(toolDefinition) {
|
||||
_buildTabForTool: function(toolDefinition) {
|
||||
if (!toolDefinition.isTargetSupported(this._target)) {
|
||||
return;
|
||||
}
|
||||
@ -482,6 +446,10 @@ Toolbox.prototype = {
|
||||
|
||||
let id = toolDefinition.id;
|
||||
|
||||
if (toolDefinition.ordinal == undefined || toolDefinition.ordinal < 0) {
|
||||
toolDefinition.ordinal = MAX_ORDINAL;
|
||||
}
|
||||
|
||||
let radio = this.doc.createElement("radio");
|
||||
// The radio element is not being used in the conventional way, thus
|
||||
// the devtools-tab class replaces the radio XBL binding with its base
|
||||
@ -489,15 +457,12 @@ Toolbox.prototype = {
|
||||
radio.className = "toolbox-tab devtools-tab";
|
||||
radio.id = "toolbox-tab-" + id;
|
||||
radio.setAttribute("toolid", id);
|
||||
if (toolDefinition.ordinal == undefined || toolDefinition.ordinal < 0) {
|
||||
toolDefinition.ordinal = MAX_ORDINAL;
|
||||
}
|
||||
radio.setAttribute("ordinal", toolDefinition.ordinal);
|
||||
radio.setAttribute("tooltiptext", toolDefinition.tooltip);
|
||||
|
||||
radio.addEventListener("command", function(id) {
|
||||
radio.addEventListener("command", () => {
|
||||
this.selectTool(id);
|
||||
}.bind(this, id));
|
||||
});
|
||||
|
||||
// spacer lets us center the image and label, while allowing cropping
|
||||
let spacer = this.doc.createElement("spacer");
|
||||
@ -537,9 +502,8 @@ Toolbox.prototype = {
|
||||
+tabs.lastChild.getAttribute("ordinal") <= toolDefinition.ordinal) {
|
||||
tabs.appendChild(radio);
|
||||
deck.appendChild(vbox);
|
||||
}
|
||||
// else, iterate over all the tabs to get the correct location.
|
||||
else {
|
||||
} else {
|
||||
// else, iterate over all the tabs to get the correct location.
|
||||
Array.some(tabs.childNodes, (node, i) => {
|
||||
if (+node.getAttribute("ordinal") > toolDefinition.ordinal) {
|
||||
tabs.insertBefore(radio, node);
|
||||
@ -558,7 +522,7 @@ Toolbox.prototype = {
|
||||
* @param {string} id
|
||||
* The id of the tool to load.
|
||||
*/
|
||||
loadTool: function TBOX_loadTool(id) {
|
||||
loadTool: function(id) {
|
||||
let deferred = promise.defer();
|
||||
let iframe = this.doc.getElementById("toolbox-panel-iframe-" + id);
|
||||
|
||||
@ -567,18 +531,19 @@ Toolbox.prototype = {
|
||||
if (panel) {
|
||||
deferred.resolve(panel);
|
||||
} else {
|
||||
this.once(id + "-ready", (panel) => {
|
||||
this.once(id + "-ready", panel => {
|
||||
deferred.resolve(panel);
|
||||
});
|
||||
}
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
let definition = gDevTools.getToolDefinitionMap().get(id);
|
||||
let definition = gDevTools.getToolDefinition(id);
|
||||
if (!definition) {
|
||||
deferred.reject(new Error("no such tool id "+id));
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
iframe = this.doc.createElement("iframe");
|
||||
iframe.className = "toolbox-panel-iframe";
|
||||
iframe.id = "toolbox-panel-iframe-" + id;
|
||||
@ -612,17 +577,17 @@ Toolbox.prototype = {
|
||||
* @param {string} id
|
||||
* The id of the tool to switch to
|
||||
*/
|
||||
selectTool: function TBOX_selectTool(id) {
|
||||
selectTool: function(id) {
|
||||
let selected = this.doc.querySelector(".devtools-tab[selected]");
|
||||
if (selected) {
|
||||
selected.removeAttribute("selected");
|
||||
}
|
||||
|
||||
let tab = this.doc.getElementById("toolbox-tab-" + id);
|
||||
tab.setAttribute("selected", "true");
|
||||
|
||||
let prevToolId = this._currentToolId;
|
||||
|
||||
if (this._currentToolId == id) {
|
||||
if (this.currentToolId == id) {
|
||||
// re-focus tool to get key events again
|
||||
this.focusTool(id);
|
||||
|
||||
@ -633,11 +598,12 @@ Toolbox.prototype = {
|
||||
if (!this.isReady) {
|
||||
throw new Error("Can't select tool, wait for toolbox 'ready' event");
|
||||
}
|
||||
let tab = this.doc.getElementById("toolbox-tab-" + id);
|
||||
|
||||
tab = this.doc.getElementById("toolbox-tab-" + id);
|
||||
|
||||
if (tab) {
|
||||
if (prevToolId) {
|
||||
this._telemetry.toolClosed(prevToolId);
|
||||
if (this.currentToolId) {
|
||||
this._telemetry.toolClosed(this.currentToolId);
|
||||
}
|
||||
this._telemetry.toolOpened(id);
|
||||
} else {
|
||||
@ -662,12 +628,12 @@ Toolbox.prototype = {
|
||||
let deck = this.doc.getElementById("toolbox-deck");
|
||||
deck.selectedIndex = index;
|
||||
|
||||
this._currentToolId = id;
|
||||
this.currentToolId = id;
|
||||
if (id != "options") {
|
||||
Services.prefs.setCharPref(this._prefs.LAST_TOOL, id);
|
||||
}
|
||||
|
||||
return this.loadTool(id).then((panel) => {
|
||||
return this.loadTool(id).then(panel => {
|
||||
// focus the tool's frame to start receiving key events
|
||||
this.focusTool(id);
|
||||
|
||||
@ -690,7 +656,7 @@ Toolbox.prototype = {
|
||||
/**
|
||||
* Loads the tool next to the currently selected tool.
|
||||
*/
|
||||
selectNextTool: function TBOX_selectNextTool() {
|
||||
selectNextTool: function() {
|
||||
let selected = this.doc.querySelector(".devtools-tab[selected]");
|
||||
let next = selected.nextSibling || selected.parentNode.firstChild;
|
||||
let tool = next.getAttribute("toolid");
|
||||
@ -700,7 +666,7 @@ Toolbox.prototype = {
|
||||
/**
|
||||
* Loads the tool just left to the currently selected tool.
|
||||
*/
|
||||
selectPreviousTool: function TBOX_selectPreviousTool() {
|
||||
selectPreviousTool: function() {
|
||||
let selected = this.doc.querySelector(".devtools-tab[selected]");
|
||||
let previous = selected.previousSibling || selected.parentNode.lastChild;
|
||||
let tool = previous.getAttribute("toolid");
|
||||
@ -713,7 +679,7 @@ Toolbox.prototype = {
|
||||
* @param {string} id
|
||||
* The id of the tool to highlight
|
||||
*/
|
||||
highlightTool: function TBOX_highlightTool(id) {
|
||||
highlightTool: function(id) {
|
||||
let tab = this.doc.getElementById("toolbox-tab-" + id);
|
||||
tab && tab.classList.add("highlighted");
|
||||
},
|
||||
@ -724,7 +690,7 @@ Toolbox.prototype = {
|
||||
* @param {string} id
|
||||
* The id of the tool to unhighlight
|
||||
*/
|
||||
unhighlightTool: function TBOX_unhighlightTool(id) {
|
||||
unhighlightTool: function(id) {
|
||||
let tab = this.doc.getElementById("toolbox-tab-" + id);
|
||||
tab && tab.classList.remove("highlighted");
|
||||
},
|
||||
@ -732,17 +698,16 @@ Toolbox.prototype = {
|
||||
/**
|
||||
* Raise the toolbox host.
|
||||
*/
|
||||
raise: function TBOX_raise() {
|
||||
raise: function() {
|
||||
this._host.raise();
|
||||
},
|
||||
|
||||
/**
|
||||
* Refresh the host's title.
|
||||
*/
|
||||
_refreshHostTitle: function TBOX_refreshHostTitle() {
|
||||
_refreshHostTitle: function() {
|
||||
let toolName;
|
||||
let toolId = this.currentToolId;
|
||||
let toolDef = gDevTools.getToolDefinitionMap().get(toolId);
|
||||
let toolDef = gDevTools.getToolDefinition(this.currentToolId);
|
||||
if (toolDef) {
|
||||
toolName = toolDef.label;
|
||||
} else {
|
||||
@ -767,15 +732,14 @@ Toolbox.prototype = {
|
||||
* @return {Host} host
|
||||
* The created host object
|
||||
*/
|
||||
_createHost: function TBOX_createHost(hostType) {
|
||||
_createHost: function(hostType) {
|
||||
if (!Hosts[hostType]) {
|
||||
throw new Error('Unknown hostType: '+ hostType);
|
||||
throw new Error("Unknown hostType: " + hostType);
|
||||
}
|
||||
let newHost = new Hosts[hostType](this.target.tab);
|
||||
|
||||
// clean up the toolbox if its window is closed
|
||||
let newHost = new Hosts[hostType](this.target.tab);
|
||||
newHost.on("window-closed", this.destroy);
|
||||
|
||||
return newHost;
|
||||
},
|
||||
|
||||
@ -786,17 +750,13 @@ Toolbox.prototype = {
|
||||
* @param {string} hostType
|
||||
* The host type of the new host object
|
||||
*/
|
||||
switchHost: function TBOX_switchHost(hostType) {
|
||||
if (hostType == this._host.type) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this._target.isLocalTab) {
|
||||
switchHost: function(hostType) {
|
||||
if (hostType == this._host.type || !this._target.isLocalTab) {
|
||||
return;
|
||||
}
|
||||
|
||||
let newHost = this._createHost(hostType);
|
||||
return newHost.create().then(function(iframe) {
|
||||
return newHost.create().then(iframe => {
|
||||
// change toolbox document's parent to the new host
|
||||
iframe.QueryInterface(Ci.nsIFrameLoaderOwner);
|
||||
iframe.swapFrameLoaders(this.frame);
|
||||
@ -812,7 +772,7 @@ Toolbox.prototype = {
|
||||
this._addKeysToWindow();
|
||||
|
||||
this.emit("host-changed");
|
||||
}.bind(this));
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
@ -822,10 +782,8 @@ Toolbox.prototype = {
|
||||
* @param {string} toolId
|
||||
* Id of the tool that was registered
|
||||
*/
|
||||
_toolRegistered: function TBOX_toolRegistered(event, toolId) {
|
||||
let defs = gDevTools.getToolDefinitionMap();
|
||||
let tool = defs.get(toolId);
|
||||
|
||||
_toolRegistered: function(event, toolId) {
|
||||
let tool = gDevTools.getToolDefinition(toolId);
|
||||
this._buildTabForTool(tool);
|
||||
},
|
||||
|
||||
@ -837,7 +795,7 @@ Toolbox.prototype = {
|
||||
* Definition or id of the tool that was unregistered. Passing the
|
||||
* tool id should be avoided as it is a temporary measure.
|
||||
*/
|
||||
_toolUnregistered: function TBOX_toolUnregistered(event, toolId) {
|
||||
_toolUnregistered: function(event, toolId) {
|
||||
if (typeof toolId != "string") {
|
||||
toolId = toolId.id;
|
||||
}
|
||||
@ -852,7 +810,7 @@ Toolbox.prototype = {
|
||||
let panel = this.doc.getElementById("toolbox-panel-" + toolId);
|
||||
|
||||
if (radio) {
|
||||
if (this._currentToolId == toolId) {
|
||||
if (this.currentToolId == toolId) {
|
||||
let nextToolName = null;
|
||||
if (radio.nextSibling) {
|
||||
nextToolName = radio.nextSibling.getAttribute("toolid");
|
||||
@ -880,30 +838,24 @@ Toolbox.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Get the toolbox's notification box
|
||||
*
|
||||
* @return The notification box element.
|
||||
*/
|
||||
getNotificationBox: function TBOX_getNotificationBox() {
|
||||
getNotificationBox: function() {
|
||||
return this.doc.getElementById("toolbox-notificationbox");
|
||||
},
|
||||
|
||||
/**
|
||||
* Remove all UI elements, detach from target and clear up
|
||||
*/
|
||||
destroy: function TBOX_destroy() {
|
||||
destroy: function() {
|
||||
// If several things call destroy then we give them all the same
|
||||
// destruction promise so we're sure to destroy only once
|
||||
if (this._destroyer) {
|
||||
return this._destroyer;
|
||||
}
|
||||
// Assign the "_destroyer" property before calling the other
|
||||
// destroyer methods to guarantee that the Toolbox's destroy
|
||||
// method is only executed once.
|
||||
let deferred = promise.defer();
|
||||
this._destroyer = deferred.promise;
|
||||
|
||||
this._target.off("navigate", this._refreshHostTitle);
|
||||
this.off("select", this._refreshHostTitle);
|
||||
@ -917,7 +869,7 @@ Toolbox.prototype = {
|
||||
if (typeof this._origAllowJavascript != "undefined") {
|
||||
let docShell = this._host.hostTab.linkedBrowser.docShell;
|
||||
docShell.allowJavascript = this._origAllowJavascript;
|
||||
delete this._origAllowJavascript;
|
||||
this._origAllowJavascript = undefined;
|
||||
}
|
||||
|
||||
let outstanding = [];
|
||||
@ -925,14 +877,14 @@ Toolbox.prototype = {
|
||||
for (let [id, panel] of this._toolPanels) {
|
||||
try {
|
||||
outstanding.push(panel.destroy());
|
||||
} catch(e) {
|
||||
} catch (e) {
|
||||
// We don't want to stop here if any panel fail to close.
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
let container = this.doc.getElementById("toolbox-buttons");
|
||||
while(container.firstChild) {
|
||||
while (container.firstChild) {
|
||||
container.removeChild(container.firstChild);
|
||||
}
|
||||
|
||||
@ -940,7 +892,7 @@ Toolbox.prototype = {
|
||||
|
||||
this._telemetry.destroy();
|
||||
|
||||
promise.all(outstanding).then(() => {
|
||||
return this._destroyer = promise.all(outstanding).then(() => {
|
||||
// Targets need to be notified that the toolbox is being torn down.
|
||||
// This is done after other destruction tasks since it may tear down
|
||||
// fronts and the debugger transport which earlier destroy methods may
|
||||
@ -951,14 +903,11 @@ Toolbox.prototype = {
|
||||
target.off("close", this.destroy);
|
||||
return target.destroy();
|
||||
}
|
||||
}).then(function() {
|
||||
}).then(() => {
|
||||
this.emit("destroyed");
|
||||
// Free _host after the call to destroyed in order to let a chance
|
||||
// to destroyed listeners to still query toolbox attributes
|
||||
this._host = null;
|
||||
deferred.resolve();
|
||||
}.bind(this));
|
||||
|
||||
return this._destroyer;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
@ -8,10 +8,6 @@
|
||||
* singleton to provide data-level functionality to the views
|
||||
*/
|
||||
let TopSites = {
|
||||
_initialized: false,
|
||||
|
||||
Site: Site,
|
||||
|
||||
prepareCache: function(aForce){
|
||||
// front to the NewTabUtils' links cache
|
||||
// -ensure NewTabUtils.links links are pre-cached
|
||||
@ -151,6 +147,7 @@ let TopSites = {
|
||||
this._sitesDirty.clear();
|
||||
this.update();
|
||||
},
|
||||
|
||||
_linkFromNode: function _linkFromNode(aNode) {
|
||||
return {
|
||||
url: aNode.getAttribute("value"),
|
||||
|
@ -16,6 +16,9 @@ XPCOMUtils.defineLazyModuleGetter(this, "Downloads",
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "FormHistory",
|
||||
"resource://gre/modules/FormHistory.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "PageThumbs",
|
||||
"resource://gre/modules/PageThumbs.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "PluralForm",
|
||||
"resource://gre/modules/PluralForm.jsm");
|
||||
|
||||
|
@ -4,7 +4,6 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
"use strict";
|
||||
|
||||
Cu.import("resource://gre/modules/PageThumbs.jsm");
|
||||
Cu.import("resource://gre/modules/devtools/dbg-server.jsm")
|
||||
|
||||
/**
|
||||
@ -108,6 +107,7 @@ var BrowserUI = {
|
||||
PanelUI.init();
|
||||
FlyoutPanelsUI.init();
|
||||
PageThumbs.init();
|
||||
NewTabUtils.init();
|
||||
SettingsCharm.init();
|
||||
NavButtonSlider.init();
|
||||
|
||||
|
@ -424,6 +424,7 @@
|
||||
<label id="about-policy-label"
|
||||
onclick="FlyoutPanelsUI.AboutFlyoutPanel.onPolicyClick(event);"
|
||||
class="text-link" value="&aboutHeader.policy.label;"/>
|
||||
<spacer class="flyoutpanel-hack"/>
|
||||
</flyoutpanel>
|
||||
|
||||
#ifdef MOZ_SERVICES_SYNC
|
||||
@ -682,9 +683,12 @@
|
||||
<description>&doNotTrack.desc;</description>
|
||||
<setting id="prefs-dnt-value" pref="privacy.donottrackheader.value" type="radio" >
|
||||
<radiogroup id="prefs-dnt-options">
|
||||
<radio id="prefs-dnt-notrack" label="&doNotTrack.options.trackingNotOkay;" value="1"/>
|
||||
<radio id="prefs-dnt-nopref" label="&doNotTrack.options.noPreference;" value="-1"/>
|
||||
<radio id="prefs-dnt-oktrack" label="&doNotTrack.options.trackingOkay;" value="0"/>
|
||||
<radio id="prefs-dnt-notrack" class="flyoutpanel-hack"
|
||||
label="&doNotTrack.options.trackingNotOkay;" value="1"/>
|
||||
<radio id="prefs-dnt-nopref" class="flyoutpanel-hack"
|
||||
label="&doNotTrack.options.noPreference;" value="-1"/>
|
||||
<radio id="prefs-dnt-oktrack" class="flyoutpanel-hack"
|
||||
label="&doNotTrack.options.trackingOkay;" value="0"/>
|
||||
</radiogroup>
|
||||
</setting>
|
||||
</settings>
|
||||
|
@ -21,7 +21,6 @@ function TopSitesView(aGrid, aMaxSites) {
|
||||
getService(Ci.nsINavHistoryService);
|
||||
history.addObserver(this, false);
|
||||
|
||||
PageThumbs.addExpirationFilter(this);
|
||||
Services.obs.addObserver(this, "Metro:RefreshTopsiteThumbnail", false);
|
||||
|
||||
NewTabUtils.allPages.register(this);
|
||||
@ -40,7 +39,6 @@ TopSitesView.prototype = Util.extend(Object.create(View.prototype), {
|
||||
|
||||
destruct: function destruct() {
|
||||
Services.obs.removeObserver(this, "Metro:RefreshTopsiteThumbnail");
|
||||
PageThumbs.removeExpirationFilter(this);
|
||||
NewTabUtils.allPages.unregister(this);
|
||||
if (StartUI.chromeWin) {
|
||||
StartUI.chromeWin.removeEventListener('MozAppbarDismissing', this, false);
|
||||
@ -216,10 +214,6 @@ TopSitesView.prototype = Util.extend(Object.create(View.prototype), {
|
||||
}
|
||||
},
|
||||
|
||||
filterForThumbnailExpiration: function filterForThumbnailExpiration(aCallback) {
|
||||
aCallback([item.getAttribute("value") for (item of this._set.children)]);
|
||||
},
|
||||
|
||||
isFirstRun: function isFirstRun() {
|
||||
return prefs.getBoolPref("browser.firstrun.show.localepicker");
|
||||
},
|
||||
|
@ -86,7 +86,3 @@ flyoutpanel[visible] {
|
||||
.flyout-close-button:active {
|
||||
-moz-image-region: rect(0 96px 32px 64px);
|
||||
}
|
||||
|
||||
.flyout-narrow {
|
||||
width: 346px;
|
||||
}
|
||||
|
@ -840,7 +840,14 @@ appbar toolbar[labelled] toolbarbutton > .toolbarbutton-text {
|
||||
list-style-image: url(chrome://browser/skin/images/appbar-icons.png);
|
||||
}
|
||||
|
||||
.flyout-narrow description,
|
||||
.flyout-narrow label {
|
||||
max-width: 266px; /* Accounts for a 40px padding on each side of the flyout */
|
||||
/* Flyout panels (sidebars) ------------------------------------------------- */
|
||||
|
||||
.flyout-narrow {
|
||||
width: 346px;
|
||||
}
|
||||
|
||||
/* Some elements don't resize to fit their container properly for some reason.
|
||||
* Setting max-width on the element or a child fixes it. */
|
||||
.flyout-narrow .flyoutpanel-hack {
|
||||
max-width: calc(346px - 2 * 40px);
|
||||
}
|
||||
|
@ -111,7 +111,6 @@ richgriditem:not([tiletype="thumbnail"]) .tile-start-container {
|
||||
richgriditem:not([iconURI]) .tile-icon-box,
|
||||
richgriditem[iconURI=""] .tile-icon-box,
|
||||
richgriditem[iconsize="large"] .tile-icon-box {
|
||||
background-color: transparent!important;
|
||||
border-color: transparent!important;
|
||||
padding: 4px;
|
||||
}
|
||||
@ -129,6 +128,7 @@ richgriditem[iconsize="large"] .tile-icon-box > image,
|
||||
left: 52px; /* label goes to the right of the favicon */
|
||||
right: 0;
|
||||
padding: 1em 6px 6px 12px;
|
||||
background: white;
|
||||
color: #333;
|
||||
margin: 0;
|
||||
-moz-margin-start: 0;
|
||||
|
@ -1,30 +0,0 @@
|
||||
/* 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/. */
|
||||
|
||||
package org.mozilla.gecko.background.announcements;
|
||||
|
||||
import org.mozilla.gecko.background.BackgroundService;
|
||||
import org.mozilla.gecko.background.common.log.Logger;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
||||
/**
|
||||
* Start the announcements service when instructed by the {@link android.app.AlarmManager}.
|
||||
*/
|
||||
public class AnnouncementsStartReceiver extends BroadcastReceiver {
|
||||
|
||||
private static final String LOG_TAG = "AnnounceStartRec";
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (AnnouncementsConstants.DISABLED) {
|
||||
return;
|
||||
}
|
||||
|
||||
Logger.debug(LOG_TAG, "AnnouncementsStartReceiver.onReceive().");
|
||||
BackgroundService.runIntentInService(context, intent, AnnouncementsService.class);
|
||||
}
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
/* 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/. */
|
||||
|
||||
package org.mozilla.gecko.background.healthreport.upload;
|
||||
|
||||
import org.mozilla.gecko.background.common.log.Logger;
|
||||
import org.mozilla.gecko.background.healthreport.HealthReportConstants;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
||||
/**
|
||||
* Watch for notifications to start the Health Report background upload service.
|
||||
*
|
||||
* Some observations:
|
||||
*
|
||||
* From the Android documentation: "Also note that as of Android 3.0 the user
|
||||
* needs to have started the application at least once before your application
|
||||
* can receive android.intent.action.BOOT_COMPLETED events."
|
||||
*
|
||||
* We really do want to launch on BOOT_COMPLETED, since it's possible for a user
|
||||
* to run Firefox, shut down the phone, then power it on again on the same day.
|
||||
* We want to submit a health report in this case, even though they haven't
|
||||
* launched Firefox since boot.
|
||||
*/
|
||||
public class HealthReportBroadcastReceiver extends BroadcastReceiver {
|
||||
public static final String LOG_TAG = HealthReportBroadcastReceiver.class.getSimpleName();
|
||||
|
||||
/**
|
||||
* Forward the intent to an IntentService to do background processing.
|
||||
*/
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (HealthReportConstants.UPLOAD_FEATURE_DISABLED) {
|
||||
Logger.debug(LOG_TAG, "Health report upload feature is compile-time disabled; not forwarding intent.");
|
||||
return;
|
||||
}
|
||||
|
||||
Logger.debug(LOG_TAG, "Health report upload feature is compile-time enabled; forwarding intent.");
|
||||
Intent service = new Intent(context, HealthReportBroadcastService.class);
|
||||
service.putExtras(intent);
|
||||
service.setAction(intent.getAction());
|
||||
context.startService(service);
|
||||
}
|
||||
}
|
@ -1,165 +0,0 @@
|
||||
/* 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/. */
|
||||
|
||||
package org.mozilla.gecko.background.healthreport.upload;
|
||||
|
||||
import org.mozilla.gecko.background.BackgroundService;
|
||||
import org.mozilla.gecko.background.common.GlobalConstants;
|
||||
import org.mozilla.gecko.background.common.log.Logger;
|
||||
import org.mozilla.gecko.background.healthreport.HealthReportConstants;
|
||||
|
||||
import android.app.AlarmManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.SharedPreferences.Editor;
|
||||
|
||||
/**
|
||||
* A service which listens to broadcast intents from the system and from the
|
||||
* browser, registering or unregistering the main
|
||||
* {@link HealthReportUploadStartReceiver} with the {@link AlarmManager}.
|
||||
*/
|
||||
public class HealthReportBroadcastService extends BackgroundService {
|
||||
public static final String LOG_TAG = HealthReportBroadcastService.class.getSimpleName();
|
||||
public static final String WORKER_THREAD_NAME = LOG_TAG + "Worker";
|
||||
|
||||
public HealthReportBroadcastService() {
|
||||
super(WORKER_THREAD_NAME);
|
||||
}
|
||||
|
||||
protected SharedPreferences getSharedPreferences() {
|
||||
return this.getSharedPreferences(HealthReportConstants.PREFS_BRANCH, GlobalConstants.SHARED_PREFERENCES_MODE);
|
||||
}
|
||||
|
||||
public long getPollInterval() {
|
||||
return getSharedPreferences().getLong(HealthReportConstants.PREF_SUBMISSION_INTENT_INTERVAL_MSEC, HealthReportConstants.DEFAULT_SUBMISSION_INTENT_INTERVAL_MSEC);
|
||||
}
|
||||
|
||||
public void setPollInterval(long interval) {
|
||||
getSharedPreferences().edit().putLong(HealthReportConstants.PREF_SUBMISSION_INTENT_INTERVAL_MSEC, interval).commit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set or cancel an alarm to submit data for a profile.
|
||||
*
|
||||
* @param context
|
||||
* Android context.
|
||||
* @param profileName
|
||||
* to submit data for.
|
||||
* @param profilePath
|
||||
* to submit data for.
|
||||
* @param enabled
|
||||
* whether the user has enabled submitting health report data for
|
||||
* this profile.
|
||||
* @param serviceEnabled
|
||||
* whether submitting should be scheduled. If the user turns off
|
||||
* submitting, <code>enabled</code> could be false but we could need
|
||||
* to delete so <code>serviceEnabled</code> could be true.
|
||||
*/
|
||||
protected void toggleAlarm(final Context context, String profileName, String profilePath, boolean enabled, boolean serviceEnabled) {
|
||||
Logger.info(LOG_TAG, (serviceEnabled ? "R" : "Unr") + "egistering health report start broadcast receiver.");
|
||||
|
||||
// PendingIntents are compared without reference to their extras. Therefore
|
||||
// even though we pass the profile details to the action, different
|
||||
// profiles will share the *same* pending intent. In a multi-profile future,
|
||||
// this will need to be addressed. See Bug 882182.
|
||||
final Intent service = new Intent(context, HealthReportUploadStartReceiver.class);
|
||||
service.setAction("upload"); // PendingIntents "lose" their extras if no action is set.
|
||||
service.putExtra("uploadEnabled", enabled);
|
||||
service.putExtra("profileName", profileName);
|
||||
service.putExtra("profilePath", profilePath);
|
||||
final PendingIntent pending = PendingIntent.getBroadcast(context, 0, service, PendingIntent.FLAG_CANCEL_CURRENT);
|
||||
|
||||
if (!serviceEnabled) {
|
||||
cancelAlarm(pending);
|
||||
return;
|
||||
}
|
||||
|
||||
final long pollInterval = getPollInterval();
|
||||
scheduleAlarm(pollInterval, pending);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onHandleIntent(Intent intent) {
|
||||
Logger.setThreadLogTag(HealthReportConstants.GLOBAL_LOG_TAG);
|
||||
|
||||
if (HealthReportConstants.UPLOAD_FEATURE_DISABLED) {
|
||||
Logger.debug(LOG_TAG, "Health report upload feature is compile-time disabled; not handling intent.");
|
||||
return;
|
||||
}
|
||||
|
||||
final String action = intent.getAction();
|
||||
Logger.debug(LOG_TAG, "Health report upload feature is compile-time enabled; handling intent with action " + action + ".");
|
||||
|
||||
if (HealthReportConstants.ACTION_HEALTHREPORT_UPLOAD_PREF.equals(action)) {
|
||||
handlePrefIntent(intent);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Intent.ACTION_BOOT_COMPLETED.equals(action) ||
|
||||
Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(action)) {
|
||||
BackgroundService.reflectContextToFennec(this,
|
||||
GlobalConstants.GECKO_PREFERENCES_CLASS,
|
||||
GlobalConstants.GECKO_BROADCAST_HEALTHREPORT_UPLOAD_PREF_METHOD);
|
||||
return;
|
||||
}
|
||||
|
||||
// Failure case.
|
||||
Logger.warn(LOG_TAG, "Unknown intent " + action + ".");
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the intent sent by the browser when it wishes to notify us
|
||||
* of the value of the user preference. Look at the value and toggle the
|
||||
* alarm service accordingly.
|
||||
*/
|
||||
protected void handlePrefIntent(Intent intent) {
|
||||
if (!intent.hasExtra("enabled")) {
|
||||
Logger.warn(LOG_TAG, "Got " + HealthReportConstants.ACTION_HEALTHREPORT_UPLOAD_PREF + " intent without enabled. Ignoring.");
|
||||
return;
|
||||
}
|
||||
|
||||
final boolean enabled = intent.getBooleanExtra("enabled", true);
|
||||
Logger.debug(LOG_TAG, intent.getStringExtra("branch") + "/" +
|
||||
intent.getStringExtra("pref") + " = " +
|
||||
(intent.hasExtra("enabled") ? enabled : ""));
|
||||
|
||||
String profileName = intent.getStringExtra("profileName");
|
||||
String profilePath = intent.getStringExtra("profilePath");
|
||||
|
||||
if (profileName == null || profilePath == null) {
|
||||
Logger.warn(LOG_TAG, "Got " + HealthReportConstants.ACTION_HEALTHREPORT_UPLOAD_PREF + " intent without profilePath or profileName. Ignoring.");
|
||||
return;
|
||||
}
|
||||
|
||||
Logger.pii(LOG_TAG, "Updating health report alarm for profile " + profileName + " at " + profilePath + ".");
|
||||
|
||||
final SharedPreferences sharedPrefs = getSharedPreferences();
|
||||
final ObsoleteDocumentTracker tracker = new ObsoleteDocumentTracker(sharedPrefs);
|
||||
final boolean hasObsoleteIds = tracker.hasObsoleteIds();
|
||||
|
||||
if (!enabled) {
|
||||
final Editor editor = sharedPrefs.edit();
|
||||
editor.remove(HealthReportConstants.PREF_LAST_UPLOAD_DOCUMENT_ID);
|
||||
|
||||
if (hasObsoleteIds) {
|
||||
Logger.debug(LOG_TAG, "Health report upload disabled; scheduling deletion of " + tracker.numberOfObsoleteIds() + " documents.");
|
||||
tracker.limitObsoleteIds();
|
||||
} else {
|
||||
// Primarily intended for debugging and testing.
|
||||
Logger.debug(LOG_TAG, "Health report upload disabled and no deletes to schedule: clearing prefs.");
|
||||
editor.remove(HealthReportConstants.PREF_FIRST_RUN);
|
||||
editor.remove(HealthReportConstants.PREF_NEXT_SUBMISSION);
|
||||
}
|
||||
|
||||
editor.commit();
|
||||
}
|
||||
|
||||
// The user can toggle us off or on, or we can have obsolete documents to
|
||||
// remove.
|
||||
final boolean serviceEnabled = hasObsoleteIds || enabled;
|
||||
toggleAlarm(this, profileName, profilePath, enabled, serviceEnabled);
|
||||
}
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
/* 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/. */
|
||||
|
||||
package org.mozilla.gecko.background.healthreport.upload;
|
||||
|
||||
import org.mozilla.gecko.background.common.log.Logger;
|
||||
import org.mozilla.gecko.background.healthreport.HealthReportConstants;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
||||
/**
|
||||
* Start the Health Report background upload service when instructed by the
|
||||
* {@link android.app.AlarmManager}.
|
||||
*/
|
||||
public class HealthReportUploadStartReceiver extends BroadcastReceiver {
|
||||
public static final String LOG_TAG = HealthReportUploadStartReceiver.class.getSimpleName();
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (HealthReportConstants.UPLOAD_FEATURE_DISABLED) {
|
||||
Logger.debug(LOG_TAG, "Health report upload feature is compile-time disabled; not starting background upload service.");
|
||||
return;
|
||||
}
|
||||
|
||||
Logger.debug(LOG_TAG, "Health report upload feature is compile-time enabled; starting background upload service.");
|
||||
Intent service = new Intent(context, HealthReportUploadService.class);
|
||||
service.setAction(intent.getAction());
|
||||
service.putExtras(intent); // profileName, profilePath, uploadEnabled are in the extras.
|
||||
context.startService(service);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user