summaryrefslogtreecommitdiff
path: root/static/favicons.js
diff options
context:
space:
mode:
Diffstat (limited to 'static/favicons.js')
-rw-r--r--static/favicons.js152
1 files changed, 152 insertions, 0 deletions
diff --git a/static/favicons.js b/static/favicons.js
new file mode 100644
index 0000000..2eac641
--- /dev/null
+++ b/static/favicons.js
@@ -0,0 +1,152 @@
+// from sizeof.cat
+
+function favicons () {
+ this.hidden = "hidden";
+ this.visibilityChange = "visibilitychange";
+ this.favicon = document.querySelector("[rel='shortcut icon']").href;
+ this.title = document.title;
+
+ /* Define a list of "services", each being a pair of favicon URL and the tab title to show. */
+ this.services = {
+ /* Reddit */
+ reddit: () => {
+ let title = "Reddit - Dive into anything";
+ let favicon = "/img/favicons/reddit.ico";
+ return {
+ title, favicon
+ }
+ },
+ /* X, formerly known as Twitter */
+ x: () => {
+ let title = "X. It's what's happening / X";
+ let favicon = "/img/favicons/x.ico";
+ return {
+ title, favicon
+ }
+ },
+ /* Bluesky */
+ bluesky: () => {
+ let title = "Discover - Bluesky";
+ let favicon = "/img/favicons/bluesky.ico";
+ return {
+ title, favicon
+ }
+ },
+ /* Wikipedia */
+ wikipedia: () => {
+ let title = "Wikipedia";
+ let favicon = "/img/favicons/wikipedia.ico";
+ return {
+ title, favicon
+ }
+ },
+ /* TikTok, where the hip kids are hanging out */
+ tiktok: () => {
+ let title = "Explore - Find your favourite videos on TikTok";
+ let favicon = "/img/favicons/tiktok.ico";
+ return {
+ title, favicon
+ }
+ },
+ /* Facebook, your grandma is most likely here */
+ facebook: () => {
+ /* Pick a random notification number between 1 and 100 */
+ let count = Math.round(Math.random() * 99) + 1;
+ let title = "(" + count + ") Facebook";
+ let favicon = "/img/favicons/facebook.ico";
+ return {
+ title, favicon
+ }
+ },
+ /* Instagram */
+ instagram: () => {
+ /* Pick a random notification number between 1 and 100 */
+ let count = Math.round(Math.random() * 99) + 1;
+ let title = "(" + count + ") Instagram";
+ let favicon = "/img/favicons/instagram.ico";
+ return {
+ title, favicon
+ }
+ }
+ }
+
+ /* Those "services" are enabled, which means the web browser tab can change
+ favicon/title using their data. */
+ this.enabledServices = [
+ 'x',
+ 'reddit',
+ 'bluesky',
+ 'instagram',
+ 'tiktok',
+ 'facebook',
+ 'wikipedia'
+ ];
+
+ /* Initialization function, checks if the web browser has the specified event
+ listeners and binds a handler to the existing one. */
+ this.init = function () {
+ if (typeof document.mozHidden !== 'undefined') {
+ this.hidden = "mozHidden";
+ this.visibilityChange = "mozvisibilitychange";
+ } else if (typeof document.msHidden !== 'undefined') {
+ this.hidden = "msHidden";
+ this.visibilityChange = "msvisibilitychange";
+ } else if (typeof document.webkitHidden !== 'undefined') {
+ this.hidden = "webkitHidden";
+ this.visibilityChange = "webkitvisibilitychange";
+ }
+ document.addEventListener(this.visibilityChange, this.handler.bind(this), false);
+ }
+
+ /* The default function which returns the initial favicon/title pair of the
+ page, so it can get swapped back upon tab activation. */
+ this.default = function () {
+ let title = this.title;
+ let favicon = this.favicon;
+ this.update({
+ title, favicon
+ });
+ }
+
+ /* This function updates the favicon/title pair of the web browser tab when
+ the tab is not focused (hidden from view). We're using a cache-busting
+ technique so that the favicon is freshly loaded and not cached. */
+ this.update = function (data) {
+ let cacheBuster = "?v=" + Math.round(Math.random() * 10000000);
+ let link = document.createElement('link');
+ link.type = "image/x-icon";
+ link.rel = "shortcut icon";
+ link.href = data.favicon + cacheBuster;
+ document.getElementsByTagName("head")[0].querySelector("[rel='shortcut icon']").remove();
+ document.getElementsByTagName("head")[0].appendChild(link);
+ document.title = data.title;
+ }
+
+ /* The spoof() function randomizes the enabled "services" and picks one from
+ them, updating the tab favicon and title. */
+ this.spoof = function () {
+ let i = Math.round(Math.random() * (this.enabledServices.length - 1));
+ let service = this.enabledServices[i];
+ if (service && this.services[service]) {
+ this.update(this.services[service]());
+ }
+ }
+
+ /* The default event handler which checks whether the current tab is hidden,
+ and if it is then it swaps the favicon/title pair with one from the
+ enabled "services". Otherwise, it shows the default favicon and title. */
+ this.handler = function () {
+ if (document[this.hidden]) {
+ this.spoof();
+ } else {
+ this.default();
+ }
+ }
+
+ /* Autorun the initialization function. */
+ this.init();
+}
+
+document.addEventListener("DOMContentLoaded", function(event) {
+ favicons();
+});