|
|
| Riga 1: |
Riga 1: |
| /* ============================================================ | | /* ============================================================ |
| * Mobile cookie cleanup — eseguito IMMEDIATAMENTE prima di tutto | | * Common.js v5 — Wiki Methode Paret |
| * Se l'UA è mobile, cancella stopMobileRedirect/mf_useformat dai cookie
| |
| * così MobileFrontend torna a servire Minerva
| |
| * ============================================================ */
| |
| ( function () {
| |
| 'use strict';
| |
| var ua = navigator.userAgent || '';
| |
| var isMobile = /iPhone|iPad|iPod|Android.*Mobile|Mobile.*Android|webOS|BlackBerry|Opera Mini|IEMobile/i.test( ua );
| |
| if ( !isMobile ) return;
| |
|
| |
| var COOKIES_TO_NUKE = [ 'stopMobileRedirect', 'mf_useformat' ];
| |
| var deleted = false;
| |
| COOKIES_TO_NUKE.forEach( function ( name ) {
| |
| if ( document.cookie.indexOf( name + '=' ) !== -1 ) {
| |
| // Cancella sul dominio corrente e dominio parente (es. .marcoparet.com)
| |
| var hostname = window.location.hostname;
| |
| var parts = hostname.split( '.' );
| |
| var domains = [ hostname ];
| |
| if ( parts.length > 2 ) {
| |
| domains.push( '.' + parts.slice( -2 ).join( '.' ) );
| |
| }
| |
| domains.forEach( function ( d ) {
| |
| document.cookie = name + '=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/; domain=' + d;
| |
| } );
| |
| // Anche senza domain
| |
| document.cookie = name + '=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/';
| |
| deleted = true;
| |
| }
| |
| } );
| |
|
| |
| // Se ho cancellato e siamo su Vector (utente che ha forzato desktop in passato),
| |
| // ricarico la pagina per ottenere Minerva
| |
| if ( deleted && document.body && /skin-vector/.test( document.body.className ) ) {
| |
| // Cookie pulito ma siamo già su Vector → ricarica per ottenere Minerva
| |
| window.location.reload();
| |
| }
| |
| }() );
| |
| | |
| /* ============================================================
| |
| * Auto-language for translated pages — v3
| |
| * ============================================================ | | * ============================================================ |
| * Tre logiche complementari:
| |
| *
| |
| * A) Atterro su pagina /XX senza uselang -> forza UI in XX
| |
| * B) UI in XX, pagina senza suffisso -> redirigo a Page/XX se esiste
| |
| * C) UI in italiano (default), pagina /XX -> redirigo alla pagina senza /XX
| |
| * (cioè: utente cambia da russo a italiano, torna alla pagina italiana)
| |
| * | | * |
| * Tutte le redirezioni avvengono solo se l'utente NON ha già scelto manualmente | | * PRINCIPIO: Non interferire con le scelte dell'utente. |
| * (cookie no_auto_lang_redirect per opt-out). | | * URL decide il contenuto. L'icona globo (ULS) decide la UI. |
| | * Niente redirect automatici incrociati. |
| * | | * |
| * L'icona globo (ULS) ha sempre priorità. | | * Le uniche logiche attive: |
| | * 1. Pulizia cookie velenosi mobile (stopMobileRedirect, mf_useformat) |
| | * → permette a MobileFrontend di servire sempre Minerva su UA mobile |
| | * 2. Pulizia cookie autolang_set residuo da versioni precedenti |
| | * → toglie l'auto-redirect bidirezionale che disturbava |
| * ============================================================ */ | | * ============================================================ */ |
| ( function ( mw ) { | | ( function () { |
| 'use strict'; | | 'use strict'; |
|
| |
|
| var SUPPORTED_LANGS = [ 'ru', 'en', 'fr', 'es', 'pt' ]; | | // ─── Cookie helpers ───────────────────────────────────── |
| var COOKIE_AUTOLANG = 'autolang_set';
| |
| var COOKIE_NO_AUTO = 'no_auto_lang_redirect';
| |
| | |
| function getCookie( name ) { | | function getCookie( name ) { |
| var match = document.cookie.match( new RegExp( '(?:^|;\\s*)' + name + '=([^;]*)' ) ); | | var m = document.cookie.match( new RegExp( '(?:^|;\\s*)' + name + '=([^;]*)' ) ); |
| return match ? decodeURIComponent( match[ 1 ] ) : null; | | return m ? decodeURIComponent( m[ 1 ] ) : null; |
| }
| |
| | |
| function setCookie( name, value, days ) {
| |
| var d = new Date();
| |
| d.setTime( d.getTime() + ( days * 24 * 60 * 60 * 1000 ) );
| |
| document.cookie = name + '=' + encodeURIComponent( value ) +
| |
| '; expires=' + d.toUTCString() + '; path=/; SameSite=Lax';
| |
| } | | } |
| | | function deleteCookie( name ) { |
| function getPageSuffixLang() { | | var hostname = window.location.hostname; |
| var title = mw.config.get( 'wgPageName' ) || ''; | | var parts = hostname.split( '.' ); |
| var m = title.match( /\/([a-z]{2})$/ ); | | var domains = [ hostname, '' ]; |
| if ( m && SUPPORTED_LANGS.indexOf( m[ 1 ] ) !== -1 ) { | | if ( parts.length > 2 ) { |
| return m[ 1 ]; | | domains.push( '.' + parts.slice( -2 ).join( '.' ) ); |
| } | | } |
| return null; | | domains.forEach( function ( d ) { |
| | var suffix = d ? '; domain=' + d : ''; |
| | document.cookie = name + '=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/' + suffix; |
| | } ); |
| } | | } |
|
| |
|
| function getTitleWithoutSuffix() { | | // ─── 1. Mobile cookie nuke ────────────────────────────── |
| var title = mw.config.get( 'wgPageName' ) || '';
| | var ua = navigator.userAgent || ''; |
| return title.replace( /\/[a-z]{2}$/, '' );
| | var isMobile = /iPhone|iPad|iPod|Android.*Mobile|Mobile.*Android|webOS|BlackBerry|Opera Mini|IEMobile/i.test( ua ); |
| }
| | var mobileCookiesDeleted = false; |
| | | if ( isMobile ) { |
| function getCurrentUILang() {
| | [ 'stopMobileRedirect', 'mf_useformat' ].forEach( function ( name ) { |
| return mw.config.get( 'wgUserLanguage' );
| | if ( getCookie( name ) !== null ) { |
| } | | deleteCookie( name ); |
| | | mobileCookiesDeleted = true; |
| function getContentLang() {
| |
| return mw.config.get( 'wgContentLanguage' ) || 'it';
| |
| } | |
| | |
| function notViewAction() {
| |
| var action = mw.config.get( 'wgAction' );
| |
| return action && action !== 'view';
| |
| }
| |
| | |
| function notMainNamespace() {
| |
| var ns = mw.config.get( 'wgNamespaceNumber' );
| |
| return ns !== 0;
| |
| } | |
| | |
| function urlHasUselang() {
| |
| var url = new URL( window.location.href );
| |
| return !!url.searchParams.get( 'uselang' );
| |
| } | |
| | |
| /* Logica A: pagina /XX, UI diversa, no uselang -> forza UI in XX */
| |
| function autoForceUI() {
| |
| var targetLang = getPageSuffixLang(); | |
| if ( !targetLang ) return false;
| |
| | |
| if ( urlHasUselang() ) {
| |
| var url = new URL( window.location.href );
| |
| setCookie( COOKIE_AUTOLANG, url.searchParams.get( 'uselang' ), 365 );
| |
| return false;
| |
| }
| |
| | |
| if ( getCurrentUILang() === targetLang ) return false;
| |
|
| |
| // Eccezione: se UI è italiana (default), NON forzare ru — l'utente ha scelto italiano
| |
| // (questa è la logica C che lascia rendere logica C)
| |
| if ( getCurrentUILang() === getContentLang() ) return false;
| |
| | |
| setCookie( COOKIE_AUTOLANG, targetLang, 365 );
| |
| var newUrl = new URL( window.location.href );
| |
| newUrl.searchParams.set( 'uselang', targetLang );
| |
| window.location.replace( newUrl.toString() );
| |
| return true;
| |
| }
| |
| | |
| /* Logica B: UI in XX, pagina senza suffisso -> redirigo a Page/XX se esiste */
| |
| function autoRedirectToTranslation() {
| |
| var uiLang = getCurrentUILang();
| |
| var contentLang = getContentLang();
| |
|
| |
| if ( !uiLang || uiLang === contentLang ) return false;
| |
| if ( SUPPORTED_LANGS.indexOf( uiLang ) === -1 ) return false;
| |
| if ( getPageSuffixLang() ) return false;
| |
| if ( getCookie( COOKIE_NO_AUTO ) ) return false;
| |
| if ( notViewAction() ) return false;
| |
| if ( notMainNamespace() ) return false;
| |
|
| |
| var currentTitle = mw.config.get( 'wgPageName' );
| |
| var targetTitle = currentTitle + '/' + uiLang;
| |
|
| |
| var api = new mw.Api();
| |
| api.get( {
| |
| action: 'query',
| |
| titles: targetTitle,
| |
| format: 'json'
| |
| } ).then( function ( data ) {
| |
| var pages = ( data.query && data.query.pages ) || {};
| |
| var found = false;
| |
| for ( var pid in pages ) {
| |
| if ( pid > 0 ) { found = true; break; } | |
| }
| |
| if ( found ) {
| |
| console.log( '[autolang B] Redirect to translated version:', targetTitle );
| |
| window.location.replace( mw.util.getUrl( targetTitle ) );
| |
| } | | } |
| } ); | | } ); |
| return true;
| |
| } | | } |
|
| |
|
| /* Logica C: UI in italiano (default), pagina /XX -> redirigo a Page (senza suffisso) */ | | // ─── 2. Auto-lang residuo (cleanup definitivo) ────────── |
| function autoRedirectToOriginal() { | | // Le versioni precedenti del Common.js settavano autolang_set per redirect |
| var uiLang = getCurrentUILang();
| | // bidirezionali tra IT/RU. Lo cancelliamo SEMPRE: niente più auto-redirect. |
| var contentLang = getContentLang();
| | if ( getCookie( 'autolang_set' ) !== null ) { |
| var pageLang = getPageSuffixLang();
| | deleteCookie( 'autolang_set' ); |
|
| |
| if ( !pageLang ) return false;
| |
| if ( uiLang !== contentLang ) return false; // solo se UI è italiana
| |
| if ( getCookie( COOKIE_NO_AUTO ) ) return false;
| |
| if ( notViewAction() ) return false;
| |
| if ( notMainNamespace() ) return false;
| |
| if ( urlHasUselang() ) return false; // l'utente sta forzando una lingua
| |
|
| |
| // L'utente ha scelto italiano ma è su pagina /XX → vai alla pagina italiana
| |
| var originalTitle = getTitleWithoutSuffix();
| |
| if ( !originalTitle ) return false;
| |
|
| |
| // Verifica esistenza pagina italiana
| |
| var api = new mw.Api();
| |
| api.get( {
| |
| action: 'query',
| |
| titles: originalTitle,
| |
| format: 'json'
| |
| } ).then( function ( data ) {
| |
| var pages = ( data.query && data.query.pages ) || {};
| |
| var found = false;
| |
| for ( var pid in pages ) {
| |
| if ( pid > 0 ) { found = true; break; }
| |
| }
| |
| if ( found ) {
| |
| console.log( '[autolang C] Redirect to original Italian:', originalTitle );
| |
| // Cancella il cookie autolang (utente vuole italiano stabilmente)
| |
| setCookie( COOKIE_AUTOLANG, contentLang, 365 );
| |
| window.location.replace( mw.util.getUrl( originalTitle ) );
| |
| }
| |
| } );
| |
| return true;
| |
| } | | } |
| | | if ( getCookie( 'no_auto_lang_redirect' ) !== null ) { |
| function init() { | | deleteCookie( 'no_auto_lang_redirect' ); |
| if ( autoForceUI() ) return;
| |
| if ( autoRedirectToOriginal() ) return;
| |
| autoRedirectToTranslation(); | |
| } | | } |
|
| |
|
| if ( typeof mw !== 'undefined' && mw.config ) { | | // ─── 3. Se mobile + appena pulito cookie + su Vector ─── |
| mw.loader.using( [ 'mediawiki.util', 'mediawiki.api', 'user.options' ] ).then( init );
| | // → reload per ottenere Minerva |
| | if ( mobileCookiesDeleted && |
| | document.body && |
| | /skin-vector/.test( document.body.className ) ) { |
| | window.location.reload(); |
| } | | } |
|
| |
|
| }( window.mediaWiki || window.mw ) ); | | }() ); |
|
| |
|
| /* ============================================================ */ | | /* ============================================================ |
| | * NIENTE auto-redirect IT↔RU. |
| | * L'utente sceglie la lingua via icona globo (ULS) o URL. |
| | * ============================================================ */ |