MediaWiki:Common.js:修订间差异

HW
HW留言 | 贡献
HW
HW留言 | 贡献
 
(未显示同一用户的28个中间版本)
第1行: 第1行:
// 立即执行闭包,避免污染全局变量
//用户名前显示头像
(function() {
mw.loader.using( 'mediawiki.util', function () {
     // 1. 提前检查皮肤,不是 Minerva 直接退出
     $( document ).ready( function () {
    if (mw.config.get('skin') !== 'minerva') return;
        function addAvatarsToElements( $elements ) {
            $elements.each( function () {
                var $link = $( this );
                if ( $link.prev( '.sp-avatar-wrapper' ).length ) {
                    return;
                }
const excludeContainers = [
'#p-views',
'#p-cactions',
'#p-tb',
'#right-navigation',
'#p-personal',
'.mw-portlet-personal'
];
// 检查是否匹配任意一个排除容器
const isExcluded = excludeContainers.some(selector => $link.closest(selector).length);
if (isExcluded) {
return;
}
 
                var href = $link.attr( 'href' );
                if ( !href ) return;
                var userPart = decodeURIComponent( href.split( '/wiki/' )[1] );
                if ( !userPart ) return;
                if ( userPart.indexOf( '/' ) !== -1 ) {
                    return;
                }
                var userName = userPart.replace( /^User:|^用户:/, '' ).replace(/_/g, ' ');
                var linkText = $link.text().trim().replace(/^User:|^用户:/, '');
                if ( linkText !== userName ) {
                    var $target = $link.find( 'span, bdi' ).first();
                    var targetText = $target.length ? $target.text().trim().replace(/^User:|^用户:/, '') : '';
                    if ( !$target.length || targetText !== userName ) {
                        return;
                    }
                }
                new mw.Api().get( {
                    action: 'parse',
                    text: '{{#avatar:' + userName + '|l}}',
                    contentmodel: 'wikitext',
                    disablelimitreport: true,
                    disableeditsection: true
                } ).done( function ( data ) {
                    if ( data.parse && data.parse.text ) {
                        var avatarHtml = data.parse.text[ '*' ];
                        var $avatarWrapper = $( '<span class="sp-avatar-wrapper" style="vertical-align: middle; margin-right: 4px; display: inline-block;"></span>' ).html( avatarHtml );
                        $avatarWrapper.find( 'img' ).css( {
    width: '2em',
    height: '2em',
    objectFit: 'cover',
    display: 'inline-block',
    verticalAlign: 'middle',
    border: 'var(--background-color-neutral, #eaecf0) 2px solid',
    boxSizing: 'border-box'
} );
                        $link.before( $avatarWrapper );
 
                        if ( mw.user.isAnon() ) {
                            return;
                        }
                        var currentUserName = mw.user.getName();
                        if ( userName !== currentUserName ) {
                            return;
                        }


    // 2. 预获取页面信息(mw.config 在页面头部就已加载,无需等待)
                        var avatarImg = $avatarWrapper.find( 'img' );
    const pageTitle = mw.config.get('wgPageName');
                        var avatarUrl = avatarImg.attr( 'src' );
    const isTalkPage = mw.config.get('wgNamespaceNumber') % 2 === 1;
                        if ( avatarUrl && avatarUrl !== '/images/avatars/default_l.gif' ) {
    const isExistingPage = mw.config.get('wgArticleId') > 0;
                            var $styleTag = $( '#dynamic-avatar-style' );
                            if ( !$styleTag.length ) {
                                $styleTag = $( '<style id="dynamic-avatar-style"></style>' ).appendTo( 'head' );
                            }
                            var css = '.minerva-icon--userAvatarOutline { background-image: url("' + avatarUrl + '"); background-repeat: no-repeat; background-size: contain; width: 30px; height: 30px; mask-image: unset; }';
                            $styleTag.text( css );
                        }
                    }
                } );
            } );
        }
        addAvatarsToElements( $( 'a[href*="/wiki/User:"], a[href*="/wiki/%E7%94%A8%E6%88%B7:"], a[href*="/wiki/用户:"]' ) );
        var observer = new MutationObserver( function ( mutations ) {
            mutations.forEach( function ( mutation ) {
                $( mutation.addedNodes ).find( 'a[href*="/wiki/User:"], a[href*="/wiki/%E7%94%A8%E6%88%B7:"], a[href*="/wiki/用户:"]' ).each( function() {
                    addAvatarsToElements( $( this ) );
                } );
            } );
        } );
        observer.observe( document.body, { childList: true, subtree: true } );
    } );
} );


    // 3. 预构造按钮 HTML(比动态创建元素更快)
    const editUrl = mw.util.getUrl(pageTitle, { action: 'edit' });
    const historyUrl = mw.util.getUrl(pageTitle, { action: 'history' });
    const talkTitle = isTalkPage ? pageTitle.replace(/^Talk:/, '') : `Talk:${pageTitle}`;
    const talkUrl = mw.util.getUrl(talkTitle);


    const buttonsHtml = `
        <div id="custom-wiki-bottom-bar" style="
            margin: 2.5rem auto 1rem;
            padding: 1rem 0;
            border-top: 1px solid #e0e0e0;
            text-align: center;
            max-width: 800px;
        ">
            <a href="${editUrl}" style="
                display: inline-block;
                margin: 0 0.75rem;
                padding: 0.5rem 1.25rem;
                background-color: #3366cc;
                color: white;
                text-decoration: none;
                border-radius: 4px;
                font-size: 0.95rem;
                font-weight: 500;
                transition: opacity 0.2s;
            " onmouseover="this.style.opacity='0.85'" onmouseout="this.style.opacity='1'">
                ${isExistingPage ? '编辑页面' : '创建页面'}
            </a>
            <a href="${historyUrl}" style="
                display: inline-block;
                margin: 0 0.75rem;
                padding: 0.5rem 1.25rem;
                background-color: #72777d;
                color: white;
                text-decoration: none;
                border-radius: 4px;
                font-size: 0.95rem;
                font-weight: 500;
                transition: opacity 0.2s;
            " onmouseover="this.style.opacity='0.85'" onmouseout="this.style.opacity='1'">
                查看历史
            </a>
            <a href="${talkUrl}" style="
                display: inline-block;
                margin: 0 0.75rem;
                padding: 0.5rem 1.25rem;
                background-color: #202122;
                color: white;
                text-decoration: none;
                border-radius: 4px;
                font-size: 0.95rem;
                font-weight: 500;
                transition: opacity 0.2s;
            " onmouseover="this.style.opacity='0.85'" onmouseout="this.style.opacity='1'">
                ${isTalkPage ? '返回条目' : '讨论页'}
            </a>
        </div>
    `;


    // 4. 【关键】DOM 一就绪就插入,不等图片/样式/钩子
//重定向
    function insertBar() {
(function() {
        const content = document.querySelector('main#content, #content');
    const url = new URL(window.location.href);
        if (content && !document.getElementById('custom-wiki-bottom-bar')) {
    const pathname = url.pathname;
            content.insertAdjacentHTML('beforeend', buttonsHtml);
    const searchParams = url.searchParams;
        }
   
     }
    const isIndexPhp = pathname === '/index.php';
    const hasOnlyTitleParam = searchParams.size === 1 && searchParams.has('title');
    const titleValue = searchParams.get('title') || '';
     const hasValidTitle = titleValue.trim() !== '';


    // 优先用 DOMContentLoaded,比 MediaWiki 的钩子快得多
     if (isIndexPhp && hasOnlyTitleParam && hasValidTitle) {
     if (document.readyState === 'loading') {
         const targetUrl = `/wiki/${encodeURIComponent(titleValue)}`;
         document.addEventListener('DOMContentLoaded', insertBar);
         window.location.replace(targetUrl);
    } else {
         insertBar(); // 如果 DOM 已经就绪,直接执行
     }
     }
})();
})();