REFACTOR: The Favcount library needs global variables

This moves the library into our lib folder, and refactored it to more
modern Javascript. I've kept the MIT license at the top of the file.

Doing this allows us to import it as a library in Ember CLI and ditch
yet another global variable.
This commit is contained in:
Robin Ward 2020-11-17 14:44:18 -05:00
parent 410214e5a9
commit 75e92e1bd7
7 changed files with 69 additions and 111 deletions

View File

@ -0,0 +1,67 @@
// This file's code is based on Favcount by Chris Hunt, Copyright 2013 Chris Hunt, MIT License
function renderIcon(canvas, img, count) {
count = Math.round(count);
if (isNaN(count) || count < 1) {
count = "";
} else if (count < 10) {
count = " " + count;
} else if (count > 99) {
count = "99";
}
// Scale canvas elements based on favicon size
let multiplier = img.width / 16;
let fontSize = multiplier * 11;
let xOffset = multiplier;
let shadow = multiplier * 2;
canvas.height = canvas.width = img.width;
let ctx = canvas.getContext("2d");
ctx.font = `bold ${fontSize}px Helvetica, Arial, sans-serif`;
if (count) {
ctx.globalAlpha = 0.4;
}
ctx.drawImage(img, 0, 0);
ctx.globalAlpha = 1.0;
// Draw white drop shadow
ctx.shadowColor = "#FFF";
ctx.shadowBlur = shadow;
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 0;
// Draw white border
ctx.fillStyle = "#FFF";
ctx.fillText(count, xOffset, fontSize);
ctx.fillText(count, xOffset + multiplier, fontSize);
ctx.fillText(count, xOffset, fontSize + multiplier);
ctx.fillText(count, xOffset + multiplier, fontSize + multiplier);
// Draw black count
ctx.fillStyle = "#000";
ctx.fillText(count, xOffset + multiplier / 2.0, fontSize + multiplier / 2.0);
// Replace favicon with new favicon
let newFavicon = document.createElement("link");
newFavicon.rel = "icon";
newFavicon.href = canvas.toDataURL("image/png");
let favicon = document.querySelector("link[rel=icon]");
let head = document.querySelector("head");
if (favicon) {
head.removeChild(favicon);
}
head.appendChild(newFavicon);
}
export default function tabCount(url, count) {
let canvas = document.createElement("canvas");
if (canvas.getContext) {
let img = document.createElement("img");
img.crossOrigin = "anonymous";
img.onload = () => renderIcon(canvas, img, count);
img.src = url;
}
}

View File

@ -1,6 +1,7 @@
import Service from "@ember/service"; import Service from "@ember/service";
import { inject as service } from "@ember/service"; import { inject as service } from "@ember/service";
import getURL from "discourse-common/lib/get-url"; import getURL from "discourse-common/lib/get-url";
import updateTabCount from "discourse/lib/update-tab-count";
export default Service.extend({ export default Service.extend({
appEvents: service(), appEvents: service(),
@ -100,7 +101,7 @@ export default Service.extend({
url = getURL("/favicon/proxied?" + encodeURIComponent(url)); url = getURL("/favicon/proxied?" + encodeURIComponent(url));
} }
new window.Favcount(url).set(this._displayCount()); updateTabCount(url, this._displayCount());
} }
}, },
}); });

View File

@ -9,7 +9,6 @@
//= require popper.js //= require popper.js
//= require bootstrap-modal.js //= require bootstrap-modal.js
//= require caret_position //= require caret_position
//= require favcount.js
//= require jquery.ba-resize.js //= require jquery.ba-resize.js
//= require jquery.color.js //= require jquery.color.js
//= require jquery.fileupload.js //= require jquery.fileupload.js

View File

