handle multiple favicons (different sizes)

This commit is contained in:
Henry Jameson 2021-06-02 12:47:54 +03:00
parent 008e711e11
commit 2a2483f4c9

View file

@ -1,53 +1,58 @@
import { find } from 'lodash'
const createFaviconService = () => { const createFaviconService = () => {
let favimg, favcanvas, favcontext, favicon const favicons = []
const faviconWidth = 128 const faviconWidth = 128
const faviconHeight = 128 const faviconHeight = 128
const badgeRadius = 32 const badgeRadius = 32
const initFaviconService = () => { const initFaviconService = () => {
const nodes = document.getElementsByTagName('link') const nodes = document.querySelectorAll('link[rel="icon"]')
favicon = find(nodes, node => node.rel === 'icon') nodes.forEach(favicon => {
if (favicon) { if (favicon) {
favcanvas = document.createElement('canvas') const favcanvas = document.createElement('canvas')
favcanvas.width = faviconWidth favcanvas.width = faviconWidth
favcanvas.height = faviconHeight favcanvas.height = faviconHeight
favimg = new Image() const favimg = new Image()
favimg.crossOrigin = 'anonymous' favimg.crossOrigin = 'anonymous'
favimg.src = favicon.href favimg.src = favicon.href
favcontext = favcanvas.getContext('2d') const favcontext = favcanvas.getContext('2d')
} favicons.push({ favcanvas, favimg, favcontext, favicon })
}
})
} }
const isImageLoaded = (img) => img.complete && img.naturalHeight !== 0 const isImageLoaded = (img) => img.complete && img.naturalHeight !== 0
const clearFaviconBadge = () => { const clearFaviconBadge = () => {
if (!favimg || !favcontext || !favicon) return if (favicons.length === 0) return
favicons.forEach(({ favimg, favcanvas, favcontext, favicon }) => {
if (!favimg || !favcontext || !favicon) return
favcontext.clearRect(0, 0, faviconWidth, faviconHeight) favcontext.clearRect(0, 0, faviconWidth, faviconHeight)
if (isImageLoaded(favimg)) { if (isImageLoaded(favimg)) {
favcontext.drawImage(favimg, 0, 0, favimg.width, favimg.height, 0, 0, faviconWidth, faviconHeight) favcontext.drawImage(favimg, 0, 0, favimg.width, favimg.height, 0, 0, faviconWidth, faviconHeight)
} }
favicon.href = favcanvas.toDataURL('image/png') favicon.href = favcanvas.toDataURL('image/png')
})
} }
const drawFaviconBadge = () => { const drawFaviconBadge = () => {
if (!favimg || !favcontext || !favcontext) return if (favicons.length === 0) return
clearFaviconBadge() clearFaviconBadge()
favicons.forEach(({ favimg, favcanvas, favcontext, favicon }) => {
if (!favimg || !favcontext || !favcontext) return
const style = getComputedStyle(document.body) const style = getComputedStyle(document.body)
const badgeColor = `${style.getPropertyValue('--badgeNotification') || 'rgb(240, 100, 100)'}` const badgeColor = `${style.getPropertyValue('--badgeNotification') || 'rgb(240, 100, 100)'}`
if (isImageLoaded(favimg)) { if (isImageLoaded(favimg)) {
favcontext.drawImage(favimg, 0, 0, favimg.width, favimg.height, 0, 0, faviconWidth, faviconHeight) favcontext.drawImage(favimg, 0, 0, favimg.width, favimg.height, 0, 0, faviconWidth, faviconHeight)
} }
favcontext.fillStyle = badgeColor favcontext.fillStyle = badgeColor
favcontext.beginPath() favcontext.beginPath()
favcontext.arc(faviconWidth - badgeRadius, badgeRadius, badgeRadius, 0, 2 * Math.PI, false) favcontext.arc(faviconWidth - badgeRadius, badgeRadius, badgeRadius, 0, 2 * Math.PI, false)
favcontext.fill() favcontext.fill()
favicon.href = favcanvas.toDataURL('image/png') favicon.href = favcanvas.toDataURL('image/png')
})
} }
return { return {