跳转到内容

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

来自槌基百科
Add double-run guard to prevent duplicate menu items
Redesign: move toggle to header pill, add Chinese labels
第1行: 第1行:
/**
/**
  * ViewerMode gadget — lets editors preview the site as a regular visitor.
  * ViewerMode gadget — reader/editor toggle pill in the site header.
  * Also fixes the missing icon on the "My blog" menu item.
  * Also fixes the missing icon on the "My blog" menu item.
  */
  */
第8行: 第8行:
     if ( mw.user.isAnon() ) { return; }
     if ( mw.user.isAnon() ) { return; }


     var STORAGE_KEY = 'mw-viewer-mode';
     var STORAGE_KEY = 'mw-viewer-mode';
    var READER_ICON  = 'vector-icon mw-ui-icon-watchlist mw-ui-icon-wikimedia-watchlist';
    var EDITOR_ICON  = 'vector-icon mw-ui-icon-wikiText mw-ui-icon-wikimedia-wikiText';
     var active = localStorage.getItem( STORAGE_KEY ) === '1';
     var active = localStorage.getItem( STORAGE_KEY ) === '1';


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


     function toggle() {
     function toggle() {
第22行: 第18行:
         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();
         updateBtn();
     }
     }


     function updateButton() {
     /* Label logic:
        var label = document.querySelector( '#pt-viewer-mode .viewer-mode-label' );
    *  viewer mode OFF → button says "阅读视图"  (click to enter reader view)
         var icon  = document.querySelector( '#pt-viewer-mode .vector-icon' );
    *  viewer mode ON  → button says "编辑视图"  (click to return to editor view)
         if ( !label ) { return; }
    */
         label.textContent   = active ? 'Editor mode' : 'Reader view';
    function updateBtn() {
        if ( icon ) { icon.className = active ? EDITOR_ICON : READER_ICON; }
         var btn = document.getElementById( 'vm-toggle' );
         if ( !btn ) { return; }
         if ( active ) {
            btn.textContent = '✏️ 编辑视图';
            btn.title      = '切换回编辑视图';
            btn.classList.add( 'vm-active' );
        } else {
            btn.textContent = '📖 阅读视图';
            btn.title      = '切换至阅读视图(隐藏编辑工具)';
            btn.classList.remove( 'vm-active' );
        }
     }
     }


     $( function () {
     $( function () {
         // Guard: only run once per page load
         /* ── Fix missing icon on "My blog" ─────────────────────── */
        if ( document.getElementById( 'pt-viewer-mode' ) ) { return; }
 
        // 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' ) ) {
             var blogIcon = document.createElement( 'span' );
             var blogIcon = document.createElement( 'span' );
             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( document.createTextNode( ' ' ), blogLink.firstChild );
             blogLink.insertBefore( blogIcon, blogLink.firstChild );
             blogLink.insertBefore( blogIcon, blogLink.firstChild );
         }
         }


         // Add toggle to end of p-personal list
         /* ── Build toggle pill ──────────────────────────────────── */
        // (logout lives in its own portlet: p-user-menu-logout)
         var btn = document.createElement( 'button' );
         var menuList = document.querySelector( '#p-personal .vector-menu-content-list' );
        btn.id        = 'vm-toggle';
         if ( !menuList ) { return; }
        btn.className = 'vm-toggle';
        btn.addEventListener( 'click', toggle );
         updateBtn();


         var li = document.createElement( 'li' );
         /* Inject into .vector-user-links-main, before the dropdown */
        li.id        = 'pt-viewer-mode';
         var target = document.querySelector( '.vector-user-links-main' ) ||
        li.className = 'mw-list-item';
                    document.querySelector( '.vector-user-links' );
 
         if ( target ) {
         var a = document.createElement( 'a' );
            target.insertBefore( btn, target.firstChild );
        a.href = '#';
         }
 
        var iconSpan = document.createElement( 'span' );
        iconSpan.className = active ? EDITOR_ICON : READER_ICON;
 
        var textSpan = document.createElement( 'span' );
        textSpan.className  = 'viewer-mode-label';
        textSpan.textContent = active ? 'Editor mode' : 'Reader view';
 
        a.appendChild( iconSpan );
         a.appendChild( document.createTextNode( ' ' ) );
        a.appendChild( textSpan );
        a.addEventListener( 'click', function ( e ) {
            e.preventDefault();
            toggle();
         } );
 
        li.appendChild( a );
        menuList.appendChild( li );
     } );
     } );
}() );
}() );

2026年3月12日 (四) 13:21的版本

/**
 * ViewerMode gadget — reader/editor toggle pill in the site header.
 * Also fixes the missing icon on the "My blog" menu item.
 */
( function () {
    'use strict';

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

    var STORAGE_KEY = 'mw-viewer-mode';
    var active = localStorage.getItem( STORAGE_KEY ) === '1';

    /* Apply class immediately on load (before DOM ready) to avoid flicker */
    if ( active ) { document.documentElement.classList.add( 'viewer-mode' ); }

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

    /* Label logic:
     *   viewer mode OFF → button says "阅读视图"  (click to enter reader view)
     *   viewer mode ON  → button says "编辑视图"  (click to return to editor view)
     */
    function updateBtn() {
        var btn = document.getElementById( 'vm-toggle' );
        if ( !btn ) { return; }
        if ( active ) {
            btn.textContent = '✏️ 编辑视图';
            btn.title       = '切换回编辑视图';
            btn.classList.add( 'vm-active' );
        } else {
            btn.textContent = '📖 阅读视图';
            btn.title       = '切换至阅读视图(隐藏编辑工具)';
            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 );
        }

        /* ── Build toggle pill ──────────────────────────────────── */
        var btn = document.createElement( 'button' );
        btn.id        = 'vm-toggle';
        btn.className = 'vm-toggle';
        btn.addEventListener( 'click', toggle );
        updateBtn();

        /* Inject into .vector-user-links-main, before the dropdown */
        var target = document.querySelector( '.vector-user-links-main' ) ||
                     document.querySelector( '.vector-user-links' );
        if ( target ) {
            target.insertBefore( btn, target.firstChild );
        }
    } );
}() );