打开/关闭菜单
打开/关闭外观设置菜单
打开/关闭个人菜单
未登录
未登录用户的IP地址会在进行任意编辑后公开展示。

MediaWiki:Common.js:修订间差异

MediaWiki界面页面
世界地图+语言切换
修复地图图片路径
第139行: 第139行:
             var bounds = [ [0, 0], [MAP_H, MAP_W] ];
             var bounds = [ [0, 0], [MAP_H, MAP_W] ];
             leafletMap = L.map( 'world-map', { crs: L.CRS.Simple, minZoom: -2, maxZoom: 2, zoomSnap: 0.5, attributionControl: false } );
             leafletMap = L.map( 'world-map', { crs: L.CRS.Simple, minZoom: -2, maxZoom: 2, zoomSnap: 0.5, attributionControl: false } );
             L.imageOverlay( '/images/Map.jpg', bounds ).addTo( leafletMap );
             L.imageOverlay( '/images/e/ea/Map.jpg', bounds ).addTo( leafletMap );
             leafletMap.fitBounds( bounds );
             leafletMap.fitBounds( bounds );
             leafletMap.setMaxBounds( [ [-MAP_H * 0.1, -MAP_W * 0.1], [MAP_H * 1.1, MAP_W * 1.1] ] );
             leafletMap.setMaxBounds( [ [-MAP_H * 0.1, -MAP_W * 0.1], [MAP_H * 1.1, MAP_W * 1.1] ] );

2026年4月16日 (四) 07:05的版本

