/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
loader.lazyRequireGetter(
this,
"HTMLTooltip",
"resource://devtools/client/shared/widgets/tooltip/HTMLTooltip.js",
true
);
const PREFERENCES = [
[
"fission.autostart",
"Enable fission in Firefox. When navigating between two domains, you " +
"will switch between two distinct processes. And if an iframe is " +
"hosted from another domain, it will run in another process",
],
[
"devtools.every-frame-target.enabled",
"When enabled, targets will be created for all iframes, no matter if " +
"they are remote or not, independently of Fission being enabled or not",
],
[
"fission.bfcacheInParent",
"Enable bfcache navigation in parent process (requires Fission and involve " +
"more top level target switching",
],
[
"devtools.debugger.features.javascript-tracing",
"Enable the JavaScript tracer. (You need to restart Firefox / the Browser Toolbox to apply this setting)",
],
];
/**
* Temporary module to show a Tooltip with the currently enabled preferences
* relevant for DevTools ongoing architectural work (e.g. Fission, EFT, …).
*
* This module should be deleted once all experimental prefs are preffed on in Nightly.
*/
function showTooltip(toolbox) {
if (!toolbox._experimentalPrefsTooltip) {
toolbox._experimentalPrefsTooltip =
new HTMLTooltip(toolbox.doc, {
type:
"doorhanger",
useXulWrapper:
true,
});
toolbox.once(
"destroy", () => toolbox._experimentalPrefsTooltip.destroy());
}
// Terrible hack to allow to toggle using the command button.
if (toolbox._experimentalPrefsTooltip.preventShow) {
return;
}
updateTooltipContent(toolbox);
const commandId =
"command-button-experimental-prefs";
toolbox._experimentalPrefsTooltip.show(toolbox.doc.getElementById(commandId));
// Follows a hack to be able to close the tooltip when clicking on the
// command button. Otherwise it will flicker and reopen.
toolbox._experimentalPrefsTooltip.preventShow =
true;
toolbox._experimentalPrefsTooltip.once(
"hidden", () => {
toolbox.win.setTimeout(
() => (toolbox._experimentalPrefsTooltip.preventShow =
false),
250
);
});
}
exports.showTooltip = showTooltip;
function updateTooltipContent(toolbox) {
const container = toolbox.doc.createElement(
"div");
/*
* This is the grid we want to have:
* +--------------------------------------------+---------------+
* | Header text | Reset button |
* +------+-----------------------------+-------+---------------+
* | Icon | Preference name | Value | Toggle button |
* +------+-----------------------------+-------+---------------+
* | Icon | Preference name | Value | Toggle button |
* +------+-----------------------------+-------+---------------+
*/
Object.assign(container.style, {
display:
"grid",
gridTemplateColumns:
"max-content minmax(300px, auto) max-content max-content",
gridColumnGap:
"8px",
gridTemplateRows: `repeat(${PREFERENCES.length + 1}, auto)`,
gridRowGap:
"8px",
padding:
"12px",
fontSize:
"11px",
});
container.classList.add(
"theme-body");
const headerContainer = toolbox.doc.createElement(
"header");
/**
* The grid layout of the header container is as follows:
*
* +-------------------------+--------------+
* | Header text | Reset button |
* +-------------------------+--------------+
*/
Object.assign(headerContainer.style, {
display:
"grid",
gridTemplateColumns:
"subgrid",
gridColumn:
"1 / -1",
});
const header = toolbox.doc.createElement(
"h1");
Object.assign(header.style, {
gridColumn:
"1 / -2",
fontSize:
"11px",
margin:
"0",
padding:
"0",
});
header.textContent =
"DevTools Experimental preferences";
const resetButton = toolbox.doc.createElement(
"button");
resetButton.addEventListener(
"click", () => {
for (
const [name] of PREFERENCES) {
Services.prefs.clearUserPref(name);
}
updateTooltipContent(toolbox);
});
resetButton.textContent =
"reset all";
headerContainer.append(header, resetButton);
const prefList = toolbox.doc.createElement(
"ul");
Object.assign(prefList.style, {
display:
"grid",
gridTemplateColumns:
"subgrid",
gridTemplateRows:
"subgrid",
// Subgrid should span all grid columns
gridColumn:
"1 / -1",
gridRow:
"2 / -1",
listStyle:
"none",
margin:
"0",
padding:
"0",
});
for (
const [name, desc] of PREFERENCES) {
const prefEl = createPreferenceListItem(toolbox, name, desc);
prefList.appendChild(prefEl);
}
container.append(headerContainer, prefList);
toolbox._experimentalPrefsTooltip.panel.innerHTML =
"";
// There is a hardcoded 320px max width for doorhanger tooltips,
// see Bug 1654020.
toolbox._experimentalPrefsTooltip.panel.style.maxWidth =
"unset";
toolbox._experimentalPrefsTooltip.panel.appendChild(container);
}
function createPreferenceListItem(toolbox, name, desc) {
const isPrefEnabled = Services.prefs.getBoolPref(name,
false);
const prefEl = toolbox.doc.createElement(
"li");
/**
* The grid layout of a preference line is as follows:
*
* +------+-----------------------------+-------+---------------+
* | Icon | Preference name | Value | Toggle button |
* +------+-----------------------------+-------+---------------+
*/
Object.assign(prefEl.style, {
margin:
"0",
lineHeight:
"12px",
display:
"grid",
alignItems:
"center",
gridTemplateColumns:
"subgrid",
gridColumn:
"1 / -1",
});
prefEl.classList.toggle(
"theme-comment", !isPrefEnabled);
// Icon
const prefInfo = toolbox.doc.createElement(
"div");
prefInfo.title = desc;
Object.assign(prefInfo.style, {
width:
"12px",
height:
"12px",
});
prefInfo.classList.add(
"experimental-pref-icon");
// Preference name
const prefTitle = toolbox.doc.createElement(
"span");
Object.assign(prefTitle.style, {
userSelect:
"text",
fontWeight: isPrefEnabled ?
"bold" :
"normal",
});
prefTitle.textContent = name;
// Value
const prefValue = toolbox.doc.createElement(
"span");
prefValue.textContent = isPrefEnabled;
// Toggle Button
const toggleButton = toolbox.doc.createElement(
"button");
toggleButton.addEventListener(
"click", () => {
Services.prefs.setBoolPref(name, !isPrefEnabled);
updateTooltipContent(toolbox);
});
toggleButton.textContent =
"toggle";
prefEl.append(prefInfo, prefTitle, prefValue, toggleButton);
return prefEl;
}
function isAnyPreferenceEnabled() {
for (
const [name] of PREFERENCES) {
const isPrefEnabled = Services.prefs.getBoolPref(name,
false);
if (isPrefEnabled) {
return true;
}
}
return false;
}
exports.isAnyPreferenceEnabled = isAnyPreferenceEnabled;