Greasy Fork is available in English.

Fix Edge Translator Inline Code (only github)

Fix Microsoft Edge translator inline <code> reorder bug and preserve original inline code text.

2026-08-21 기준 버전입니다. 최신 버전을 확인하세요.

이 스크립트를 설치하려면 Tampermonkey, Greasemonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

이 스크립트를 설치하려면 Tampermonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Userscripts와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 유저 스크립트 관리자 확장 프로그램이 필요합니다.

(이미 유저 스크립트 관리자가 설치되어 있습니다. 설치를 진행합니다!)

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

(이미 유저 스타일 관리자가 설치되어 있습니다. 설치를 진행합니다!)

// ==UserScript==
// @name         Fix Edge Translator Inline Code (only github)
// @name:zh-CN   修复 Edge 翻译器翻译github行内代码错位与误翻译
// @namespace    https://github.com/你的用户名
// @version      1.0.0
// @description  Fix Microsoft Edge translator inline <code> reorder bug and preserve original inline code text.
// @description:zh-CN 修复 Edge 全文翻译时行内 <code> 被移动到句尾、代码内容被错误翻译的问题。
// @author       你的名字
// @license      MIT
// @match        https://github.com/*
// @grant        none
// @run-at       document-idle
// ==/UserScript==

(function () {
    'use strict';

    const WRAPPER_CLASS = 'edge-code-wrapper';
    const ORIGINAL_ATTR = 'data-edge-original-code';

    function processCode(code) {
        if (!(code instanceof HTMLElement)) {
            return;
        }

        if (code.tagName !== 'CODE') {
            return;
        }

        // 跳过真正的代码块
        if (code.closest('pre')) {
            return;
        }

        // 已处理
        if (
            code.parentElement &&
            code.parentElement.classList.contains(WRAPPER_CLASS)
        ) {
            return;
        }

        // 保存原始文本
        code.setAttribute(ORIGINAL_ATTR, code.textContent);

        // 包一层 span,避免 Edge 把 code 移到句尾
        const wrapper = document.createElement('span');
        wrapper.className = WRAPPER_CLASS;

        code.parentNode.insertBefore(wrapper, code);
        wrapper.appendChild(code);
    }

    function restoreCode(code) {
        if (!(code instanceof HTMLElement)) {
            return;
        }

        if (code.tagName !== 'CODE') {
            return;
        }

        const original = code.getAttribute(ORIGINAL_ATTR);

        if (original === null) {
            return;
        }

        // Edge 翻译器改了内容,就恢复
        if (code.textContent !== original) {
            code.textContent = original;
        }
    }

    function processRoot(root) {
        if (!(root instanceof Element)) {
            return;
        }

        if (root.matches('code')) {
            processCode(root);
            restoreCode(root);
        }

        root.querySelectorAll('code').forEach(code => {
            processCode(code);
            restoreCode(code);
        });
    }

    // 初始处理
    document.querySelectorAll('code').forEach(processCode);

    // 监听 Edge 翻译和 GitHub 动态更新
    const observer = new MutationObserver(mutations => {
        for (const mutation of mutations) {

            // 文本被翻译时
            if (mutation.type === 'characterData') {
                const parent = mutation.target.parentElement;

                if (parent && parent.tagName === 'CODE') {
                    restoreCode(parent);
                }
            }

            // DOM 被新增/替换时
            for (const node of mutation.addedNodes) {
                processRoot(node);
            }

            // 某些翻译实现会直接替换 code 子节点
            if (
                mutation.type === 'childList' &&
                mutation.target instanceof HTMLElement &&
                mutation.target.tagName === 'CODE'
            ) {
                restoreCode(mutation.target);
            }
        }
    });

    observer.observe(document.body, {
        childList: true,
        subtree: true,
        characterData: true
    });
})();