Bug 1246514 - Switch toolbox-options.xul to HTML. r=bgrins
Change the XUL label + vbox to fieldset + legend as it's the most relevant
element for describing form sections.
Moreover, we don't have to look for a previous label when we hide a fieldset.
Edit scripts and tests files to adapt them to the HTML file structure.
MozReview-Commit-ID: LBfXfLRX6aj
--- a/devtools/client/definitions.js
+++ b/devtools/client/definitions.js
@@ -55,17 +55,17 @@ loader.lazyGetter(this, "memoryStrings",
var Tools = {};
exports.Tools = Tools;
// Definitions
Tools.options = {
id: "options",
ordinal: 0,
- url: "chrome://devtools/content/framework/toolbox-options.xul",
+ url: "chrome://devtools/content/framework/toolbox-options.xhtml",
icon: "chrome://devtools/skin/images/tool-options.svg",
invertIconForLightTheme: true,
bgTheme: "theme-body",
label: l10n("options.label", toolboxStrings),
iconOnly: true,
panelLabel: l10n("options.panelLabel", toolboxStrings),
tooltip: l10n("optionsButton.tooltip", toolboxStrings),
inMenu: false,
--- a/devtools/client/framework/options-panel.css
+++ b/devtools/client/framework/options-panel.css
@@ -1,80 +1,107 @@
/* 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/. */
+:root{
+ -moz-user-select: none;
+}
#options-panel-container {
overflow: auto;
}
#options-panel {
display: block;
}
.options-vertical-pane {
display: inline;
float: left;
}
-.options-vertical-pane > label {
- display: block;
-}
-
.options-vertical-pane {
margin: 5px;
- width: calc(100%/3 - 30px);
+ width: calc(100%/3 - 10px);
min-width: 320px;
- -moz-padding-start: 5px;
-}
-
-#devtools-theme-box {
- margin-left: 0px;
- padding-left: 0px;
+ padding-inline-start: 5px;
+ box-sizing: border-box;
}
/* Snap to 50% width once there is not room for 3 columns anymore.
This prevents having 2 columns showing in a row, but taking up
only ~66% of the available space. */
@media (max-width: 1000px) {
.options-vertical-pane {
- width: calc(100%/2 - 30px);
+ width: calc(100%/2 - 10px);
}
}
-.options-vertical-pane > label {
- padding: 2px 0;
+.options-vertical-pane fieldset {
+ border: none;
+}
+
+.options-vertical-pane fieldset legend {
font-size: 1.4rem;
+ margin-inline-start: -15px;
+ margin-bottom: 3px;
+ cursor: default;
+}
+
+.options-vertical-pane fieldset + fieldset {
+ margin-top: 1rem;
}
.options-groupbox {
- -moz-margin-start: 15px;
+ margin-inline-start: 15px;
padding: 2px;
}
+.options-groupbox label {
+ display: flex;
+ padding: 4px 0;
+ align-items: center;
+}
+
+/* Add padding for label of select inputs in order to
+ align it with surrounding checkboxes */
+.options-groupbox label span:first-child {
+ padding-inline-start: 5px;
+}
+
+.options-groupbox label span + select {
+ margin-inline-start: 4px;
+}
+
+.options-groupbox.horizontal-options-groupbox label {
+ display: inline-flex;
+ align-items: baseline;
+}
+
+.options-groupbox.horizontal-options-groupbox label + label {
+ margin-inline-start: 4px;
+}
+
.options-groupbox > *,
.options-groupbox > .hidden-labels-box > checkbox {
padding: 2px;
}
.options-groupbox > .hidden-labels-box {
padding: 0;
}
.options-citation-label {
- font-size: 1rem !important;
- /* !important is required otherwise font-size will still be 1.4rem */
+ display: inline-block;
+ font-size: 1rem;
font-style: italic;
- padding: 4px 0 0; /* To align it with the checkbox */
+ /* To align it with the checkbox */
+ padding: 4px 0 0;
+ padding-inline-end: 4px;
}
-.hidden-labels-box:not(.visible) > label,
-.hidden-labels-box.visible ~ .hidden-labels-box > label:last-child {
- display: none;
+#devtools-sourceeditor-keybinding-select {
+ min-width: 130px;
}
-#devtools-sourceeditor-keybinding-menulist {
- min-width: 100px;
+#devtools-sourceeditor-tabsize-select {
+ min-width: 80px;
}
-
-#devtools-sourceeditor-tabsize-menulist {
- min-width: 50px;
-}
--- a/devtools/client/framework/test/browser_toolbox_options.js
+++ b/devtools/client/framework/test/browser_toolbox_options.js
@@ -67,17 +67,18 @@ function* testOptionsShortcut() {
is(toolbox.currentToolId, "webconsole", "webconsole is reselected (2)");
synthesizeKeyFromKeyTag(doc.getElementById("toolbox-options-key2"));
is(toolbox.currentToolId, "options", "Toolbox selected via shortcut key (2)");
}
function* testOptions() {
let tool = toolbox.getPanel("options");
panelWin = tool.panelWin;
- let prefNodes = tool.panelDoc.querySelectorAll("checkbox[data-pref]");
+ let prefNodes = tool.panelDoc.querySelectorAll(
+ "input[type=checkbox][data-pref]");
// Store modified pref names so that they can be cleared on error.
for (let node of tool.panelDoc.querySelectorAll("[data-pref]")) {
let pref = node.getAttribute("data-pref");
modifiedPrefs.push(pref);
}
for (let node of prefNodes) {
@@ -85,50 +86,49 @@ function* testOptions() {
// Test clicking the checkbox for each options pref
yield testMouseClick(node, prefValue);
// Do again with opposite values to reset prefs
yield testMouseClick(node, !prefValue);
}
- let prefDropdowns = tool.panelDoc.querySelectorAll("menulist[data-pref]");
- for (let node of prefDropdowns) {
- yield testMenuList(node);
+ let prefSelects = tool.panelDoc.querySelectorAll("select[data-pref]");
+ for (let node of prefSelects) {
+ yield testSelect(node);
}
}
-function* testMenuList(menulist) {
- let pref = menulist.getAttribute("data-pref");
- let menuitems = menulist.querySelectorAll("menuitem");
- info ("Checking menu list for: " + pref);
+function* testSelect(select) {
+ let pref = select.getAttribute("data-pref");
+ let options = Array.from(select.options);
+ info("Checking select for: " + pref);
- is (menulist.selectedItem.value, GetPref(pref), "Menu starts out selected");
+ is(select.options[select.selectedIndex].value, GetPref(pref),
+ "select starts out selected");
- for (let menuitem of menuitems) {
- if (menuitem === menulist.selectedItem) {
+ for (let option of options) {
+ if (options.indexOf(option) === select.selectedIndex) {
continue;
}
let deferred = promise.defer();
gDevTools.once("pref-changed", (event, data) => {
if (data.pref == pref) {
ok(true, "Correct pref was changed");
- is (GetPref(pref), menuitem.value, "Preference been switched for " + pref);
+ is (GetPref(pref), option.value, "Preference been switched for " + pref);
} else {
ok(false, "Pref " + pref + " was not changed correctly");
}
deferred.resolve();
});
- menulist.selectedItem = menuitem;
- let commandEvent = menulist.ownerDocument.createEvent("XULCommandEvent");
- commandEvent.initCommandEvent("command", true, true, window, 0, false, false,
- false, false, null);
- menulist.dispatchEvent(commandEvent);
+ select.selectedIndex = options.indexOf(option);
+ let changeEvent = new Event("change");
+ select.dispatchEvent(changeEvent);
yield deferred.promise;
}
}
function* testMouseClick(node, prefValue) {
let deferred = promise.defer();
@@ -152,17 +152,19 @@ function* testMouseClick(node, prefValue
info("Click event synthesized for pref " + pref);
EventUtils.synthesizeMouseAtCenter(node, {}, panelWin);
});
yield deferred.promise;
}
function* testToggleTools() {
- let toolNodes = panelWin.document.querySelectorAll("#default-tools-box > checkbox:not([unsupported]), #additional-tools-box > checkbox:not([unsupported])");
+ let toolNodes = panelWin.document.querySelectorAll(
+ "#default-tools-box input[type=checkbox]:not([data-unsupported])," +
+ "#additional-tools-box input[type=checkbox]:not([data-unsupported])");
let enabledTools = [...toolNodes].filter(node => node.checked);
let toggleableTools = gDevTools.getDefaultTools().filter(tool => {
return tool.visibilityswitch;
}).concat(gDevTools.getAdditionalTools());
for (let node of toolNodes) {
let id = node.getAttribute("id");
--- a/devtools/client/framework/test/browser_toolbox_options_disable_buttons.js
+++ b/devtools/client/framework/test/browser_toolbox_options_disable_buttons.js
@@ -52,17 +52,17 @@ function testSelectTool(aToolbox) {
deferred.resolve();
});
toolbox.selectTool("options");
return deferred.promise;
}
function testPreferenceAndUIStateIsConsistent() {
- let checkNodes = [...panelWin.document.querySelectorAll("#enabled-toolbox-buttons-box > checkbox")];
+ let checkNodes = [...panelWin.document.querySelectorAll("#enabled-toolbox-buttons-box input[type=checkbox]")];
let toolboxButtonNodes = [...doc.querySelectorAll(".command-button")];
toolboxButtonNodes.push(doc.getElementById("command-button-frames"));
let toggleableTools = toolbox.toolboxButtons;
// The noautohide button is only displayed in the browser toolbox
toggleableTools = toggleableTools.filter(tool => tool.id != "command-button-noautohide");
for (let tool of toggleableTools) {
@@ -72,17 +72,17 @@ function testPreferenceAndUIStateIsConsi
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 checkNodes = [...panelWin.document.querySelectorAll("#enabled-toolbox-buttons-box input[type=checkbox]")];
let toolboxButtonNodes = [...doc.querySelectorAll(".command-button")];
let toggleableTools = toolbox.toolboxButtons;
// The noautohide button is only displayed in the browser toolbox
toggleableTools = toggleableTools.filter(tool => tool.id != "command-button-noautohide");
toolboxButtonNodes = toolboxButtonNodes.filter(btn => btn.id != "command-button-noautohide");
is (checkNodes.length, toggleableTools.length, "All of the buttons are toggleable." );
@@ -94,17 +94,17 @@ function testToggleToolboxButtons() {
let matchedButtons = toolboxButtonNodes.filter(button=>button.id === id);
is (matchedCheckboxes.length, 1,
"There should be a single toggle checkbox for: " + id);
is (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,
+ is (matchedCheckboxes[0].nextSibling.textContent, 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;
@@ -112,37 +112,32 @@ function testToggleToolboxButtons() {
}
// 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);
+ node.click();
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();
--- a/devtools/client/framework/test/browser_toolbox_theme_registration.js
+++ b/devtools/client/framework/test/browser_toolbox_theme_registration.js
@@ -27,61 +27,70 @@ add_task(function* themeRegistration() {
});
is(themeId, "test-theme", "theme-registered event handler sent theme id");
ok(gDevTools.getThemeDefinitionMap().has(themeId), "theme added to map");
});
add_task(function* themeInOptionsPanel() {
- let panel = toolbox.getCurrentPanel();
let panelWin = toolbox.getCurrentPanel().panelWin;
let doc = panelWin.frameElement.contentDocument;
- let themeOption = doc.querySelector("#devtools-theme-box > radio[value=test-theme]");
+ let themeBox = doc.getElementById("devtools-theme-box");
+ let testThemeOption = themeBox.querySelector(
+ "input[type=radio][value=test-theme]");
- ok(themeOption, "new theme exists in the Options panel");
+ ok(testThemeOption, "new theme exists in the Options panel");
- let testThemeOption = doc.querySelector("#devtools-theme-box > radio[value=test-theme]");
- let lightThemeOption = doc.querySelector("#devtools-theme-box > radio[value=light]");
+ let lightThemeOption = themeBox.querySelector(
+ "input[type=radio][value=light]");
- let color = panelWin.getComputedStyle(testThemeOption).color;
+ let color = panelWin.getComputedStyle(themeBox).color;
isnot(color, "rgb(255, 0, 0)", "style unapplied");
+ let onThemeSwithComplete = once(panelWin, "theme-switch-complete");
+
// Select test theme.
testThemeOption.click();
info("Waiting for theme to finish loading");
- yield once(panelWin, "theme-switch-complete");
+ yield onThemeSwithComplete;
- color = panelWin.getComputedStyle(testThemeOption).color;
+ color = panelWin.getComputedStyle(themeBox).color;
is(color, "rgb(255, 0, 0)", "style applied");
+ onThemeSwithComplete = once(panelWin, "theme-switch-complete");
+
// Select light theme
lightThemeOption.click();
info("Waiting for theme to finish loading");
- yield once(panelWin, "theme-switch-complete");
+ yield onThemeSwithComplete;
- color = panelWin.getComputedStyle(testThemeOption).color;
+ color = panelWin.getComputedStyle(themeBox).color;
isnot(color, "rgb(255, 0, 0)", "style unapplied");
+ onThemeSwithComplete = once(panelWin, "theme-switch-complete");
// Select test theme again.
testThemeOption.click();
+ yield onThemeSwithComplete;
});
add_task(function* themeUnregistration() {
+ let onUnRegisteredTheme = once(gDevTools, "theme-unregistered");
gDevTools.unregisterTheme("test-theme");
+ yield onUnRegisteredTheme;
ok(!gDevTools.getThemeDefinitionMap().has("test-theme"), "theme removed from map");
let panelWin = toolbox.getCurrentPanel().panelWin;
let doc = panelWin.frameElement.contentDocument;
- let themeBox = doc.querySelector("#devtools-theme-box");
+ let themeBox = doc.getElementById("devtools-theme-box");
// The default light theme must be selected now.
- is(themeBox.selectedItem, themeBox.querySelector("[value=light]"),
- "theme light must be selected");
+ is(themeBox.querySelector("#devtools-theme-box [value=light]").checked, true,
+ "light theme must be selected");
});
add_task(function* cleanup() {
yield toolbox.destroy();
toolbox = null;
});
--- a/devtools/client/framework/test/doc_theme.css
+++ b/devtools/client/framework/test/doc_theme.css
@@ -1,3 +1,3 @@
-.theme-test #devtools-theme-box radio {
+.theme-test #devtools-theme-box {
color: red !important;
}
--- a/devtools/client/framework/toolbox-options.js
+++ b/devtools/client/framework/toolbox-options.js
@@ -101,17 +101,16 @@ OptionsPanel.prototype = {
// For local debugging we need to make the target remote.
if (!this.target.isRemote) {
yield this.target.makeRemote();
}
this.setupToolsList();
this.setupToolbarButtonsList();
this.setupThemeList();
- this.updateDefaultTheme();
yield this.populatePreferences();
this.isReady = true;
this.emit("ready");
return this;
}),
_addListeners: function() {
gDevTools.on("pref-changed", this._prefChanged);
@@ -138,44 +137,53 @@ OptionsPanel.prototype = {
},
_themeRegistered: function(event, themeId) {
this.setupThemeList();
},
_themeUnregistered: function(event, theme) {
let themeBox = this.panelDoc.getElementById("devtools-theme-box");
- let themeOption = themeBox.querySelector("[value=" + theme.id + "]");
+ let themeInput = themeBox.querySelector(`[value=${theme.id}]`);
- if (themeOption) {
- themeBox.removeChild(themeOption);
+ if (themeInput) {
+ themeInput.parentNode.remove();
}
},
setupToolbarButtonsList: function() {
- let enabledToolbarButtonsBox = this.panelDoc.getElementById("enabled-toolbox-buttons-box");
- enabledToolbarButtonsBox.textContent = "";
+ let enabledToolbarButtonsBox = this.panelDoc.getElementById(
+ "enabled-toolbox-buttons-box");
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", InfallibleGetBoolPref(tool.visibilityswitch));
- checkbox.addEventListener("command", onCheckboxClick.bind(this, checkbox));
- return checkbox;
+ let checkboxLabel = this.panelDoc.createElement("label");
+ let checkboxSpanLabel = this.panelDoc.createElement("span");
+ checkboxSpanLabel.textContent = tool.label;
+ let checkboxInput = this.panelDoc.createElement("input");
+ checkboxInput.setAttribute("type", "checkbox");
+ checkboxInput.setAttribute("id", tool.id);
+ if (InfallibleGetBoolPref(tool.visibilityswitch)) {
+ checkboxInput.setAttribute("checked", true);
+ }
+ checkboxInput.addEventListener("change",
+ onCheckboxClick.bind(this, checkboxInput));
+
+ checkboxLabel.appendChild(checkboxInput);
+ checkboxLabel.appendChild(checkboxSpanLabel);
+ return checkboxLabel;
};
for (let tool of toggleableButtons) {
if (!tool.isTargetSupported(this.toolbox.target)) {
continue;
}
enabledToolbarButtonsBox.appendChild(createCommandCheckbox(tool));
@@ -183,47 +191,57 @@ OptionsPanel.prototype = {
},
setupToolsList: function() {
let defaultToolsBox = this.panelDoc.getElementById("default-tools-box");
let additionalToolsBox = this.panelDoc.getElementById("additional-tools-box");
let toolsNotSupportedLabel = this.panelDoc.getElementById("tools-not-supported-label");
let atleastOneToolNotSupported = false;
- defaultToolsBox.textContent = "";
- additionalToolsBox.textContent = "";
-
let onCheckboxClick = function(id) {
let toolDefinition = gDevTools._tools.get(id);
// Set the kill switch pref boolean to true
Services.prefs.setBoolPref(toolDefinition.visibilityswitch, this.checked);
if (this.checked) {
gDevTools.emit("tool-registered", id);
}
else {
gDevTools.emit("tool-unregistered", toolDefinition);
}
};
let createToolCheckbox = tool => {
- let checkbox = this.panelDoc.createElement("checkbox");
- checkbox.setAttribute("id", tool.id);
- checkbox.setAttribute("tooltiptext", tool.tooltip || "");
+ let checkboxLabel = this.panelDoc.createElement("label");
+ let checkboxInput = this.panelDoc.createElement("input");
+ checkboxInput.setAttribute("type", "checkbox");
+ checkboxInput.setAttribute("id", tool.id);
+ checkboxInput.setAttribute("title", tool.tooltip || "");
+
+ let checkboxSpanLabel = this.panelDoc.createElement("span");
if (tool.isTargetSupported(this.target)) {
- checkbox.setAttribute("label", tool.label);
+ checkboxSpanLabel.textContent = tool.label;
}
else {
atleastOneToolNotSupported = true;
- checkbox.setAttribute("label",
- l10n("options.toolNotSupportedMarker", tool.label));
- checkbox.setAttribute("unsupported", "");
+ checkboxSpanLabel.textContent = l10n(
+ "options.toolNotSupportedMarker", tool.label);
+ checkboxInput.setAttribute("data-unsupported", "true");
+ checkboxInput.setAttribute("disabled", "true");
}
- checkbox.setAttribute("checked", InfallibleGetBoolPref(tool.visibilityswitch));
- checkbox.addEventListener("command", onCheckboxClick.bind(checkbox, tool.id));
- return checkbox;
+
+ if (InfallibleGetBoolPref(tool.visibilityswitch)) {
+ checkboxInput.setAttribute("checked", "true");
+ }
+
+ checkboxInput.addEventListener("change",
+ onCheckboxClick.bind(checkboxInput, tool.id));
+
+ checkboxLabel.appendChild(checkboxInput);
+ checkboxLabel.appendChild(checkboxSpanLabel);
+ return checkboxLabel;
};
// Populating the default tools lists
let toggleableTools = gDevTools.getDefaultTools().filter(tool => {
return tool.visibilityswitch && !tool.hiddenInOptions;
});
for (let tool of toggleableTools) {
@@ -234,111 +252,127 @@ OptionsPanel.prototype = {
let atleastOneAddon = false;
for (let tool of gDevTools.getAdditionalTools()) {
atleastOneAddon = true;
additionalToolsBox.appendChild(createToolCheckbox(tool));
}
if (!atleastOneAddon) {
additionalToolsBox.style.display = "none";
- additionalToolsBox.previousSibling.style.display = "none";
}
if (!atleastOneToolNotSupported) {
toolsNotSupportedLabel.style.display = "none";
}
this.panelWin.focus();
},
setupThemeList: function() {
let themeBox = this.panelDoc.getElementById("devtools-theme-box");
- themeBox.textContent = "";
let createThemeOption = theme => {
- let radio = this.panelDoc.createElement("radio");
- radio.setAttribute("value", theme.id);
- radio.setAttribute("label", theme.label);
- return radio;
+ let inputLabel = this.panelDoc.createElement("label");
+ let inputRadio = this.panelDoc.createElement("input");
+ inputRadio.setAttribute("type", "radio");
+ inputRadio.setAttribute("value", theme.id);
+ inputRadio.setAttribute("name", "devtools-theme-item");
+ inputRadio.addEventListener("change", function(e) {
+ setPrefAndEmit(themeBox.getAttribute("data-pref"),
+ e.target.value);
+ });
+
+ let inputSpanLabel = this.panelDoc.createElement("span");
+ inputSpanLabel.textContent = theme.label;
+ inputLabel.appendChild(inputRadio);
+ inputLabel.appendChild(inputSpanLabel);
+
+ return inputLabel;
};
// Populating the default theme list
let themes = gDevTools.getThemeDefinitionArray();
for (let theme of themes) {
themeBox.appendChild(createThemeOption(theme));
}
this.updateCurrentTheme();
},
populatePreferences: function() {
- let prefCheckboxes = this.panelDoc.querySelectorAll("checkbox[data-pref]");
- for (let checkbox of prefCheckboxes) {
- checkbox.checked = GetPref(checkbox.getAttribute("data-pref"));
- checkbox.addEventListener("command", function() {
- setPrefAndEmit(this.getAttribute("data-pref"), this.checked);
- }.bind(checkbox));
- }
- let prefRadiogroups = this.panelDoc.querySelectorAll("radiogroup[data-pref]");
- for (let radiogroup of prefRadiogroups) {
- let selectedValue = GetPref(radiogroup.getAttribute("data-pref"));
- for (let radio of radiogroup.childNodes) {
- radiogroup.selectedIndex = -1;
- if (radio.getAttribute("value") == selectedValue) {
- radiogroup.selectedItem = radio;
- break;
- }
+ let prefCheckboxes = this.panelDoc.querySelectorAll(
+ "input[type=checkbox][data-pref]");
+ for (let prefCheckbox of prefCheckboxes) {
+ if (GetPref(prefCheckbox.getAttribute("data-pref"))) {
+ prefCheckbox.setAttribute("checked", true);
}
- radiogroup.addEventListener("select", function() {
- setPrefAndEmit(this.getAttribute("data-pref"), this.selectedItem.getAttribute("value"));
- }.bind(radiogroup));
+ prefCheckbox.addEventListener("change", function(e) {
+ let checkbox = e.target;
+ setPrefAndEmit(checkbox.getAttribute("data-pref"), checkbox.checked);
+ });
}
- let prefMenulists = this.panelDoc.querySelectorAll("menulist[data-pref]");
- for (let menulist of prefMenulists) {
- let pref = GetPref(menulist.getAttribute("data-pref"));
- let menuitems = menulist.querySelectorAll("menuitem");
- for (let menuitem of menuitems) {
- let value = menuitem.value;
- if (value == pref) { // non strict check to allow int values.
- menulist.selectedItem = menuitem;
- break;
+ // Themes radio inputs are handled in setupThemeList
+ let prefRadiogroups = this.panelDoc.querySelectorAll(
+ ".radiogroup[data-pref]:not(#devtools-theme-box)");
+ for (let radioGroup of prefRadiogroups) {
+ let selectedValue = GetPref(radioGroup.getAttribute("data-pref"));
+
+ for (let radioInput of radioGroup.querySelectorAll("input[type=radio]")) {
+ if (radioInput.getAttribute("value") == selectedValue) {
+ radioInput.setAttribute("checked", true);
}
+
+ radioInput.addEventListener("change", function(e) {
+ setPrefAndEmit(radioGroup.getAttribute("data-pref"),
+ e.target.value);
+ });
}
- menulist.addEventListener("command", function() {
- setPrefAndEmit(this.getAttribute("data-pref"), this.value);
- }.bind(menulist));
+ }
+ let prefSelects = this.panelDoc.querySelectorAll("select[data-pref]");
+ for (let prefSelect of prefSelects) {
+ let pref = GetPref(prefSelect.getAttribute("data-pref"));
+ let options = [...prefSelect.options];
+ options.some(function(option) {
+ let value = option.value;
+ // non strict check to allow int values.
+ if (value == pref) {
+ prefSelect.selectedIndex = options.indexOf(option);
+ return true;
+ }
+ });
+
+ prefSelect.addEventListener("change", function(e) {
+ let select = e.target;
+ setPrefAndEmit(select.getAttribute("data-pref"),
+ select.options[select.selectedIndex].value);
+ });
}
if (this.target.activeTab) {
- return this.target.client.attachTab(this.target.activeTab._actor).then(([response,client]) => {
+ return this.target.client.attachTab(this.target.activeTab._actor).then(([response, client]) => {
this._origJavascriptEnabled = !response.javascriptEnabled;
this.disableJSNode.checked = this._origJavascriptEnabled;
- this.disableJSNode.addEventListener("click", this._disableJSClicked, false);
+ this.disableJSNode.addEventListener("click",
+ this._disableJSClicked, false);
});
- } else {
- this.disableJSNode.hidden = true;
}
- },
-
- updateDefaultTheme: function() {
- // Make sure a theme is set in case the previous one coming from
- // an extension isn't available anymore.
- let themeBox = this.panelDoc.getElementById("devtools-theme-box");
- if (themeBox.selectedIndex == -1) {
- themeBox.selectedItem = themeBox.querySelector("[value=light]");
- }
+ this.disableJSNode.hidden = true;
},
updateCurrentTheme: function() {
let currentTheme = GetPref("devtools.theme");
let themeBox = this.panelDoc.getElementById("devtools-theme-box");
- let themeOption = themeBox.querySelector("[value=" + currentTheme + "]");
+ let themeRadioInput = themeBox.querySelector(`[value=${currentTheme}]`);
- if (themeOption) {
- themeBox.selectedItem = themeOption;
+ if (themeRadioInput) {
+ themeRadioInput.click();
+ } else {
+ // If the current theme does not exist anymore, switch to light theme
+ let lightThemeInputRadio = themeBox.querySelector("[value=light]");
+ lightThemeInputRadio.click();
}
},
/**
* Disables JavaScript for the currently loaded tab. We force a page refresh
* here because setting docShell.allowJavascript to true fails to block JS
* execution from event listeners added using addEventListener(), AJAX calls
* and timers. The page refresh prevents these things from being added in the
rename from devtools/client/framework/toolbox-options.xul
rename to devtools/client/framework/toolbox-options.xhtml
--- a/devtools/client/framework/toolbox-options.xul
+++ b/devtools/client/framework/toolbox-options.xhtml
@@ -1,175 +1,191 @@
<?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 [
+<!DOCTYPE html [
<!ENTITY % toolboxDTD SYSTEM "chrome://devtools/locale/toolbox.dtd" >
%toolboxDTD;
]>
-<?xml-stylesheet rel="stylesheet" href="chrome://global/skin/" type="text/css"?>
-<?xml-stylesheet rel="stylesheet" href="chrome://devtools/content/framework/options-panel.css" type="text/css"?>
-
-<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <title>Toolbox option</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+ <link rel="stylesheet" href="chrome://devtools/content/framework/options-panel.css" type="text/css"/>
+ <script type="application/javascript;version=1.8" src="chrome://devtools/content/shared/theme-switching.js"/>
+ </head>
+ <body role="application" class="theme-body">
+ <form id="options-panel">
+ <div id="tools-box" class="options-vertical-pane">
+ <fieldset id="default-tools-box" class="options-groupbox" tabindex="0">
+ <legend>&options.selectDefaultTools.label;</legend>
+ </fieldset>
- <script type="application/javascript;version=1.8"
- src="chrome://devtools/content/shared/theme-switching.js"/>
- <hbox id="options-panel-container" flex="1">
- <hbox id="options-panel" class="theme-body" flex="1">
- <vbox id="tools-box" class="options-vertical-pane" flex="1">
- <label>&options.selectDefaultTools.label;</label>
- <vbox id="default-tools-box" class="options-groupbox" tabindex="0"/>
- <label>&options.selectAdditionalTools.label;</label>
- <vbox id="additional-tools-box" class="options-groupbox"/>
- <label>&options.selectEnabledToolboxButtons.label;</label>
- <vbox id="enabled-toolbox-buttons-box" class="options-groupbox"/>
- <label id="tools-not-supported-label"
- class="options-citation-label theme-comment"
- >&options.toolNotSupported.label;</label>
+ <fieldset id="additional-tools-box" class="options-groupbox">
+ <legend>&options.selectAdditionalTools.label;</legend>
+ </fieldset>
+
+ <fieldset id="enabled-toolbox-buttons-box" class="options-groupbox">
+ <legend>&options.selectEnabledToolboxButtons.label;</legend>
+ <span id="tools-not-supported-label"
+ class="options-citation-label theme-comment">
+ &options.toolNotSupported.label;</span>
+ </fieldset>
+ </div>
+
+ <div class="options-vertical-pane">
+ <fieldset id="devtools-theme-box"
+ class="options-groupbox
+ horizontal-options-groupbox
+ radiogroup"
+ data-pref="devtools.theme">
+ <legend>&options.selectDevToolsTheme.label2;</legend>
+ </fieldset>
- </vbox>
- <vbox class="options-vertical-pane" flex="1">
- <label>&options.selectDevToolsTheme.label2;</label>
- <vbox id="theme-options" class="options-groupbox">
- <radiogroup id="devtools-theme-box"
- class="options-groupbox"
- data-pref="devtools.theme"
- orient="horizontal">
- </radiogroup>
- </vbox>
- <label>&options.commonPrefs.label;</label>
- <vbox id="commonprefs-options" class="options-groupbox">
- <checkbox label="&options.enablePersistentLogs.label;"
- tooltiptext="&options.enablePersistentLogs.tooltip;"
- data-pref="devtools.webconsole.persistlog"/>
- </vbox>
- <label>&options.context.inspector;</label>
- <vbox id="inspector-options" class="options-groupbox">
- <checkbox label="&options.showUserAgentStyles.label;"
- tooltiptext="&options.showUserAgentStyles.tooltip;"
- data-pref="devtools.inspector.showUserAgentStyles"/>
- <checkbox label="&options.collapseAttrs.label;"
- tooltiptext="&options.collapseAttrs.tooltip;"
- data-pref="devtools.markup.collapseAttributes"/>
- <description>
- <label control="defaultColorUnitMenuList"
- accesskey="&options.defaultColorUnit.accesskey;"
- >&options.defaultColorUnit.label;</label>
- <hbox>
- <menulist id="defaultColorUnitMenuList"
- data-pref="devtools.defaultColorUnit">
- <menupopup>
- <menuitem label="&options.defaultColorUnit.authored;" value="authored"/>
- <menuitem label="&options.defaultColorUnit.hex;" value="hex"/>
- <menuitem label="&options.defaultColorUnit.hsl;" value="hsl"/>
- <menuitem label="&options.defaultColorUnit.rgb;" value="rgb"/>
- <menuitem label="&options.defaultColorUnit.name;" value="name"/>
- </menupopup>
- </menulist>
- </hbox>
- </description>
- </vbox>
- <label>&options.webconsole.label;</label>
- <vbox id="webconsole-options" class="options-groupbox">
- <checkbox id="webconsole-timestamp-messages"
- label="&options.timestampMessages.label;"
- tooltiptext="&options.timestampMessages.tooltip;"
- data-pref="devtools.webconsole.timestampMessages"/>
- </vbox>
- <label>&options.styleeditor.label;</label>
- <vbox id="styleeditor-options" class="options-groupbox">
- <checkbox label="&options.stylesheetSourceMaps.label;"
- tooltiptext="&options.stylesheetSourceMaps.tooltip;"
- data-pref="devtools.styleeditor.source-maps-enabled"/>
- <checkbox label="&options.stylesheetAutocompletion.label;"
- tooltiptext="&options.stylesheetAutocompletion.tooltip;"
- data-pref="devtools.styleeditor.autocompletion-enabled"/>
- </vbox>
- </vbox>
+ <fieldset id="commonprefs-options" class="options-groupbox">
+ <legend>&options.commonPrefs.label;</legend>
+ <label title="&options.enablePersistentLogs.tooltip;">
+ <input type="checkbox" data-pref="devtools.webconsole.persistlog" />
+ &options.enablePersistentLogs.label;
+ </label>
+ </fieldset>
+
+ <fieldset id="inspector-options" class="options-groupbox">
+ <legend>&options.context.inspector;</legend>
+ <label title="&options.showUserAgentStyles.tooltip;">
+ <input type="checkbox"
+ data-pref="devtools.inspector.showUserAgentStyles"/>
+ <span>&options.showUserAgentStyles.label;</span>
+ </label>
+ <label title="&options.collapseAttrs.tooltip;">
+ <input type="checkbox"
+ data-pref="devtools.markup.collapseAttributes"/>
+ <span>&options.collapseAttrs.label;</span>
+ </label>
+ <label>
+ <span>&options.defaultColorUnit.label;</span>
+ <select id="defaultColorUnitMenuList"
+ data-pref="devtools.defaultColorUnit">
+ <option value="authored">&options.defaultColorUnit.authored;</option>
+ <option value="hex">&options.defaultColorUnit.hex;</option>
+ <option value="hsl">&options.defaultColorUnit.hsl;</option>
+ <option value="rgb">&options.defaultColorUnit.rgb;</option>
+ <option value="name">&options.defaultColorUnit.name;</option>
+ </select>
+ </label>
+ </fieldset>
+
+ <fieldset id="webconsole-options" class="options-groupbox">
+ <legend>&options.webconsole.label;</legend>
+ <label title="&options.timestampMessages.tooltip;">
+ <input type="checkbox"
+ id="webconsole-timestamp-messages"
+ data-pref="devtools.webconsole.timestampMessages"/>
+ <span>&options.timestampMessages.label;</span>
+ </label>
+ </fieldset>
- <vbox id="sourceeditor-box" class="options-vertical-pane" flex="1">
- <label>&options.sourceeditor.label;</label>
- <vbox id="sourceeditor-options" class="options-groupbox">
- <checkbox id="devtools-sourceeditor-detectindentation"
- label="&options.sourceeditor.detectindentation.label;"
- tooltiptext="&options.sourceeditor.detectindentation.tooltip;"
- data-pref="devtools.editor.detectindentation"/>
- <checkbox id="devtools-sourceeditor-autoclosebrackets"
- label="&options.sourceeditor.autoclosebrackets.label;"
- tooltiptext="&options.sourceeditor.autoclosebrackets.tooltip;"
- data-pref="devtools.editor.autoclosebrackets"/>
- <checkbox id="devtools-sourceeditor-expandtab"
- label="&options.sourceeditor.expandtab.label;"
- tooltiptext="&options.sourceeditor.expandtab.tooltip;"
- data-pref="devtools.editor.expandtab"/>
- <description>
- <label control="devtools-sourceeditor-tabsize-menulist"
- accesskey="&options.sourceeditor.tabsize.accesskey;"
- >&options.sourceeditor.tabsize.label;</label>
- <hbox>
- <menulist id="devtools-sourceeditor-tabsize-menulist"
- data-pref="devtools.editor.tabsize">
- <menupopup>
- <menuitem label="2" value="2"/>
- <menuitem label="4" value="4"/>
- <menuitem label="8" value="8"/>
- </menupopup>
- </menulist>
- </hbox>
- </description>
- <description>
- <label control="devtools-sourceeditor-keybinding-menulist"
- accesskey="&options.sourceeditor.keybinding.accesskey;"
- >&options.sourceeditor.keybinding.label;</label>
- <hbox>
- <menulist id="devtools-sourceeditor-keybinding-menulist"
- data-pref="devtools.editor.keymap">
- <menupopup>
- <menuitem value="default"
- label="&options.sourceeditor.keybinding.default.label;"/>
- <menuitem label="Vim" value="vim"/>
- <menuitem label="Emacs" value="emacs"/>
- <menuitem label="Sublime Text" value="sublime"/>
- </menupopup>
- </menulist>
- </hbox>
- </description>
- </vbox>
- <label>&options.context.advancedSettings;</label>
- <vbox id="context-options" class="options-groupbox">
- <checkbox id="devtools-show-gecko-data"
- label="&options.showPlatformData.label;"
- tooltiptext="&options.showPlatformData.tooltip;"
- data-pref="devtools.performance.ui.show-platform-data"/>
- <checkbox id="devtools-disable-cache"
- label="&options.disableCache.label2;"
- tooltiptext="&options.disableCache.tooltip2;"
- data-pref="devtools.cache.disabled"/>
- <checkbox id="devtools-disable-javascript"
- label="&options.disableJavaScript.label;"
- tooltiptext="&options.disableJavaScript.tooltip;"/>
- <checkbox id="devtools-enable-serviceWorkersTesting"
- label="&options.enableServiceWorkersHTTP.label;"
- tooltiptext="&options.enableServiceWorkersHTTP.tooltip;"
- data-pref="devtools.serviceWorkers.testing.enabled"/>
- <hbox class="hidden-labels-box">
- <checkbox label="&options.enableChrome.label5;"
- tooltiptext="&options.enableChrome.tooltip3;"
- data-pref="devtools.chrome.enabled"/>
- </hbox>
- <hbox class="hidden-labels-box">
- <checkbox label="&options.enableRemote.label3;"
- tooltiptext="&options.enableRemote.tooltip;"
- data-pref="devtools.debugger.remote-enabled"/>
- </hbox>
- <hbox class="hidden-labels-box">
- <checkbox label="&options.enableWorkers.label;"
- tooltiptext="&options.enableWorkers.tooltip;"
- data-pref="devtools.debugger.workers"/>
- </hbox>
- <label class="options-citation-label theme-comment"
- >&options.context.triggersPageRefresh;</label>
- </vbox>
- </vbox>
- </hbox>
- </hbox>
-</window>
+ <fieldset id="styleeditor-options" class="options-groupbox">
+ <legend>&options.styleeditor.label;</legend>
+ <label title="&options.stylesheetSourceMaps.tooltip;">
+ <input type="checkbox"
+ data-pref="devtools.styleeditor.source-maps-enabled"/>
+ <span>&options.stylesheetSourceMaps.label;</span>
+ </label>
+ <label title="&options.stylesheetAutocompletion.tooltip;">
+ <input type="checkbox"
+ data-pref="devtools.styleeditor.autocompletion-enabled"/>
+ <span>&options.stylesheetAutocompletion.label;</span>
+ </label>
+ </fieldset>
+ </div>
+
+ <div class="options-vertical-pane">
+ <fieldset id="sourceeditor-options" class="options-groupbox">
+ <legend>&options.sourceeditor.label;</legend>
+ <label title="&options.sourceeditor.detectindentation.tooltip;">
+ <input type="checkbox"
+ id="devtools-sourceeditor-detectindentation"
+ data-pref="devtools.editor.detectindentation"/>
+ <span>&options.sourceeditor.detectindentation.label;</span>
+ </label>
+ <label title="&options.sourceeditor.autoclosebrackets.tooltip;">
+ <input type="checkbox"
+ id="devtools-sourceeditor-autoclosebrackets"
+ data-pref="devtools.editor.autoclosebrackets"/>
+ <span>&options.sourceeditor.autoclosebrackets.label;</span>
+ </label>
+ <label title="&options.sourceeditor.expandtab.tooltip;">
+ <input type="checkbox"
+ id="devtools-sourceeditor-expandtab"
+ data-pref="devtools.editor.expandtab"/>
+ <span>&options.sourceeditor.expandtab.label;</span>
+ </label>
+ <label>
+ <span>&options.sourceeditor.tabsize.label;</span>
+ <select id="devtools-sourceeditor-tabsize-select"
+ data-pref="devtools.editor.tabsize">
+ <option label="2">2</option>
+ <option label="4">4</option>
+ <option label="8">8</option>
+ </select>
+ </label>
+ <label>
+ <span>&options.sourceeditor.keybinding.label;</span>
+ <select id="devtools-sourceeditor-keybinding-select"
+ data-pref="devtools.editor.keymap">
+ <option value="default">&options.sourceeditor.keybinding.default.label;</option>
+ <option value="vim">Vim</option>
+ <option value="emacs">Emacs</option>
+ <option value="sublime">Sublime Text</option>
+ </select>
+ </label>
+ </fieldset>
+
+ <fieldset id="context-options" class="options-groupbox">
+ <legend>&options.context.advancedSettings;</legend>
+ <label title="&options.showPlatformData.tooltip;">
+ <input type="checkbox"
+ id="devtools-show-gecko-data"
+ data-pref="devtools.performance.ui.show-platform-data"/>
+ <span>&options.showPlatformData.label;</span>
+ </label>
+ <label title="&options.disableCache.tooltip2;">
+ <input type="checkbox"
+ id="devtools-disable-cache"
+ data-pref="devtools.cache.disabled"/>
+ <span>&options.disableCache.label2;</span>
+ </label>
+ <label title="&options.disableJavaScript.tooltip;">
+ <input type="checkbox"
+ id="devtools-disable-javascript"/>
+ <span>&options.disableJavaScript.label;</span>
+ </label>
+ <label title="&options.enableServiceWorkersHTTP.tooltip;">
+ <input type="checkbox"
+ id="devtools-enable-serviceWorkersTesting"
+ data-pref="devtools.serviceWorkers.testing.enabled"/>
+ <span>&options.enableServiceWorkersHTTP.label;</span>
+ </label>
+ <label title="&options.enableChrome.tooltip3;">
+ <input type="checkbox"
+ data-pref="devtools.chrome.enabled"/>
+ <span>&options.enableChrome.label5;</span>
+ </label>
+ <label title="&options.enableRemote.tooltip;">
+ <input type="checkbox"
+ data-pref="devtools.debugger.remote-enabled"/>
+ <span>&options.enableRemote.label3;</span>
+ </label>
+ <label title="&options.enableWorkers.tooltip;">
+ <input type="checkbox"
+ data-pref="devtools.debugger.workers"/>
+ <span>&options.enableWorkers.label;</span>
+ </label>
+ <span class="options-citation-label theme-comment"
+ >&options.context.triggersPageRefresh;</span>
+ </fieldset>
+ </div>
+
+ </form>
+ </body>
+</html>
--- a/devtools/client/jar.mn
+++ b/devtools/client/jar.mn
@@ -105,17 +105,17 @@ devtools.jar:
content/memory/initializer.js (memory/initializer.js)
content/promisedebugger/promise-controller.js (promisedebugger/promise-controller.js)
content/promisedebugger/promise-panel.js (promisedebugger/promise-panel.js)
content/promisedebugger/promise-debugger.xhtml (promisedebugger/promise-debugger.xhtml)
content/commandline/commandline.css (commandline/commandline.css)
content/commandline/commandlineoutput.xhtml (commandline/commandlineoutput.xhtml)
content/commandline/commandlinetooltip.xhtml (commandline/commandlinetooltip.xhtml)
content/framework/toolbox-window.xul (framework/toolbox-window.xul)
- content/framework/toolbox-options.xul (framework/toolbox-options.xul)
+ content/framework/toolbox-options.xhtml (framework/toolbox-options.xhtml)
content/framework/toolbox-options.js (framework/toolbox-options.js)
content/framework/toolbox.xul (framework/toolbox.xul)
content/framework/toolbox-init.js (framework/toolbox-init.js)
content/framework/options-panel.css (framework/options-panel.css)
content/framework/toolbox-process-window.xul (framework/toolbox-process-window.xul)
* content/framework/toolbox-process-window.js (framework/toolbox-process-window.js)
content/framework/dev-edition-promo/dev-edition-promo.xul (framework/dev-edition-promo/dev-edition-promo.xul)
* content/framework/dev-edition-promo/dev-edition-promo.css (framework/dev-edition-promo/dev-edition-promo.css)