|
|
| (3 versioni intermedie di uno stesso utente non sono mostrate) |
| Riga 1: |
Riga 1: |
| /* ============================================================ | | /* ============================================================ |
| * Mobile cookie cleanup — eseguito IMMEDIATAMENTE prima di tutto | | * Common.js v7 — 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: | | * REGOLA UNICA: |
| * | | * URL /Titolo → UI italiana |
| * A) Atterro su pagina /XX senza uselang -> forza UI in XX
| | * URL /Titolo/ru → UI russa |
| * 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 | | * Mobile detection v7: |
| * (cioè: utente cambia da russo a italiano, torna alla pagina italiana)
| | * - Touch capability (funziona anche con "Versione Desktop" del browser) |
| * | | * - Viewport width <= 1200 (più tollerante: cattura anche desktop mode 1080) |
| * Tutte le redirezioni avvengono solo se l'utente NON ha già scelto manualmente | | * - Una delle due basta |
| * (cookie no_auto_lang_redirect per opt-out). | |
| * | |
| * L'icona globo (ULS) ha sempre priorità. | |
| * ============================================================ */ | | * ============================================================ */ |
| ( function ( mw ) { | | ( function ( mw ) { |
| Riga 57: |
Riga 15: |
|
| |
|
| var SUPPORTED_LANGS = [ 'ru', 'en', 'fr', 'es', 'pt' ]; | | var SUPPORTED_LANGS = [ 'ru', 'en', 'fr', 'es', 'pt' ]; |
| 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() { | | // ─── DETECTION MOBILE ROBUSTA ────────────────────────── |
| var title = mw.config.get( 'wgPageName' ) || '';
| | var ua = navigator.userAgent || ''; |
| return title.replace( /\/[a-z]{2}$/, '' );
| | var isMobileUA = /iPhone|iPad|iPod|Android|Mobile|webOS|BlackBerry|Opera Mini|IEMobile|Silk/i.test( ua ); |
| }
| | var viewportWidth = window.innerWidth || document.documentElement.clientWidth || 1024; |
| | var isSmallViewport = viewportWidth <= 1200; |
| | var hasTouch = ( 'ontouchstart' in window ) || |
| | ( navigator.maxTouchPoints > 0 ) || |
| | ( navigator.msMaxTouchPoints > 0 ); |
|
| |
|
| function getCurrentUILang() { | | // Mobile se: UA mobile OPPURE (touch + viewport piccolino) |
| return mw.config.get( 'wgUserLanguage' );
| | // Il caso "Versione Desktop attivata" ha touch=true e viewport ~1080 → cattura |
| }
| | var isMobile = isMobileUA || ( hasTouch && isSmallViewport ); |
|
| |
|
| function getContentLang() { | | if ( isMobile ) { |
| return mw.config.get( 'wgContentLanguage' ) || 'it'; | | [ 'stopMobileRedirect', 'mf_useformat' ].forEach( function ( n ) { |
| | if ( getCookie( n ) !== null ) deleteCookie( n ); |
| | } ); |
| } | | } |
|
| |
|
| function notViewAction() { | | [ 'autolang_set', 'no_auto_lang_redirect' ].forEach( function ( n ) { |
| var action = mw.config.get( 'wgAction' ); | | if ( getCookie( n ) !== null ) deleteCookie( n ); |
| return action && action !== 'view';
| | } ); |
| } | |
|
| |
|
| function notMainNamespace() { | | // ─── Force ?useformat=mobile se mobile + su Vector ───── |
| var ns = mw.config.get( 'wgNamespaceNumber' ); | | if ( isMobile && |
| return ns !== 0;
| | document.body && |
| | /skin-vector/.test( document.body.className ) ) { |
| | var url = new URL( window.location.href ); |
| | if ( url.searchParams.get( 'useformat' ) !== 'mobile' ) { |
| | url.searchParams.set( 'useformat', 'mobile' ); |
| | window.location.replace( url.toString() ); |
| | return; |
| | } |
| } | | } |
|
| |
|
| function urlHasUselang() { | | // ─── URL decide UI lingua ───────────────────────────── |
| var url = new URL( window.location.href ); | | function syncUILangFromURL() { |
| return !!url.searchParams.get( 'uselang' );
| | if ( typeof mw === 'undefined' || !mw.config ) return; |
| }
| |
|
| |
|
| /* Logica A: pagina /XX, UI diversa, no uselang -> forza UI in XX */
| | var pageName = mw.config.get( 'wgPageName' ) || ''; |
| function autoForceUI() {
| | var currentUI = mw.config.get( 'wgUserLanguage' ); |
| var targetLang = getPageSuffixLang(); | | var contentLang = mw.config.get( 'wgContentLanguage' ) || 'it'; |
| if ( !targetLang ) return false; | |
|
| |
|
| if ( urlHasUselang() ) { | | var match = pageName.match( /\/([a-z]{2})$/ ); |
| var url = new URL( window.location.href );
| | var desiredLang; |
| setCookie( COOKIE_AUTOLANG, url.searchParams.get( 'uselang' ), 365 );
| | if ( match && SUPPORTED_LANGS.indexOf( match[ 1 ] ) !== -1 ) { |
| return false; | | desiredLang = match[ 1 ]; |
| | } else { |
| | desiredLang = contentLang; |
| } | | } |
|
| |
|
| if ( getCurrentUILang() === targetLang ) return false; | | if ( currentUI === desiredLang ) return; |
|
| |
| // 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 action = mw.config.get( 'wgAction' ); |
| var newUrl = new URL( window.location.href ); | | if ( action && action !== 'view' ) return; |
| 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 */
| | var ns = mw.config.get( 'wgNamespaceNumber' ); |
| function autoRedirectToTranslation() {
| | if ( ns < 0 ) return; |
| 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) */
| | var url = new URL( window.location.href ); |
| function autoRedirectToOriginal() {
| | if ( url.searchParams.get( 'uselang' ) ) return; |
| var uiLang = getCurrentUILang(); | |
| var contentLang = getContentLang();
| |
| var pageLang = getPageSuffixLang();
| |
|
| |
| 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;
| |
| }
| |
|
| |
|
| function init() {
| | url.searchParams.set( 'uselang', desiredLang ); |
| if ( autoForceUI() ) return; | | window.location.replace( url.toString() ); |
| if ( autoRedirectToOriginal() ) return; | |
| autoRedirectToTranslation();
| |
| } | | } |
|
| |
|
| if ( typeof mw !== 'undefined' && mw.config ) { | | if ( typeof mw !== 'undefined' && mw.config ) { |
| mw.loader.using( [ 'mediawiki.util', 'mediawiki.api', 'user.options' ] ).then( init ); | | mw.loader.using( [ 'mediawiki.util' ] ).then( syncUILangFromURL ); |
| } | | } |
|
| |
|
| }( window.mediaWiki || window.mw ) ); | | }( window.mediaWiki || window.mw ) ); |
|
| |
| /* ============================================================ */
| |