Bug 974947 - Add preferences to hide command buttons on DevTools tabbar;r=jwalker

This commit is contained in:
Brian Grinstead 2014-03-06 16:02:11 -06:00
parent 879600bd51
commit c343268b42
8 changed files with 256 additions and 15 deletions

View File

@ -1120,6 +1120,14 @@ pref("devtools.toolbox.toolbarSpec", '["splitconsole", "paintflashing toggle","t
pref("devtools.toolbox.sideEnabled", true);
pref("devtools.toolbox.zoomValue", "1");
// Toolbox Button preferences
pref("devtools.command-button-pick.enabled", true);
pref("devtools.command-button-splitconsole.enabled", true);
pref("devtools.command-button-paintflashing.enabled", false);
pref("devtools.command-button-tilt.enabled", false);
pref("devtools.command-button-scratchpad.enabled", false);
pref("devtools.command-button-responsive.enabled", true);
// Inspector preferences
// Enable the Inspector
pref("devtools.inspector.enabled", true);

View File

@ -47,11 +47,6 @@
padding: 4px 0 0; /* To align it with the checkbox */
}
.options-citation-label + label {
padding: 3px 0 0 !important; /* To align it with the checkbox */
font-style: italic;
}
.hidden-labels-box:not(.visible) > label,
.hidden-labels-box.visible ~ .hidden-labels-box > label:last-child {
display: none;

View File

@ -15,6 +15,7 @@ support-files =
[browser_toolbox_highlight.js]
[browser_toolbox_hosts.js]
[browser_toolbox_options.js]
[browser_toolbox_options_disable_buttons.js]
[browser_toolbox_options_disable_cache.js]
[browser_toolbox_options_disable_js.js]
# [browser_toolbox_raise.js] # Bug 962258

View File

@ -0,0 +1,148 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
let doc = null, toolbox = null, panelWin = null, modifiedPrefs = [];
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)
.then(testToggleToolboxButtons)
.then(testPrefsAreRespectedWhenReopeningToolbox)
.then(cleanup, errorHandler);
}, true);
content.location = "data:text/html;charset=utf8,test for dynamically registering and unregistering tools";
}
function testPrefsAreRespectedWhenReopeningToolbox() {
let deferred = promise.defer();
let target = TargetFactory.forTab(gBrowser.selectedTab);
info ("Closing toolbox to test after reopening");
gDevTools.closeToolbox(target).then(() => {
let target = TargetFactory.forTab(gBrowser.selectedTab);
gDevTools.showToolbox(target)
.then(testSelectTool)
.then(() => {
info ("Toolbox has been reopened. Checking UI state.");
testPreferenceAndUIStateIsConsistent();
deferred.resolve();
});
});
return deferred.promise;
}
function testSelectTool(aToolbox) {
let deferred = promise.defer();
info ("Selecting the options panel");
toolbox = aToolbox;
doc = toolbox.doc;
toolbox.once("options-selected", (event, tool) => {
ok(true, "Options panel selected via selectTool method");
panelWin = tool.panelWin;
deferred.resolve();
});
toolbox.selectTool("options");
return deferred.promise;
}
function testPreferenceAndUIStateIsConsistent() {
let checkNodes = [...panelWin.document.querySelectorAll("#enabled-toolbox-buttons-box > checkbox")];
let toolboxButtonNodes = [...doc.querySelectorAll("#toolbox-buttons > toolbarbutton")];
let toggleableTools = toolbox.toolboxButtons;
for (let tool of toggleableTools) {
let isVisible = getBoolPref(tool.visibilityswitch);
let button = toolboxButtonNodes.filter(button=>button.id === tool.id)[0];
is (!button.hasAttribute("hidden"), isVisible, "Button visibility matches pref for " + tool.id);
let check = checkNodes.filter(node=>node.id === tool.id)[0];
is (check.checked, isVisible, "Checkbox should be selected based on current pref for " + tool.id);
}
}
function testToggleToolboxButtons() {
let checkNodes = [...panelWin.document.querySelectorAll("#enabled-toolbox-buttons-box > checkbox")];
let toolboxButtonNodes = [...doc.querySelectorAll("#toolbox-buttons > toolbarbutton")];
let visibleButtons = toolboxButtonNodes.filter(button=>!button.hasAttribute("hidden"));
let toggleableTools = toolbox.toolboxButtons;
is (checkNodes.length, toggleableTools.length, "All of the buttons are toggleable." );
is (checkNodes.length, toolboxButtonNodes.length, "All of the DOM buttons are toggleable." );
for (let tool of toggleableTools) {
let id = tool.id;
let matchedCheckboxes = checkNodes.filter(node=>node.id === id);
let matchedButtons = toolboxButtonNodes.filter(button=>button.id === id);
ok (matchedCheckboxes.length === 1,
"There should be a single toggle checkbox for: " + id);
ok (matchedButtons.length === 1,
"There should be a DOM button for: " + id);
is (matchedButtons[0], tool.button,
"DOM buttons should match for: " + id);
is (matchedCheckboxes[0].getAttribute("label"), tool.label,
"The label for checkbox matches the tool definition.")
is (matchedButtons[0].getAttribute("tooltiptext"), tool.label,
"The tooltip for button matches the tool definition.")
}
// Store modified pref names so that they can be cleared on error.
for (let tool of toggleableTools) {
let pref = tool.visibilityswitch;
modifiedPrefs.push(pref);
}
// Try checking each checkbox, making sure that it changes the preference
for (let node of checkNodes) {
let tool = toggleableTools.filter(tool=>tool.id === node.id)[0];
let isVisible = getBoolPref(tool.visibilityswitch);
testPreferenceAndUIStateIsConsistent();
toggleButton(node);
testPreferenceAndUIStateIsConsistent();
let isVisibleAfterClick = getBoolPref(tool.visibilityswitch);
is (isVisible, !isVisibleAfterClick,
"Clicking on the node should have toggled visibility preference for " + tool.visibilityswitch);
}
return promise.resolve();
}
function getBoolPref(key) {
return Services.prefs.getBoolPref(key);
}
function toggleButton(node) {
node.scrollIntoView();
EventUtils.synthesizeMouseAtCenter(node, {}, panelWin);
}
function cleanup() {
toolbox.destroy().then(function() {
gBrowser.removeCurrentTab();
for (let pref of modifiedPrefs) {
Services.prefs.clearUserPref(pref);
}
toolbox = doc = panelWin = modifiedPrefs = null;
finish();
});
}
function errorHandler(error) {
ok(false, "Unexpected error: " + error);
cleanup();
}

