forked from mirrors/gecko-dev
		
	
		
			
				
	
	
		
			129 lines
		
	
	
	
		
			4.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			129 lines
		
	
	
	
		
			4.3 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: [],
 | |
|         authorStyleDisabled: false,
 | |
|         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 = styleSheetInfo.authorStyleDisabled;
 | |
|     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);
 | |
|     sheetData.authorStyleDisabled = false;
 | |
|     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() {
 | |
|     let sheetData = this._getStyleSheetInfo(gBrowser.selectedBrowser);
 | |
|     sheetData.authorStyleDisabled = true;
 | |
|     this._sendMessageToAll("PageStyle:Disable", {});
 | |
|   },
 | |
| };
 | 
