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:
parent
410214e5a9
commit
75e92e1bd7
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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());
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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'
|
||||||
}, {
|
}, {
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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);
|
|
|
@ -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"
|
||||||
|
|
Loading…
Reference in New Issue