2020-11-02 05:46:49 -08:00
|
|
|
const createFaviconService = () => {
|
2021-06-02 02:47:54 -07:00
|
|
|
const favicons = []
|
2020-11-03 01:55:29 -08:00
|
|
|
const faviconWidth = 128
|
|
|
|
const faviconHeight = 128
|
|
|
|
const badgeRadius = 32
|
2020-11-02 05:46:49 -08:00
|
|
|
|
|
|
|
const initFaviconService = () => {
|
2021-06-02 02:47:54 -07:00
|
|
|
const nodes = document.querySelectorAll('link[rel="icon"]')
|
|
|
|
nodes.forEach(favicon => {
|
|
|
|
if (favicon) {
|
|
|
|
const favcanvas = document.createElement('canvas')
|
|
|
|
favcanvas.width = faviconWidth
|
|
|
|
favcanvas.height = faviconHeight
|
|
|
|
const favimg = new Image()
|
|
|
|
favimg.crossOrigin = 'anonymous'
|
|
|
|
favimg.src = favicon.href
|
|
|
|
const favcontext = favcanvas.getContext('2d')
|
|
|
|
favicons.push({ favcanvas, favimg, favcontext, favicon })
|
|
|
|
}
|
|
|
|
})
|
2020-11-02 05:46:49 -08:00
|
|
|
}
|
|
|
|
|
2020-11-03 01:55:29 -08:00
|
|
|
const isImageLoaded = (img) => img.complete && img.naturalHeight !== 0
|
|
|
|
|
2020-11-02 05:46:49 -08:00
|
|
|
const clearFaviconBadge = () => {
|
2021-06-02 02:47:54 -07:00
|
|
|
if (favicons.length === 0) return
|
|
|
|
favicons.forEach(({ favimg, favcanvas, favcontext, favicon }) => {
|
|
|
|
if (!favimg || !favcontext || !favicon) return
|
2020-11-02 05:46:49 -08:00
|
|
|
|
2021-06-02 02:47:54 -07:00
|
|
|
favcontext.clearRect(0, 0, faviconWidth, faviconHeight)
|
|
|
|
if (isImageLoaded(favimg)) {
|
|
|
|
favcontext.drawImage(favimg, 0, 0, favimg.width, favimg.height, 0, 0, faviconWidth, faviconHeight)
|
|
|
|
}
|
|
|
|
favicon.href = favcanvas.toDataURL('image/png')
|
|
|
|
})
|
2020-11-02 05:46:49 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
const drawFaviconBadge = () => {
|
2021-06-02 02:47:54 -07:00
|
|
|
if (favicons.length === 0) return
|
2020-11-02 05:46:49 -08:00
|
|
|
clearFaviconBadge()
|
2021-06-02 02:47:54 -07:00
|
|
|
favicons.forEach(({ favimg, favcanvas, favcontext, favicon }) => {
|
|
|
|
if (!favimg || !favcontext || !favcontext) return
|
|
|
|
|
|
|
|
const style = getComputedStyle(document.body)
|
|
|
|
const badgeColor = `${style.getPropertyValue('--badgeNotification') || 'rgb(240, 100, 100)'}`
|
2020-11-02 05:46:49 -08:00
|
|
|
|
2021-06-02 02:47:54 -07:00
|
|
|
if (isImageLoaded(favimg)) {
|
|
|
|
favcontext.drawImage(favimg, 0, 0, favimg.width, favimg.height, 0, 0, faviconWidth, faviconHeight)
|
|
|
|
}
|
|
|
|
favcontext.fillStyle = badgeColor
|
|
|
|
favcontext.beginPath()
|
|
|
|
favcontext.arc(faviconWidth - badgeRadius, badgeRadius, badgeRadius, 0, 2 * Math.PI, false)
|
|
|
|
favcontext.fill()
|
|
|
|
favicon.href = favcanvas.toDataURL('image/png')
|
|
|
|
})
|
2020-11-02 05:46:49 -08:00
|
|
|
}
|
|
|
|
|
2023-11-08 15:53:48 -08:00
|
|
|
const getOriginalFavicons = () => [...favicons]
|
|
|
|
|
2020-11-02 05:46:49 -08:00
|
|
|
return {
|
|
|
|
initFaviconService,
|
|
|
|
clearFaviconBadge,
|
2023-11-08 15:53:48 -08:00
|
|
|
drawFaviconBadge,
|
|
|
|
getOriginalFavicons
|
2020-11-02 05:46:49 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const FaviconService = createFaviconService()
|
|
|
|
|
|
|
|
export default FaviconService
|