diff options
author | awy <awy@awy.one> | 2025-08-15 03:01:21 +0300 |
---|---|---|
committer | awy <awy@awy.one> | 2025-08-15 03:01:21 +0300 |
commit | a9370a08517668b3e98cc1d0bd42df407a76c220 (patch) | |
tree | 37e7bdb0e76f5495f798e077e45d377c0c3870c0 /data/extensions/uBlock0@raymondhill.net/js/theme.js | |
parent | b73acfe395ea849fcd15c9886a7f4631f2b6f82b (diff) |
Diffstat (limited to 'data/extensions/uBlock0@raymondhill.net/js/theme.js')
-rw-r--r-- | data/extensions/uBlock0@raymondhill.net/js/theme.js | 149 |
1 files changed, 149 insertions, 0 deletions
diff --git a/data/extensions/uBlock0@raymondhill.net/js/theme.js b/data/extensions/uBlock0@raymondhill.net/js/theme.js new file mode 100644 index 0000000..111272f --- /dev/null +++ b/data/extensions/uBlock0@raymondhill.net/js/theme.js @@ -0,0 +1,149 @@ +/******************************************************************************* + + 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 +*/ + +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 { 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 { 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, +}; |