diff --git a/app/assets/javascripts/discourse/app/lib/update-tab-count.js b/app/assets/javascripts/discourse/app/lib/update-tab-count.js new file mode 100644 index 00000000000..db574730a90 --- /dev/null +++ b/app/assets/javascripts/discourse/app/lib/update-tab-count.js @@ -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; + } +} diff --git a/app/assets/javascripts/discourse/app/services/document-title.js b/app/assets/javascripts/discourse/app/services/document-title.js index 944940c0988..5fea2a8b2a9 100644 --- a/app/assets/javascripts/discourse/app/services/document-title.js +++ b/app/assets/javascripts/discourse/app/services/document-title.js @@ -1,6 +1,7 @@ import Service from "@ember/service"; import { inject as service } from "@ember/service"; import getURL from "discourse-common/lib/get-url"; +import updateTabCount from "discourse/lib/update-tab-count"; export default Service.extend({ appEvents: service(), @@ -100,7 +101,7 @@ export default Service.extend({ url = getURL("/favicon/proxied?" + encodeURIComponent(url)); } - new window.Favcount(url).set(this._displayCount()); + updateTabCount(url, this._displayCount()); } }, }); diff --git a/app/assets/javascripts/vendor.js b/app/assets/javascripts/vendor.js index e6c081a193c..6ab4a12dcae 100644 --- a/app/assets/javascripts/vendor.js +++ b/app/assets/javascripts/vendor.js @@ -9,7 +9,6 @@ //= require popper.js //= require bootstrap-modal.js //= require caret_position -//= require favcount.js //= require jquery.ba-resize.js //= require jquery.color.js //= require jquery.fileupload.js diff --git a/lib/tasks/javascript.rake b/lib/tasks/javascript.rake index 27ba82f8a39..a1bc19f04bb 100644 --- a/lib/tasks/javascript.rake +++ b/lib/tasks/javascript.rake @@ -59,8 +59,6 @@ def dependencies }, { source: 'spectrum-colorpicker/spectrum.css', public: true - }, { - source: 'favcount/favcount.js' }, { source: 'handlebars/dist/handlebars.js' }, { diff --git a/package.json b/package.json index bc68a43701a..15b4d4b1915 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,6 @@ "chart.js": "2.9.3", "chartjs-plugin-datalabels": "^0.7.0", "eslint-config-discourse": "^1.1.5", - "favcount": "https://github.com/chrishunt/favcount", "handlebars": "^4.7.0", "highlight.js": "https://github.com/highlightjs/highlight.js", "intersection-observer": "^0.5.1", diff --git a/vendor/assets/javascripts/favcount.js b/vendor/assets/javascripts/favcount.js deleted file mode 100644 index dabd6704864..00000000000 --- a/vendor/assets/javascripts/favcount.js +++ /dev/null @@ -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); diff --git a/yarn.lock b/yarn.lock index 9d7b9ebf803..483c5a306c5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1227,10 +1227,6 @@ fastq@^1.6.0: dependencies: 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: version "2.0.1" resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.1.tgz#fc84fb39d2709cf3ff6d743706157bb5708a8a85"