跳转到内容

MediaWiki:Gadget-ViewerMode.js:修订间差异

来自槌基百科
直接注入DOM,修复Vector 2022兼容性,补全我的博客图标
Simulate full visitor view: hide user menu + custom buttons, add escape pill
 
(未显示同一用户的5个中间版本)
第1行: 第1行:
/**
/**
  * ViewerMode gadget — lets editors preview the site as a regular visitor.
  * ViewerMode gadget — simulates a genuine visitor's view as closely as possible.
  * Also fixes the missing icon on the "我的博客" menu item.
  * In reader view: hides ALL editor UI (edit buttons, user menu, custom admin buttons).
* An "退出阅读视图" escape pill is fixed bottom-left so you can always get back.
  */
  */
( function () {
( function () {
     'use strict';
     'use strict';


    // Only run for logged-in users
     if ( mw.user.isAnon() ) { return; }
     if ( mw.user.isAnon() ) {
        return;
    }


     var STORAGE_KEY = 'mw-viewer-mode';
     var STORAGE_KEY = 'mw-viewer-mode';
     var active = localStorage.getItem( STORAGE_KEY ) === '1';
     var active     = localStorage.getItem( STORAGE_KEY ) === '1';
    var btn        = null;  // header pill
    var exitBtn    = null;  // escape pill (bottom-left, only visible in reader view)


    // Apply class immediately on load to prevent flash of edit elements
     if ( active ) { document.documentElement.classList.add( 'viewer-mode' ); }
     if ( active ) {
        document.documentElement.classList.add( 'viewer-mode' );
    }


     function toggle() {
     function setActive( state ) {
         active = !active;
         active = state;
         localStorage.setItem( STORAGE_KEY, active ? '1' : '0' );
         localStorage.setItem( STORAGE_KEY, active ? '1' : '0' );
         document.documentElement.classList.toggle( 'viewer-mode', active );
         document.documentElement.classList.toggle( 'viewer-mode', active );
         updateButton();
         updateUI();
     }
     }


     function updateButton() {
     function toggle() { setActive( !active ); }
         var label = document.querySelector( '#pt-viewer-mode .viewer-mode-label' );
 
        if ( !label ) { return; }
    function updateUI() {
        label.textContent = active ? '编辑者模式' : '读者模式';
         if ( btn ) {
        var icon = document.querySelector( '#pt-viewer-mode .vector-icon' );
            if ( active ) {
        if ( icon ) {
                btn.textContent = '📖 阅读视图';
            icon.className = active
                btn.classList.add( 'vm-active' );
                ? 'vector-icon mw-ui-icon-userContributions mw-ui-icon-wikimedia-userContributions'
            } else {
                 : 'vector-icon mw-ui-icon-eye mw-ui-icon-wikimedia-eye';
                btn.textContent = '📖 阅读视图';
                 btn.classList.remove( 'vm-active' );
            }
         }
         }
     }
     }


     $( function () {
     $( function () {
         // --- Fix missing icon on 我的博客 ---
         /* ── Fix missing icon on "My blog" ─────────────────────── */
         var blogLink = document.querySelector( '#pt-simpleblog_myblog a' );
         var blogLink = document.querySelector( '#pt-simpleblog_myblog a' );
         if ( blogLink && !blogLink.querySelector( '.vector-icon' ) ) {
         if ( blogLink && !blogLink.querySelector( '.vector-icon' ) ) {
第45行: 第44行:
             blogIcon.className = 'vector-icon mw-ui-icon-article mw-ui-icon-wikimedia-article';
             blogIcon.className = 'vector-icon mw-ui-icon-article mw-ui-icon-wikimedia-article';
             blogLink.insertBefore( blogIcon, blogLink.firstChild );
             blogLink.insertBefore( blogIcon, blogLink.firstChild );
            blogLink.insertBefore( document.createTextNode( '\u00a0' ), blogIcon.nextSibling );
         }
         }


         // --- Add viewer-mode toggle to personal menu ---
         /* ── Header toggle pill ─────────────────────────────────── */
        var menuList = document.querySelector( '#p-personal .vector-menu-content-list' );
         btn = document.createElement( 'button' );
        if ( !menuList ) { return; }
         btn.id       = 'vm-toggle';
 
         btn.className = 'vm-toggle';
        // Only show toggle if user has any edit controls on this page
         btn.textContent = '📖 阅读视图';
         // (safe for all logged-in users; harmless if no edit controls exist)
         btn.title     = '模拟访客视图(隐藏所有编辑工具)';
        var li = document.createElement( 'li' );
         btn.addEventListener( 'click', toggle );
         li.id = 'pt-viewer-mode';
         if ( active ) { btn.classList.add( 'vm-active' ); }
         li.className = 'mw-list-item';
 
        var a = document.createElement( 'a' );
         a.href = '#';
         a.title = active ? '切换回编辑者模式' : '切换到读者模式,预览访客视图';
 
         var iconSpan = document.createElement( 'span' );
         iconSpan.className = active
            ? 'vector-icon mw-ui-icon-userContributions mw-ui-icon-wikimedia-userContributions'
            : 'vector-icon mw-ui-icon-eye mw-ui-icon-wikimedia-eye';


         var textSpan = document.createElement( 'span' );
         var target = document.querySelector( '.vector-user-links-main' ) ||
        textSpan.className = 'viewer-mode-label';
                    document.querySelector( '.vector-user-links' );
         textSpan.textContent = active ? '编辑者模式' : '读者模式';
         if ( target ) { target.insertBefore( btn, target.firstChild ); }


         a.appendChild( iconSpan );
         /* ── Escape pill (bottom-left, only shown in reader view) ─ */
         a.appendChild( document.createTextNode( '\u00a0' ) );
         exitBtn = document.createElement( 'button' );
         a.appendChild( textSpan );
         exitBtn.id        = 'vm-exit';
 
         exitBtn.className = 'vm-exit';
         a.addEventListener( 'click', function ( e ) {
         exitBtn.innerHTML = '✏️ 退出阅读视图';
            e.preventDefault();
         exitBtn.title    = '切换回编辑视图';
            toggle();
         exitBtn.addEventListener( 'click', toggle );
         } );
         document.body.appendChild( exitBtn );
 
         li.appendChild( a );
 
        // Insert before the logout item, or append at end
        var logoutItem = document.getElementById( 'pt-logout' );
         if ( logoutItem ) {
            menuList.insertBefore( li, logoutItem );
         } else {
            menuList.appendChild( li );
        }
     } );
     } );
}() );
}() );

