1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
|
/* -*- 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", {});
},
};
|