summaryrefslogtreecommitdiffstats
path: root/browser/base/content/browser-pagestyle.js
diff options
context:
space:
mode:
Diffstat (limited to 'browser/base/content/browser-pagestyle.js')
-rw-r--r--browser/base/content/browser-pagestyle.js125
1 files changed, 125 insertions, 0 deletions
diff --git a/browser/base/content/browser-pagestyle.js b/browser/base/content/browser-pagestyle.js
new file mode 100644
index 0000000000..4266ffd69e
--- /dev/null
+++ b/browser/base/content/browser-pagestyle.js
@@ -0,0 +1,125 @@
+/* -*- 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.setAttribute(
+ "oncommand",
+ "gPageStyleMenu.switchStyleSheet(this.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", {});
+ },
+};