2026年3月12日 (四) 13:26的最新版本

/**
 * ViewerMode gadget — simulates a genuine visitor's view as closely as possible.
 * In reader view: hides ALL editor UI (edit buttons, user menu, custom admin buttons).
 * An "退出阅读视图" escape pill is fixed bottom-left so you can always get back.
 */
( function () {
    'use strict';

    if ( mw.user.isAnon() ) { return; }

    var STORAGE_KEY = 'mw-viewer-mode';
    var active      = localStorage.getItem( STORAGE_KEY ) === '1';
    var btn         = null;   // header pill
    var exitBtn     = null;   // escape pill (bottom-left, only visible in reader view)

    if ( active ) { document.documentElement.classList.add( 'viewer-mode' ); }

    function setActive( state ) {
        active = state;
        localStorage.setItem( STORAGE_KEY, active ? '1' : '0' );
        document.documentElement.classList.toggle( 'viewer-mode', active );
        updateUI();
    }

    function toggle() { setActive( !active ); }

    function updateUI() {
        if ( btn ) {
            if ( active ) {
                btn.textContent = '📖 阅读视图';
                btn.classList.add( 'vm-active' );
            } else {
                btn.textContent = '📖 阅读视图';
                btn.classList.remove( 'vm-active' );
            }
        }
    }

    $( function () {
        /* ── Fix missing icon on "My blog" ─────────────────────── */
        var blogLink = document.querySelector( '#pt-simpleblog_myblog a' );
        if ( blogLink && !blogLink.querySelector( '.vector-icon' ) ) {
            var blogIcon = document.createElement( 'span' );
            blogIcon.className = 'vector-icon mw-ui-icon-article mw-ui-icon-wikimedia-article';
            blogLink.insertBefore( blogIcon, blogLink.firstChild );
        }

        /* ── Header toggle pill ─────────────────────────────────── */
        btn = document.createElement( 'button' );
        btn.id        = 'vm-toggle';
        btn.className = 'vm-toggle';
        btn.textContent = '📖 阅读视图';
        btn.title     = '模拟访客视图(隐藏所有编辑工具)';
        btn.addEventListener( 'click', toggle );
        if ( active ) { btn.classList.add( 'vm-active' ); }

        var target = document.querySelector( '.vector-user-links-main' ) ||
                     document.querySelector( '.vector-user-links' );
        if ( target ) { target.insertBefore( btn, target.firstChild ); }

        /* ── Escape pill (bottom-left, only shown in reader view) ─ */
        exitBtn = document.createElement( 'button' );
        exitBtn.id        = 'vm-exit';
        exitBtn.className = 'vm-exit';
        exitBtn.innerHTML = '✏️ 退出阅读视图';
        exitBtn.title     = '切换回编辑视图';
        exitBtn.addEventListener( 'click', toggle );
        document.body.appendChild( exitBtn );
    } );
}() );