зеркало из https://github.com/mozilla/gecko-dev.git
merge m-c to fx-team
This commit is contained in:
Коммит
2ac1bf9865
|
@ -1038,6 +1038,7 @@ pref("devtools.toolbox.host", "bottom");
|
|||
pref("devtools.toolbox.selectedTool", "webconsole");
|
||||
pref("devtools.toolbox.toolbarSpec", '["paintflashing toggle","tilt toggle","scratchpad","resize toggle"]');
|
||||
pref("devtools.toolbox.sideEnabled", true);
|
||||
pref("devtools.toolbox.disabledTools", "[]");
|
||||
|
||||
// Enable the Inspector
|
||||
pref("devtools.inspector.enabled", true);
|
||||
|
|
|
@ -48,6 +48,7 @@ XPCOMUtils.defineLazyModuleGetter(this, "TargetFactory",
|
|||
gcli.addCommand({
|
||||
name: "addon list",
|
||||
description: gcli.lookup("addonListDesc"),
|
||||
returnType: "addonsInfo",
|
||||
params: [{
|
||||
name: 'type',
|
||||
type: {
|
||||
|
@ -55,70 +56,78 @@ XPCOMUtils.defineLazyModuleGetter(this, "TargetFactory",
|
|||
data: ["dictionary", "extension", "locale", "plugin", "theme", "all"]
|
||||
},
|
||||
defaultValue: 'all',
|
||||
description: gcli.lookup("addonListTypeDesc"),
|
||||
description: gcli.lookup("addonListTypeDesc")
|
||||
}],
|
||||
exec: function(aArgs, context) {
|
||||
function representEnabledAddon(aAddon) {
|
||||
return "<li><![CDATA[" + aAddon.name + "\u2002" + aAddon.version +
|
||||
getAddonStatus(aAddon) + "]]></li>";
|
||||
let deferred = context.defer();
|
||||
function pendingOperations(aAddon) {
|
||||
let allOperations = ["PENDING_ENABLE",
|
||||
"PENDING_DISABLE",
|
||||
"PENDING_UNINSTALL",
|
||||
"PENDING_INSTALL",
|
||||
"PENDING_UPGRADE"];
|
||||
return allOperations.reduce(function(operations, opName) {
|
||||
return aAddon.pendingOperations & AddonManager[opName] ?
|
||||
operations.concat(opName) :
|
||||
operations;
|
||||
}, []);
|
||||
}
|
||||
let types = aArgs.type === "all" ? null : [aArgs.type];
|
||||
AddonManager.getAddonsByTypes(types, function(addons) {
|
||||
deferred.resolve({
|
||||
addons: addons.map(function(addon) {
|
||||
return {
|
||||
name: addon.name,
|
||||
version: addon.version,
|
||||
isActive: addon.isActive,
|
||||
pendingOperations: pendingOperations(addon)
|
||||
};
|
||||
}),
|
||||
type: aArgs.type
|
||||
});
|
||||
});
|
||||
return deferred.promise;
|
||||
}
|
||||
});
|
||||
|
||||
gcli.addConverter({
|
||||
from: "addonsInfo",
|
||||
to: "view",
|
||||
exec: function(addonsInfo, context) {
|
||||
if (!addonsInfo.addons.length) {
|
||||
return context.createView({
|
||||
html: "<p>${message}</p>",
|
||||
data: { message: gcli.lookup("addonNoneOfType") }
|
||||
});
|
||||
}
|
||||
|
||||
function representDisabledAddon(aAddon) {
|
||||
return "<li class=\"gcli-addon-disabled\">" +
|
||||
"<![CDATA[" + aAddon.name + "\u2002" + aAddon.version + aAddon.version +
|
||||
"]]></li>";
|
||||
let headerLookups = {
|
||||
"dictionary": "addonListDictionaryHeading",
|
||||
"extension": "addonListExtensionHeading",
|
||||
"locale": "addonListLocaleHeading",
|
||||
"plugin": "addonListPluginHeading",
|
||||
"theme": "addonListThemeHeading",
|
||||
"all": "addonListAllHeading"
|
||||
};
|
||||
let header = gcli.lookup(headerLookups[addonsInfo.type] ||
|
||||
"addonListUnknownHeading");
|
||||
|
||||
let operationLookups = {
|
||||
"PENDING_ENABLE": "addonPendingEnable",
|
||||
"PENDING_DISABLE": "addonPendingDisable",
|
||||
"PENDING_UNINSTALL": "addonPendingUninstall",
|
||||
"PENDING_INSTALL": "addonPendingInstall",
|
||||
"PENDING_UPGRADE": "addonPendingUpgrade"
|
||||
};
|
||||
function lookupOperation(opName) {
|
||||
let lookupName = operationLookups[opName];
|
||||
return lookupName ? gcli.lookup(lookupName) : opName;
|
||||
}
|
||||
|
||||
function getAddonStatus(aAddon) {
|
||||
let operations = [];
|
||||
|
||||
if (aAddon.pendingOperations & AddonManager.PENDING_ENABLE) {
|
||||
operations.push("PENDING_ENABLE");
|
||||
}
|
||||
|
||||
if (aAddon.pendingOperations & AddonManager.PENDING_DISABLE) {
|
||||
operations.push("PENDING_DISABLE");
|
||||
}
|
||||
|
||||
if (aAddon.pendingOperations & AddonManager.PENDING_UNINSTALL) {
|
||||
operations.push("PENDING_UNINSTALL");
|
||||
}
|
||||
|
||||
if (aAddon.pendingOperations & AddonManager.PENDING_INSTALL) {
|
||||
operations.push("PENDING_INSTALL");
|
||||
}
|
||||
|
||||
if (aAddon.pendingOperations & AddonManager.PENDING_UPGRADE) {
|
||||
operations.push("PENDING_UPGRADE");
|
||||
}
|
||||
|
||||
if (operations.length) {
|
||||
return " (" + operations.join(", ") + ")";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares two addons by their name. Used in sorting.
|
||||
*/
|
||||
function compareAddonNames(aNameA, aNameB) {
|
||||
return String.localeCompare(aNameA.name, aNameB.name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the promise which is the scope (this) of this function, filling
|
||||
* it with an HTML representation of the passed add-ons.
|
||||
*/
|
||||
function list(aType, aAddons) {
|
||||
if (!aAddons.length) {
|
||||
this.resolve(gcli.lookup("addonNoneOfType"));
|
||||
}
|
||||
|
||||
// Separate the enabled add-ons from the disabled ones.
|
||||
function arrangeAddons(addons) {
|
||||
let enabledAddons = [];
|
||||
let disabledAddons = [];
|
||||
|
||||
aAddons.forEach(function(aAddon) {
|
||||
addons.forEach(function(aAddon) {
|
||||
if (aAddon.isActive) {
|
||||
enabledAddons.push(aAddon);
|
||||
} else {
|
||||
|
@ -126,48 +135,68 @@ XPCOMUtils.defineLazyModuleGetter(this, "TargetFactory",
|
|||
}
|
||||
});
|
||||
|
||||
let header;
|
||||
switch(aType) {
|
||||
case "dictionary":
|
||||
header = gcli.lookup("addonListDictionaryHeading");
|
||||
break;
|
||||
case "extension":
|
||||
header = gcli.lookup("addonListExtensionHeading");
|
||||
break;
|
||||
case "locale":
|
||||
header = gcli.lookup("addonListLocaleHeading");
|
||||
break;
|
||||
case "plugin":
|
||||
header = gcli.lookup("addonListPluginHeading");
|
||||
break;
|
||||
case "theme":
|
||||
header = gcli.lookup("addonListThemeHeading");
|
||||
case "all":
|
||||
header = gcli.lookup("addonListAllHeading");
|
||||
break;
|
||||
default:
|
||||
header = gcli.lookup("addonListUnknownHeading");
|
||||
function compareAddonNames(aNameA, aNameB) {
|
||||
return String.localeCompare(aNameA.name, aNameB.name);
|
||||
}
|
||||
enabledAddons.sort(compareAddonNames);
|
||||
disabledAddons.sort(compareAddonNames);
|
||||
|
||||
// Map and sort the add-ons, and create an HTML list.
|
||||
let message = header +
|
||||
"<ol>" +
|
||||
enabledAddons.sort(compareAddonNames).map(representEnabledAddon).join("") +
|
||||
disabledAddons.sort(compareAddonNames).map(representDisabledAddon).join("") +
|
||||
"</ol>";
|
||||
|
||||
this.resolve(context.createView({ html: message }));
|
||||
return enabledAddons.concat(disabledAddons);
|
||||
}
|
||||
|
||||
// Create the promise that will be resolved when the add-on listing has
|
||||
// been finished.
|
||||
let deferred = context.defer();
|
||||
let types = aArgs.type == "all" ? null : [aArgs.type];
|
||||
AddonManager.getAddonsByTypes(types, list.bind(deferred, aArgs.type));
|
||||
return deferred.promise;
|
||||
function isActiveForToggle(addon) {
|
||||
return (addon.isActive && ~~addon.pendingOperations.indexOf("PENDING_DISABLE"));
|
||||
}
|
||||
|
||||
return context.createView({
|
||||
html: addonsListHtml,
|
||||
data: {
|
||||
header: header,
|
||||
addons: arrangeAddons(addonsInfo.addons).map(function(addon) {
|
||||
return {
|
||||
name: addon.name,
|
||||
label: addon.name.replace(/\s/g, "_") +
|
||||
(addon.version ? "_" + addon.version : ""),
|
||||
status: addon.isActive ? "enabled" : "disabled",
|
||||
version: addon.version,
|
||||
pendingOperations: addon.pendingOperations.length ?
|
||||
(" (" + gcli.lookup("addonPending") + ": "
|
||||
+ addon.pendingOperations.map(lookupOperation).join(", ")
|
||||
+ ")") :
|
||||
"",
|
||||
toggleActionName: isActiveForToggle(addon) ? "disable": "enable",
|
||||
toggleActionMessage: isActiveForToggle(addon) ?
|
||||
gcli.lookup("addonListOutDisable") :
|
||||
gcli.lookup("addonListOutEnable")
|
||||
};
|
||||
}),
|
||||
onclick: createUpdateHandler(context),
|
||||
ondblclick: createExecuteHandler(context)
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
var addonsListHtml = "" +
|
||||
"<table>" +
|
||||
" <caption>${header}</caption>" +
|
||||
" <tbody>" +
|
||||
" <tr foreach='addon in ${addons}'" +
|
||||
" class=\"gcli-addon-${addon.status}\">" +
|
||||
" <td>${addon.name} ${addon.version}</td>" +
|
||||
" <td>${addon.pendingOperations}</td>" +
|
||||
" <td>" +
|
||||
" <span class='gcli-out-shortcut'" +
|
||||
" data-command='addon ${addon.toggleActionName} ${addon.label}'" +
|
||||
" onclick='${onclick}'" +
|
||||
" ondblclick='${ondblclick}'" +
|
||||
" >${addon.toggleActionMessage}</span>" +
|
||||
" </td>" +
|
||||
" </tr>" +
|
||||
" </tbody>" +
|
||||
"</table>" +
|
||||
"";
|
||||
|
||||
// We need a list of addon names for the enable and disable commands. Because
|
||||
// getting the name list is async we do not add the commands until we have the
|
||||
// list.
|
||||
|
@ -310,6 +339,57 @@ XPCOMUtils.defineLazyModuleGetter(this, "TargetFactory",
|
|||
module.CmdAddonFlags.addonsLoaded = true;
|
||||
Services.obs.notifyObservers(null, "gcli_addon_commands_ready", null);
|
||||
});
|
||||
|
||||
/**
|
||||
* Helper to find the 'data-command' attribute and call some action on it.
|
||||
* @see |updateCommand()| and |executeCommand()|
|
||||
*/
|
||||
function withCommand(element, action) {
|
||||
var command = element.getAttribute("data-command");
|
||||
if (!command) {
|
||||
command = element.querySelector("*[data-command]")
|
||||
.getAttribute("data-command");
|
||||
}
|
||||
|
||||
if (command) {
|
||||
action(command);
|
||||
}
|
||||
else {
|
||||
console.warn("Missing data-command for " + util.findCssSelector(element));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a handler to update the requisition to contain the text held in the
|
||||
* first matching data-command attribute under the currentTarget of the event.
|
||||
* @param context Either a Requisition or an ExecutionContext or another object
|
||||
* that contains an |update()| function that follows a similar contract.
|
||||
*/
|
||||
function createUpdateHandler(context) {
|
||||
return function(ev) {
|
||||
withCommand(ev.currentTarget, function(command) {
|
||||
context.update(command);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a handler to execute the text held in the data-command attribute
|
||||
* under the currentTarget of the event.
|
||||
* @param context Either a Requisition or an ExecutionContext or another object
|
||||
* that contains an |update()| function that follows a similar contract.
|
||||
*/
|
||||
function createExecuteHandler(context) {
|
||||
return function(ev) {
|
||||
withCommand(ev.currentTarget, function(command) {
|
||||
context.exec({
|
||||
visible: true,
|
||||
typed: command
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}(this));
|
||||
|
||||
/* CmdCalllog -------------------------------------------------------------- */
|
||||
|
|
|
@ -200,10 +200,6 @@
|
|||
key="&debuggerUI.searchFunction.key;"
|
||||
modifiers="accel"
|
||||
command="functionSearchCommand"/>
|
||||
<key id="functionSearchKey"
|
||||
key="&debuggerUI.searchFunction.altkey;"
|
||||
modifiers="accel shift"
|
||||
command="functionSearchCommand"/>
|
||||
<key id="tokenSearchKey"
|
||||
key="&debuggerUI.searchToken.key;"
|
||||
modifiers="accel"
|
||||
|
|
|
@ -135,7 +135,7 @@ this.Toolbox = function Toolbox(target, selectedTool, hostType) {
|
|||
selectedTool = Services.prefs.getCharPref(this._prefs.LAST_TOOL);
|
||||
}
|
||||
let definitions = gDevTools.getToolDefinitionMap();
|
||||
if (!definitions.get(selectedTool)) {
|
||||
if (!definitions.get(selectedTool) && selectedTool != "options") {
|
||||
selectedTool = "webconsole";
|
||||
}
|
||||
this._defaultToolId = selectedTool;
|
||||
|
@ -263,6 +263,7 @@ Toolbox.prototype = {
|
|||
closeButton.addEventListener("command", this.destroy, true);
|
||||
|
||||
this._buildDockButtons();
|
||||
this._buildOptions();
|
||||
this._buildTabs();
|
||||
this._buildButtons();
|
||||
this._addKeysToWindow();
|
||||
|
@ -280,6 +281,21 @@ Toolbox.prototype = {
|
|||
return deferred.promise;
|
||||
},
|
||||
|
||||
_buildOptions: function TBOX__buildOptions() {
|
||||
this.optionsButton = this.doc.getElementById("toolbox-tab-options");
|
||||
this.optionsButton.addEventListener("command", function() {
|
||||
this.selectTool("options");
|
||||
}.bind(this), false);
|
||||
|
||||
let iframe = this.doc.getElementById("toolbox-panel-iframe-options");
|
||||
this._toolPanels.set("options", iframe);
|
||||
|
||||
let key = this.doc.getElementById("toolbox-options-key");
|
||||
key.addEventListener("command", function(toolId) {
|
||||
this.selectTool(toolId);
|
||||
}.bind(this, "options"), true);
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds the keys and commands to the Toolbox Window in window mode.
|
||||
*/
|
||||
|
@ -288,7 +304,7 @@ Toolbox.prototype = {
|
|||
return;
|
||||
}
|
||||
let doc = this.doc.defaultView.parent.document;
|
||||
for (let [id, toolDefinition] of gDevTools._tools) {
|
||||
for (let [id, toolDefinition] of gDevTools.getToolDefinitionMap()) {
|
||||
if (toolDefinition.key) {
|
||||
// Prevent multiple entries for the same tool.
|
||||
if (doc.getElementById("key_" + id)) {
|
||||
|
@ -475,16 +491,30 @@ Toolbox.prototype = {
|
|||
break;
|
||||
}
|
||||
}
|
||||
tabstrip.selectedIndex = index;
|
||||
tabstrip.selectedItem = tab;
|
||||
|
||||
// and select the right iframe
|
||||
let deck = this.doc.getElementById("toolbox-deck");
|
||||
deck.selectedIndex = index;
|
||||
// offset by 1 due to options panel
|
||||
if (id == "options") {
|
||||
deck.selectedIndex = 0;
|
||||
this.optionsButton.setAttribute("checked", true);
|
||||
}
|
||||
else {
|
||||
deck.selectedIndex = index != -1 ? index + 1: -1;
|
||||
this.optionsButton.removeAttribute("checked");
|
||||
}
|
||||
|
||||
let definition = gDevTools.getToolDefinitionMap().get(id);
|
||||
|
||||
this._currentToolId = id;
|
||||
|
||||
let resolveSelected = panel => {
|
||||
this.emit("select", id);
|
||||
this.emit(id + "-selected", panel);
|
||||
deferred.resolve(panel);
|
||||
};
|
||||
|
||||
let iframe = this.doc.getElementById("toolbox-panel-iframe-" + id);
|
||||
if (!iframe) {
|
||||
iframe = this.doc.createElement("iframe");
|
||||
|
@ -505,11 +535,9 @@ Toolbox.prototype = {
|
|||
this._toolPanels.set(id, panel);
|
||||
|
||||
this.emit(id + "-ready", panel);
|
||||
this.emit("select", id);
|
||||
this.emit(id + "-selected", panel);
|
||||
gDevTools.emit(id + "-ready", this, panel);
|
||||
|
||||
deferred.resolve(panel);
|
||||
resolveSelected(panel);
|
||||
}.bind(this));
|
||||
}.bind(this);
|
||||
|
||||
|
@ -518,14 +546,22 @@ Toolbox.prototype = {
|
|||
} else {
|
||||
let panel = this._toolPanels.get(id);
|
||||
// only emit 'select' event if the iframe has been loaded
|
||||
if (panel) {
|
||||
this.emit("select", id);
|
||||
this.emit(id + "-selected", panel);
|
||||
deferred.resolve(panel);
|
||||
if (panel && (!panel.contentDocument ||
|
||||
panel.contentDocument.readyState == "complete")) {
|
||||
resolveSelected(panel);
|
||||
}
|
||||
else if (panel) {
|
||||
let boundLoad = function() {
|
||||
panel.removeEventListener("DOMContentLoaded", boundLoad, true);
|
||||
resolveSelected(panel);
|
||||
};
|
||||
panel.addEventListener("DOMContentLoaded", boundLoad, true);
|
||||
}
|
||||
}
|
||||
|
||||
Services.prefs.setCharPref(this._prefs.LAST_TOOL, id);
|
||||
if (id != "options") {
|
||||
Services.prefs.setCharPref(this._prefs.LAST_TOOL, id);
|
||||
}
|
||||
|
||||
return deferred.promise;
|
||||
},
|
||||
|
@ -543,8 +579,8 @@ Toolbox.prototype = {
|
|||
_refreshHostTitle: function TBOX_refreshHostTitle() {
|
||||
let toolName;
|
||||
let toolId = this.currentToolId;
|
||||
if (toolId) {
|
||||
let toolDef = gDevTools.getToolDefinitionMap().get(toolId);
|
||||
let toolDef = gDevTools.getToolDefinitionMap().get(toolId);
|
||||
if (toolDef) {
|
||||
toolName = toolDef.label;
|
||||
} else {
|
||||
// no tool is selected
|
||||
|
@ -638,6 +674,12 @@ Toolbox.prototype = {
|
|||
* Id of the tool that was unregistered
|
||||
*/
|
||||
_toolUnregistered: function TBOX_toolUnregistered(event, toolId) {
|
||||
if (this._toolPanels.has(toolId)) {
|
||||
let instance = this._toolPanels.get(toolId);
|
||||
instance.destroy();
|
||||
this._toolPanels.delete(toolId);
|
||||
}
|
||||
|
||||
let radio = this.doc.getElementById("toolbox-tab-" + toolId);
|
||||
let panel = this.doc.getElementById("toolbox-panel-" + toolId);
|
||||
|
||||
|
@ -668,12 +710,6 @@ Toolbox.prototype = {
|
|||
key.parentNode.removeChild(key);
|
||||
}
|
||||
}
|
||||
|
||||
if (this._toolPanels.has(toolId)) {
|
||||
let instance = this._toolPanels.get(toolId);
|
||||
instance.destroy();
|
||||
this._toolPanels.delete(toolId);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
|
@ -710,6 +746,7 @@ Toolbox.prototype = {
|
|||
|
||||
let outstanding = [];
|
||||
|
||||
this._toolPanels.delete("options");
|
||||
for (let [id, panel] of this._toolPanels) {
|
||||
outstanding.push(panel.destroy());
|
||||
}
|
||||
|
|
|
@ -97,6 +97,20 @@ DevTools.prototype = {
|
|||
}
|
||||
},
|
||||
|
||||
getDefaultTools: function DT_getDefaultTools() {
|
||||
return defaultTools;
|
||||
},
|
||||
|
||||
getAdditionalTools: function DT_getAdditionalTools() {
|
||||
let tools = [];
|
||||
for (let [key, value] of this._tools) {
|
||||
if (defaultTools.indexOf(value) == -1) {
|
||||
tools.push(value);
|
||||
}
|
||||
}
|
||||
return tools;
|
||||
},
|
||||
|
||||
/**
|
||||
* Allow ToolBoxes to get at the list of tools that they should populate
|
||||
* themselves with.
|
||||
|
@ -106,6 +120,10 @@ DevTools.prototype = {
|
|||
*/
|
||||
getToolDefinitionMap: function DT_getToolDefinitionMap() {
|
||||
let tools = new Map();
|
||||
let disabledTools = [];
|
||||
try {
|
||||
disabledTools = JSON.parse(Services.prefs.getCharPref("devtools.toolbox.disabledTools"));
|
||||
} catch(ex) {}
|
||||
|
||||
for (let [key, value] of this._tools) {
|
||||
let enabled;
|
||||
|
@ -116,7 +134,7 @@ DevTools.prototype = {
|
|||
enabled = true;
|
||||
}
|
||||
|
||||
if (enabled) {
|
||||
if (enabled && disabledTools.indexOf(key) == -1) {
|
||||
tools.set(key, value);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ MOCHITEST_BROWSER_FILES = \
|
|||
browser_toolbox_sidebar.js \
|
||||
browser_toolbox_window_shortcuts.js \
|
||||
browser_toolbox_window_title_changes.js \
|
||||
browser_toolbox_options.js \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
|
|
@ -0,0 +1,142 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
let tempScope = {};
|
||||
Cu.import("resource:///modules/devtools/Target.jsm", tempScope);
|
||||
let TargetFactory = tempScope.TargetFactory;
|
||||
let doc = null, toolbox = null, panelWin = null, index = 0, prefValues = [], prefNodes = [];
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
let target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onLoad(evt) {
|
||||
gBrowser.selectedBrowser.removeEventListener(evt.type, onLoad, true);
|
||||
gDevTools.showToolbox(target).then(testSelectTool);
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html,test for dynamically registering and unregistering tools";
|
||||
}
|
||||
|
||||
function testSelectTool(aToolbox) {
|
||||
toolbox = aToolbox;
|
||||
doc = toolbox.doc;
|
||||
toolbox.once("options-selected", testOptionsShortcut);
|
||||
toolbox.selectTool("options");
|
||||
}
|
||||
|
||||
function testOptionsShortcut() {
|
||||
ok(true, "Toolbox selected via selectTool method");
|
||||
toolbox.once("options-selected", testOptionsButtonClick);
|
||||
toolbox.selectTool("webconsole")
|
||||
.then(() => synthesizeKeyFromKeyTag("toolbox-options-key", doc));
|
||||
}
|
||||
|
||||
function testOptionsButtonClick() {
|
||||
ok(true, "Toolbox selected via shortcut");
|
||||
toolbox.once("options-selected", testOptions);
|
||||
toolbox.selectTool("webconsole")
|
||||
.then(() => doc.getElementById("toolbox-tab-options").click());
|
||||
}
|
||||
|
||||
function testOptions(event, iframe) {
|
||||
ok(true, "Toolbox selected via button click");
|
||||
panelWin = iframe.contentWindow;
|
||||
let panelDoc = iframe.contentDocument;
|
||||
// Testing pref changes
|
||||
let prefCheckboxes = panelDoc.querySelectorAll("checkbox[data-pref]");
|
||||
for (let checkbox of prefCheckboxes) {
|
||||
prefNodes.push(checkbox);
|
||||
prefValues.push(Services.prefs.getBoolPref(checkbox.getAttribute("data-pref")));
|
||||
}
|
||||
// Do again with opposite values to reset prefs
|
||||
for (let checkbox of prefCheckboxes) {
|
||||
prefNodes.push(checkbox);
|
||||
prefValues.push(!Services.prefs.getBoolPref(checkbox.getAttribute("data-pref")));
|
||||
}
|
||||
testMouseClicks();
|
||||
}
|
||||
|
||||
function testMouseClicks() {
|
||||
if (index == prefValues.length) {
|
||||
checkTools();
|
||||
return;
|
||||
}
|
||||
gDevTools.once("pref-changed", prefChanged);
|
||||
info("Click event synthesized for index " + index);
|
||||
EventUtils.synthesizeMouse(prefNodes[index], 10, 10, {}, panelWin);
|
||||
}
|
||||
|
||||
function prefChanged(event, data) {
|
||||
if (data.pref == prefNodes[index].getAttribute("data-pref")) {
|
||||
ok(true, "Correct pref was changed");
|
||||
is(data.oldValue, prefValues[index], "Previous value is correct");
|
||||
is(data.newValue, !prefValues[index], "New value is correct");
|
||||
index++;
|
||||
testMouseClicks();
|
||||
return;
|
||||
}
|
||||
ok(false, "Pref was not changed correctly");
|
||||
cleanup();
|
||||
}
|
||||
|
||||
function checkTools() {
|
||||
let toolsPref = panelWin.document.querySelectorAll("#default-tools-box > checkbox");
|
||||
prefNodes = [];
|
||||
index = 0;
|
||||
for (let tool of toolsPref) {
|
||||
prefNodes.push(tool);
|
||||
}
|
||||
toggleTools();
|
||||
}
|
||||
|
||||
function toggleTools() {
|
||||
if (index < prefNodes.length) {
|
||||
gDevTools.once("tool-unregistered", checkUnregistered);
|
||||
EventUtils.synthesizeMouse(prefNodes[index], 10, 10, {}, panelWin);
|
||||
}
|
||||
else if (index < 2*prefNodes.length) {
|
||||
gDevTools.once("tool-registered", checkRegistered);
|
||||
EventUtils.synthesizeMouse(prefNodes[index - prefNodes.length], 10, 10, {}, panelWin);
|
||||
}
|
||||
else {
|
||||
cleanup();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
function checkUnregistered(event, data) {
|
||||
if (data == prefNodes[index].getAttribute("id")) {
|
||||
ok(true, "Correct tool removed");
|
||||
// checking tab on the toolbox
|
||||
ok(!doc.getElementById("toolbox-tab-" + data), "Tab removed for " + data);
|
||||
index++;
|
||||
toggleTools();
|
||||
return;
|
||||
}
|
||||
ok(false, "Something went wrong, " + data + " was not unregistered");
|
||||
cleanup();
|
||||
}
|
||||
|
||||
function checkRegistered(event, data) {
|
||||
if (data == prefNodes[index - prefNodes.length].getAttribute("id")) {
|
||||
ok(true, "Correct tool added back");
|
||||
// checking tab on the toolbox
|
||||
ok(doc.getElementById("toolbox-tab-" + data), "Tab added back for " + data);
|
||||
index++;
|
||||
toggleTools();
|
||||
return;
|
||||
}
|
||||
ok(false, "Something went wrong, " + data + " was not registered back");
|
||||
cleanup();
|
||||
}
|
||||
|
||||
function cleanup() {
|
||||
toolbox.destroy().then(function() {
|
||||
gBrowser.removeCurrentTab();
|
||||
toolbox = doc = prefNodes = prefValues = panelWin = null;
|
||||
finish();
|
||||
});
|
||||
}
|
|
@ -47,3 +47,29 @@ registerCleanupFunction(function tearDown() {
|
|||
gBrowser.removeCurrentTab();
|
||||
}
|
||||
});
|
||||
|
||||
function synthesizeKeyFromKeyTag(aKeyId, document) {
|
||||
let key = document.getElementById(aKeyId);
|
||||
isnot(key, null, "Successfully retrieved the <key> node");
|
||||
|
||||
let modifiersAttr = key.getAttribute("modifiers");
|
||||
|
||||
let name = null;
|
||||
|
||||
if (key.getAttribute("keycode"))
|
||||
name = key.getAttribute("keycode");
|
||||
else if (key.getAttribute("key"))
|
||||
name = key.getAttribute("key");
|
||||
|
||||
isnot(name, null, "Successfully retrieved keycode/key");
|
||||
|
||||
let modifiers = {
|
||||
shiftKey: modifiersAttr.match("shift"),
|
||||
ctrlKey: modifiersAttr.match("ctrl"),
|
||||
altKey: modifiersAttr.match("alt"),
|
||||
metaKey: modifiersAttr.match("meta"),
|
||||
accelKey: modifiersAttr.match("accel")
|
||||
}
|
||||
|
||||
EventUtils.synthesizeKey(name, modifiers);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,105 @@
|
|||
|
||||
const { utils: Cu } = Components;
|
||||
const DISABLED_TOOLS = "devtools.toolbox.disabledTools";
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource:///modules/devtools/gDevTools.jsm");
|
||||
|
||||
window.addEventListener("load", function onLoad() {
|
||||
window.removeEventListener("load", onLoad);
|
||||
setupToolsList();
|
||||
populatePreferences();
|
||||
});
|
||||
|
||||
function setupToolsList() {
|
||||
let disabledTools = [];
|
||||
try {
|
||||
disabledTools = JSON.parse(Services.prefs.getCharPref(DISABLED_TOOLS));
|
||||
} catch(ex) {
|
||||
Cu.reportError("Error parsing pref " + DISABLED_TOOLS + " as JSON.");
|
||||
}
|
||||
let defaultToolsBox = document.getElementById("default-tools-box");
|
||||
let additionalToolsBox = document.getElementById("additional-tools-box");
|
||||
|
||||
defaultToolsBox.textContent = "";
|
||||
additionalToolsBox.textContent = "";
|
||||
|
||||
let onCheckboxClick = function(id) {
|
||||
if (disabledTools.indexOf(id) > -1) {
|
||||
disabledTools.splice(disabledTools.indexOf(id), 1);
|
||||
Services.prefs.setCharPref(DISABLED_TOOLS, JSON.stringify(disabledTools));
|
||||
gDevTools.emit("tool-registered", id);
|
||||
}
|
||||
else {
|
||||
disabledTools.push(id);
|
||||
Services.prefs.setCharPref(DISABLED_TOOLS, JSON.stringify(disabledTools));
|
||||
gDevTools.emit("tool-unregistered", id);
|
||||
}
|
||||
};
|
||||
|
||||
// Populating the default tools lists
|
||||
for (let tool of gDevTools.getDefaultTools()) {
|
||||
let checkbox = document.createElement("checkbox");
|
||||
checkbox.setAttribute("id", tool.id);
|
||||
checkbox.setAttribute("label", tool.label);
|
||||
checkbox.setAttribute("tooltiptext", tool.tooltip || "");
|
||||
checkbox.setAttribute("checked", disabledTools.indexOf(tool.id) == -1);
|
||||
checkbox.addEventListener("command", onCheckboxClick.bind(null, tool.id));
|
||||
defaultToolsBox.appendChild(checkbox);
|
||||
}
|
||||
|
||||
// Populating the additional tools list that came from add-ons.
|
||||
let atleastOneAddon = false;
|
||||
for (let tool of gDevTools.getAdditionalTools()) {
|
||||
atleastOneAddon = true;
|
||||
let checkbox = document.createElement("checkbox");
|
||||
checkbox.setAttribute("id", tool.id);
|
||||
checkbox.setAttribute("label", tool.label);
|
||||
checkbox.setAttribute("tooltiptext", tool.tooltip || "");
|
||||
checkbox.setAttribute("checked", disabledTools.indexOf(tool.id) == -1);
|
||||
checkbox.addEventListener("command", onCheckboxClick.bind(null, tool.id));
|
||||
additionalToolsBox.appendChild(checkbox);
|
||||
}
|
||||
|
||||
if (!atleastOneAddon) {
|
||||
additionalToolsBox.style.display = "none";
|
||||
additionalToolsBox.previousSibling.style.display = "none";
|
||||
}
|
||||
|
||||
window.focus();
|
||||
}
|
||||
|
||||
function populatePreferences() {
|
||||
let prefCheckboxes = document.querySelectorAll("checkbox[data-pref]");
|
||||
for (let checkbox of prefCheckboxes) {
|
||||
checkbox.checked = Services.prefs.getBoolPref(checkbox.getAttribute("data-pref"));
|
||||
checkbox.addEventListener("command", function() {
|
||||
let data = {
|
||||
pref: this.getAttribute("data-pref"),
|
||||
newValue: this.checked
|
||||
};
|
||||
data.oldValue = Services.prefs.getBoolPref(data.pref);
|
||||
Services.prefs.setBoolPref(data.pref, data.newValue);
|
||||
gDevTools.emit("pref-changed", data);
|
||||
}.bind(checkbox));
|
||||
}
|
||||
let prefRadiogroups = document.querySelectorAll("radiogroup[data-pref]");
|
||||
for (let radiogroup of prefRadiogroups) {
|
||||
let selectedValue = Services.prefs.getCharPref(radiogroup.getAttribute("data-pref"));
|
||||
for (let radio of radiogroup.childNodes) {
|
||||
radiogroup.selectedIndex = -1;
|
||||
if (radio.getAttribute("value") == selectedValue) {
|
||||
radiogroup.selectedItem = radio;
|
||||
break;
|
||||
}
|
||||
}
|
||||
radiogroup.addEventListener("select", function() {
|
||||
let data = {
|
||||
pref: this.getAttribute("data-pref"),
|
||||
newValue: this.selectedItem.getAttribute("value")
|
||||
};
|
||||
data.oldValue = Services.prefs.getCharPref(data.pref);
|
||||
Services.prefs.setCharPref(data.pref, data.newValue);
|
||||
gDevTools.emit("pref-changed", data);
|
||||
}.bind(radiogroup));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
<?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/toolbox.css" type="text/css"?>
|
||||
<?xml-stylesheet rel="stylesheet" href="chrome://browser/skin/devtools/toolbox.css" type="text/css"?>
|
||||
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
<script type="application/javascript;version=1.8" src="toolbox-options.js"></script>
|
||||
<hbox id="options-panel-container" flex="1">
|
||||
<hbox id="options-panel" flex="1">
|
||||
<vbox id="tools-box" class="options-vertical-pane" flex="1">
|
||||
<label value="&options.selectDefaultTools.label;"/>
|
||||
<vbox id="default-tools-box" class="options-groupbox" tabindex="0"/>
|
||||
<label value="&options.selectAdditionalTools.label;"/>
|
||||
<vbox id="additional-tools-box" class="options-groupbox"/>
|
||||
</vbox>
|
||||
<vbox class="options-vertical-pane" flex="1">
|
||||
<label value="&options.selectDevToolsTheme.label;"/>
|
||||
<radiogroup id="devtools-theme-box"
|
||||
class="options-groupbox"
|
||||
data-pref="devtools.theme"
|
||||
orient="horizontal">
|
||||
<radio value="light" label="&options.lightTheme.label;"/>
|
||||
<radio value="dark" label="&options.darkTheme.label;"/>
|
||||
</radiogroup>
|
||||
<label value="&options.context.label;"/>
|
||||
<vbox id="context-options" class="options-groupbox">
|
||||
<checkbox label="&options.enableChrome.label;"
|
||||
tooltiptext="&options.enableChrome.tooltip;"
|
||||
data-pref="devtools.chrome.enabled"/>
|
||||
<checkbox label="&options.enableRemote.label;"
|
||||
tooltiptext="&options.enableRemote.tooltip;"
|
||||
data-pref="devtools.debugger.remote-enabled"/>
|
||||
</vbox>
|
||||
</vbox>
|
||||
</hbox>
|
||||
</hbox>
|
||||
</window>
|
|
@ -13,3 +13,21 @@
|
|||
.command-button > .toolbarbutton-text {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#options-panel-container {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
#options-panel {
|
||||
overflow-y: auto;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.options-vertical-pane {
|
||||
display: inline;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.options-vertical-pane > label {
|
||||
display: block;
|
||||
}
|
||||
|
|
|
@ -18,6 +18,12 @@
|
|||
|
||||
<commandset id="editMenuCommands"/>
|
||||
<keyset id="editMenuKeys"/>
|
||||
<keyset id="toolbox-keyset">
|
||||
<key id="toolbox-options-key"
|
||||
key="&toolboxOptionsButton.key;"
|
||||
oncommand="void(0);"
|
||||
modifiers="shift, accel"/>
|
||||
</keyset>
|
||||
|
||||
<notificationbox id="toolbox-notificationbox" flex="1">
|
||||
<toolbar class="devtools-tabbar">
|
||||
|
@ -28,6 +34,10 @@
|
|||
<hbox id="toolbox-dock-buttons"/>
|
||||
</hbox>
|
||||
#endif
|
||||
<toolbarbutton id="toolbox-tab-options"
|
||||
autocheck="false"
|
||||
class="command-button toolbox-tab devtools-tab"
|
||||
tooltiptext="&toolboxOptionsButton.tooltip;"/>
|
||||
<hbox id="toolbox-tabs" flex="1">
|
||||
</hbox>
|
||||
<hbox id="toolbox-buttons" pack="end"/>
|
||||
|
@ -41,6 +51,14 @@
|
|||
#endif
|
||||
</toolbar>
|
||||
<deck id="toolbox-deck" flex="1">
|
||||
<vbox id="toolbox-panel-options"
|
||||
class="toolbox-panel">
|
||||
<iframe id="toolbox-panel-iframe-options"
|
||||
class="toolbox-panel-iframe"
|
||||
flex="1" forceOwnRefreshDriver=""
|
||||
src="chrome://browser/content/devtools/framework/toolbox-options.xul">
|
||||
</iframe>
|
||||
</vbox>
|
||||
</deck>
|
||||
</notificationbox>
|
||||
</window>
|
||||
|
|
|
@ -57,6 +57,8 @@ browser.jar:
|
|||
content/browser/devtools/commandlineoutput.xhtml (commandline/commandlineoutput.xhtml)
|
||||
content/browser/devtools/commandlinetooltip.xhtml (commandline/commandlinetooltip.xhtml)
|
||||
content/browser/devtools/framework/toolbox-window.xul (framework/toolbox-window.xul)
|
||||
content/browser/devtools/framework/toolbox-options.xul (framework/toolbox-options.xul)
|
||||
content/browser/devtools/framework/toolbox-options.js (framework/toolbox-options.js)
|
||||
* content/browser/devtools/framework/toolbox.xul (framework/toolbox.xul)
|
||||
content/browser/devtools/framework/toolbox.css (framework/toolbox.css)
|
||||
content/browser/devtools/inspector/inspector.xul (inspector/inspector.xul)
|
||||
|
|
|
@ -3,15 +3,64 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
(function() {
|
||||
const DEVTOOLS_SKIN_URL = "chrome://browser/skin/devtools/";
|
||||
|
||||
function forceStyle() {
|
||||
let computedStyle = window.getComputedStyle(document.documentElement);
|
||||
if (!computedStyle) {
|
||||
// Null when documentElement is not ready. This method is anyways not
|
||||
// required then as scrollbars would be in their state without flushing.
|
||||
return;
|
||||
}
|
||||
let display = computedStyle.display; // Save display value
|
||||
document.documentElement.style.display = "none";
|
||||
window.getComputedStyle(document.documentElement).display; // Flush
|
||||
document.documentElement.style.display = display; // Restore
|
||||
}
|
||||
|
||||
function switchTheme(theme, old_theme) {
|
||||
let winUtils = window.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindowUtils);
|
||||
if (old_theme && theme != old_theme) {
|
||||
let old_theme_url = Services.io.newURI(DEVTOOLS_SKIN_URL + old_theme +
|
||||
"-theme.css", null, null);
|
||||
try {
|
||||
winUtils.removeSheet(old_theme_url, window.AUTHOR_SHEET);
|
||||
} catch(ex) {}
|
||||
}
|
||||
let theme_url = Services.io.newURI(DEVTOOLS_SKIN_URL + theme + "-theme.css",
|
||||
null, null);
|
||||
winUtils.loadSheet(theme_url, window.AUTHOR_SHEET);
|
||||
let scrollbar_url =
|
||||
Services.io.newURI(DEVTOOLS_SKIN_URL + "floating-scrollbars-light.css",
|
||||
null, null);
|
||||
if (theme == "dark") {
|
||||
winUtils.loadSheet(scrollbar_url, window.AGENT_SHEET);
|
||||
forceStyle();
|
||||
}
|
||||
else if (old_theme == "dark") {
|
||||
try {
|
||||
winUtils.removeSheet(scrollbar_url, window.AGENT_SHEET);
|
||||
} catch(ex) {}
|
||||
forceStyle();
|
||||
}
|
||||
document.documentElement.classList.remove("theme-" + old_theme);
|
||||
document.documentElement.classList.add("theme-" + theme);
|
||||
}
|
||||
|
||||
function handlePrefChange(event, data) {
|
||||
if (data.pref == "devtools.theme") {
|
||||
switchTheme(data.newValue, data.oldValue);
|
||||
}
|
||||
}
|
||||
|
||||
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource:///modules/devtools/gDevTools.jsm");
|
||||
let theme = Services.prefs.getCharPref("devtools.theme");
|
||||
let theme_url = Services.io.newURI("chrome://browser/skin/devtools/" + theme + "-theme.css", null, null);
|
||||
let winUtils = window.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
|
||||
winUtils.loadSheet(theme_url, window.AUTHOR_SHEET);
|
||||
if (theme == "dark") {
|
||||
let scrollbar_url = Services.io.newURI("chrome://browser/skin/devtools/floating-scrollbars-light.css", null, null);
|
||||
winUtils.loadSheet(scrollbar_url, window.AGENT_SHEET);
|
||||
}
|
||||
document.documentElement.classList.add("theme-" + theme);
|
||||
switchTheme(theme);
|
||||
gDevTools.on("pref-changed", handlePrefChange);
|
||||
window.addEventListener("unload", function() {
|
||||
gDevTools.off("pref-changed", handlePrefChange);
|
||||
});
|
||||
})()
|
||||
|
|
|
@ -117,7 +117,9 @@ SideMenuWidget.prototype = {
|
|||
* The element associated with the displayed item.
|
||||
*/
|
||||
removeChild: function SMW_removeChild(aChild) {
|
||||
aChild.parentNode.removeChild(aChild);
|
||||
// Remove the item itself, not the contents.
|
||||
let item = aChild.parentNode;
|
||||
item.parentNode.removeChild(item);
|
||||
this._orderedMenuElementsArray.splice(
|
||||
this._orderedMenuElementsArray.indexOf(aChild), 1);
|
||||
|
||||
|
|
|
@ -90,7 +90,6 @@
|
|||
- in the source editor's context menu for the function search operation. -->
|
||||
<!ENTITY debuggerUI.searchFunction "Search for function definition">
|
||||
<!ENTITY debuggerUI.searchFunction.key "D">
|
||||
<!ENTITY debuggerUI.searchFunction.altkey "O">
|
||||
|
||||
<!-- LOCALIZATION NOTE (debuggerUI.searchToken): This is the text that appears
|
||||
- in the source editor's context menu for the token search operation. -->
|
||||
|
|
|
@ -543,6 +543,28 @@ addonListThemeHeading=The following themes are currently installed:
|
|||
addonListAllHeading=The following add-ons are currently installed:
|
||||
addonListUnknownHeading=The following add-ons of the selected type are currently installed:
|
||||
|
||||
# LOCALIZATION NOTE (addonListOutEnable, addonListOutDisable) Used in the
|
||||
# output of the 'addon list' command as the labels for the enable/disable
|
||||
# action buttons in the listing. This string is designed to be shown in a
|
||||
# small action button next to the addon name, which is why it should be as
|
||||
# short as possible.
|
||||
addonListOutEnable=Enable
|
||||
addonListOutDisable=Disable
|
||||
|
||||
# LOCALIZATION NOTE (addonPending, addonPendingEnable, addonPendingDisable,
|
||||
# addonPendingUninstall, addonPendingInstall, addonPendingUpgrade) Used in
|
||||
# the output of the 'addon list' command as the descriptions of pending
|
||||
# addon operations. addonPending is used as a prefix for a list of pending
|
||||
# actions (named by the other lookup variables). These strings are designed
|
||||
# to be shown alongside addon names, which is why they should be as short
|
||||
# as possible.
|
||||
addonPending=pending
|
||||
addonPendingEnable=enable
|
||||
addonPendingDisable=disable
|
||||
addonPendingUninstall=uninstall
|
||||
addonPendingInstall=install
|
||||
addonPendingUpgrade=upgrade
|
||||
|
||||
# LOCALIZATION NOTE (addonNameDesc) A very short description of the
|
||||
# name parameter of numerous add-on commands. This string is designed to be shown
|
||||
# in a menu alongside the command name, which is why it should be as short as
|
||||
|
|
|
@ -2,6 +2,46 @@
|
|||
- 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/. -->
|
||||
|
||||
<!-- LOCALIZATION NOTE : FILE This file contains the Toolbox strings -->
|
||||
<!-- LOCALIZATION NOTE : FILE Do not translate key -->
|
||||
|
||||
<!ENTITY closeCmd.key "W">
|
||||
|
||||
<!ENTITY toolboxCloseButton.tooltip "Close Developer Tools">
|
||||
<!ENTITY toolboxCloseButton.tooltip "Close Developer Tools">
|
||||
<!ENTITY toolboxOptionsButton.tooltip "Toggle Options Panel">
|
||||
<!ENTITY toolboxOptionsButton.key "O">
|
||||
|
||||
<!-- LOCALIZATION NOTE (options.context.label): This is the label for the
|
||||
- heading of the group of two about:config preferences to toggle chrome
|
||||
- and remote debugging in the options panel. -->
|
||||
<!ENTITY options.context.label "Advanced settings (requires a browser restart)">
|
||||
|
||||
<!-- LOCALIZATION NOTE (options.enableChrome.label): This is the label for the
|
||||
- checkbox that toggles chrome debugging, i.e. devtools.chrome.enabled
|
||||
- boolean preference in about:config, in the options panel. -->
|
||||
<!ENTITY options.enableChrome.label "Enable chrome debugging">
|
||||
<!ENTITY options.enableChrome.tooltip "Turning this option on will allow you to use various developer tools in browser context">
|
||||
|
||||
<!-- LOCALIZATION NOTE (options.enableRemote.label): This is the label for the
|
||||
- checkbox that toggles remote debugging, i.e. devtools.debugger.remote-enabled
|
||||
- boolean preference in about:config, in the options panel. -->
|
||||
<!ENTITY options.enableRemote.label "Enable remote debugging">
|
||||
<!ENTITY options.enableRemote.tooltip "Turning this option on will allow the developer tools to debug remote Firefox instance like Firefox OS">
|
||||
|
||||
<!-- LOCALIZATION NOTE (options.selectDefaultTools.label): This is the label for
|
||||
- the heading of group of checkboxes corresponding to the default developer
|
||||
- tools. -->
|
||||
<!ENTITY options.selectDefaultTools.label "Default Firefox Developer Tools">
|
||||
|
||||
<!-- LOCALIZATION NOTE (options.selectDefaultTools.label): This is the label for
|
||||
- the heading of group of checkboxes corresponding to the developer tools
|
||||
- added by add-ons. This heading is hidden when there is no developer tool
|
||||
- installed by add-ons. -->
|
||||
<!ENTITY options.selectAdditionalTools.label "Developer Tools installed by add-ons">
|
||||
|
||||
<!-- LOCALIZATION NOTE (options.selectDevToolsTheme.label): This is the label for
|
||||
- the heading of the radiobox corresponding to the theme of the developer
|
||||
- tools. -->
|
||||
<!ENTITY options.selectDevToolsTheme.label "Choose DevTools theme:">
|
||||
<!ENTITY options.darkTheme.label "Dark theme">
|
||||
<!ENTITY options.lightTheme.label "Light theme">
|
||||
|
|
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 707 B |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 700 B |
|
@ -37,19 +37,16 @@
|
|||
|
||||
.theme-checkbox {
|
||||
display: inline-block;
|
||||
border: 1px solid rgba(160,160,160,0.4);
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
padding: 2px;
|
||||
background-color: transparent;
|
||||
background-repeat: no-repeat;
|
||||
border: 0;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
padding: 0;
|
||||
outline: none;
|
||||
background: url("chrome://browser/skin/devtools/checkbox-dark.png") no-repeat;
|
||||
}
|
||||
|
||||
.theme-checkbox[checked] {
|
||||
background-clip: content-box;
|
||||
background-image: linear-gradient(to bottom right, transparent 48%, rgba(160,160,160,1) 48%, rgba(160,160,160,1) 52%, transparent 52%),
|
||||
linear-gradient(to bottom left, transparent 48%, rgba(160,160,160,1) 48%, rgba(160,160,160,1) 52%, transparent 52%);
|
||||
background: url("chrome://browser/skin/devtools/checkbox-dark.png") 14px 0;
|
||||
}
|
||||
|
||||
.theme-selected {
|
||||
|
|
|
@ -37,19 +37,16 @@
|
|||
|
||||
.theme-checkbox {
|
||||
display: inline-block;
|
||||
border: 1px solid rgba(160,160,160,0.4);
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
padding: 2px;
|
||||
background-color: transparent;
|
||||
background-repeat: no-repeat;
|
||||
border: 0;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
padding: 0;
|
||||
outline: none;
|
||||
background: url("chrome://browser/skin/devtools/checkbox-light.png") no-repeat;
|
||||
}
|
||||
|
||||
.theme-checkbox[checked] {
|
||||
background-clip: content-box;
|
||||
background-image: linear-gradient(to bottom right, transparent 48%, rgba(160,160,160,1) 48%, rgba(160,160,160,1) 52%, transparent 52%),
|
||||
linear-gradient(to bottom left, transparent 48%, rgba(160,160,160,1) 48%, rgba(160,160,160,1) 52%, transparent 52%);
|
||||
background: url("chrome://browser/skin/devtools/checkbox-light.png") 14px 0;
|
||||
}
|
||||
|
||||
.theme-selected {
|
||||
|
|
|
@ -128,6 +128,19 @@
|
|||
-moz-image-region: rect(0px, 48px, 16px, 32px);
|
||||
}
|
||||
|
||||
#toolbox-tab-options {
|
||||
list-style-image: url("chrome://browser/skin/devtools/option-icon.png");
|
||||
-moz-image-region: rect(0px 16px 16px 0px);
|
||||
}
|
||||
|
||||
#toolbox-tab-options[checked=true] {
|
||||
-moz-image-region: rect(0px 32px 16px 16px);
|
||||
}
|
||||
|
||||
#toolbox-tab-options > image {
|
||||
opacity: 1;
|
||||
-moz-margin-start: 0;
|
||||
}
|
||||
|
||||
/* Tabs */
|
||||
|
||||
|
@ -224,3 +237,28 @@
|
|||
background-position: top right, top left, left, right;
|
||||
box-shadow: 1px -1px 0 hsla(206,37%,4%,.2) inset;
|
||||
}
|
||||
|
||||
#options-panel {
|
||||
background-image: url("chrome://browser/skin/newtab/noise.png");
|
||||
}
|
||||
|
||||
.options-vertical-pane {
|
||||
margin: 15px;
|
||||
width: calc(50% - 30px);
|
||||
min-width: 400px;
|
||||
-moz-padding-start: 5px;
|
||||
}
|
||||
|
||||
.options-vertical-pane > label {
|
||||
padding: 5px 0;
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
|
||||
.options-groupbox {
|
||||
-moz-margin-start: 15px;
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.options-groupbox > * {
|
||||
padding: 2px;
|
||||
}
|
||||
|
|
|
@ -131,6 +131,8 @@ browser.jar:
|
|||
skin/classic/browser/devtools/webconsole.css (devtools/webconsole.css)
|
||||
skin/classic/browser/devtools/webconsole_networkpanel.css (devtools/webconsole_networkpanel.css)
|
||||
skin/classic/browser/devtools/webconsole.png (devtools/webconsole.png)
|
||||
skin/classic/browser/devtools/checkbox-dark.png (devtools/checkbox-dark.png)
|
||||
skin/classic/browser/devtools/checkbox-light.png (devtools/checkbox-light.png)
|
||||
skin/classic/browser/devtools/commandline.css (devtools/commandline.css)
|
||||
skin/classic/browser/devtools/markup-view.css (devtools/markup-view.css)
|
||||
skin/classic/browser/devtools/orion.css (devtools/orion.css)
|
||||
|
|
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 707 B |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 700 B |
|
@ -37,19 +37,16 @@
|
|||
|
||||
.theme-checkbox {
|
||||
display: inline-block;
|
||||
border: 1px solid rgba(160,160,160,0.4);
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
padding: 2px;
|
||||
background-color: transparent;
|
||||
background-repeat: no-repeat;
|
||||
border: 0;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
padding: 0;
|
||||
outline: none;
|
||||
background: url("chrome://browser/skin/devtools/checkbox-dark.png") no-repeat;
|
||||
}
|
||||
|
||||
.theme-checkbox[checked] {
|
||||
background-clip: content-box;
|
||||
background-image: linear-gradient(to bottom right, transparent 48%, rgba(160,160,160,1) 48%, rgba(160,160,160,1) 52%, transparent 52%),
|
||||
linear-gradient(to bottom left, transparent 48%, rgba(160,160,160,1) 48%, rgba(160,160,160,1) 52%, transparent 52%);
|
||||
background: url("chrome://browser/skin/devtools/checkbox-dark.png") 14px 0;
|
||||
}
|
||||
|
||||
.theme-selected {
|
||||
|
|
|
@ -37,19 +37,16 @@
|
|||
|
||||
.theme-checkbox {
|
||||
display: inline-block;
|
||||
border: 1px solid rgba(160,160,160,0.4);
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
padding: 2px;
|
||||
background-color: transparent;
|
||||
background-repeat: no-repeat;
|
||||
border: 0;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
padding: 0;
|
||||
outline: none;
|
||||
background: url("chrome://browser/skin/devtools/checkbox-light.png") no-repeat;
|
||||
}
|
||||
|
||||
.theme-checkbox[checked] {
|
||||
background-clip: content-box;
|
||||
background-image: linear-gradient(to bottom right, transparent 48%, rgba(160,160,160,1) 48%, rgba(160,160,160,1) 52%, transparent 52%),
|
||||
linear-gradient(to bottom left, transparent 48%, rgba(160,160,160,1) 48%, rgba(160,160,160,1) 52%, transparent 52%);
|
||||
background: url("chrome://browser/skin/devtools/checkbox-light.png") 14px 0;
|
||||
}
|
||||
|
||||
.theme-selected {
|
||||
|
|
|
@ -116,6 +116,20 @@
|
|||
-moz-image-region: rect(0px, 48px, 16px, 32px);
|
||||
}
|
||||
|
||||
#toolbox-tab-options {
|
||||
list-style-image: url("chrome://browser/skin/devtools/option-icon.png");
|
||||
-moz-image-region: rect(0px 16px 16px 0px);
|
||||
border-left: 1px solid hsla(206,37%,4%,.45);
|
||||
}
|
||||
|
||||
#toolbox-tab-options[checked=true] {
|
||||
-moz-image-region: rect(0px 32px 16px 16px);
|
||||
}
|
||||
|
||||
#toolbox-tab-options > image {
|
||||
opacity: 1;
|
||||
-moz-margin-start: 0;
|
||||
}
|
||||
|
||||
/* Tabs */
|
||||
|
||||
|
@ -134,7 +148,6 @@
|
|||
|
||||
#toolbox-tabs {
|
||||
margin: 0;
|
||||
border-left: 1px solid hsla(206,37%,4%,.45);
|
||||
}
|
||||
|
||||
.devtools-tab {
|
||||
|
@ -211,3 +224,28 @@
|
|||
background-position: top right, top left, left, right;
|
||||
box-shadow: 1px -1px 0 hsla(206,37%,4%,.2) inset;
|
||||
}
|
||||
|
||||
#options-panel {
|
||||
background-image: url("chrome://browser/skin/newtab/noise.png");
|
||||
}
|
||||
|
||||
.options-vertical-pane {
|
||||
margin: 15px;
|
||||
width: calc(50% - 30px);
|
||||
min-width: 400px;
|
||||
-moz-padding-start: 5px;
|
||||
}
|
||||
|
||||
.options-vertical-pane > label {
|
||||
padding: 5px 0;
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
|
||||
.options-groupbox {
|
||||
-moz-margin-start: 15px;
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.options-groupbox > * {
|
||||
padding: 2px;
|
||||
}
|
||||
|
|
|
@ -216,6 +216,8 @@ browser.jar:
|
|||
skin/classic/browser/devtools/goto-mdn.png (devtools/goto-mdn.png)
|
||||
skin/classic/browser/devtools/ruleview.css (devtools/ruleview.css)
|
||||
skin/classic/browser/devtools/commandline.css (devtools/commandline.css)
|
||||
skin/classic/browser/devtools/checkbox-dark.png (devtools/checkbox-dark.png)
|
||||
skin/classic/browser/devtools/checkbox-light.png (devtools/checkbox-light.png)
|
||||
skin/classic/browser/devtools/markup-view.css (devtools/markup-view.css)
|
||||
skin/classic/browser/devtools/orion.css (devtools/orion.css)
|
||||
skin/classic/browser/devtools/orion-container.css (devtools/orion-container.css)
|
||||
|
|
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 707 B |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 700 B |
|
@ -37,19 +37,16 @@
|
|||
|
||||
.theme-checkbox {
|
||||
display: inline-block;
|
||||
border: 1px solid rgba(160,160,160,0.4);
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
padding: 2px;
|
||||
background-color: transparent;
|
||||
background-repeat: no-repeat;
|
||||
border: 0;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
padding: 0;
|
||||
outline: none;
|
||||
background: url("chrome://browser/skin/devtools/checkbox-dark.png") no-repeat;
|
||||
}
|
||||
|
||||
.theme-checkbox[checked] {
|
||||
background-clip: content-box;
|
||||
background-image: linear-gradient(to bottom right, transparent 48%, rgba(160,160,160,1) 48%, rgba(160,160,160,1) 52%, transparent 52%),
|
||||
linear-gradient(to bottom left, transparent 48%, rgba(160,160,160,1) 48%, rgba(160,160,160,1) 52%, transparent 52%);
|
||||
background: url("chrome://browser/skin/devtools/checkbox-dark.png") 14px 0;
|
||||
}
|
||||
|
||||
.theme-selected {
|
||||
|
|
|
@ -37,19 +37,16 @@
|
|||
|
||||
.theme-checkbox {
|
||||
display: inline-block;
|
||||
border: 1px solid rgba(160,160,160,0.4);
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
padding: 2px;
|
||||
background-color: transparent;
|
||||
background-repeat: no-repeat;
|
||||
border: 0;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
padding: 0;
|
||||
outline: none;
|
||||
background: url("chrome://browser/skin/devtools/checkbox-light.png") no-repeat;
|
||||
}
|
||||
|
||||
.theme-checkbox[checked] {
|
||||
background-clip: content-box;
|
||||
background-image: linear-gradient(to bottom right, transparent 48%, rgba(160,160,160,1) 48%, rgba(160,160,160,1) 52%, transparent 52%),
|
||||
linear-gradient(to bottom left, transparent 48%, rgba(160,160,160,1) 48%, rgba(160,160,160,1) 52%, transparent 52%);
|
||||
background: url("chrome://browser/skin/devtools/checkbox-light.png") 14px 0;
|
||||
}
|
||||
|
||||
.theme-selected {
|
||||
|
|
|
@ -131,6 +131,19 @@
|
|||
-moz-image-region: rect(0px, 48px, 16px, 32px);
|
||||
}
|
||||
|
||||
#toolbox-tab-options {
|
||||
list-style-image: url("chrome://browser/skin/devtools/option-icon.png");
|
||||
-moz-image-region: rect(0px 16px 16px 0px);
|
||||
}
|
||||
|
||||
#toolbox-tab-options[checked=true] {
|
||||
-moz-image-region: rect(0px 32px 16px 16px);
|
||||
}
|
||||
|
||||
#toolbox-tab-options > image {
|
||||
opacity: 1;
|
||||
-moz-margin-start: 0;
|
||||
}
|
||||
|
||||
/* Tabs */
|
||||
|
||||
|
@ -220,3 +233,28 @@
|
|||
background-position: top right, top left, left, right;
|
||||
box-shadow: 1px -1px 0 hsla(206,37%,4%,.2) inset;
|
||||
}
|
||||
|
||||
#options-panel {
|
||||
background-image: url("chrome://browser/skin/newtab/noise.png");
|
||||
}
|
||||
|
||||
.options-vertical-pane {
|
||||
margin: 15px;
|
||||
width: calc(50% - 30px);
|
||||
min-width: 400px;
|
||||
-moz-padding-start: 5px;
|
||||
}
|
||||
|
||||
.options-vertical-pane > label {
|
||||
padding: 5px 0;
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
|
||||
.options-groupbox {
|
||||
-moz-margin-start: 15px;
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.options-groupbox > * {
|
||||
padding: 2px;
|
||||
}
|
||||
|
|
|
@ -156,6 +156,8 @@ browser.jar:
|
|||
skin/classic/browser/devtools/command-responsivemode.png (devtools/command-responsivemode.png)
|
||||
skin/classic/browser/devtools/command-scratchpad.png (devtools/command-scratchpad.png)
|
||||
skin/classic/browser/devtools/command-tilt.png (devtools/command-tilt.png)
|
||||
skin/classic/browser/devtools/checkbox-dark.png (devtools/checkbox-dark.png)
|
||||
skin/classic/browser/devtools/checkbox-light.png (devtools/checkbox-light.png)
|
||||
skin/classic/browser/devtools/markup-view.css (devtools/markup-view.css)
|
||||
skin/classic/browser/devtools/orion.css (devtools/orion.css)
|
||||
skin/classic/browser/devtools/orion-container.css (devtools/orion-container.css)
|
||||
|
@ -396,6 +398,8 @@ browser.jar:
|
|||
skin/classic/aero/browser/devtools/command-responsivemode.png (devtools/command-responsivemode.png)
|
||||
skin/classic/aero/browser/devtools/command-scratchpad.png (devtools/command-scratchpad.png)
|
||||
skin/classic/aero/browser/devtools/command-tilt.png (devtools/command-tilt.png)
|
||||
skin/classic/aero/browser/devtools/checkbox-dark.png (devtools/checkbox-dark.png)
|
||||
skin/classic/aero/browser/devtools/checkbox-light.png (devtools/checkbox-light.png)
|
||||
skin/classic/aero/browser/devtools/alerticon-warning.png (devtools/alerticon-warning.png)
|
||||
skin/classic/aero/browser/devtools/goto-mdn.png (devtools/goto-mdn.png)
|
||||
skin/classic/aero/browser/devtools/ruleview.css (devtools/ruleview.css)
|
||||
|
|
|
@ -493,7 +493,7 @@ ThreadActor.prototype = {
|
|||
promises.push(promise);
|
||||
}
|
||||
|
||||
return resolveAll(promises).then(function () {
|
||||
return all(promises).then(function () {
|
||||
return { frames: frames };
|
||||
});
|
||||
},
|
||||
|
@ -562,7 +562,7 @@ ThreadActor.prototype = {
|
|||
let originalLocation = this.sources.getOriginalLocation(aLocation.url,
|
||||
aLocation.line);
|
||||
|
||||
return resolveAll([response, originalLocation])
|
||||
return all([response, originalLocation])
|
||||
.then(([aResponse, {url, line}]) => {
|
||||
if (aResponse.actualLocation) {
|
||||
let actualOrigLocation = this.sources.getOriginalLocation(
|
||||
|
@ -692,8 +692,8 @@ ThreadActor.prototype = {
|
|||
* Get the script and source lists from the debugger.
|
||||
*/
|
||||
_discoverScriptsAndSources: function TA__discoverScriptsAndSources() {
|
||||
return resolveAll([this._addScript(s)
|
||||
for (s of this.dbg.findScripts())]);
|
||||
return all([this._addScript(s)
|
||||
for (s of this.dbg.findScripts())]);
|
||||
},
|
||||
|
||||
onSources: function TA_onSources(aRequest) {
|
||||
|
|
|
@ -25,11 +25,7 @@ Cu.import("resource://gre/modules/jsdebugger.jsm");
|
|||
addDebuggerToGlobal(this);
|
||||
|
||||
Cu.import("resource://gre/modules/commonjs/sdk/core/promise.js");
|
||||
const { defer, resolve, reject } = Promise;
|
||||
let promisedArray = Promise.promised(Array);
|
||||
function resolveAll(aPromises) {
|
||||
return promisedArray.apply(null, aPromises);
|
||||
};
|
||||
const { defer, resolve, reject, all } = Promise;
|
||||
|
||||
Cu.import("resource://gre/modules/devtools/SourceMap.jsm");
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче