有觉性 以安住且中立的心 照见身心的实相

MediaWiki:Common.js:修订间差异

来自Dhamma.cn
法藏​(留言 | 贡献)
小无编辑摘要
法藏​(留言 | 贡献)
小无编辑摘要
第918行: 第918行:


}
}




第923行: 第926行:


/* =========================================================
/* =========================================================
   Dhamma.cn 划词复制开示落款 (UrlShortener 适配版)
   Dhamma.cn 划词复制开示 - 终极稳定版
   ========================================================= */
   ========================================================= */
(function () {
    console.log('[Dhamma-Copy] 划词复制脚本已成功启动!');
    function createPopover() {
        var popover = document.getElementById('dhamma-copy-popover');
        if (popover) return popover;
        popover = document.createElement('div');
        popover.id = 'dhamma-copy-popover';
        // z-index 设为最高,防止被任何皮肤组件遮挡
        popover.style.cssText = 'display:none; position:absolute; z-index:2147483647; background:#ffffff; border:1px solid rgba(0,0,0,0.15); border-radius:8px; box-shadow:0 4px 18px rgba(0,0,0,0.2); padding:6px; font-size:13px; line-height:1.4; white-space:nowrap;';
        var btn = document.createElement('button');
        btn.id = 'dhamma-copy-btn';
        btn.innerHTML = '📋 复制该段开示(带出处)';
        btn.style.cssText = 'background:#4d6b57; color:#ffffff; border:none; border-radius:5px; padding:6px 14px; font-size:13px; cursor:pointer; font-weight:600; display:block;';
        popover.appendChild(btn);
        document.body.appendChild(popover);


mw.loader.using(['jquery', 'mediawiki.util']).then(function () {
         return popover;
   
    // 1. 确保弹窗 DOM 节点被注入至 body 根节点
    if ($('#dhamma-copy-popover').length === 0) {
         $('body').append(
            '<div id="dhamma-copy-popover">' +
                '<button id="dhamma-copy-btn">📋 复制该段开示(带出处)</button>' +
            '</div>'
        );
     }
     }


    var $popover = $('#dhamma-copy-popover');
     // 自动抓取 UrlShortener 生成的短网址
    var currentSelectionText = '';
     function getShortUrl() {
 
         var shortlink = document.querySelector('link[rel="shortlink"]');
     // 2. 提取 UrlShortener 生成的短网址
        if (shortlink && shortlink.getAttribute('href')) {
     function getUrlShortenerUrl() {
            var href = shortlink.getAttribute('href');
        // ① 优先读取 UrlShortener 扩展在 <head> 注入的 <link rel="shortlink">
             return href.indexOf('http') === 0 ? href : window.location.origin + href;
         var shortlink = $('link[rel="shortlink"]').attr('href');
        if (shortlink) {
             return (shortlink.indexOf('http') === 0) ? shortlink : (window.location.origin + shortlink);
         }
         }
 
         if (window.mw && mw.config && mw.config.get('wgShortUrl')) {
        // ② 读取 MediaWiki 配置文件中的短网址定义
             var sUrl = mw.config.get('wgShortUrl');
         if (mw.config.get('wgShortUrl')) {
             return sUrl.indexOf('http') === 0 ? sUrl : window.location.origin + sUrl;
             var confUrl = mw.config.get('wgShortUrl');
             return (confUrl.indexOf('http') === 0) ? confUrl : (window.location.origin + confUrl);
         }
         }
        return window.location.href.split('#')[0].split('?')[0];
    }


        // ③ 读取侧边栏或工具栏上的短网址/固定链接
    var currentText = '';
        var sidebarUrl = $('#t-shorturl a, #t-permalink a').attr('href');
        if (sidebarUrl) {
            return (sidebarUrl.indexOf('http') === 0) ? sidebarUrl : (window.location.origin + sidebarUrl);
        }


         // ④ 兜底方案:返回规范的标准长网址
    function checkAndShowPopover() {
         return window.location.origin + mw.util.getUrl(mw.config.get('wgPageName'));
         var popover = createPopover();
    }
         var btn = document.getElementById('dhamma-copy-btn');
        var sel = window.getSelection();
        var text = sel ? sel.toString().trim() : '';


    // 3. 全局监听鼠标/触控划词事件
        // 未选中或选中文本小于 2 个字则隐藏
    $(document).on('mouseup touchend', function (e) {
        if (!text || text.length < 2) {
        // 如果点击的是弹窗自身,不隐藏
            popover.style.display = 'none';
        if ($(e.target).closest('#dhamma-copy-popover').length > 0) {
             return;
             return;
         }
         }


         setTimeout(function () {
         currentText = text;
             var selection = window.getSelection();
 
             var text = selection ? selection.toString().trim() : '';
        if (sel.rangeCount > 0) {
             var range = sel.getRangeAt(0);
             var rect = range.getBoundingClientRect();


            // 未选中或选中文本少于 2 个字时隐藏浮窗
             if (rect.width === 0 && rect.height === 0) {
             if (!text || text.length < 2) {
                 popover.style.display = 'none';
                 $popover.hide();
                 return;
                 return;
             }
             }


             currentSelectionText = text;
             var scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0;
 
            var scrollLeft = window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft || 0;
            // 获取选区位置并计算浮窗坐标
            if (selection.rangeCount > 0) {
                var range = selection.getRangeAt(0);
                var rect = range.getBoundingClientRect();


                if (rect.width === 0 && rect.height === 0) {
            var popWidth = popover.offsetWidth || 190;
                    $popover.hide();
            var popHeight = popover.offsetHeight || 38;
                    return;
                }


                var popWidth  = $popover.outerWidth() || 200;
            var top = rect.top + scrollTop - popHeight - 10;
                var popHeight = $popover.outerHeight() || 38;
            var left = rect.left + scrollLeft + (rect.width / 2) - (popWidth / 2);


                var scrollTop  = $(window).scrollTop();
            if (left < 10) left = 10;
                var scrollLeft = $(window).scrollLeft();
            if (top < scrollTop + 10) {
 
                top = rect.bottom + scrollTop + 10;
                // 默认位于选中文本正上方 10px 处
                var top  = rect.top + scrollTop - popHeight - 10;
                var left = rect.left + scrollLeft + (rect.width / 2) - (popWidth / 2);
 
                // 边界安全防护(防止超出屏幕边缘)
                if (left < 10) left = 10;
                if (top < scrollTop + 10) {
                    top = rect.bottom + scrollTop + 10; // 空间不够时展示在下方
                }
 
                $popover.css({
                    top: top + 'px',
                    left: left + 'px'
                }).show();
             }
             }
        }, 30);
    });


    // 4. 点击空白区域自动隐藏浮窗
            popover.style.top = top + 'px';
    $(document).on('mousedown touchstart', function (e) {
            popover.style.left = left + 'px';
        if (!$(e.target).closest('#dhamma-copy-popover').length) {
             popover.style.display = 'block';
             $popover.hide();
        }
    });


    // 5. 点击按钮执行格式化落款复制
            // 点击复制事件处理
    $(document).on('click', '#dhamma-copy-btn', function (e) {
            btn.onclick = function (e) {
        e.stopPropagation();
                e.stopPropagation();
        e.preventDefault();
                e.preventDefault();


        if (!currentSelectionText) return;
                var title = (window.mw && mw.config && mw.config.get('wgTitle')) || document.title;
                var site = (window.mw && mw.config && mw.config.get('wgSiteName')) || 'Dhamma.cn';
                var url = getShortUrl();


        var pageTitle = mw.config.get('wgTitle') || document.title;
                var output =  
        var siteName  = mw.config.get('wgSiteName') || 'Dhamma.cn';
                    '“' + currentText + '”\n\n' +
        var shortUrl  = getUrlShortenerUrl();
                    '----------------------------------------\n' +
                    '法谈摘自:' + site + ' 《' + title + '》\n' +
                    '该篇网址:' + url + '\n' +
                    '转载请保持原文,随喜分享,Sadhu!';


        // 拼接开示文本与格式化落款
                if (navigator.clipboard && navigator.clipboard.writeText) {
        var formattedOutput =
                    navigator.clipboard.writeText(output).then(function () {
            '“' + currentSelectionText + '”\n\n' +
                        showFeedback(btn, popover);
            '----------------------------------------\n' +
                    }).catch(function () {
            '法谈摘自:' + siteName + ' 《' + pageTitle + '》\n' +
                        fallbackCopy(output, btn, popover);
            '该篇网址:' + shortUrl + '\n' +
                    });
            '转载请保持原文,随喜分享,Sadhu!';
                } else {
 
                    fallbackCopy(output, btn, popover);
        // 写入操作系统剪贴板
                }
        if (navigator.clipboard && navigator.clipboard.writeText) {
            };
            navigator.clipboard.writeText(formattedOutput).then(function () {
                showSuccessFeedback();
            }).catch(function () {
                fallbackCopy(formattedOutput);
            });
        } else {
            fallbackCopy(formattedOutput);
         }
         }
     });
     }


    // 复制成功提示
     function showFeedback(btn, popover) {
     function showSuccessFeedback() {
         btn.innerHTML = '✅ 已复制开示及出处';
         var $btn = $('#dhamma-copy-btn');
         btn.style.background = '#2e7d32';
         $btn.html('✅ 已复制开示及出处').css('background', '#2e7d32');
         setTimeout(function () {
         setTimeout(function () {
             $btn.html('📋 复制该段开示(带出处)').css('background', '#4d6b57');
             btn.innerHTML = '📋 复制该段开示(带出处)';
             $popover.hide();
            btn.style.background = '#4d6b57';
             popover.style.display = 'none';
         }, 1200);
         }, 1200);
     }
     }


    // 兼容旧版浏览器的剪贴板降级处理
     function fallbackCopy(text, btn, popover) {
     function fallbackCopy(text) {
         var ta = document.createElement('textarea');
         var $temp = $('<textarea>');
         ta.value = text;
         $('body').append($temp);
        ta.style.position = 'fixed';
         $temp.val(text).select();
        ta.style.opacity = '0';
         document.body.appendChild(ta);
        ta.select();
         document.execCommand('copy');
         document.execCommand('copy');
         $temp.remove();
         document.body.removeChild(ta);
         showSuccessFeedback();
         showFeedback(btn, popover);
     }
     }
});
 
    // 多重监听,兼容鼠标选词和手机触摸选词
    document.addEventListener('mouseup', function () { setTimeout(checkAndShowPopover, 50); });
    document.addEventListener('touchend', function () { setTimeout(checkAndShowPopover, 50); });
 
    // 点击空白区域关闭浮窗
    document.addEventListener('mousedown', function (e) {
        var popover = document.getElementById('dhamma-copy-popover');
        if (popover && !popover.contains(e.target)) {
            popover.style.display = 'none';
        }
    });
})();

