Fork of Chiri for Astro for my blog
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat: revise FaviconThemeSwitcher handling

the3ash 2eaef78d 524ff78c

+49 -29
+49 -29
src/components/ui/FaviconThemeSwitcher.astro
··· 1 1 <script is:inline> 2 - // Favicon theme switcher for system theme-based favicon updates 2 + // Favicon theme switcher for system theme-based favicon updates, using external SVG file 3 3 class FaviconThemeSwitcher { 4 4 constructor() { 5 5 this.faviconLink = ··· 12 12 return 13 13 } 14 14 15 - this.currentColor = null 16 15 this.mediaQuery = window.matchMedia('(prefers-color-scheme: dark)') 17 - 18 - // SVG template 19 - this.svgTemplate = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> 20 - <path 21 - id="favicon-path" 22 - d="M12.3785 2C16.2799 2.0001 15.793 5.9958 15.3053 7.99414C16.7687 6.99515 19.8498 5.92943 21.6451 8.99414C23.1079 11.4917 19.6947 14.3221 17.7437 14.9883C19.2069 15.9875 21.3523 18.5847 18.231 20.9824C15.1095 23.3803 12.7031 20.983 11.8902 19.4844C10.9146 20.983 8.28152 23.3801 5.55039 20.9824C2.81905 18.5846 4.41233 16.3199 5.55039 15.4873C3.76201 14.9878 0.672689 12.0909 2.62363 8.49414C3.85202 6.22947 7.01339 6.66254 7.98886 7.49512C7.6637 5.66344 8.47661 2 12.3785 2ZM12.3121 9.49316C8.42708 9.49327 7.3044 16.1247 12.3121 15.4375C15.6222 14.9833 15.6814 9.49316 12.3121 9.49316Z" 23 - fill="{{color}}" 24 - /> 25 - </svg>` 16 + this.svgUrl = '/favicon.svg' 17 + this.currentColor = null 18 + this.svgContent = null 26 19 27 - // Listen for system theme changes 28 20 this.mediaQuery.addEventListener('change', () => this.updateFavicon()) 21 + this.init() 22 + } 29 23 30 - // Set initial favicon color 24 + async init() { 25 + if (!this.svgContent) { 26 + try { 27 + const res = await fetch(this.svgUrl) 28 + this.svgContent = await res.text() 29 + } catch (e) { 30 + console.warn('Failed to fetch favicon.svg:', e) 31 + return 32 + } 33 + } 31 34 this.updateFavicon() 32 35 } 33 36 34 37 updateFavicon() { 35 - const newColor = this.mediaQuery.matches ? '#ccc' : '#111' 36 - 37 - if (this.currentColor !== newColor) { 38 - this.currentColor = newColor 39 - this.updateFaviconColor(newColor) 40 - } 38 + const color = this.mediaQuery.matches ? '#ccc' : '#111' 39 + if (this.currentColor === color) return 40 + this.currentColor = color 41 + this.updateFaviconColor(color) 41 42 } 42 43 43 44 updateFaviconColor(color) { 45 + if (!this.svgContent) return 44 46 try { 45 - // Replace color placeholder in SVG template 46 - const svgContent = this.svgTemplate.replace(/\{\{color\}\}/g, color) 47 + const parser = new DOMParser() 48 + const doc = parser.parseFromString(this.svgContent, 'image/svg+xml') 49 + 50 + // Remove all <style> tags 51 + doc.querySelectorAll('style').forEach((style) => style.remove()) 52 + 53 + // Recursively set fill attribute for all elements 54 + function setFillRecursively(node) { 55 + if (node.nodeType === 1) { 56 + // Element node 57 + node.setAttribute('fill', color) 58 + // Remove fill from style attribute if present 59 + if (node.hasAttribute('style')) { 60 + let style = node.getAttribute('style') 61 + style = style.replace(/fill\s*:\s*[^;]+;?/gi, '') 62 + node.setAttribute('style', style) 63 + } 64 + for (let i = 0; i < node.childNodes.length; i++) { 65 + setFillRecursively(node.childNodes[i]) 66 + } 67 + } 68 + } 69 + setFillRecursively(doc.documentElement) 47 70 48 - // Create blob URL from the SVG content 49 - const blob = new Blob([svgContent], { type: 'image/svg+xml' }) 71 + const serializer = new XMLSerializer() 72 + const svg = serializer.serializeToString(doc) 73 + const blob = new Blob([svg], { type: 'image/svg+xml' }) 50 74 const blobUrl = URL.createObjectURL(blob) 51 - 52 - // Update favicon href 53 75 this.faviconLink.href = blobUrl 54 - 55 - // Clean up previous blob URL if it exists 56 76 if (this.previousBlobUrl) { 57 77 URL.revokeObjectURL(this.previousBlobUrl) 58 78 } 59 79 this.previousBlobUrl = blobUrl 60 - } catch (error) { 61 - console.warn('Failed to update favicon color:', error) 80 + } catch (e) { 81 + console.warn('Failed to update favicon color:', e) 62 82 } 63 83 } 64 84 }