Replace specific favicon with a old one on cnblogs.
// ==UserScript==
// @name Get Old Cnblogs Favicon Back
// @name:en Get Old Cnblogs Favicon Back
// @name:zh 恢复博客园旧版网站图标
// @name:es Recuperar el antiguo favicon de Cnblogs.
// @name:fr Récupérer l'ancien favicon de Cnblogs.
// @name:de Altes Cnblogs-Favicon zurückholen.
// @name:ja 古いCnblogsのファビコンを取り戻す
// @name:ko 이전 Cnblogs 파비콘 되찾기
// @name:ru Вернуть старый фавикон Cnblogs
// @name:pt Recuperar o antigo favicon do Cnblogs.
// @name:it Recupera la vecchia favicon di Cnblogs.
// @name:nl Oude Cnblogs Favicon terughalen.
// @name:ar استعادة أيقونة Cnblogs القديمة
// @name:hi पुराने Cnblogs फ़ेविकॉन को वापस लाएँ
// @name:tr Eski Cnblogs Favicon'unu Geri Getir.
// @name:pl Przywróć starą ikonę Cnblogs
// @name:sv Få tillbaka gamla Cnblogs favicon
// @name:fi Hae vanha Cnblogsin kuvake takaisin
// @name:da Få det gamle Cnblogs Favicon tilbage
// @name:no Få tilbake det gamle Cnblogs-faviconet
// @name:cs Získat zpět starý favicon Cnblogs
// @name:hu Régi Cnblogs Favicon visszaállítása
// @name:ro Recuperați vechiul favicon Cnblogs.
// @name:bg Върни старата икона на Cnblogs.
// @name:el Επαναφορά του παλιού Favicon του Cnblogs.
// @name:uk Повернути старий Favicon Cnblogs
// @name:th นำ Favicon เก่าของ Cnblogs กลับมา
// @name:vi Lấy lại favicon cũ của Cnblogs.
// @name:id Dapatkan Kembali Favicon Cnblogs Lama
// @name:ms Dapatkan Kembali Favicon Cnblogs Lama
// @namespace http://tampermonkey.net/
// @version 1.1.1
// @description Replace specific favicon with a old one on cnblogs.
// @description:en Replace specific favicon with a old one on cnblogs.
// @description:zh 将博客园新版图标替换为旧版图标。
// @description:es Reemplazar el favicon específico por uno antiguo en cnblogs.
// @description:fr Remplacer le favicon spécifique par un ancien sur cnblogs.
// @description:de Ersetzen Sie das spezifische Favicon durch ein altes auf cnblogs.
// @description:ja cnblogsで特定のファビコンを古いものに置き換える。
// @description:ko cnblogs에서 특정 파비콘을 이전 것으로 교체합니다.
// @description:ru Заменить конкретный фавикон старым на cnblogs.
// @description:pt Substituir o favicon específico por um antigo no cnblogs.
// @description:it Sostituire la favicon specifica con una vecchia su cnblogs.
// @description:nl Vervang specifiek favicon door een oude op cnblogs.
// @description:ar استبدل الأيقونة المفضلة المحددة بأخرى قديمة على cnblogs.
// @description:hi cnblogs पर विशिष्ट फ़ेविकॉन को पुराने वाले से बदलें।
// @description:tr cnblogs'ta belirli favori simgesini eski bir simgeyle değiştirin.
// @description:pl Zastąp konkretną ikonę witryny (favicon) starą na cnblogs.
// @description:sv Byt ut specifik favicon mot en gammal på cnblogs.
// @description:fi Korvaa tietty favicon vanhalla cnblogsissa.
// @description:da Erstat specifik favicon med en gammel en på cnblogs.
// @description:no Bytt ut et spesifikt favicon med et gammelt på cnblogs.
// @description:cs Nahradit konkrétní faviconu starou na cnblogs.
// @description:hu Cserélje ki a specifikus favicont egy régire a cnblogs-on.
// @description:ro Înlocuiți faviconul specific cu unul vechi pe cnblogs.
// @description:bg Замени конкретен фавикон със стария на cnblogs.
// @description:el Αντικαταστήστε το συγκεκριμένο favicon με ένα παλιό στο cnblogs.
// @description:uk Замінити конкретний фавікон на старий на cnblogs.
// @description:th เปลี่ยน favicon เฉพาะด้วยอันเก่าบน cnblogs.
// @description:vi Thay thế favicon cụ thể bằng một cái cũ trên cnblogs.
// @description:id Gantikan favicon tertentu dengan yang lama di cnblogs.
// @description:ms Gantikan favicon tertentu dengan yang lama di cnblogs.
// @author aspen138
// @icon https://assets.cnblogs.com/favicon_v3_preview.ico?v=1
// @icon64 https://assets.cnblogs.com/favicon_v3_preview.ico?v=1
// @match *://*.cnblogs.com/*
// @include *://*.cnblogs.com/*
// @exclude *://passport.cnblogs.com/*
// @resource old_favicon https://assets.cnblogs.com/favicon.ico
// @connect cnblogs.com
// @grant none
// @run-at document-start
// @license MIT
// ==/UserScript==
(function () {
'use strict';
// Favicon URLs
const FAVICON_URL_V3 = 'https://assets.cnblogs.com/favicon_v3_preview.ico?v=1';
const FAVICON_URL_COMMON = 'https://common.cnblogs.com/favicon.svg';
const FAVICON_URL_V3P2 = 'https://assets.cnblogs.com/favicon_v3_2.ico';
const FAVICON_URL_DEFAULT = FAVICON_URL_V3; // Default favicon to use
// Link mappings for different icon types
const linkMap = {
"icon": FAVICON_URL_DEFAULT,
"shortcut icon": FAVICON_URL_DEFAULT,
"apple-touch-icon": FAVICON_URL_COMMON, // Use SVG for Apple touch icon
};
// Meta tag mappings
const metaMap = {
"application-name": "博客园",
"apple-mobile-web-app-title": "博客园"
};
function main() {
waitForElement("body").then(() => {
console.log("CNBlogs favicon enhancer: Body loaded, initializing...");
});
waitForElement("head").then(() => {
console.log("CNBlogs favicon enhancer: Head loaded, applying changes...");
monitorHead();
monitorTitle();
});
}
// Utility function to wait for elements to load
async function waitForElement(selector) {
const el = document.querySelector(selector);
if (el) return el;
return new Promise((resolve) => {
const fn = () => {
const el2 = document.querySelector(selector);
if (el2) {
return resolve(el2);
}
requestAnimationFrame(fn);
};
requestAnimationFrame(fn);
});
}
// Monitor and update favicon and related elements
function monitorHead() {
const sync = () => {
// Update favicon links
Object.entries(linkMap).forEach(([rel, targetValue]) => {
let link = document.querySelector(`link[rel="${rel}"]`);
// If link doesn't exist, create it
if (!link) {
link = document.createElement("link");
link.rel = rel;
document.head.appendChild(link);
}
// Update href if different
if (link.getAttribute("href") !== targetValue) {
link.setAttribute("href", targetValue);
console.log(`CNBlogs favicon enhancer: Updated ${rel} to ${targetValue}`);
}
});
// Update meta tags
Object.entries(metaMap).forEach(([name, targetValue]) => {
let meta = document.querySelector(`meta[name="${name}"]`);
// If meta doesn't exist, create it
if (!meta) {
meta = document.createElement("meta");
meta.name = name;
document.head.appendChild(meta);
}
// Update content if different
if (meta.getAttribute("content") !== targetValue) {
meta.setAttribute("content", targetValue);
console.log(`CNBlogs favicon enhancer: Updated meta ${name} to ${targetValue}`);
}
});
// Handle notification-based favicon switching (if applicable)
handleNotificationFavicon();
};
// Initial sync
sync();
// Monitor for changes
const mutationObserverOptions = {
subtree: true,
characterData: true,
childList: true,
attributes: true
};
// Re-sync when page visibility changes
window.addEventListener("visibilitychange", sync);
// Monitor head for changes
new MutationObserver(sync).observe(document.head, mutationObserverOptions);
console.log("CNBlogs favicon enhancer: Monitoring started");
}
// Handle notification-based favicon switching
function handleNotificationFavicon() {
// Check for notification indicators (adjust selector based on CNBlogs structure)
const hasNotification = document.querySelector('[class*="notification"], [class*="unread"], .msg-count, [data-count]:not([data-count="0"])');
if (hasNotification) {
// Use a different favicon when there are notifications
const notificationFavicon = FAVICON_URL_V3P2;
const faviconLink = document.querySelector('link[rel="icon"], link[rel="shortcut icon"]');
if (faviconLink && faviconLink.getAttribute("href") !== notificationFavicon) {
faviconLink.setAttribute("href", notificationFavicon);
console.log("CNBlogs favicon enhancer: Switched to notification favicon");
}
}
}
// Monitor and enhance page title
async function monitorTitle() {
const titleEl = await waitForElement("head > title");
const sync = () => {
const currentTitle = document.title;
// Enhance title with CNBlogs branding if needed
let newTitle = currentTitle;
// Add notification count to title if present
const notificationElement = document.querySelector('[class*="notification"], .msg-count');
if (notificationElement) {
const count = notificationElement.textContent.trim();
if (count && count !== '0' && !currentTitle.startsWith(`(${count})`)) {
newTitle = `(${count}) ${currentTitle}`;
}
}
// Ensure "博客园" branding is present
if (!newTitle.includes("博客园") && !newTitle.includes("CNBlogs")) {
if (newTitle.includes(" - ")) {
newTitle = newTitle.replace(" - ", " - 博客园 - ");
} else {
newTitle = `${newTitle} - 博客园`;
}
}
if (newTitle !== document.title) {
document.title = newTitle;
console.log(`CNBlogs favicon enhancer: Title updated to "${newTitle}"`);
}
};
// Initial sync
sync();
// Monitor for changes
window.addEventListener("visibilitychange", sync);
new MutationObserver(sync).observe(titleEl, {
subtree: true,
characterData: true,
childList: true
});
// Also monitor for dynamic content changes that might affect notifications
new MutationObserver(sync).observe(document.body, {
subtree: true,
childList: true,
attributes: true,
attributeFilter: ['class', 'data-count']
});
console.log("CNBlogs favicon enhancer: Title monitoring started");
}
// Initialize when DOM is ready
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', main);
} else {
main();
}
console.log("CNBlogs favicon enhancer: Script loaded and initialized");
})();