Apple Emoji Anywhere

Forces websites to use Apple emoji font

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         Apple Emoji Anywhere
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  Forces websites to use Apple emoji font
// @author       LushyTheDev
// @match        *://**/*
// @grant        none
// @run-at       document-start
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';
    
    // Create and inject stylesheet
    const injectStylesheet = () => {
        const style = document.createElement('style');
        style.textContent = `
            /* Force Apple Color Emoji font */
            @font-face {
                font-family: 'Apple Color Emoji Fallback';
                src: local('Apple Color Emoji');
                /* This includes specific Apple emoji code points */
                unicode-range: U+0023, U+0034, U+0037, U+00A9, U+2049, U+2199, U+21AA, U+23EA, U+23EC, 
                              U+23F0, U+2611, U+2649, U+264C, U+264F, U+2652, U+2660, U+2666, U+26AB, 
                              U+26F5, U+26FA, U+2702, U+2705, U+270B, U+270C, U+2712, U+2733, U+2744, 
                              U+274C, U+2754, U+2757, U+2795, U+27B0, U+2935, U+2B06, U+2B07, U+2B50, 
                              U+3297, U+FE0F, U+1F0CF, U+1F171, U+1F17F, U+1F191, U+1F196, U+1F197, 
                              U+1F199, U+1F19A, U+1F1E9, U+1F1EA, U+1F1EB, U+1F1F0, U+1F1F7, U+1F1FA, 
                              U+1F202, U+1F236, U+1F238, U+1F23A, U+1F300, U+1F305, U+1F306, U+1F309, 
                              U+1F30C, U+1F30E, U+1F311, U+1F314, U+1F317, U+1F31B, U+1F31E, U+1F330, 
                              U+1F334, U+1F338, U+1F339, U+1F33D, U+1F33E, U+1F33F, U+1F341, U+1F34C, 
                              U+1F34F, U+1F352, U+1F353, U+1F355, U+1F357, U+1F358, U+1F35B, U+1F360, 
                              U+1F363, U+1F367, U+1F36A, U+1F36D, U+1F36E, U+1F372, U+1F375, U+1F379, 
                              U+1F37A, U+1F385, U+1F386, U+1F389, U+1F391, U+1F392, U+1F3A1, U+1F3A5, 
                              U+1F3A8, U+1F3A9, U+1F3AB, U+1F3AF, U+1F3B3, U+1F3BA, U+1F3BB, U+1F3BE, 
                              U+1F3C0, U+1F3C1, U+1F3C3, U+1F3C6, U+1F3CA, U+1F3E2, U+1F3E6, U+1F3E8, 
                              U+1F3EC, U+1F405, U+1F40B, U+1F40F, U+1F410, U+1F412, U+1F414, U+1F416, 
                              U+1F41B, U+1F420, U+1F424, U+1F429, U+1F42A, U+1F42B, U+1F42E, U+1F431, 
                              U+1F432, U+1F438, U+1F439, U+1F43B, U+1F43C, U+1F442, U+1F444, U+1F445, 
                              U+1F447, U+1F44A, U+1F44E, U+1F44F, U+1F453, U+1F455, U+1F457, U+1F458, 
                              U+1F45C, U+1F45E, U+1F465, U+1F467, U+1F46C, U+1F46F, U+1F476, U+1F477, 
                              U+1F478, U+1F481, U+1F482, U+1F484, U+1F487, U+1F48A, U+1F48F, U+1F497, 
                              U+1F498, U+1F499, U+1F49A, U+1F4A0, U+1F4A1, U+1F4A3, U+1F4A5, U+1F4A6, 
                              U+1F4A9, U+1F4AE, U+1F4B0, U+1F4B7, U+1F4B8, U+1F4B9, U+1F4BD, U+1F4BE, 
                              U+1F4C3, U+1F4C7, U+1F4C8, U+1F4CB, U+1F4CD, U+1F4D0, U+1F4D4, U+1F4D8, 
                              U+1F4DD, U+1F4DE, U+1F4E1, U+1F4E3, U+1F4E4, U+1F4ED, U+1F4EE, U+1F4EF, 
                              U+1F4F1, U+1F4F2, U+1F4F6, U+1F502, U+1F505, U+1F508, U+1F50E, U+1F50F, 
                              U+1F514, U+1F516, U+1F51B, U+1F51F, U+1F520, U+1F525, U+1F529, U+1F52D, 
                              U+1F52E, U+1F52F, U+1F530, U+1F531, U+1F535, U+1F539, U+1F53B, U+1F53C, 
                              U+1F552, U+1F555, U+1F558, U+1F55A, U+1F55C, U+1F55F, U+1F562, U+1F567, 
                              U+1F595, U+1F5FE, U+1F5FF, U+1F606, U+1F607, U+1F608, U+1F60A, U+1F60E, 
                              U+1F60F, U+1F612, U+1F615, U+1F617, U+1F61A, U+1F61C, U+1F61E, U+1F620, 
                              U+1F625, U+1F627, U+1F62A, U+1F62D, U+1F630, U+1F631, U+1F634, U+1F63B, 
                              U+1F63E, U+1F640, U+1F648, U+1F64C, U+1F680, U+1F682, U+1F685, U+1F68B, 
                              U+1F68C, U+1F68F, U+1F691, U+1F693, U+1F695, U+1F698, U+1F69D, U+1F6A0, 
                              U+1F6A2, U+1F6A5, U+1F6AB, U+1F6AF, U+1F6B0, U+1F6B2, U+1F6B4, U+1F6B7, 
                              U+1F6BA, U+1F6BF, U+1F6C4, U+1F6C5, U+1F95A, U+1FAB2, U+20E3, U+200D, 
                              U+2642;
            }

            /* Apply Apple emoji to all text on all websites */
            * {
                font-family: -apple-system, BlinkMacSystemFont, 'Apple Color Emoji Fallback', 
                            system-ui, sans-serif !important;
            }

            /* Special fixes for Twitter */
            .r-sdzlij {
                font-family: 'Apple Color Emoji Fallback' !important;
            }
            
            /* Special handling for emoji elements on twitter */
            [data-testid="tweetText"] .emoji,
            [data-testid="tweetText"] img.Emoji,
            img.Emoji, div.Emoji, span.Emoji,
            img[src*="emoji"],
            img[src*="twemoji"] {
                display: none !important;
            }
            
            /* Show underlying character instead of hidden emoji images */
            [data-testid="tweetText"] img.Emoji:after,
            img.Emoji:after, div.Emoji:after, span.Emoji:after {
                content: attr(alt);
                font-family: 'Apple Color Emoji Fallback' !important;
                font-size: 1em;
            }
        `;
        document.head.appendChild(style);
    };

    // Apply to the DOM as early as possible
    if (document.head) {
        injectStylesheet();
    } else {
        // If the document hasn't fully loaded yet, wait for the head
        const observer = new MutationObserver((mutations, obs) => {
            if (document.head) {
                injectStylesheet();
                obs.disconnect();
            }
        });
        
        observer.observe(document.documentElement, {
            childList: true,
            subtree: true
        });
    }
    
    // Optional: Add a more aggressive emoji replacer for Twitter's custom emoji images
    const replaceTwitterEmojis = () => {
        // Find all emoji images and replace them with their alt text
        const emojiImages = document.querySelectorAll('img.Emoji, img[src*="emoji"], img[src*="twemoji"]');
        
        emojiImages.forEach(img => {
            if (img.alt && img.alt.match(/\p{Emoji}/u)) {
                const span = document.createElement('span');
                span.style.fontFamily = 'Apple Color Emoji Fallback';
                span.textContent = img.alt;
                img.parentNode.replaceChild(span, img);
            }
        });
    };
    
    // Run this periodically on Twitter
    if (window.location.hostname.includes('twitter.com') || 
        window.location.hostname.includes('x.com')) {
        
        // Initial run
        setTimeout(replaceTwitterEmojis, 1000);
        
        // Then keep checking as the user scrolls
        setInterval(replaceTwitterEmojis, 2000);
        
        // Also run when new content loads
        const tweetObserver = new MutationObserver(mutations => {
            replaceTwitterEmojis();
        });
        
        document.addEventListener('DOMContentLoaded', () => {
            const timeline = document.querySelector('[data-testid="primaryColumn"]');
            if (timeline) {
                tweetObserver.observe(timeline, {
                    childList: true,
                    subtree: true
                });
            }
        });
    }
})();