124 lines
4.1 KiB
JavaScript
124 lines
4.1 KiB
JavaScript
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
|
|
* 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/. */
|
|
|
|
/* eslint-env mozilla/browser-window */
|
|
|
|
var gPageStyleMenu = {
|
|
_getStyleSheetInfo(browser) {
|
|
let actor =
|
|
browser.browsingContext.currentWindowGlobal?.getActor("PageStyle");
|
|
let styleSheetInfo;
|
|
if (actor) {
|
|
styleSheetInfo = actor.getSheetInfo();
|
|
} else {
|
|
// Fallback if the actor is missing or we don't have a window global.
|
|
// It's unlikely things will work well but let's be optimistic,
|
|
// rather than throwing exceptions immediately.
|
|
styleSheetInfo = {
|
|
filteredStyleSheets: [],
|
|
preferredStyleSheetSet: true,
|
|
};
|
|
}
|
|
return styleSheetInfo;
|
|
},
|
|
|
|
fillPopup(menuPopup) {
|
|
let styleSheetInfo = this._getStyleSheetInfo(gBrowser.selectedBrowser);
|
|
var noStyle = menuPopup.firstElementChild;
|
|
var persistentOnly = noStyle.nextElementSibling;
|
|
var sep = persistentOnly.nextElementSibling;
|
|
while (sep.nextElementSibling) {
|
|
menuPopup.removeChild(sep.nextElementSibling);
|
|
}
|
|
|
|
let styleSheets = styleSheetInfo.filteredStyleSheets;
|
|
var currentStyleSheets = {};
|
|
var styleDisabled =
|
|
!!gBrowser.selectedBrowser.browsingContext?.authorStyleDisabledDefault;
|
|
var haveAltSheets = false;
|
|
var altStyleSelected = false;
|
|
|
|
for (let currentStyleSheet of styleSheets) {
|
|
if (!currentStyleSheet.disabled) {
|
|
altStyleSelected = true;
|
|
}
|
|
|
|
haveAltSheets = true;
|
|
|
|
let lastWithSameTitle = null;
|
|
if (currentStyleSheet.title in currentStyleSheets) {
|
|
lastWithSameTitle = currentStyleSheets[currentStyleSheet.title];
|
|
}
|
|
|
|
if (!lastWithSameTitle) {
|
|
let menuItem = document.createXULElement("menuitem");
|
|
menuItem.setAttribute("type", "radio");
|
|
menuItem.setAttribute("label", currentStyleSheet.title);
|
|
menuItem.setAttribute("data", currentStyleSheet.title);
|
|
menuItem.setAttribute(
|
|
"checked",
|
|
!currentStyleSheet.disabled && !styleDisabled
|
|
);
|
|
menuItem.addEventListener("command", event =>
|
|
this.switchStyleSheet(event.currentTarget.getAttribute("data"))
|
|
);
|
|
menuPopup.appendChild(menuItem);
|
|
currentStyleSheets[currentStyleSheet.title] = menuItem;
|
|
} else if (currentStyleSheet.disabled) {
|
|
lastWithSameTitle.removeAttribute("checked");
|
|
}
|
|
}
|
|
|
|
noStyle.setAttribute("checked", styleDisabled);
|
|
persistentOnly.setAttribute("checked", !altStyleSelected && !styleDisabled);
|
|
persistentOnly.hidden = styleSheetInfo.preferredStyleSheetSet
|
|
? haveAltSheets
|
|
: false;
|
|
sep.hidden = (noStyle.hidden && persistentOnly.hidden) || !haveAltSheets;
|
|
},
|
|
|
|
/**
|
|
* Send a message to all PageStyleParents by walking the BrowsingContext tree.
|
|
* @param message
|
|
* The string message to send to each PageStyleChild.
|
|
* @param data
|
|
* The data to send to each PageStyleChild within the message.
|
|
*/
|
|
_sendMessageToAll(message, data) {
|
|
let contextsToVisit = [gBrowser.selectedBrowser.browsingContext];
|
|
while (contextsToVisit.length) {
|
|
let currentContext = contextsToVisit.pop();
|
|
let global = currentContext.currentWindowGlobal;
|
|
|
|
if (!global) {
|
|
continue;
|
|
}
|
|
|
|
let actor = global.getActor("PageStyle");
|
|
actor.sendAsyncMessage(message, data);
|
|
|
|
contextsToVisit.push(...currentContext.children);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Switch the stylesheet of all documents in the current browser.
|
|
* @param title The title of the stylesheet to switch to.
|
|
*/
|
|
switchStyleSheet(title) {
|
|
let sheetData = this._getStyleSheetInfo(gBrowser.selectedBrowser);
|
|
for (let sheet of sheetData.filteredStyleSheets) {
|
|
sheet.disabled = sheet.title !== title;
|
|
}
|
|
this._sendMessageToAll("PageStyle:Switch", { title });
|
|
},
|
|
|
|
/**
|
|
* Disable all stylesheets. Called with View > Page Style > No Style.
|
|
*/
|
|
disableStyle() {
|
|
this._sendMessageToAll("PageStyle:Disable", {});
|
|
},
|
|
};
|