2026年9月19日 (六) 22:07的版本

/**
 * =========================================================
 * Dhamma.cn 阅读显示设置
 * MediaWiki 1.43
 *
 * 功能:
 *  - 背景主题
 *  - 字号
 *  - 行距
 *  - 阅读宽度
 *  - 字体
 *  - localStorage 保存
 * =========================================================
 */

(function () {

    'use strict';


    /* =====================================================
       1. 默认设置
       ===================================================== */

    var defaults = {

        theme: 'default',

        fontSize: 18,

        lineHeight: 1.9,

        maxWidth: 900,

        fontFamily: 'system'

    };


    /* =====================================================
       2. 从 localStorage 读取
       ===================================================== */

    var settings = {};

    try {

        var saved =
            localStorage.getItem('dhammaReaderSettings');

        if (saved) {

            settings =
                Object.assign(
                    {},
                    defaults,
                    JSON.parse(saved)
                );

        } else {

            settings =
                Object.assign({}, defaults);

        }

    } catch (e) {

        settings =
            Object.assign({}, defaults);

    }


    /* =====================================================
       3. 保存设置
       ===================================================== */

    function saveSettings() {

        try {

            localStorage.setItem(
                'dhammaReaderSettings',
                JSON.stringify(settings)
            );

        } catch (e) {

            // 浏览器禁用 localStorage 时忽略
        }

    }


    /* =====================================================
       4. 字体
       ===================================================== */

    var fonts = {

        system:
            '-apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans SC", "Microsoft YaHei", Arial, sans-serif',

        serif:
            '"Noto Serif SC", "Source Han Serif SC", "Songti SC", "SimSun", serif',

        sans:
            '"Noto Sans SC", "Source Han Sans SC", "Microsoft YaHei", Arial, sans-serif'

    };


    /* =====================================================
       5. 应用设置
       ===================================================== */

    function applySettings() {

        var root =
            document.documentElement;

        var body =
            document.body;


        /* -----------------------------
           背景主题
           ----------------------------- */

        body.classList.remove(
            'reader-theme-default',
            'reader-theme-cream',
            'reader-theme-zen',
            'reader-theme-dark'
        );

        body.classList.add(
            'reader-theme-' + settings.theme
        );


        /* -----------------------------
           字号
           ----------------------------- */

        root.style.setProperty(
            '--reader-font-size',
            settings.fontSize + 'px'
        );


        /* -----------------------------
           行距
           ----------------------------- */

        root.style.setProperty(
            '--reader-line-height',
            settings.lineHeight
        );


        /* -----------------------------
           阅读宽度
           ----------------------------- */

        root.style.setProperty(
            '--reader-max-width',
            settings.maxWidth + 'px'
        );


        /* -----------------------------
           字体
           ----------------------------- */

        root.style.setProperty(
            '--reader-font-family',
            fonts[settings.fontFamily]
        );

    }


    /* =====================================================
       6. 创建设置按钮
       ===================================================== */

    function createSettingsButton() {

        if (
            document.getElementById(
                'reader-settings-button'
            )
        ) {
            return;
        }


        var button =
            document.createElement('button');

        button.id =
            'reader-settings-button';

        button.type =
            'button';

        button.setAttribute(
            'aria-label',
            '阅读设置'
        );

        button.setAttribute(
            'title',
            '阅读设置'
        );

        button.innerHTML =
            '⚙';


        document.body.appendChild(button);


        button.addEventListener(
            'click',
            function () {

                var panel =
                    document.getElementById(
                        'reader-settings-panel'
                    );

                if (!panel) {
                    return;
                }

                panel.classList.toggle(
                    'reader-settings-open'
                );

            }
        );

    }


    /* =====================================================
       7. 创建设置面板
       ===================================================== */

    function createSettingsPanel() {

        if (
            document.getElementById(
                'reader-settings-panel'
            )
        ) {
            return;
        }


        var panel =
            document.createElement('div');

        panel.id =
            'reader-settings-panel';


        panel.setAttribute(
            'role',
            'dialog'
        );

        panel.setAttribute(
            'aria-label',
            '阅读显示设置'
        );


        panel.innerHTML = `

            <div class="reader-settings-title">
                阅读显示设置
            </div>


            <!-- =========================
                 主题
                 ========================= -->

            <div class="reader-setting-group">

                <span class="reader-setting-label">
                    背景
                </span>

                <div class="reader-theme-buttons">

                    <button
                        type="button"
                        class="reader-theme-button reader-theme-default-button"
                        data-theme="default">
                        默认
                    </button>

                    <button
                        type="button"
                        class="reader-theme-button reader-theme-cream-button"
                        data-theme="cream">
                        米白
                    </button>

                    <button
                        type="button"
                        class="reader-theme-button reader-theme-zen-button"
                        data-theme="zen">
                        禅意
                    </button>

                    <button
                        type="button"
                        class="reader-theme-button reader-theme-dark-button"
                        data-theme="dark">
                        夜间
                    </button>

                </div>

            </div>


            <!-- =========================
                 字号
                 ========================= -->

            <div class="reader-setting-group">

                <span class="reader-setting-label">
                    字号
                </span>

                <div class="reader-range-row">

                    <span>A−</span>

                    <input
                        id="reader-font-size"
                        class="reader-range"
                        type="range"
                        min="14"
                        max="26"
                        step="1">

                    <span>A+</span>

                    <span
                        id="reader-font-size-value"
                        class="reader-range-value">
                    </span>

                </div>

            </div>


            <!-- =========================
                 行距
                 ========================= -->

            <div class="reader-setting-group">

                <span class="reader-setting-label">
                    行距
                </span>

                <div class="reader-range-row">

                    <span>窄</span>

                    <input
                        id="reader-line-height"
                        class="reader-range"
                        type="range"
                        min="1.4"
                        max="2.4"
                        step="0.1">

                    <span>宽</span>

                    <span
                        id="reader-line-height-value"
                        class="reader-range-value">
                    </span>

                </div>

            </div>


            <!-- =========================
                 阅读宽度
                 ========================= -->

            <div class="reader-setting-group">

                <span class="reader-setting-label">
                    阅读宽度
                </span>

                <div class="reader-range-row">

                    <span>窄</span>

                    <input
                        id="reader-max-width"
                        class="reader-range"
                        type="range"
                        min="680"
                        max="1200"
                        step="20">

                    <span>宽</span>

                    <span
                        id="reader-max-width-value"
                        class="reader-range-value">
                    </span>

                </div>

            </div>


            <!-- =========================
                 字体
                 ========================= -->

            <div class="reader-setting-group">

                <span class="reader-setting-label">
                    字体
                </span>

                <div class="reader-font-buttons">

                    <button
                        type="button"
                        class="reader-font-button"
                        data-font="system">
                        系统字体
                    </button>

                    <button
                        type="button"
                        class="reader-font-button"
                        data-font="serif">
                        宋体
                    </button>

                    <button
                        type="button"
                        class="reader-font-button"
                        data-font="sans">
                        黑体
                    </button>

                </div>

            </div>


            <!-- =========================
                 恢复默认
                 ========================= -->

            <button
                id="reader-settings-reset"
                type="button">

                恢复默认设置

            </button>

        `;


        document.body.appendChild(panel);


        bindSettingsEvents();

        updateSettingsUI();

    }


    /* =====================================================
       8. 绑定事件
       ===================================================== */

    function bindSettingsEvents() {


        /* -----------------------------
           主题
           ----------------------------- */

        document
            .querySelectorAll(
                '.reader-theme-button'
            )
            .forEach(function (button) {

                button.addEventListener(
                    'click',
                    function () {

                        settings.theme =
                            this.dataset.theme;

                        applySettings();

                        saveSettings();

                        updateSettingsUI();

                    }
                );

            });


        /* -----------------------------
           字号
           ----------------------------- */

        var fontSize =
            document.getElementById(
                'reader-font-size'
            );

        fontSize.addEventListener(
            'input',
            function () {

                settings.fontSize =
                    parseInt(
                        this.value,
                        10
                    );

                applySettings();

                saveSettings();

                updateSettingsUI();

            }
        );


        /* -----------------------------
           行距
           ----------------------------- */

        var lineHeight =
            document.getElementById(
                'reader-line-height'
            );

        lineHeight.addEventListener(
            'input',
            function () {

                settings.lineHeight =
                    parseFloat(
                        this.value
                    );

                applySettings();

                saveSettings();

                updateSettingsUI();

            }
        );


        /* -----------------------------
           阅读宽度
           ----------------------------- */

        var maxWidth =
            document.getElementById(
                'reader-max-width'
            );

        maxWidth.addEventListener(
            'input',
            function () {

                settings.maxWidth =
                    parseInt(
                        this.value,
                        10
                    );

                applySettings();

                saveSettings();

                updateSettingsUI();

            }
        );


        /* -----------------------------
           字体
           ----------------------------- */

        document
            .querySelectorAll(
                '.reader-font-button'
            )
            .forEach(function (button) {

                button.addEventListener(
                    'click',
                    function () {

                        settings.fontFamily =
                            this.dataset.font;

                        applySettings();

                        saveSettings();

                        updateSettingsUI();

                    }
                );

            });


        /* -----------------------------
           恢复默认
           ----------------------------- */

        document
            .getElementById(
                'reader-settings-reset'
            )
            .addEventListener(
                'click',
                function () {

                    settings =
                        Object.assign(
                            {},
                            defaults
                        );

                    applySettings();

                    saveSettings();

                    updateSettingsUI();

                }
            );

    }


    /* =====================================================
       9. 更新界面
       ===================================================== */

    function updateSettingsUI() {


        /* -----------------------------
           主题按钮
           ----------------------------- */

        document
            .querySelectorAll(
                '.reader-theme-button'
            )
            .forEach(function (button) {

                button.classList.toggle(
                    'active',
                    button.dataset.theme ===
                    settings.theme
                );

            });


        /* -----------------------------
           字号
           ----------------------------- */

        var fontSize =
            document.getElementById(
                'reader-font-size'
            );

        var fontSizeValue =
            document.getElementById(
                'reader-font-size-value'
            );

        if (fontSize) {

            fontSize.value =
                settings.fontSize;

            fontSizeValue.textContent =
                settings.fontSize + 'px';

        }


        /* -----------------------------
           行距
           ----------------------------- */

        var lineHeight =
            document.getElementById(
                'reader-line-height'
            );

        var lineHeightValue =
            document.getElementById(
                'reader-line-height-value'
            );

        if (lineHeight) {

            lineHeight.value =
                settings.lineHeight;

            lineHeightValue.textContent =
                settings.lineHeight;

        }


        /* -----------------------------
           阅读宽度
           ----------------------------- */

        var maxWidth =
            document.getElementById(
                'reader-max-width'
            );

        var maxWidthValue =
            document.getElementById(
                'reader-max-width-value'
            );

        if (maxWidth) {

            maxWidth.value =
                settings.maxWidth;

            maxWidthValue.textContent =
                settings.maxWidth + 'px';

        }


        /* -----------------------------
           字体
           ----------------------------- */

        document
            .querySelectorAll(
                '.reader-font-button'
            )
            .forEach(function (button) {

                button.classList.toggle(
                    'active',
                    button.dataset.font ===
                    settings.fontFamily
                );

            });

    }


    /* =====================================================
       10. 点击页面其他地方关闭面板
       ===================================================== */

    function bindOutsideClick() {

        document.addEventListener(
            'click',
            function (event) {

                var panel =
                    document.getElementById(
                        'reader-settings-panel'
                    );

                var button =
                    document.getElementById(
                        'reader-settings-button'
                    );

                if (!panel || !button) {
                    return;
                }


                if (
                    panel.contains(event.target) ||
                    button.contains(event.target)
                ) {
                    return;
                }


                panel.classList.remove(
                    'reader-settings-open'
                );

            }
        );

    }


    /* =====================================================
       11. 初始化
       ===================================================== */

    function initReaderSettings() {

        applySettings();

        createSettingsButton();

        createSettingsPanel();

        bindOutsideClick();

    }


    /*
     * MediaWiki 页面加载完成以后执行。
     */
/* =====================================================
   MediaWiki 初始化
   ===================================================== */

function startReaderSettings() {

    if (
        document.getElementById(
            'reader-settings-button'
        )
    ) {
        return;
    }

    initReaderSettings();
}


/*
 * MediaWiki 页面加载完成后执行。
 *
 * 使用 mw.loader.using + jQuery ready,
 * 避免 Common.js 加载时 DOMContentLoaded
 * 已经执行完毕的问题。
 */

if (
    typeof mw !== 'undefined' &&
    mw.loader
) {

    mw.loader.using([], function () {

        $(startReaderSettings);

    });

} else {

    if (
        document.readyState === 'loading'
    ) {

        document.addEventListener(
            'DOMContentLoaded',
            startReaderSettings
        );

    } else {

        startReaderSettings();

    }

}







/* =========================================================
   Dhamma.cn 划词复制开示 - 终极稳定版
   ========================================================= */
(function () {
    console.log('[Dhamma-Copy] 划词复制脚本已成功启动!');

    function createPopover() {
        var popover = document.getElementById('dhamma-copy-popover');
        if (popover) return popover;

        popover = document.createElement('div');
        popover.id = 'dhamma-copy-popover';
        // z-index 设为最高,防止被任何皮肤组件遮挡
        popover.style.cssText = 'display:none; position:absolute; z-index:2147483647; background:#ffffff; border:1px solid rgba(0,0,0,0.15); border-radius:8px; box-shadow:0 4px 18px rgba(0,0,0,0.2); padding:6px; font-size:13px; line-height:1.4; white-space:nowrap;';

        var btn = document.createElement('button');
        btn.id = 'dhamma-copy-btn';
        btn.innerHTML = '📋 复制该段开示(带出处)';
        btn.style.cssText = 'background:#4d6b57; color:#ffffff; border:none; border-radius:5px; padding:6px 14px; font-size:13px; cursor:pointer; font-weight:600; display:block;';

        popover.appendChild(btn);
        document.body.appendChild(popover);

        return popover;
    }

    // 自动抓取 UrlShortener 生成的短网址
    function getShortUrl() {
        var shortlink = document.querySelector('link[rel="shortlink"]');
        if (shortlink && shortlink.getAttribute('href')) {
            var href = shortlink.getAttribute('href');
            return href.indexOf('http') === 0 ? href : window.location.origin + href;
        }
        if (window.mw && mw.config && mw.config.get('wgShortUrl')) {
            var sUrl = mw.config.get('wgShortUrl');
            return sUrl.indexOf('http') === 0 ? sUrl : window.location.origin + sUrl;
        }
        return window.location.href.split('#')[0].split('?')[0];
    }

    var currentText = '';

    function checkAndShowPopover() {
        var popover = createPopover();
        var btn = document.getElementById('dhamma-copy-btn');
        var sel = window.getSelection();
        var text = sel ? sel.toString().trim() : '';

        // 未选中或选中文本小于 2 个字则隐藏
        if (!text || text.length < 2) {
            popover.style.display = 'none';
            return;
        }

        currentText = text;

        if (sel.rangeCount > 0) {
            var range = sel.getRangeAt(0);
            var rect = range.getBoundingClientRect();

            if (rect.width === 0 && rect.height === 0) {
                popover.style.display = 'none';
                return;
            }

            var scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0;
            var scrollLeft = window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft || 0;

            var popWidth = popover.offsetWidth || 190;
            var popHeight = popover.offsetHeight || 38;

            var top = rect.top + scrollTop - popHeight - 10;
            var left = rect.left + scrollLeft + (rect.width / 2) - (popWidth / 2);

            if (left < 10) left = 10;
            if (top < scrollTop + 10) {
                top = rect.bottom + scrollTop + 10;
            }

            popover.style.top = top + 'px';
            popover.style.left = left + 'px';
            popover.style.display = 'block';

            // 点击复制事件处理
            btn.onclick = function (e) {
                e.stopPropagation();
                e.preventDefault();

                var title = (window.mw && mw.config && mw.config.get('wgTitle')) || document.title;
                var site = (window.mw && mw.config && mw.config.get('wgSiteName')) || 'Dhamma.cn';
                var url = getShortUrl();

                var output = 
                    '“' + currentText + '”\n\n' +
                    '----------------------------------------\n' +
                    '法谈摘自:' + site + ' 《' + title + '》\n' +
                    '该篇网址:' + url + '\n' +
                    '转载请保持原文,随喜分享,Sadhu!';

                if (navigator.clipboard && navigator.clipboard.writeText) {
                    navigator.clipboard.writeText(output).then(function () {
                        showFeedback(btn, popover);
                    }).catch(function () {
                        fallbackCopy(output, btn, popover);
                    });
                } else {
                    fallbackCopy(output, btn, popover);
                }
            };
        }
    }

    function showFeedback(btn, popover) {
        btn.innerHTML = '✅ 已复制开示及出处';
        btn.style.background = '#2e7d32';
        setTimeout(function () {
            btn.innerHTML = '📋 复制该段开示(带出处)';
            btn.style.background = '#4d6b57';
            popover.style.display = 'none';
        }, 1200);
    }

    function fallbackCopy(text, btn, popover) {
        var ta = document.createElement('textarea');
        ta.value = text;
        ta.style.position = 'fixed';
        ta.style.opacity = '0';
        document.body.appendChild(ta);
        ta.select();
        document.execCommand('copy');
        document.body.removeChild(ta);
        showFeedback(btn, popover);
    }

    // 多重监听,兼容鼠标选词和手机触摸选词
    document.addEventListener('mouseup', function () { setTimeout(checkAndShowPopover, 50); });
    document.addEventListener('touchend', function () { setTimeout(checkAndShowPopover, 50); });

    // 点击空白区域关闭浮窗
    document.addEventListener('mousedown', function (e) {
        var popover = document.getElementById('dhamma-copy-popover');
        if (popover && !popover.contains(e.target)) {
            popover.style.display = 'none';
        }
    });
})();