@ -59,8 +59,6 @@ def dependencies
}, { }, {
source: 'spectrum-colorpicker/spectrum.css', source: 'spectrum-colorpicker/spectrum.css',
public: true public: true
}, {
source: 'favcount/favcount.js'
}, { }, {
source: 'handlebars/dist/handlebars.js' source: 'handlebars/dist/handlebars.js'
}, { }, {

View File

@ -15,7 +15,6 @@
"chart.js": "2.9.3", "chart.js": "2.9.3",
"chartjs-plugin-datalabels": "^0.7.0", "chartjs-plugin-datalabels": "^0.7.0",
"eslint-config-discourse": "^1.1.5", "eslint-config-discourse": "^1.1.5",
"favcount": "https://github.com/chrishunt/favcount",
"handlebars": "^4.7.0", "handlebars": "^4.7.0",
"highlight.js": "https://github.com/highlightjs/highlight.js", "highlight.js": "https://github.com/highlightjs/highlight.js",
"intersection-observer": "^0.5.1", "intersection-observer": "^0.5.1",

View File

@ -1,102 +0,0 @@
/*
* favcount.js v1.5.0
* http://chrishunt.co/favcount
* Dynamically updates the favicon with a number.
*
* Copyright 2013, Chris Hunt
* Released under the MIT license
*/
(function(){
function Favcount(icon) {
this.icon = icon;
this.opacity = 0.4;
this.canvas = document.createElement('canvas');
this.font = "Helvetica, Arial, sans-serif";
}
Favcount.prototype.set = function(count) {
var self = this,
img = document.createElement('img');
if (self.canvas.getContext) {
img.crossOrigin = "anonymous";
img.onload = function() {
drawCanvas(self.canvas, self.opacity, self.font, img, normalize(count));
};
img.src = this.icon;
}
};
function normalize(count) {
count = Math.round(count);
if (isNaN(count) || count < 1) {
return '';
} else if (count < 10) {
return ' ' + count;
} else if (count > 99) {
return '99';
} else {
return count;
}
}
function drawCanvas(canvas, opacity, font, img, count) {
var head = document.getElementsByTagName('head')[0],
favicon = document.querySelector('link[rel=icon]'),
newFavicon = document.createElement('link'),
multiplier, fontSize, context, xOffset, yOffset, border, shadow;
// Scale canvas elements based on favicon size
multiplier = img.width / 16;
fontSize = multiplier * 11;
xOffset = multiplier;
yOffset = multiplier * 11;
border = multiplier;
shadow = multiplier * 2;
canvas.height = canvas.width = img.width;
context = canvas.getContext('2d');
context.font = 'bold ' + fontSize + 'px ' + font;
// Draw faded favicon background
if (count) { context.globalAlpha = opacity; }
context.drawImage(img, 0, 0);
context.globalAlpha = 1.0;
// Draw white drop shadow
context.shadowColor = '#FFF';
context.shadowBlur = shadow;
context.shadowOffsetX = 0;
context.shadowOffsetY = 0;
// Draw white border
context.fillStyle = '#FFF';
context.fillText(count, xOffset, yOffset);
context.fillText(count, xOffset + border, yOffset);
context.fillText(count, xOffset, yOffset + border);
context.fillText(count, xOffset + border, yOffset + border);
// Draw black count
context.fillStyle = '#000';
context.fillText(count,
xOffset + (border / 2.0),
yOffset + (border / 2.0)
);
// Replace favicon with new favicon
newFavicon.rel = 'icon';
newFavicon.href = canvas.toDataURL('image/png');
if (favicon) { head.removeChild(favicon); }
head.appendChild(newFavicon);
}
this.Favcount = Favcount;
}).call(this);
(function(){
Favcount.VERSION = '1.5.1';
}).call(this);

View File

@ -1227,10 +1227,6 @@ fastq@^1.6.0:
dependencies: dependencies:
reusify "^1.0.4" reusify "^1.0.4"
"favcount@https://github.com/chrishunt/favcount":
version "0.0.0"
resolved "https://github.com/chrishunt/favcount#d053eac5ce33e2e299363ab927103e2ff6c7361e"
fb-watchman@^2.0.0: fb-watchman@^2.0.0:
version "2.0.1" version "2.0.1"
resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.1.tgz#fc84fb39d2709cf3ff6d743706157bb5708a8a85" resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.1.tgz#fc84fb39d2709cf3ff6d743706157bb5708a8a85"