browser-pagestyle.js (4198B)
1 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- 2 * This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 var gPageStyleMenu = { 7 _getStyleSheetInfo(browser) { 8 let actor = 9 browser.browsingContext.currentWindowGlobal?.getActor("PageStyle"); 10 let styleSheetInfo; 11 if (actor) { 12 styleSheetInfo = actor.getSheetInfo(); 13 } else { 14 // Fallback if the actor is missing or we don't have a window global. 15 // It's unlikely things will work well but let's be optimistic, 16 // rather than throwing exceptions immediately. 17 styleSheetInfo = { 18 filteredStyleSheets: [], 19 preferredStyleSheetSet: true, 20 }; 21 } 22 return styleSheetInfo; 23 }, 24 25 fillPopup(menuPopup) { 26 let styleSheetInfo = this._getStyleSheetInfo(gBrowser.selectedBrowser); 27 var noStyle = menuPopup.firstElementChild; 28 var persistentOnly = noStyle.nextElementSibling; 29 var sep = persistentOnly.nextElementSibling; 30 while (sep.nextElementSibling) { 31 menuPopup.removeChild(sep.nextElementSibling); 32 } 33 34 let styleSheets = styleSheetInfo.filteredStyleSheets; 35 var currentStyleSheets = {}; 36 var styleDisabled = 37 !!gBrowser.selectedBrowser.browsingContext?.authorStyleDisabledDefault; 38 var haveAltSheets = false; 39 var altStyleSelected = false; 40 41 for (let currentStyleSheet of styleSheets) { 42 if (!currentStyleSheet.disabled) { 43 altStyleSelected = true; 44 } 45 46 haveAltSheets = true; 47 48 let lastWithSameTitle = null; 49 if (currentStyleSheet.title in currentStyleSheets) { 50 lastWithSameTitle = currentStyleSheets[currentStyleSheet.title]; 51 } 52 53 if (!lastWithSameTitle) { 54 let menuItem = document.createXULElement("menuitem"); 55 menuItem.setAttribute("type", "radio"); 56 menuItem.setAttribute("label", currentStyleSheet.title); 57 menuItem.setAttribute("data", currentStyleSheet.title); 58 menuItem.toggleAttribute( 59 "checked", 60 !currentStyleSheet.disabled && !styleDisabled 61 ); 62 menuItem.addEventListener("command", event => 63 this.switchStyleSheet(event.currentTarget.getAttribute("data")) 64 ); 65 menuPopup.appendChild(menuItem); 66 currentStyleSheets[currentStyleSheet.title] = menuItem; 67 } else if (currentStyleSheet.disabled) { 68 lastWithSameTitle.removeAttribute("checked"); 69 } 70 } 71 72 noStyle.toggleAttribute("checked", styleDisabled); 73 persistentOnly.toggleAttribute( 74 "checked", 75 !altStyleSelected && !styleDisabled 76 ); 77 persistentOnly.hidden = styleSheetInfo.preferredStyleSheetSet 78 ? haveAltSheets 79 : false; 80 sep.hidden = (noStyle.hidden && persistentOnly.hidden) || !haveAltSheets; 81 }, 82 83 /** 84 * Send a message to all PageStyleParents by walking the BrowsingContext tree. 85 * 86 * @param message 87 * The string message to send to each PageStyleChild. 88 * @param data 89 * The data to send to each PageStyleChild within the message. 90 */ 91 _sendMessageToAll(message, data) { 92 let contextsToVisit = [gBrowser.selectedBrowser.browsingContext]; 93 while (contextsToVisit.length) { 94 let currentContext = contextsToVisit.pop(); 95 let global = currentContext.currentWindowGlobal; 96 97 if (!global) { 98 continue; 99 } 100 101 let actor = global.getActor("PageStyle"); 102 actor.sendAsyncMessage(message, data); 103 104 contextsToVisit.push(...currentContext.children); 105 } 106 }, 107 108 /** 109 * Switch the stylesheet of all documents in the current browser. 110 * 111 * @param title The title of the stylesheet to switch to. 112 */ 113 switchStyleSheet(title) { 114 let sheetData = this._getStyleSheetInfo(gBrowser.selectedBrowser); 115 for (let sheet of sheetData.filteredStyleSheets) { 116 sheet.disabled = sheet.title !== title; 117 } 118 this._sendMessageToAll("PageStyle:Switch", { title }); 119 }, 120 121 /** 122 * Disable all stylesheets. Called with View > Page Style > No Style. 123 */ 124 disableStyle() { 125 this._sendMessageToAll("PageStyle:Disable", {}); 126 }, 127 };