diff --git a/instance/pleroma-mods/pleroma-mod-catify/mod.js b/instance/pleroma-mods/pleroma-mod-catify/mod.js index db02da8326..3f34191c1a 100644 --- a/instance/pleroma-mods/pleroma-mod-catify/mod.js +++ b/instance/pleroma-mods/pleroma-mod-catify/mod.js @@ -1,34 +1,34 @@ function ColorDetector (image) { - this.color = { r:0, g:0, b:0 }; - this.image = image; + this.color = { r: 0, g: 0, b: 0 }; + this.image = image; } [ function componentToHex (c) { - var hex = Math.max(Math.min(c, 255),0).toString(16); - return hex.length == 1 ? '0' + hex : hex; + var hex = Math.max(Math.min(c, 255), 0).toString(16); + return hex.length === 1 ? "0" + hex : hex; }, function getHexColor (offset) { - if(!offset) { - offset = {r:0,g:0,b:0}; + if (!offset) { + offset = { r: 0, g: 0, b: 0 }; } - return "#" - + this.componentToHex(this.color.r + offset.r) - + this.componentToHex(this.color.g + offset.g) - + this.componentToHex(this.color.b + offset.b); + return "#" + + this.componentToHex(this.color.r + offset.r) + + this.componentToHex(this.color.g + offset.g) + + this.componentToHex(this.color.b + offset.b); }, function detect () { return new Promise((resolve) => { let blockSize = 5; - const canvas = document.createElement('canvas'); - const context = canvas.getContext && canvas.getContext('2d'); - let data, width, height, - i = -4, - rgb = {r:0,g:0,b:0}, - length, - count = 0; - if(!context) { + const canvas = document.createElement("canvas"); + const context = canvas.getContext && canvas.getContext("2d"); + let data; let width; let height; + let i = -4; + let rgb = { r: 0, g: 0, b: 0 }; + let length; + let count = 0; + if (!context) { console.warn("can't get context of avatar"); resolve(this.color); return; @@ -41,7 +41,7 @@ function ColorDetector (image) { try { data = context.getImageData(0, 0, width, height); - } catch(e) { + } catch (e) { console.error("can't get image data"); console.error(e); resolve(this.color); @@ -50,110 +50,104 @@ function ColorDetector (image) { length = data.data.length; - while ( ( i += blockSize * 4) < length ) { + while ((i += blockSize * 4) < length) { ++count; rgb.r += data.data[i]; - rgb.g += data.data[i+1]; - rgb.b += data.data[i+2]; + rgb.g += data.data[i + 1]; + rgb.b += data.data[i + 2]; } - this.color.r = ~~(rgb.r/count); - this.color.g = ~~(rgb.g/count); - this.color.b = ~~(rgb.b/count); + this.color.r = ~~(rgb.r / count); + this.color.g = ~~(rgb.g / count); + this.color.b = ~~(rgb.b / count); resolve(this.color); }); } ].forEach((fn) => { ColorDetector.prototype[fn.name] = fn; }); -function PleromaCat(handle) { +function PleromaCat (handle) { this.handle = handle; this.colors = { - backgroundColor: '#000000', - borderColor: '#000000' + backgroundColor: "#000000", + borderColor: "#000000" }; this.config = { - 'nya': { + "nya": { enabled: true, - matcher: "(^|\s|>)な+(\s|<|$)", + matcher: "(^|\s|>)な+(\s|<|$)", // eslint-disable-line no-useless-escape replacer: { source: "な", - dest: 'にゃ' - }, + dest: "にゃ" + } } }; this.loadConfig(); } [ function loadConfig () { - window.fetch(PleromaModLoader.getModDir() + "pleroma-mod-catify/config.json").then((response) => { - if (response.ok) { - response.json().then((json) => { - if (!json.nya) { - return; - } - this.config.nya.enabled = json.nya.enabled; - if (this.config.nya.enabled) { - this.config.nya.matcher = json.nya.matcher || this.config.nya.matcher; - this.config.nya.replacer.source = json.nya.replacer.source || this.config.nya.replacer.source; - this.config.nya.replacer.dest = json.nya.replacer.dest || this.config.nya.replacer.dest; - } - }).catch((error) => { - console.error("can't load catify config"); - console.error(error); - }); - } - }).catch((error) => { - console.warn("can't load catify configuration"); - console.warn(error); - }); + const json = PleromaModCatify.config; + if (!json.nya) { + return; + } + this.config.nya.enabled = json.nya.enabled; + if (this.config.nya.enabled) { + this.config.nya.matcher = json.nya.matcher || this.config.nya.matcher; + this.config.nya.replacer.source = json.nya.replacer.source || this.config.nya.replacer.source; + this.config.nya.replacer.dest = json.nya.replacer.dest || this.config.nya.replacer.dest; + } }, function getClassName () { - return 'USER____' + this.handle.replace(/@/g,'_AT_').replace(/\./g,'_'); + return "USER____" + this.handle.replace(/@/g, "_AT_").replace(/\./g, "_"); }, - function makeCat () { - var posts = document.querySelectorAll("." + this.getClassName()); - this.makeCatByClassName('user-info'); - this.makeCatByClassName('basic-user-card', 'basic-user-card-screen-name'); - for(const currentPost of posts) { - this.makeCatByElement(currentPost); - this.nyaByPost(currentPost); + function makeCat (element) { + if (!element) { + element = document; + } + if (element.querySelectorAll) { + var posts = element.querySelectorAll("." + this.getClassName()); + this.makeCatByClassName("user-info"); + this.makeCatByClassName("basic-user-card", "basic-user-card-screen-name"); + for (const currentPost of posts) { + this.makeCatByElement(currentPost); + this.nyaByPost(currentPost); + } } }, function makeCatByClassName (className, usernameClass) { - if(!className) { - className = 'user-info'; + if (!className) { + className = "user-info"; } if (!usernameClass) { - usernameClass = 'user-screen-name'; + usernameClass = "user-screen-name"; } const userinfos = document.querySelectorAll("." + className); - for(const infoIndex in userinfos) { - if(userinfos[infoIndex].querySelector && !/cat$/.test(userinfos[infoIndex].innerText)) { + for (const infoIndex in userinfos) { + if (userinfos[infoIndex].querySelector && !/cat$/.test(userinfos[infoIndex].innerText)) { const handle = userinfos[infoIndex].querySelector("." + usernameClass); - const regexHandle = new RegExp(this.handle, 'i'); - if(handle) { - if(regexHandle.test(handle.innerText)) { + const regexHandle = new RegExp(this.handle, "i"); + if (handle) { + if (regexHandle.test(handle.innerText)) { this.makeCatByElement(userinfos[infoIndex]); } } - } + } } }, function makeCatByElement (element) { - if(element.querySelectorAll) { - if(!/cat$/.test(element.className)) { - element.className += ' cat'; + if (element.querySelectorAll) { + if (!/cat$/.test(element.className)) { + element.className += " cat"; } - const avatars = element.querySelectorAll('.avatar'); - for(const avatarIndex in avatars) { + const avatars = element.querySelectorAll(".avatar"); + for (const avatarIndex in avatars) { const currentAvatar = avatars[avatarIndex]; - if(currentAvatar.style) { - if(this.colors.borderColor == '#000000') { + if (currentAvatar.style) { + if (this.colors.borderColor === "#000000") { this.detectColors(currentAvatar); } currentAvatar.style.backgroundColor = this.colors.backgroundColor; @@ -164,16 +158,16 @@ function PleromaCat(handle) { }, function nyaByPost (element) { - if(element.querySelectorAll && this.config.nya.enabled) { - const contents = element.querySelectorAll('.status-content'); - for(const content of contents) { - if(content.innerHTML) { + if (element.querySelectorAll && this.config.nya.enabled) { + const contents = element.querySelectorAll(".status-content"); + for (const content of contents) { + if (content.innerHTML) { const regex = new RegExp(this.config.nya.matcher, "g"); let match; - while((match = regex.exec(content.innerHTML))!==null) { + while ((match = regex.exec(content.innerHTML)) !== null) { const source = match[0]; const dest = source.replace( - new RegExp(this.config.nya.replacer.source, "g"), + new RegExp(this.config.nya.replacer.source, "g"), this.config.nya.replacer.dest ); content.innerHTML = content.innerHTML.replace(source, dest); @@ -184,14 +178,14 @@ function PleromaCat(handle) { }, function detectColors (avatarElement) { - const images = avatarElement.querySelectorAll('img'); - for(const imageIndex in images) { + const images = avatarElement.querySelectorAll("img"); + for (const imageIndex in images) { images[imageIndex].crossOrigin = "anonymous"; const colorAvatar = () => { const detector = new ColorDetector(images[imageIndex]); detector.detect().then((color) => { this.colors.backgroundColor = detector.getHexColor(); - this.colors.borderColor = detector.getHexColor({r:-40,g:-40,b:-40}); + this.colors.borderColor = detector.getHexColor({ r: -40, g: -40, b: -40 }); avatarElement.style.backgroundColor = this.colors.backgroundColor; avatarElement.style.borderColor = this.colors.borderColor; }); @@ -206,7 +200,7 @@ function PleromaCat(handle) { } ].forEach((fn) => { PleromaCat.prototype[fn.name] = fn; }); -function PleromaModCatify() { +function PleromaModCatify () { this.cats = {}; this.config = { stylesheet: "style.css", @@ -234,12 +228,13 @@ function PleromaModCatify() { ] }, filter: [ + "user-info", "timeline", "panel-body", "main", "active", "status-body" - ], + ] }; this.loadConfig(); @@ -249,6 +244,7 @@ function PleromaModCatify() { window.fetch(PleromaModLoader.getModDir() + "pleroma-mod-catify/config.json").then((response) => { if (response.ok) { response.json().then((json) => { + PleromaModCatify.config = json; this.config.triggers.displayName = json.triggers.displayName; this.config.triggers.instances = json.triggers.instances; }).catch((error) => { @@ -263,8 +259,13 @@ function PleromaModCatify() { }, function onMutation (mutation, observer) { + if (mutation.target.classList.contains("user-info")) { + mutation.target.classList.remove("cat"); + } this.detectCats(); - this.catify(); + for (const element of mutation.addedNodes) { + this.catify(element); + } }, function onReady () { @@ -273,27 +274,34 @@ function PleromaModCatify() { this.catify(); }, + function onDestroy () { + const allCats = document.querySelectorAll(".cat"); + for (const cat of allCats) { + cat.classList.remove("cat"); + } + }, + function run () { PleromaModLoader.includeModCss("pleroma-mod-catify/" + this.config.stylesheet); }, function addCat (handle) { handle = handle.trim(); - if(!this.cats.hasOwnProperty(handle)) { + if (!this.cats.handle) { this.cats[handle] = new PleromaCat(handle); } }, function areYouACat () { - const profile = document.querySelector('.user-card'); - const pattern = this.config.triggers.displayName.join('|'); - const regex = new RegExp(pattern, 'i'); - if(profile) { - const username = profile.querySelector('.user-name'); - if(username) { - if(regex.test(username.innerText)) { - const accountName = profile.querySelector('.user-screen-name'); - if(accountName) { + const profile = document.querySelector(".user-card"); + const pattern = this.config.triggers.displayName.join("|"); + const regex = new RegExp(pattern, "i"); + if (profile) { + const username = profile.querySelector(".user-name"); + if (username) { + if (regex.test(username.innerText)) { + const accountName = profile.querySelector(".user-screen-name"); + if (accountName) { this.addCat(accountName.innerText.substring(1), true); } } @@ -302,24 +310,24 @@ function PleromaModCatify() { }, function detectCatsByClassName (classname, usernameClass, accountnameClass) { - classname = classname || 'name-and-account-name'; - usernameClass = usernameClass || 'user-name'; - accountnameClass = accountnameClass || 'account-name'; + classname = classname || "name-and-account-name"; + usernameClass = usernameClass || "user-name"; + accountnameClass = accountnameClass || "account-name"; const nameAndAccountNames = document.querySelectorAll("." + classname); - const regexName = new RegExp(this.config.triggers.displayName.join('|'),'i'); - const regexInstance = new RegExp(this.config.triggers.instances.join('|'),'i'); - for(const currentAccount of nameAndAccountNames) { - if(currentAccount.querySelector) { + const regexName = new RegExp(this.config.triggers.displayName.join("|"), "i"); + const regexInstance = new RegExp(this.config.triggers.instances.join("|"), "i"); + for (const currentAccount of nameAndAccountNames) { + if (currentAccount.querySelector) { let isCat = false; const username = currentAccount.querySelector("." + usernameClass); - if(username) { + if (username) { isCat = regexName.test(username.innerText); } const account = currentAccount.querySelector("." + accountnameClass); - if(account) { + if (account) { const handle = account.innerText; isCat = isCat || regexInstance.test(handle); - if(isCat) { + if (isCat) { this.addCat(handle); } } @@ -328,13 +336,13 @@ function PleromaModCatify() { }, function detectCats () { - this.detectCatsByClassName('name-and-account-name'); - this.detectCatsByClassName('basic-user-card', 'basic-user-card-user-name-value', 'basic-user-card-screen-name'); + this.detectCatsByClassName("name-and-account-name"); + this.detectCatsByClassName("basic-user-card", "basic-user-card-user-name-value", "basic-user-card-screen-name"); }, - function catify () { - for(const catKey in this.cats) { - this.cats[catKey].makeCat(); + function catify (element) { + for (const catKey in this.cats) { + this.cats[catKey].makeCat(element); } } ].forEach((fn) => { PleromaModCatify.prototype[fn.name] = fn; }); diff --git a/instance/pleroma-mods/pleroma-mod-catify/style.css b/instance/pleroma-mods/pleroma-mod-catify/style.css index b8e715a17c..08ce64b72b 100644 --- a/instance/pleroma-mods/pleroma-mod-catify/style.css +++ b/instance/pleroma-mods/pleroma-mod-catify/style.css @@ -1,15 +1,3 @@ -.post-status-form button.btn.btn-default::after { - content: "Submit"; - line-height: 0; - text-indent: initial; - display: block; -} - -.post-status-form button.btn.btn-default { - text-indent: -9999px; - line-height: 0; -} - .cat>:not(.status-body) .avatar::before, .cat>:not(.status-body) .avatar::after { content: ""; display: inline-block; @@ -33,7 +21,7 @@ z-index: 1; } -.cat>:not(.status-body) .avatar img { +.cat>:not(.status-body) .avatar img, .cat>:not(.status-body) .avatar canvas { border-radius: 100%; top: 0; bottom: 0;