View File

@ -61,6 +61,7 @@ OptionsPanel.prototype = {
return targetPromise.then(() => {
this.setupToolsList();
this.setupToolbarButtonsList();
this.populatePreferences();
this._disableJSClicked = this._disableJSClicked.bind(this);
@ -81,6 +82,43 @@ OptionsPanel.prototype = {
});
},
setupToolbarButtonsList: function() {
let enabledToolbarButtonsBox = this.panelDoc.getElementById("enabled-toolbox-buttons-box");
enabledToolbarButtonsBox.textContent = "";
let toggleableButtons = this.toolbox.toolboxButtons;
let setToolboxButtonsVisibility =
this.toolbox.setToolboxButtonsVisibility.bind(this.toolbox);
let onCheckboxClick = (checkbox) => {
let toolDefinition = toggleableButtons.filter(tool => tool.id === checkbox.id)[0];
Services.prefs.setBoolPref(toolDefinition.visibilityswitch, checkbox.checked);
setToolboxButtonsVisibility();
};
let createCommandCheckbox = tool => {
let checkbox = this.panelDoc.createElement("checkbox");
checkbox.setAttribute("id", tool.id);
checkbox.setAttribute("label", tool.label);
checkbox.setAttribute("checked", this.getBoolPref(tool.visibilityswitch));
checkbox.addEventListener("command", onCheckboxClick.bind(this, checkbox));
return checkbox;
};
for (let tool of toggleableButtons) {
enabledToolbarButtonsBox.appendChild(createCommandCheckbox(tool));
}
},
getBoolPref: function(key) {
try {
return Services.prefs.getBoolPref(key);
}
catch (ex) {
return true;
}
},
setupToolsList: function() {
let defaultToolsBox = this.panelDoc.getElementById("default-tools-box");
let additionalToolsBox = this.panelDoc.getElementById("additional-tools-box");
@ -90,15 +128,6 @@ OptionsPanel.prototype = {
defaultToolsBox.textContent = "";
additionalToolsBox.textContent = "";
let pref = function(key) {
try {
return Services.prefs.getBoolPref(key);
}
catch (ex) {
return true;
}
};
let onCheckboxClick = function(id) {
let toolDefinition = gDevTools._tools.get(id);
// Set the kill switch pref boolean to true
@ -124,7 +153,7 @@ OptionsPanel.prototype = {
l10n("options.toolNotSupportedMarker", tool.label));
checkbox.setAttribute("unsupported", "");
}
checkbox.setAttribute("checked", pref(tool.visibilityswitch));
checkbox.setAttribute("checked", this.getBoolPref(tool.visibilityswitch));
checkbox.addEventListener("command", onCheckboxClick.bind(checkbox, tool.id));
return checkbox;
};

View File

@ -20,9 +20,12 @@
<vbox id="default-tools-box" class="options-groupbox" tabindex="0"/>
<label value="&options.selectAdditionalTools.label;"/>
<vbox id="additional-tools-box" class="options-groupbox"/>
<label value="&options.selectEnabledToolboxButtons.label;"/>
<vbox id="enabled-toolbox-buttons-box" class="options-groupbox"/>
<label id="tools-not-supported-label"
class="options-citation-label theme-comment"
value="&options.toolNotSupported.label;"/>
</vbox>
<vbox class="options-vertical-pane" flex="1">
<label value="&options.selectDevToolsTheme.label;"/>

View File

@ -543,6 +543,7 @@ Toolbox.prototype = {
this.doc, this._requisition);
let container = this.doc.getElementById("toolbox-buttons");
buttons.forEach(container.appendChild.bind(container));
this.setToolboxButtonsVisibility();
},
/**
@ -562,6 +563,57 @@ Toolbox.prototype = {
this._pickerButton.addEventListener("command", this._togglePicker, false);
},
/**
* Return all toolbox buttons (command buttons, plus any others that were
* added manually).
*/
get toolboxButtons() {
// White-list buttons that can be toggled to prevent adding prefs for
// addons that have manually inserted toolbarbuttons into DOM.
return [
"command-button-pick",
"command-button-splitconsole",
"command-button-responsive",
"command-button-paintflashing",
"command-button-tilt",
"command-button-scratchpad"
].map(id => {
let button = this.doc.getElementById(id);
// Some buttons may not exist inside of Browser Toolbox
if (!button) {
return false;
}
return {
id: id,
button: button,
label: button.getAttribute("tooltiptext"),
visibilityswitch: "devtools." + id + ".enabled"
}
}).filter(button=>button);
},
/**
* Ensure the visibility of each toolbox button matches the
* preference value. Simply hide buttons that are preffed off.
*/
setToolboxButtonsVisibility: function() {
this.toolboxButtons.forEach(buttonSpec => {
let {visibilityswitch, id, button}=buttonSpec;
let on = true;
try {
on = Services.prefs.getBoolPref(visibilityswitch);
} catch (ex) { }
if (button) {
if (on) {
button.removeAttribute("hidden");
} else {
button.setAttribute("hidden", "true");
}
}
});
},
/**
* Build a tab for one tool definition and add to the toolbox
*

View File

@ -92,6 +92,11 @@
- installed by add-ons. -->
<!ENTITY options.selectAdditionalTools.label "Developer Tools installed by add-ons">
<!-- LOCALIZATION NOTE (options.selectEnabledToolboxButtons.label): This is the label for
- the heading of group of checkboxes corresponding to the default developer
- tool buttons. -->
<!ENTITY options.selectEnabledToolboxButtons.label "Available Toolbox Buttons">
<!-- LOCALIZATION NOTE (options.toolNotSupported.label): This is the label for
- the explanation of the * marker on a tool which is currently not supported
- for the target of the toolbox. -->