( function () {
    'use strict';
    var MAIN_SITE = 'https://www.dolshipmaker.vip';
    var WIKI_BASE = 'https://wiki.dolshipmaker.vip';

    function setupLogout() {
        $( document ).on( 'click', '[href*="action=logout"], [href*="UserLogout"], [data-mw-logouturl]', function(e) {
            e.preventDefault();
            e.stopImmediatePropagation();
            new mw.Api().postWithToken( 'csrf', { action: 'logout' } )
            .then( function() {
                return fetch( MAIN_SITE + '/api/auth/cookie-logout', { method: 'POST', credentials: 'include' } );
            } )
            .catch( function(){} )
            .finally( function() {
                window.location.href = WIKI_BASE + '/wiki/首页';
            } );
            return false;
        } );
    }

    function interceptLoginButton() {
        $( document ).on( 'click', 'a[href*="Special:UserLogin"], a[href*="action=login"]', function(e) {
            e.preventDefault();
            window.location.href = MAIN_SITE + '/login.html?redirect=' + encodeURIComponent( window.location.href );
        } );
    }

    function interceptRegisterButton() {
        $( document ).on( 'click', 'a[href*="Special:CreateAccount"], a[href*="action=createaccount"]', function(e) {
            e.preventDefault();
            window.location.href = MAIN_SITE + '/register.html?redirect=' + encodeURIComponent( window.location.href );
        } );
    }

    function interceptEditForAnon() {
        if ( mw.config.get( 'wgUserId' ) !== 0 ) return;
        $( document ).on( 'click', 'a[href*="action=edit"], a[href*="veaction=edit"]', function(e) {
            e.preventDefault();
            window.location.href = MAIN_SITE + '/login.html?redirect=' + encodeURIComponent( window.location.href );
        } );
    }

    var currentLang = localStorage.getItem( 'dol-wiki-lang' ) || 'zh';

    function applyLang( lang ) {
        currentLang = lang;
        localStorage.setItem( 'dol-wiki-lang', lang );
        $( '.lang-btn' ).css( { background: 'transparent', color: '#b0c4d8' } );
        $( '.lang-btn[data-lang="' + lang + '"]' ).css( { background: '#c9a84c', color: '#0a1628' } );
        $( document ).trigger( 'dol-lang-change', [ lang ] );
    }

    function setupLangSwitch() {
        $( document ).on( 'click', '.lang-btn', function() {
            applyLang( $( this ).data( 'lang' ) );
        } );
        applyLang( currentLang );
    }

    var MAP_W = 4096, MAP_H = 2048;
    var GAME_W = 16384, GAME_H = 8192;
    var leafletMap = null;
    var cityMarkers = [];

    function gameToMap( gx, gy ) {
        return [ MAP_H - ( gy / GAME_H * MAP_H ), gx / GAME_W * MAP_W ];
    }

    function parseCityWikitext( title, wikitext ) {
        var city = { title: title };
        [ 'id', 'zh', 'zh-tw', 'ja', 'en', '坐标', '船厂', 'type', 'region', 'country' ].forEach( function( f ) {
            var m = wikitext.match( new RegExp( '\\|' + f + '=([^\\|\\}]*)' ) );
            city[ f ] = m ? m[1].trim() : '';
        } );
        return city;
    }

    function getCityName( city ) {
        return city[ currentLang ] || city['zh'] || city.title;
    }

    function updateMarkerTooltips() {
        cityMarkers.forEach( function( item ) {
            item.marker.setTooltipContent( getCityName( item.city ) );
        } );
    }

    function showCityDetail( city ) {
        $( '#city-detail-name' ).text( getCityName( city ) );
        $( '#city-detail-type' ).text( city.type );
        $( '#city-detail-region' ).text( city.region );
        $( '#city-detail-country' ).text( city.country );
        $( '#city-detail-coord' ).text( city['坐标'] );
        $( '#city-detail-shipyard' ).text( city['船厂'] );
        $( '#city-detail-link' ).attr( 'href', WIKI_BASE + '/wiki/' + encodeURIComponent( city.title ) );
        $( '#city-detail' ).show();
    }

    function loadCitiesOnMap( L ) {
        var api = new mw.Api();
        api.get( { action: 'query', list: 'allpages', apprefix: '城市/', aplimit: 500, format: 'json' } )
        .then( function( data ) {
            var titles = data.query.allpages.map( function( p ) { return p.title; } );
            if ( !titles.length ) return;
            var batches = [];
            for ( var i = 0; i < titles.length; i += 50 ) batches.push( titles.slice( i, i + 50 ) );
            batches.forEach( function( batch ) {
                api.get( { action: 'query', titles: batch.join( '|' ), prop: 'revisions', rvprop: 'content', format: 'json' } )
                .then( function( res ) {
                    Object.values( res.query.pages ).forEach( function( page ) {
                        if ( !page.revisions ) return;
                        var wt = page.revisions[0]['*'] || page.revisions[0].content || '';
                        var city = parseCityWikitext( page.title, wt );
                        if ( !city['坐标'] ) return;
                        var parts = city['坐标'].split( ',' );
                        if ( parts.length !== 2 ) return;
                        var gx = parseInt( parts[0] ), gy = parseInt( parts[1] );
                        if ( isNaN(gx) || isNaN(gy) ) return;
                        var marker = L.circleMarker( gameToMap( gx, gy ), {
                            radius: 4, fillColor: '#c9a84c', color: '#fff', weight: 1, opacity: 1, fillOpacity: 0.9
                        } ).addTo( leafletMap );
                        marker.bindTooltip( getCityName( city ), { permanent: false, direction: 'top', className: 'city-tooltip' } );
                        marker.on( 'click', function() { showCityDetail( city ); } );
                        cityMarkers.push( { marker: marker, city: city } );
                    } );
                } );
            } );
        } );
    }

    function initWorldMap() {
        if ( !document.getElementById( 'world-map' ) ) return;
        mw.loader.load( 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.css', 'text/css' );
        var script = document.createElement( 'script' );
        script.src = 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.js';
        script.onload = function() {
            var L = window.L;
            var bounds = [ [0, 0], [MAP_H, MAP_W] ];
            leafletMap = L.map( 'world-map', { crs: L.CRS.Simple, minZoom: -2, maxZoom: 2, zoomSnap: 0.5, attributionControl: false } );
            L.imageOverlay( '/images/e/ea/Map.jpg', bounds ).addTo( leafletMap );
            leafletMap.fitBounds( bounds );
            leafletMap.setMaxBounds( [ [-MAP_H * 0.1, -MAP_W * 0.1], [MAP_H * 1.1, MAP_W * 1.1] ] );
            loadCitiesOnMap( L );
            $( document ).on( 'dol-lang-change', function() { updateMarkerTooltips(); } );
        };
        document.head.appendChild( script );
    }

    mw.loader.using( 'mediawiki.util' ).done( function() {
        $( document ).ready( function() {
            setupLogout();
            interceptLoginButton();
            interceptRegisterButton();
            interceptEditForAnon();
            setupLangSwitch();
            initWorldMap();
        } );
    } );
}() );