208 lines
6.6 KiB
JavaScript
208 lines
6.6 KiB
JavaScript
|
// ==UserScript==
|
||
|
// @name Status Bar
|
||
|
// @author xiaoxiaoflood
|
||
|
// @include main
|
||
|
// @startup UC.statusBar.exec(win);
|
||
|
// @shutdown UC.statusBar.destroy();
|
||
|
// @onlyonce
|
||
|
// ==/UserScript==
|
||
|
|
||
|
const { CustomizableUI, StatusPanel } = window;
|
||
|
|
||
|
UC.statusBar = {
|
||
|
PREF_ENABLED: "userChromeJS.statusbar.enabled",
|
||
|
PREF_STATUSTEXT: "userChromeJS.statusbar.appendStatusText",
|
||
|
|
||
|
get enabled() {
|
||
|
return xPref.get(this.PREF_ENABLED);
|
||
|
},
|
||
|
|
||
|
get textInBar() {
|
||
|
return this.enabled && xPref.get(this.PREF_STATUSTEXT);
|
||
|
},
|
||
|
|
||
|
init: function () {
|
||
|
xPref.set(this.PREF_ENABLED, true, true);
|
||
|
xPref.set(this.PREF_STATUSTEXT, true, true);
|
||
|
this.enabledListener = xPref.addListener(this.PREF_ENABLED, (isEnabled) => {
|
||
|
CustomizableUI.getWidget("status-dummybar").instances.forEach(
|
||
|
(dummyBar) => {
|
||
|
dummyBar.node.setAttribute("collapsed", !isEnabled);
|
||
|
}
|
||
|
);
|
||
|
});
|
||
|
this.textListener = xPref.addListener(this.PREF_STATUSTEXT, (isEnabled) => {
|
||
|
if (!UC.statusBar.enabled) return;
|
||
|
|
||
|
_uc.windows((doc, win) => {
|
||
|
let StatusPanel = win.StatusPanel;
|
||
|
if (isEnabled)
|
||
|
win.statusbar.textNode.appendChild(StatusPanel._labelElement);
|
||
|
else StatusPanel.panel.appendChild(StatusPanel._labelElement);
|
||
|
});
|
||
|
});
|
||
|
|
||
|
this.setStyle();
|
||
|
_uc.sss.loadAndRegisterSheet(this.STYLE.url, this.STYLE.type);
|
||
|
|
||
|
CustomizableUI.registerArea("status-bar", {});
|
||
|
|
||
|
Services.obs.addObserver(this, "browser-delayed-startup-finished");
|
||
|
},
|
||
|
|
||
|
exec: function (win) {
|
||
|
let document = win.document;
|
||
|
let StatusPanel = win.StatusPanel;
|
||
|
|
||
|
let dummystatusbar = _uc.createElement(document, "toolbar", {
|
||
|
id: "status-dummybar",
|
||
|
toolbarname: "Status Bar",
|
||
|
hidden: "true",
|
||
|
});
|
||
|
dummystatusbar.collapsed = !this.enabled;
|
||
|
dummystatusbar.setAttribute = function (att, value) {
|
||
|
let result = Element.prototype.setAttribute.apply(this, arguments);
|
||
|
|
||
|
if (att == "collapsed") {
|
||
|
let StatusPanel = win.StatusPanel;
|
||
|
if (value === true) {
|
||
|
xPref.set(UC.statusBar.PREF_ENABLED, false);
|
||
|
win.statusbar.node.setAttribute("collapsed", true);
|
||
|
StatusPanel.panel.appendChild(StatusPanel._labelElement);
|
||
|
win.statusbar.node.parentNode.collapsed = true;
|
||
|
} else {
|
||
|
xPref.set(UC.statusBar.PREF_ENABLED, true);
|
||
|
win.statusbar.node.setAttribute("collapsed", false);
|
||
|
if (UC.statusBar.textInBar)
|
||
|
win.statusbar.textNode.appendChild(StatusPanel._labelElement);
|
||
|
win.statusbar.node.parentNode.collapsed = false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return result;
|
||
|
};
|
||
|
win.gNavToolbox.appendChild(dummystatusbar);
|
||
|
|
||
|
win.statusbar.node = _uc.createElement(document, "toolbar", {
|
||
|
id: "status-bar",
|
||
|
customizable: "true",
|
||
|
context: "toolbar-context-menu",
|
||
|
mode: "icons",
|
||
|
});
|
||
|
|
||
|
win.statusbar.textNode = _uc.createElement(document, "toolbaritem", {
|
||
|
id: "status-text",
|
||
|
flex: "1",
|
||
|
width: "100",
|
||
|
});
|
||
|
if (this.textInBar)
|
||
|
win.statusbar.textNode.appendChild(StatusPanel._labelElement);
|
||
|
win.statusbar.node.appendChild(win.statusbar.textNode);
|
||
|
|
||
|
win.eval(
|
||
|
'Object.defineProperty(StatusPanel, "_label", {' +
|
||
|
Object.getOwnPropertyDescriptor(StatusPanel, "_label")
|
||
|
.set.toString()
|
||
|
.replace(/^set _label/, "set")
|
||
|
.replace(
|
||
|
/((\s+)this\.panel\.setAttribute\("inactive", "true"\);)/,
|
||
|
"$2this._labelElement.value = val;$1"
|
||
|
) +
|
||
|
", enumerable: true, configurable: true});"
|
||
|
);
|
||
|
|
||
|
let bottomBox = document.createElement("vbox");
|
||
|
bottomBox.id = "browser-bottombox";
|
||
|
bottomBox.append(win.statusbar.node);
|
||
|
|
||
|
if (!this.enabled) bottomBox.collapsed = true;
|
||
|
|
||
|
document
|
||
|
.getElementById("fullscreen-and-pointerlock-wrapper")
|
||
|
.insertAdjacentElement("afterend", bottomBox);
|
||
|
|
||
|
win.addEventListener("fullscreen", this.fsEvent);
|
||
|
|
||
|
if (document.readyState === "complete") this.observe(win);
|
||
|
},
|
||
|
|
||
|
fsEvent: function (ev) {
|
||
|
const { StatusPanel, fullScreen, statusbar } = ev.target;
|
||
|
if (fullScreen) StatusPanel.panel.appendChild(StatusPanel._labelElement);
|
||
|
else statusbar.textNode.appendChild(StatusPanel._labelElement);
|
||
|
},
|
||
|
|
||
|
observe: function (win) {
|
||
|
CustomizableUI.registerToolbarNode(win.statusbar.node);
|
||
|
},
|
||
|
|
||
|
orig: Object.getOwnPropertyDescriptor(StatusPanel, "_label").set.toString(),
|
||
|
|
||
|
setStyle: function () {
|
||
|
this.STYLE = {
|
||
|
url: Services.io.newURI(
|
||
|
"data:text/css;charset=UTF-8," +
|
||
|
encodeURIComponent(`
|
||
|
@-moz-document url('${_uc.BROWSERCHROME}') {
|
||
|
#status-bar {
|
||
|
color: initial !important;
|
||
|
/*background-color: var(--toolbar-non-lwt-bgcolor);*/
|
||
|
}
|
||
|
#status-text > #statuspanel-label {
|
||
|
border-top: 0 !important;
|
||
|
/*background-color: unset !important;
|
||
|
color: #444;*/
|
||
|
}
|
||
|
#status-bar > #status-text {
|
||
|
display: flex !important;
|
||
|
justify-content: center !important;
|
||
|
align-content: center !important;
|
||
|
flex-direction: column !important;
|
||
|
-moz-window-dragging: drag;
|
||
|
}
|
||
|
toolbarpaletteitem #status-text:before {
|
||
|
content: "Status text";
|
||
|
color: red;
|
||
|
border: 1px #aaa solid;
|
||
|
border-radius: 3px;
|
||
|
font-weight: bold;
|
||
|
}
|
||
|
/*#browser-bottombox:not([collapsed]) {
|
||
|
border-top: 1px solid #BCBEBF !important;
|
||
|
}*/
|
||
|
:root[inFullscreen]:not([macOSNativeFullscreen]) #browser-bottombox {
|
||
|
visibility: collapse !important;
|
||
|
}
|
||
|
}
|
||
|
`)
|
||
|
),
|
||
|
type: _uc.sss.USER_SHEET,
|
||
|
};
|
||
|
},
|
||
|
|
||
|
destroy: function () {
|
||
|
const { CustomizableUI } = Services.wm.getMostRecentBrowserWindow();
|
||
|
|
||
|
xPref.removeListener(this.enabledListener);
|
||
|
xPref.removeListener(this.textListener);
|
||
|
CustomizableUI.unregisterArea("status-bar");
|
||
|
_uc.sss.unregisterSheet(this.STYLE.url, this.STYLE.type);
|
||
|
_uc.windows((doc, win) => {
|
||
|
const { eval, statusbar, StatusPanel } = win;
|
||
|
eval(
|
||
|
'Object.defineProperty(StatusPanel, "_label", {' +
|
||
|
this.orig.replace(/^set _label/, "set") +
|
||
|
", enumerable: true, configurable: true});"
|
||
|
);
|
||
|
StatusPanel.panel.appendChild(StatusPanel._labelElement);
|
||
|
doc.getElementById("status-dummybar").remove();
|
||
|
statusbar.node.remove();
|
||
|
win.removeEventListener("fullscreen", this.fsEvent);
|
||
|
});
|
||
|
Services.obs.removeObserver(this, "browser-delayed-startup-finished");
|
||
|
delete UC.statusBar;
|
||
|
},
|
||
|
};
|
||
|
|
||
|
UC.statusBar.init();
|