refactor: status bar

This commit is contained in:
adamp01
2022-10-27 07:22:09 -07:00
committed by Alex Kontos
parent 1d86cc9c39
commit cf8a14469b
6 changed files with 119 additions and 116 deletions

View File

@@ -21,7 +21,7 @@ XPCOMUtils.defineLazyModuleGetters(lazy, {
Overlays: "resource:///modules/Overlays.sys.mjs", Overlays: "resource:///modules/Overlays.sys.mjs",
PrefUtils: "resource:///modules/PrefUtils.jsm", PrefUtils: "resource:///modules/PrefUtils.jsm",
PrivateTab: "resource:///modules/PrivateTab.sys.mjs", PrivateTab: "resource:///modules/PrivateTab.sys.mjs",
StatusBar: "resource:///modules/StatusBar.jsm", StatusBar: "resource:///modules/StatusBar.sys.mjs",
TabFeatures: "resource:///modules/TabFeatures.jsm", TabFeatures: "resource:///modules/TabFeatures.jsm",
UICustomizations: "resource:///modules/UICustomizations.jsm", UICustomizations: "resource:///modules/UICustomizations.jsm",
}); });

View File

@@ -2,30 +2,25 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
const EXPORTED_SYMBOLS = ["StatusBar"]; const lazy = {};
const { CustomizableUI } = ChromeUtils.import( ChromeUtils.defineESModuleGetters(lazy, {
"resource:///modules/CustomizableUI.jsm" CustomizableUI: "resource:///modules/CustomizableUI.sys.mjs",
); BrowserUtils: "resource:///modules/BrowserUtils.sys.mjs",
PrefUtils: "resource:///modules/PrefUtils.sys.mjs",
setTimeout: "resource://gre/modules/Timer.sys.mjs",
});
const { setTimeout } = ChromeUtils.import("resource://gre/modules/Timer.jsm"); export const StatusBar = {
const { PrefUtils } = ChromeUtils.import("resource:///modules/PrefUtils.jsm");
const { BrowserUtils } = ChromeUtils.import(
"resource:///modules/BrowserUtils.jsm"
);
const StatusBar = {
PREF_ENABLED: "browser.statusbar.enabled", PREF_ENABLED: "browser.statusbar.enabled",
PREF_STATUSTEXT: "browser.statusbar.appendStatusText", PREF_STATUSTEXT: "browser.statusbar.appendStatusText",
get enabled() { get enabled() {
return PrefUtils.get(this.PREF_ENABLED); return lazy.PrefUtils.get(this.PREF_ENABLED);
}, },
get showLinks() { get showLinks() {
return PrefUtils.get(this.PREF_STATUSTEXT); return lazy.PrefUtils.get(this.PREF_STATUSTEXT);
}, },
get textInBar() { get textInBar() {
@@ -37,7 +32,8 @@ const StatusBar = {
@-moz-document url('chrome://browser/content/browser.xhtml') { @-moz-document url('chrome://browser/content/browser.xhtml') {
#status-bar { #status-bar {
color: initial !important; color: initial !important;
background-color: var(--toolbar-non-lwt-bgcolor) !important; border-top: 1px solid var(--chrome-content-separator-color);
background-color: var(--toolbar-bgcolor);
} }
:root[customizing] #status-bar { :root[customizing] #status-bar {
visibility: visible !important; visibility: visible !important;
@@ -53,11 +49,29 @@ const StatusBar = {
border-radius: 3px !important; border-radius: 3px !important;
font-weight: bold !important; font-weight: bold !important;
} }
#status-bar > #status-text { #wrapper-status-text > #status-text > #statuspanel-label {
display: none;
}
#status-bar #status-text {
display: flex !important; display: flex !important;
justify-content: center !important; justify-content: center !important;
align-content: center !important; align-items: center !important;
flex-direction: column !important; height: calc(2 * var(--toolbarbutton-inner-padding) + 16px);
}
toolbarpaletteitem #status-text:before {
content: "Status text";
color: red;
border: 1px #aaa solid;
border-radius: 3px;
font-weight: bold;
display: flex;
justify-content: center;
align-content: center;
flex-direction: column;
align-items: center;
margin-inline: var(--toolbarbutton-outer-padding);
width: 100%;
height: 100%;
} }
/* Ensure text color of status bar widgets set correctly */ /* Ensure text color of status bar widgets set correctly */
toolbar .toolbarbutton-1 { toolbar .toolbarbutton-1 {
@@ -69,7 +83,7 @@ const StatusBar = {
init(window) { init(window) {
if (!window.document.getElementById("status-dummybar")) { if (!window.document.getElementById("status-dummybar")) {
setTimeout(() => { lazy.setTimeout(() => {
this.init(window); this.init(window);
}, 25); }, 25);
} else if (!window.statusbar.node) { } else if (!window.statusbar.node) {
@@ -79,86 +93,87 @@ const StatusBar = {
this.configureBottomBox(window); this.configureBottomBox(window);
this.initPrefListeners(); this.initPrefListeners();
this.registerArea(window, "status-bar"); this.registerArea(window, "status-bar");
BrowserUtils.setStyle(this.style); lazy.BrowserUtils.setStyle(this.style);
} }
}, },
async initPrefListeners() { async initPrefListeners() {
this.enabledListener = PrefUtils.addObserver( this.enabledListener = lazy.PrefUtils.addObserver(
this.PREF_ENABLED, this.PREF_ENABLED,
isEnabled => { (isEnabled) => {
this.setStatusBarVisibility(isEnabled); this.setStatusBarVisibility(isEnabled);
this.setStatusTextVisibility(); this.setStatusTextVisibility();
} }
); );
this.textListener = PrefUtils.addObserver( this.textListener = lazy.PrefUtils.addObserver(
this.PREF_STATUSTEXT, this.PREF_STATUSTEXT,
isEnabled => { (_isEnabled) => {
this.setStatusTextVisibility(); this.setStatusTextVisibility();
} }
); );
}, },
async setStatusBarVisibility(isEnabled) { async setStatusBarVisibility(isEnabled) {
CustomizableUI.getWidget("status-dummybar").instances.forEach(dummyBar => { const instances =
lazy.CustomizableUI.getWidget("status-dummybar").instances;
for (const dummyBar of instances) {
dummyBar.node.setAttribute("collapsed", !isEnabled); dummyBar.node.setAttribute("collapsed", !isEnabled);
}); }
}, },
async setStatusTextVisibility() { async setStatusTextVisibility() {
if (this.enabled && this.showLinks) { if (this.enabled && this.showLinks) {
// Status bar enabled and want to display links in it // Status bar enabled and want to display links in it
this.executeInAllWindows(window => { this.executeInAllWindows((window) => {
let StatusPanel = window.StatusPanel; const StatusPanel = window.StatusPanel;
window.statusbar.textNode.appendChild(StatusPanel._labelElement); window.statusbar.textNode.appendChild(StatusPanel._labelElement);
}); });
} else if (!this.enabled && this.showLinks) { } else if (!this.enabled && this.showLinks) {
// Status bar disabled so display links in StatusPanel // Status bar disabled so display links in StatusPanel
this.executeInAllWindows(window => { this.executeInAllWindows((window) => {
let StatusPanel = window.StatusPanel; const StatusPanel = window.StatusPanel;
StatusPanel.panel.firstChild.appendChild(StatusPanel._labelElement); StatusPanel.panel.appendChild(StatusPanel._labelElement);
StatusPanel.panel.firstChild.hidden = false; StatusPanel.panel.firstChild.hidden = false;
}); });
} else { } else {
// Don't display links // Don't display links
this.executeInAllWindows(window => { this.executeInAllWindows((window) => {
let StatusPanel = window.StatusPanel; const StatusPanel = window.StatusPanel;
StatusPanel.panel.firstChild.appendChild(StatusPanel._labelElement); StatusPanel.panel.appendChild(StatusPanel._labelElement);
StatusPanel.panel.firstChild.hidden = true; StatusPanel.panel.firstChild.hidden = true;
}); });
} }
}, },
async registerArea(aWindow, aArea) { async registerArea(aWindow, aArea) {
if (!CustomizableUI.areas.includes("status-bar")) { if (!lazy.CustomizableUI.areas.includes("status-bar")) {
CustomizableUI.registerArea(aArea, { lazy.CustomizableUI.registerArea(aArea, {
type: CustomizableUI.TYPE_TOOLBAR, type: lazy.CustomizableUI.TYPE_TOOLBAR,
defaultPlacements: [ defaultPlacements: ["screenshot-button", "fullscreen-button"],
"screenshot-button",
"zoom-controls",
"fullscreen-button",
],
}); });
let tb = aWindow.document.getElementById("status-dummybar"); const tb = aWindow.document.getElementById("status-dummybar");
CustomizableUI.registerToolbarNode(tb); lazy.CustomizableUI.registerToolbarNode(tb);
} }
}, },
async configureDummyBar(aWindow, aId) { async configureDummyBar(aWindow, aId) {
let { document } = aWindow; const { document } = aWindow;
let el = document.getElementById(aId); const el = document.getElementById(aId);
el.collapsed = !this.enabled; el.collapsed = !this.enabled;
el.setAttribute = function(att, value) { el.setAttribute = function (att, value, ...rest) {
let result = Element.prototype.setAttribute.apply(this, arguments); const result = Element.prototype.setAttribute.apply(this, [
att,
value,
...rest,
]);
if (att == "collapsed") { if (att === "collapsed") {
let StatusPanel = aWindow.StatusPanel; const StatusPanel = aWindow.StatusPanel;
if (value === true) { if (value === true) {
PrefUtils.set(StatusBar.PREF_ENABLED, false); lazy.PrefUtils.set(StatusBar.PREF_ENABLED, false);
aWindow.statusbar.node.setAttribute("collapsed", true); aWindow.statusbar.node.setAttribute("collapsed", true);
StatusPanel.panel.firstChild.appendChild(StatusPanel._labelElement); StatusPanel.panel.appendChild(StatusPanel._labelElement);
} else { } else {
PrefUtils.set(StatusBar.PREF_ENABLED, true); lazy.PrefUtils.set(StatusBar.PREF_ENABLED, true);
aWindow.statusbar.node.setAttribute("collapsed", false); aWindow.statusbar.node.setAttribute("collapsed", false);
if (StatusBar.textInBar) { if (StatusBar.textInBar) {
aWindow.statusbar.textNode.appendChild(StatusPanel._labelElement); aWindow.statusbar.textNode.appendChild(StatusPanel._labelElement);
@@ -171,7 +186,7 @@ const StatusBar = {
}, },
configureStatusBar(aWindow) { configureStatusBar(aWindow) {
let StatusPanel = aWindow.StatusPanel; const StatusPanel = aWindow.StatusPanel;
aWindow.statusbar.node = aWindow.document.getElementById("status-bar"); aWindow.statusbar.node = aWindow.document.getElementById("status-bar");
aWindow.statusbar.textNode = aWindow.document.getElementById("status-text"); aWindow.statusbar.textNode = aWindow.document.getElementById("status-text");
if (this.textInBar) { if (this.textInBar) {
@@ -182,32 +197,32 @@ const StatusBar = {
}, },
async overrideStatusPanelLabel(aWindow) { async overrideStatusPanelLabel(aWindow) {
// eslint-disable-next-line no-unused-vars const { StatusPanel } = aWindow.wrappedJSObject;
let { StatusPanel, MousePosTracker } = aWindow;
// eslint-disable-next-line no-unused-vars const originalSetter = Object.getOwnPropertyDescriptor(
let window = aWindow; StatusPanel,
// TODO: Should be able to do this with a WrappedJSObject instead "_label"
// eslint-disable-next-line no-eval ).set;
eval(
'Object.defineProperty(StatusPanel, "_label", {' + Object.defineProperty(StatusPanel, "_label", {
Object.getOwnPropertyDescriptor(StatusPanel, "_label") set(val) {
.set.toString() if (this._labelElement) {
.replace(/^set _label/, "set") this._labelElement.value = val;
.replace( }
/((\s+)this\.panel\.setAttribute\("inactive", "true"\);)/, originalSetter.call(this, val);
"$2this._labelElement.value = val;$1" },
) + enumerable: true,
", enumerable: true, configurable: true});" configurable: true,
); });
}, },
async configureBottomBox(aWindow) { async configureBottomBox(aWindow) {
let { document } = aWindow; const { document } = aWindow;
let bottomBox = document.getElementById("browser-bottombox"); const bottomBox = document.getElementById("browser-bottombox");
CustomizableUI.registerToolbarNode(aWindow.statusbar.node); lazy.CustomizableUI.registerToolbarNode(aWindow.statusbar.node);
bottomBox.appendChild(aWindow.statusbar.node); bottomBox.appendChild(aWindow.statusbar.node);
}, },
}; };
// Inherited props // Inherited props
StatusBar.executeInAllWindows = BrowserUtils.executeInAllWindows; StatusBar.executeInAllWindows = lazy.BrowserUtils.executeInAllWindows;

View File

@@ -3,11 +3,10 @@
- License, v. 2.0. If a copy of the MPL was not distributed with this - 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/. --> - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<overlay id="tabfeature-overlay" xmlns:html="http://www.w3.org/1999/xhtml" <overlay id="tabfeature-overlay" xmlns:html="http://www.w3.org/1999/xhtml"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<toolbox id="navigator-toolbox"> <toolbox id="navigator-toolbox">
<toolbar id="status-dummybar" toolbarname="Status Bar" hidden="true" /> <toolbar id="status-dummybar" toolbarname="Status Bar" accesskey="" hidden="true" />
</toolbox> </toolbox>
<vbox id="browser-bottombox"> <vbox id="browser-bottombox">
<toolbar id="status-bar" customizable="true" context="toolbar-context-menu" mode="icons" <toolbar id="status-bar" customizable="true" context="toolbar-context-menu" mode="icons"

View File

@@ -5,7 +5,7 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/. # file, You can obtain one at http://mozilla.org/MPL/2.0/.
EXTRA_JS_MODULES += [ EXTRA_JS_MODULES += [
"StatusBar.jsm", "StatusBar.sys.mjs",
] ]
BROWSER_CHROME_MANIFESTS += ["test/browser/browser.ini"] BROWSER_CHROME_MANIFESTS += ["test/browser/browser.ini"]

View File

@@ -1,5 +1,3 @@
"use strict";
// Test status bar is present // Test status bar is present
add_task(async function testStatusBarPresent() { add_task(async function testStatusBarPresent() {
let el = document.getElementById("status-bar"); let el = document.getElementById("status-bar");

View File

@@ -1,14 +1,12 @@
"use strict"; const { synthesizeDrop, synthesizeMouseAtCenter } = EventUtils;
var { synthesizeDrop, synthesizeMouseAtCenter } = EventUtils; const _STATUSBAR_ENABLED_PREF = "browser.statusbar.enabled";
const STATUSBAR_ENABLED_PREF = "browser.statusbar.enabled";
/** /**
* Helper for opening toolbar context menu. * Helper for opening toolbar context menu.
*/ */
async function openToolbarContextMenu(contextMenu, target) { async function _openToolbarContextMenu(contextMenu, target) {
let popupshown = BrowserTestUtils.waitForEvent(contextMenu, "popupshown"); const popupshown = BrowserTestUtils.waitForEvent(contextMenu, "popupshown");
EventUtils.synthesizeMouseAtCenter(target, { type: "contextmenu" }); EventUtils.synthesizeMouseAtCenter(target, { type: "contextmenu" });
await popupshown; await popupshown;
} }
@@ -17,11 +15,11 @@ async function openToolbarContextMenu(contextMenu, target) {
* Helpers for Customizable UI * Helpers for Customizable UI
*/ */
function startCustomizing(aWindow = window) { function _startCustomizing(aWindow = window) {
if (aWindow.document.documentElement.getAttribute("customizing") == "true") { if (aWindow.document.documentElement.getAttribute("customizing") === "true") {
return null; return null;
} }
let customizationReadyPromise = BrowserTestUtils.waitForEvent( const customizationReadyPromise = BrowserTestUtils.waitForEvent(
aWindow.gNavToolbox, aWindow.gNavToolbox,
"customizationready" "customizationready"
); );
@@ -29,11 +27,11 @@ function startCustomizing(aWindow = window) {
return customizationReadyPromise; return customizationReadyPromise;
} }
function endCustomizing(aWindow = window) { function _endCustomizing(aWindow = window) {
if (aWindow.document.documentElement.getAttribute("customizing") != "true") { if (aWindow.document.documentElement.getAttribute("customizing") !== "true") {
return true; return true;
} }
let afterCustomizationPromise = BrowserTestUtils.waitForEvent( const afterCustomizationPromise = BrowserTestUtils.waitForEvent(
aWindow.gNavToolbox, aWindow.gNavToolbox,
"aftercustomization" "aftercustomization"
); );
@@ -41,8 +39,8 @@ function endCustomizing(aWindow = window) {
return afterCustomizationPromise; return afterCustomizationPromise;
} }
function assertAreaPlacements(areaId, expectedPlacements) { function _assertAreaPlacements(areaId, expectedPlacements) {
let actualPlacements = getAreaWidgetIds(areaId); const actualPlacements = getAreaWidgetIds(areaId);
placementArraysEqual(areaId, actualPlacements, expectedPlacements); placementArraysEqual(areaId, actualPlacements, expectedPlacements);
} }
@@ -51,32 +49,25 @@ function getAreaWidgetIds(areaId) {
} }
function placementArraysEqual(areaId, actualPlacements, expectedPlacements) { function placementArraysEqual(areaId, actualPlacements, expectedPlacements) {
info("Actual placements: " + actualPlacements.join(", ")); info(`Actual placements: ${actualPlacements.join(", ")}`);
info("Expected placements: " + expectedPlacements.join(", ")); info(`Expected placements: ${expectedPlacements.join(", ")}`);
is( is(
actualPlacements.length, actualPlacements.length,
expectedPlacements.length, expectedPlacements.length,
"Area " + areaId + " should have " + expectedPlacements.length + " items." `Area ${areaId} should have ${expectedPlacements.length} items.`
); );
let minItems = Math.min(expectedPlacements.length, actualPlacements.length); const minItems = Math.min(expectedPlacements.length, actualPlacements.length);
for (let i = 0; i < minItems; i++) { for (let i = 0; i < minItems; i++) {
if (typeof expectedPlacements[i] == "string") { if (typeof expectedPlacements[i] === "string") {
is( is(
actualPlacements[i], actualPlacements[i],
expectedPlacements[i], expectedPlacements[i],
"Item " + i + " in " + areaId + " should match expectations." `Item ${i} in ${areaId} should match expectations.`
); );
} else if (expectedPlacements[i] instanceof RegExp) { } else if (expectedPlacements[i] instanceof RegExp) {
ok( ok(
expectedPlacements[i].test(actualPlacements[i]), expectedPlacements[i].test(actualPlacements[i]),
"Item " + `Item ${i} (${actualPlacements[i]}) in ${areaId} should match ${expectedPlacements[i]}`
i +
" (" +
actualPlacements[i] +
") in " +
areaId +
" should match " +
expectedPlacements[i]
); );
} else { } else {
ok( ok(
@@ -88,13 +79,13 @@ function placementArraysEqual(areaId, actualPlacements, expectedPlacements) {
} }
} }
function simulateItemDrag(aToDrag, aTarget, aEvent = {}, aOffset = 2) { function _simulateItemDrag(aToDrag, aTarget, aEvent = {}, aOffset = 2) {
let ev = aEvent; let ev = aEvent;
if (ev == "end" || ev == "start") { if (ev === "end" || ev === "start") {
let win = aTarget.ownerGlobal; const win = aTarget.ownerGlobal;
const dwu = win.windowUtils; const dwu = win.windowUtils;
let bounds = dwu.getBoundsWithoutFlushing(aTarget); const bounds = dwu.getBoundsWithoutFlushing(aTarget);
if (ev == "end") { if (ev === "end") {
ev = { ev = {
clientX: bounds.right - aOffset, clientX: bounds.right - aOffset,
clientY: bounds.bottom - aOffset, clientY: bounds.bottom - aOffset,