stylesheet-utils.js (2255B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 "use strict"; 6 7 function stylesheetLoadPromise(styleSheet) { 8 return new Promise((resolve, reject) => { 9 styleSheet.addEventListener("load", resolve, { once: true }); 10 styleSheet.addEventListener("error", reject, { once: true }); 11 }); 12 } 13 14 /** 15 * Put the DevTools theme stylesheet into the provided chrome document. 16 * 17 * @param {Document} doc 18 * The chrome document where the stylesheet should be appended. 19 * @param {string} url 20 * The url of the stylesheet to load. 21 * @return {object} 22 * - styleSheet {XMLStylesheetProcessingInstruction} the instruction node created. 23 * - loadPromise {Promise} that will resolve/reject when the stylesheet finishes 24 * or fails to load. 25 */ 26 function appendStyleSheet(doc, url) { 27 const styleSheet = doc.createElementNS( 28 "http://www.w3.org/1999/xhtml", 29 "link" 30 ); 31 styleSheet.setAttribute("rel", "stylesheet"); 32 styleSheet.setAttribute("href", url); 33 const loadPromise = stylesheetLoadPromise(styleSheet); 34 35 // In order to make overriding styles sane, we want the order of loaded 36 // sheets to be something like this: 37 // global.css 38 // *-theme.css (the file loaded here) 39 // document-specific-sheet.css 40 // See Bug 1582786 / https://phabricator.services.mozilla.com/D46530#inline-284756. 41 42 // If there is a global sheet then insert after it. 43 const globalSheet = doc.querySelector( 44 "link[href='chrome://global/skin/global.css']" 45 ); 46 if (globalSheet) { 47 globalSheet.after(styleSheet); 48 return { styleSheet, loadPromise }; 49 } 50 51 // Otherwise insert before any existing link. 52 const links = doc.querySelectorAll("link"); 53 if (links.length) { 54 links[0].before(styleSheet); 55 return { styleSheet, loadPromise }; 56 } 57 58 // Fall back to putting at the start of the head or in a non-HTML doc the 59 // start of the document. 60 if (doc.head) { 61 doc.head.prepend(styleSheet); 62 } else { 63 doc.documentElement.prepend(styleSheet); 64 } 65 66 return { styleSheet, loadPromise }; 67 } 68 69 exports.appendStyleSheet = appendStyleSheet;