diff --git a/index.html b/index.html
index 13f720b..1cf909c 100644
--- a/index.html
+++ b/index.html
@@ -178,11 +178,13 @@
Value
document.getElementById('set').addEventListener('click', () => {
const value = document.getElementById('value').value
+ localStorage.setItem('value', value)
badgin.set(value ? parseInt(value, 10) : value, options)
})
document.getElementById('clear').addEventListener('click', () => {
document.getElementById('value').value = ''
+ localStorage.setItem('value', '')
badgin.clear()
})
@@ -232,6 +234,13 @@ Value
script.src = isLocalhost
? '/build/index.iife.js'
: 'https://unpkg.com/badgin/build/index.iife.js'
+ script.onload = () => {
+ const value = localStorage.getItem('value')
+ if (value) {
+ document.getElementById('value').value = localStorage.getItem('value')
+ document.getElementById('set').click()
+ }
+ }
document.head.appendChild(script)
diff --git a/src/favicon.ts b/src/favicon.ts
index aee5cb3..7b5676c 100644
--- a/src/favicon.ts
+++ b/src/favicon.ts
@@ -12,6 +12,14 @@ type Favicon = HTMLLinkElement
type BestFavicon = Favicon | null
+export const DefaultValue: Value = 0
+
+export const DefaultOptions: Options = {
+ backgroundColor: '#424242',
+ color: '#ffffff',
+ indicator: '!',
+}
+
// Get all favicons of the page
const getFavicons = (): Favicon[] => {
const links = document.head.getElementsByTagName('link')
@@ -86,34 +94,34 @@ const getBestFavicon = (): BestFavicon => {
return bestFavicon
}
-// Calculate the size of the font and canvas element based on device's ratio
-const ratio = Math.ceil(window.devicePixelRatio) || 1
-const size = 16 * ratio
-
-// Options
-export const defaultOptions: Options = {
- backgroundColor: '#424242',
- color: '#ffffff',
- indicator: '!',
-}
-
// References to the favicons that we need to track in order to reset and update the counters
const current: {
- canvas: HTMLCanvasElement | null
- context: CanvasRenderingContext2D | null
favicons: Favicon[] | null
bestFavicon: BestFavicon
bestFaviconImage: HTMLImageElement | null
value: Value
options: Options
} = {
- canvas: null,
- context: null,
favicons: null,
bestFavicon: null,
bestFaviconImage: null,
- value: 0,
- options: defaultOptions,
+ value: DefaultValue,
+ options: DefaultOptions,
+}
+
+// Get size depending on screen density
+const devicePixelRatioListener = window.matchMedia(
+ 'screen and (min-resolution: 2dppx)'
+)
+const getRatio = () => {
+ return Math.ceil(window.devicePixelRatio) || 1
+}
+const handleRatioChange = () => {
+ console.log('handleRatioChange')
+ set(current.value, current.options)
+}
+const getSize = () => {
+ return 16 * getRatio()
}
// Update favicon
@@ -145,31 +153,25 @@ const drawFavicon = (
value: Value,
options: Options
) => {
- if (!current.canvas || !current.context) {
+ const size = getSize()
+ const canvas = document.createElement('canvas')
+ canvas.width = size
+ canvas.height = size
+ const context = canvas.getContext('2d')
+ if (!context) {
return
}
- // Clear old canvas
- current.context.clearRect(0, 0, size, size)
-
// Draw new image
- current.context.drawImage(
- image,
- 0,
- 0,
- image.width,
- image.height,
- 0,
- 0,
- size,
- size
- )
+ image.width = size
+ image.height = size
+ context.drawImage(image, 0, 0, image.width, image.height)
// Draw bubble on the top
- drawBubble(current.context, value, options)
+ drawBubble(context, value, options)
// Refresh tag in page
- setFavicon(current.canvas.toDataURL())
+ setFavicon(canvas.toDataURL())
}
// Draws the bubble on the canvas
@@ -198,14 +200,16 @@ const drawBubble = (
}
// Calculate position etc.
+ const size = getSize()
+ const ratio = getRatio()
const length = finalValue.length - 1
- const width = 8 * ratio + 4 * ratio * length
+ const width = Math.min(8 * ratio + 4 * ratio * length, size)
const height = 7 * ratio
const top = size - height
- const left = size - width - ratio
+ const left = size - width
const bottom = 16 * ratio
const right = 16 * ratio
- const radius = 5 * ratio
+ const radius = 3 * ratio
// Bubble
context.save()
@@ -232,21 +236,12 @@ const drawBubble = (
context.fillStyle = options.color
context.textAlign = 'center'
context.textBaseline = 'top'
- context.fillText(finalValue, left + width / 2 + 1, 9 * ratio + 1)
+ context.fillText(finalValue, left + width / 2, 9 * ratio + 1)
context.restore()
}
export function isAvailable() {
- if (!current.context) {
- const canvas = document.createElement('canvas')
- canvas.width = size
- canvas.height = size
-
- current.canvas = canvas
- current.context = canvas.getContext ? canvas.getContext('2d') : null
- }
-
- return !!current.context && !!getBestFavicon()
+ return !!getBestFavicon()
}
export function set(value: Value, options?: Partial) {
@@ -264,8 +259,6 @@ export function set(value: Value, options?: Partial) {
if (bestFavicon) {
const bestFaviconImage = document.createElement('img')
- bestFaviconImage.width = size
- bestFaviconImage.height = size
// Allow cross origin resource requests if the image is not a data:uri
if (!bestFavicon.href.match(/^data/)) {
@@ -279,12 +272,15 @@ export function set(value: Value, options?: Partial) {
current.bestFavicon = bestFavicon
current.bestFaviconImage = bestFaviconImage
}
+
+ // Once the device pixel ratio changes we set the value again
+ devicePixelRatioListener.addListener(handleRatioChange)
}
if (!current.favicons) {
current.favicons = getFavicons()
}
- // Draw icon
+ // The image is required for setting the badge
if (!current.bestFaviconImage) {
return false
}
@@ -308,6 +304,13 @@ export function clear() {
return
}
+ // Reset value and options
+ current.value = DefaultValue
+ current.options = DefaultOptions
+
+ // Remove old listener
+ devicePixelRatioListener.removeListener(handleRatioChange)
+
if (current.favicons) {
// Remove current favicons
for (const favicon of getFavicons()) {