-
Notifications
You must be signed in to change notification settings - Fork 0
/
favicon-mode-switcher.js
executable file
·57 lines (45 loc) · 2.15 KB
/
favicon-mode-switcher.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
/** @license MIT favicon-mode-switcher __VERSION__ (c) 2021 Jonas Kuske */
/** @typedef { import('index').ColorScheme } ColorScheme */
/** @typedef { import('index').Icon } Icon */
/** @typedef { import('index').FaviconTarget } FaviconTarget */
/** @typedef { import('index').default } FaviconModeSwitcher */
const DEBUG = true
const warn = (/** @type { string } */ msg) => typeof console !== 'undefined' && console.warn(msg)
/** @type { FaviconModeSwitcher } */
let faviconModeSwitcher = (options) => {
let isBrowser = typeof window !== 'undefined'
if (!isBrowser || !window.matchMedia) return () => {}
options = Array.isArray(options) || options instanceof NodeList ? options : [options]
/** @type { Icon[] } */
let icons = []
;[].forEach.call(options, (/** @type { FaviconTarget } */ target) => {
if (typeof target === 'string' || target instanceof HTMLLinkElement) {
target = { element: target }
}
// prettier-ignore
let linkElement = target && (
typeof target.element === 'string' ? document.querySelector(target.element) : target.element
)
if (linkElement instanceof HTMLLinkElement) {
icons.push({ linkElement, hrefConfig: target.href, baseHref: linkElement.href })
} else if (DEBUG) {
warn('[favicon-mode-switcher] Icon not found or not an HTMLLinkElement: ' + target)
}
})
let addColorQuery = (/** @type { ColorScheme } */ colorScheme) => {
let mediaQuery = matchMedia('(prefers-color-scheme:' + colorScheme + ')')
// prettier-ignore
let updateFn = () => mediaQuery.matches && icons.forEach(icon => (
// If href config exists, set specified href. Else toggle "dark" / "light" on existing href.
icon.linkElement.href = icon.hrefConfig
? icon.hrefConfig[colorScheme] || icon.baseHref
: icon.linkElement.href.replace(/dark|light/, colorScheme)
))
mediaQuery.addListener(updateFn)
return updateFn(), () => mediaQuery.removeListener(updateFn)
}
let undoDarkQ = addColorQuery('dark')
let undoLightQ = addColorQuery('light')
return () => (undoDarkQ(), undoLightQ(), icons.forEach((i) => (i.linkElement.href = i.baseHref)))
}
export default faviconModeSwitcher