diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 05:47:55 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 05:47:55 +0000 |
commit | 31d6ff6f931696850c348007241195ab3b2eddc7 (patch) | |
tree | 615cb1c57ce9f6611bad93326b9105098f379609 /src/js/theme.js | |
parent | Initial commit. (diff) | |
download | ublock-origin-31d6ff6f931696850c348007241195ab3b2eddc7.tar.xz ublock-origin-31d6ff6f931696850c348007241195ab3b2eddc7.zip |
Adding upstream version 1.55.0+dfsg.upstream/1.55.0+dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/js/theme.js')
-rw-r--r-- | src/js/theme.js | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/src/js/theme.js b/src/js/theme.js new file mode 100644 index 0000000..d3f9b00 --- /dev/null +++ b/src/js/theme.js @@ -0,0 +1,151 @@ +/******************************************************************************* + + uBlock Origin - a comprehensive, efficient content blocker + Copyright (C) 2014-present Raymond Hill + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see {http://www.gnu.org/licenses/}. + + Home: https://github.com/gorhill/uBlock +*/ + +'use strict'; + +function getActualTheme(nominalTheme) { + let theme = nominalTheme || 'light'; + if ( nominalTheme === 'auto' ) { + if ( typeof self.matchMedia === 'function' ) { + const mql = self.matchMedia('(prefers-color-scheme: dark)'); + theme = mql instanceof Object && mql.matches === true + ? 'dark' + : 'light'; + } else { + theme = 'light'; + } + } + return theme; +} + +function setTheme(theme, propagate = false) { + theme = getActualTheme(theme); + let w = self; + for (;;) { + const rootcl = w.document.documentElement.classList; + if ( theme === 'dark' ) { + rootcl.add('dark'); + rootcl.remove('light'); + } else /* if ( theme === 'light' ) */ { + rootcl.add('light'); + rootcl.remove('dark'); + } + if ( propagate === false ) { break; } + if ( w === w.parent ) { break; } + w = w.parent; + try { void w.document; } catch(ex) { return; } + } +} + +function setAccentColor( + accentEnabled, + accentColor, + propagate, + stylesheet = '' +) { + if ( accentEnabled && stylesheet === '' && self.hsluv !== undefined ) { + const toRGB = hsl => self.hsluv.hsluvToRgb(hsl).map(a => Math.round(a * 255)).join(' '); + // Normalize first + const hsl = self.hsluv.hexToHsluv(accentColor); + hsl[0] = Math.round(hsl[0] * 10) / 10; + hsl[1] = Math.round(Math.min(100, Math.max(0, hsl[1]))); + // Use normalized result to derive all shades + const shades = [ 5, 10, 20, 30, 40, 50, 60, 70, 80, 90, 95 ]; + const text = []; + text.push(':root.accented {'); + for ( const shade of shades ) { + hsl[2] = shade; + text.push(` --primary-${shade}: ${toRGB(hsl)};`); + } + text.push('}'); + hsl[1] = Math.min(25, hsl[1]); + hsl[2] = 80; + text.push( + ':root.light.accented {', + ` --button-surface-rgb: ${toRGB(hsl)};`, + '}', + ); + hsl[2] = 30; + text.push( + ':root.dark.accented {', + ` --button-surface-rgb: ${toRGB(hsl)};`, + '}', + ); + text.push(''); + stylesheet = text.join('\n'); + vAPI.messaging.send('dom', { what: 'uiAccentStylesheet', stylesheet }); + } + let w = self; + for (;;) { + const wdoc = w.document; + let style = wdoc.querySelector('style#accentColors'); + if ( style !== null ) { style.remove(); } + if ( accentEnabled ) { + style = wdoc.createElement('style'); + style.id = 'accentColors'; + style.textContent = stylesheet; + wdoc.head.append(style); + wdoc.documentElement.classList.add('accented'); + } else { + wdoc.documentElement.classList.remove('accented'); + } + if ( propagate === false ) { break; } + if ( w === w.parent ) { break; } + w = w.parent; + try { void w.document; } catch(ex) { break; } + } +} + +{ + // https://github.com/uBlockOrigin/uBlock-issues/issues/1044 + // Offer the possibility to bypass uBO's default styling + vAPI.messaging.send('dom', { what: 'uiStyles' }).then(response => { + if ( typeof response !== 'object' || response === null ) { return; } + setTheme(response.uiTheme); + if ( response.uiAccentCustom ) { + setAccentColor( + true, + response.uiAccentCustom0, + false, + response.uiAccentStylesheet + ); + } + if ( response.uiStyles !== 'unset' ) { + document.body.style.cssText = response.uiStyles; + } + }); + + const rootcl = document.documentElement.classList; + if ( vAPI.webextFlavor.soup.has('mobile') ) { + rootcl.add('mobile'); + } else { + rootcl.add('desktop'); + } + if ( window.matchMedia('(min-resolution: 150dpi)').matches ) { + rootcl.add('hidpi'); + } +} + +export { + getActualTheme, + setTheme, + setAccentColor, +}; |