1// To avoid Flash of Unstyled Content, the body is hidden. 2// Here we'll find the first web component and wait for it to be upgraded. 3// When it is, we'll remove this invisibility from the body. 4 5const memoryStorage = (() => { 6 const values = {}; 7 8 return { 9 getItem(key) { 10 return Object.prototype.hasOwnProperty.call(values, key) ? values[key] : null; 11 }, 12 setItem(key, value) { 13 values[key] = String(value); 14 }, 15 removeItem(key) { 16 delete values[key]; 17 } 18 }; 19})(); 20 21function getThemeStorage() { 22 try { 23 const storage = window.localStorage; 24 if (storage == null) { 25 return memoryStorage; 26 } 27 28 return storage; 29 } catch { 30 return memoryStorage; 31 } 32} 33 34function readStoredTheme(storageName) { 35 if (!storageName) { 36 return null; 37 } 38 39 const storage = getThemeStorage(); 40 41 try { 42 const theme = storage.getItem(storageName); 43 return theme ? JSON.parse(theme) : null; 44 } catch { 45 try { 46 storage.removeItem(storageName); 47 } catch { 48 } 49 50 return null; 51 } 52} 53 54class LoadingTheme extends HTMLElement { 55 56 className = "hidden-body"; 57 defaultDarkColor = "#272727"; 58 defaultLightColor = "#fbfbfb"; 59 60 constructor() { 61 super(); 62 } 63 64 // Attributes to observe 65 static observedAttributes = ["mode", "storage-name"]; 66 67 // Custom element added to page. 68 connectedCallback() { 69 // Attributes 70 const storageName = this.getAttribute("storage-name"); 71 const mode = this.getAttribute("mode"); 72 const primaryColor = this.getAttribute("primary-color"); 73 const neutralColor = this.getAttribute("neutral-color"); 74 const storedTheme = readStoredTheme(storageName); 75 76 const isDark = (modeSaved, isSystemDark) => { 77 switch (modeSaved) { 78 case "dark": 79 return true; 80 case "light": 81 return false; 82 default: 83 return isSystemDark ? true : false; 84 } 85 }; 86 87 // Compute the saved or the system theme (dark/light). 88 const modeSaved = mode ?? storedTheme?.mode; 89 const primaryColorSaved = primaryColor ?? storedTheme?.primaryColor; 90 const neutralColorSaved = neutralColor ?? storedTheme?.neutralColor; 91 const isSystemDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches; 92 const bgColor = isDark(modeSaved, isSystemDark) ? this.defaultDarkColor : this.defaultLightColor; 93 94 // console.log("LoadingTheme", { storageName, mode, modeSaved, isSystemDark, bgColor }); 95 96 // Create a ".hidden-unstyled-body" class 97 // where the background-color is dark or light. 98 var css = `.${this.className} { visibility: hidden; background-color: ${bgColor}; }`; 99 100 // Add a <style> element to the <head> element 101 const head = document.head || document.getElementsByTagName('head')[0]; 102 const style = document.createElement('style'); 103 104 head.appendChild(style); 105 style.appendChild(document.createTextNode(css)); 106 107 document.body.classList.add(this.className); 108 109 110 // Add a <fluent-design-theme mode="dark|light" /> sub-element 111 // Do not add the "storage-name"" to avoid unwanted local storage. 112 const designTheme = document.createElement("fluent-design-theme"); 113 designTheme.setAttribute("mode", modeSaved); 114 designTheme.setAttribute("primary-color", primaryColorSaved); 115 designTheme.setAttribute("neutral-color", neutralColorSaved); 116 this.appendChild(designTheme); 117 118 // Wait for the fluentui web components to be loaded 119 // and to remove the className to show the <body> content. 120 customElements.whenDefined("fluent-design-theme").then(() => { 121 document.body.classList.remove(this.className); 122 }); 123 } 124 125 // Attributes has changed. 126 attributeChangedCallback(name, oldValue, newValue) { 127 128 } 129} 130 131customElements.define("loading-theme", LoadingTheme);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.