« MediaWiki:Vector-2022.js » : différence entre les versions
Aucun résumé des modifications |
Aucun résumé des modifications |
||
| Ligne 3 311 : | Ligne 3 311 : | ||
mw.hook( 'wikipage.content' ).add( function ( $content ) { | mw.hook( 'wikipage.content' ).add( function ( $content ) { | ||
if ( typeof wkIsNs === 'function' && !wkIsNs( 0 ) ) return; | |||
$content.on( 'click', 'a.wk-js-nav', function ( e ) { | $content.on( 'click', 'a.wk-js-nav', function ( e ) { | ||
Version du 6 février 2026 à 17:29
/* ============================================
Wikidébats — Vector 2022 + i18n centralisée (MW 1.43)
============================================ */
( function () {
'use strict';
/* =========================
Singletons DOM/jQuery (micro-opt)
========================= */
var D = document;
var W = window;
var $D = $( D );
var $W = $( W );
var $B = $( D.body );
/* =========================
Constantes de concat (micro-opt)
========================= */
var WK_OPEN = '{{';
var WK_CLOSE = '}}';
var WK_SEP = '|';
var WK_EQ = '=';
/* =========================
I18N loader + helpers
========================= */
function wkLoadI18n() {
var lang = ( mw.config.get( 'wgUserLanguage' ) || 'fr' ).toLowerCase();
var base = 'MediaWiki:Wikidebats.i18n.';
var fallback = 'fr';
function load( l ) {
var url = mw.util.wikiScript( 'index' ) +
'?title=' + encodeURIComponent( base + l + '.js' ) +
'&action=raw&ctype=text/javascript';
return new Promise( function ( resolve, reject ) {
mw.loader.getScript( url )
.done( resolve )
.fail( reject );
} );
}
return load( lang ).catch( function () {
return load( fallback );
} );
}
function wkMsg( key /*, ...params */ ) {
var params = Array.prototype.slice.call( arguments, 1 );
try {
if ( mw && mw.message && mw.message( key ).exists() ) {
return mw.msg.apply( mw, [ key ].concat( params ) );
}
} catch ( e ) {}
return key;
}
function wkMsgD( key, def /*, ...params */ ) {
var params = Array.prototype.slice.call( arguments, 2 );
var v = wkMsg.apply( null, [ key ].concat( params ) );
return ( v === key ) ? def : v;
}
function wkTpl( key, def /*, ...params */ ) {
var params = Array.prototype.slice.call( arguments, 2 );
return wkMsgD.apply( null, [ key, def ].concat( params ) );
}
function wkParam( key, def ) {
return wkMsgD( key, def );
}
function wkForm( key, def ) {
return wkMsgD( key, def );
}
/* =========================
I18N fast cache
========================= */
var wkMsgFastCache = Object.create( null );
function wkHasCache( obj, k ) {
return Object.prototype.hasOwnProperty.call( obj, k );
}
function wkParamFast( key, def ) {
var k = 'p|' + key + '|' + def;
if ( wkHasCache( wkMsgFastCache, k ) ) return wkMsgFastCache[ k ];
wkMsgFastCache[ k ] = wkParam( key, def );
return wkMsgFastCache[ k ];
}
function wkTplFast( key, def ) {
var k = 't|' + key + '|' + def;
if ( wkHasCache( wkMsgFastCache, k ) ) return wkMsgFastCache[ k ];
wkMsgFastCache[ k ] = wkTpl( key, def );
return wkMsgFastCache[ k ];
}
function wkFormFast( key, def ) {
var k = 'f|' + key + '|' + def;
if ( wkHasCache( wkMsgFastCache, k ) ) return wkMsgFastCache[ k ];
wkMsgFastCache[ k ] = wkForm( key, def );
return wkMsgFastCache[ k ];
}
/* =========================
I18N “pré-caches” (safe) : évite les recalculs en handlers
========================= */
var WK_P = {
page: null,
argument: null,
type: null,
level: null,
root: null,
path: null,
warnings: null
};
var WK_T = {
breadcrumbMenu: null,
more: null,
latest: null,
hover: null
};
var WK_F = {
summary: null,
citations: null,
references: null
};
function wkWarmI18nCaches() {
if ( WK_P.page !== null ) return;
WK_P.page = wkParamFast( 'wk-param-page', 'page' );
WK_P.argument = wkParamFast( 'wk-param-argument', 'argument' );
WK_P.type = wkParamFast( 'wk-param-type', 'type' );
WK_P.level = wkParamFast( 'wk-param-level', 'niveau' );
WK_P.root = wkParamFast( 'wk-param-root', 'racine' );
WK_P.path = wkParamFast( 'wk-param-path', 'chemin' );
WK_P.warnings = wkParamFast( 'wk-param-warnings', 'avertissements' );
WK_T.breadcrumbMenu = wkTplFast( 'wk-tpl-breadcrumb-menu', "Fil d'Ariane (menu)" );
WK_T.more = wkTplFast( 'wk-tpl-more-content', 'Contenu supplémentaire' );
WK_T.hoverMap = wkTplFast( 'wk-tpl-hover-map', 'Survol de carte des arguments' );
WK_T.hoverWP = wkTplFast( 'wk-tpl-hover-wikipedia', 'Survol de lien Wikipédia' );
WK_T.latest = wkTplFast( 'wk-tpl-latest-changes', 'Dernières contributions' );
/* Hover : template dépend du HTML (dataset), donc ici on “warm” seulement les strings génériques */
WK_T.hover = null;
WK_F.summary = wkFormFast( 'wk-form-summary', 'Résumé' );
WK_F.citations = wkFormFast( 'wk-form-citations', 'Citations' );
WK_F.references = wkFormFast( 'wk-form-references', 'Références' );
}
/* ========================
Helpers contexte + once
======================== */
function wkIsNs( ns ) {
try { return mw.config.get( 'wgNamespaceNumber' ) === ns; } catch ( e ) { return false; }
}
function wkIsView() {
return D.body && D.body.classList.contains( 'action-view' );
}
function wkIsFormEdit() {
return !!D.querySelector( '.mw-special-FormEdit, .mw-editable.action-formedit' );
}
function wkOnce( key ) {
try {
if ( D.documentElement.dataset[ key ] === '1' ) return false;
D.documentElement.dataset[ key ] = '1';
return true;
} catch ( e ) { return true; }
}
function wkIdle( fn ) {
if ( W.requestIdleCallback ) {
requestIdleCallback( fn, { timeout: 500 } );
} else {
setTimeout( fn, 0 );
}
}
function wkRafThrottle( fn ) {
var raf = 0;
return function () {
if ( raf ) return;
raf = requestAnimationFrame( function () {
raf = 0;
fn();
} );
};
}
function wkRootNode( root ) {
if ( !root ) return D;
if ( root.jquery && root.length ) return root[ 0 ];
if ( root.nodeType ) return root;
return D;
}
/* =========================
HTML replace helper (fragment)
========================= */
function wkReplaceHtml( $target, html ) {
if ( !$target || !$target.length ) return;
var tmp = D.createElement( 'div' );
tmp.innerHTML = html;
var frag = D.createDocumentFragment();
while ( tmp.firstChild ) frag.appendChild( tmp.firstChild );
$target[ 0 ].replaceWith( frag );
}
function wkGetWikiTitleFromHrefRaw( href ) {
if ( !href ) return '';
var m = href.match( /\/wiki\/([^#?]+)/ );
return ( m && m[ 1 ] ) ? m[ 1 ] : '';
}
function hrefToPageTitle( href ) {
if ( !href ) return '';
var page = href.replace( /^.*\/wiki\//, '' );
page = decodeURIComponent( page );
page = page.replace( /_/g, ' ' );
return page;
}
/* =========================
API Parse — pool + dédup + caches (LRU) + fail cache
+ priorité de queue (hover > bc > latest/more > arg > def)
+ annulation des jobs en file
========================= */
var wkApi = null;
var WK_PARSE_CONCURRENCY = 2;
var WK_PARSE_CACHE_MAX = {
bc: 80,
arg: 160,
hover: 120,
latest: 0,
more: 0,
def: 80
};
var wkParseCacheBC = new Map();
var wkParseCacheArg = new Map();
var wkParseCacheHover = new Map();
var wkParseCacheLatest = new Map();
var wkParseCacheMore = new Map();
var wkParseCacheDef = new Map();
var wkArgEmbedCache = new Map();
var wkParseInFlight = new Map();
var wkParseQueue = [];
var wkParseActive = 0;
var WK_PARSE_FAIL_TTL_MS = 15000;
var wkParseFailUntil = new Map();
var WK_PARSE_PRIORITY = {
hover: 0,
bc: 1,
latest: 2,
more: 2,
arg: 3,
def: 4
};
function wkGetApi() {
if ( wkApi ) return wkApi;
wkApi = new mw.Api();
return wkApi;
}
function wkGetBucketCache( bucket ) {
if ( bucket === 'bc' ) return wkParseCacheBC;
if ( bucket === 'arg' ) return wkParseCacheArg;
if ( bucket === 'hover' ) return wkParseCacheHover;
if ( bucket === 'latest' ) return wkParseCacheLatest;
if ( bucket === 'more' ) return wkParseCacheMore;
return wkParseCacheDef;
}
function wkCacheGetLRU( cache, key ) {
if ( !cache || !cache.has || !cache.size ) return null;
if ( !cache.has( key ) ) return null;
var v = cache.get( key );
cache.delete( key );
cache.set( key, v );
return v;
}
function wkCacheSetLRU( cache, max, key, value ) {
if ( !cache || typeof max !== 'number' || max <= 0 ) return;
if ( cache.has( key ) ) cache.delete( key );
cache.set( key, value );
while ( cache.size > max ) {
var firstKey = cache.keys().next().value;
if ( typeof firstKey === 'undefined' ) break;
cache.delete( firstKey );
}
}
function wkFailIsHot( bucket, keyLocal ) {
var k = bucket + '|' + keyLocal;
var until = wkParseFailUntil.get( k ) || 0;
if ( until > Date.now() ) return true;
if ( until ) wkParseFailUntil.delete( k );
return false;
}
function wkFailTouch( bucket, keyLocal ) {
var k = bucket + '|' + keyLocal;
wkParseFailUntil.set( k, Date.now() + WK_PARSE_FAIL_TTL_MS );
}
function wkParseCancel( bucket, wikitext ) {
var keyLocal = String( wikitext || '' );
var inFlightKey = String( bucket || 'def' ) + '|' + keyLocal;
for ( var i = wkParseQueue.length - 1; i >= 0; i-- ) {
if ( wkParseQueue[ i ] && wkParseQueue[ i ].inFlightKey === inFlightKey ) {
var job = wkParseQueue.splice( i, 1 )[ 0 ];
if ( wkParseInFlight.has( inFlightKey ) ) wkParseInFlight.delete( inFlightKey );
try { job.reject( new Error( 'wkParse:cancelled' ) ); } catch ( e ) {}
break;
}
}
}
function wkParseWikitext( wikitext, bucket ) {
bucket = bucket || 'def';
var cache = wkGetBucketCache( bucket );
var keyLocal = String( wikitext || '' );
var inFlightKey = bucket + '|' + keyLocal;
var cached = wkCacheGetLRU( cache, keyLocal );
if ( cached !== null ) return Promise.resolve( cached );
if ( wkFailIsHot( bucket, keyLocal ) ) return Promise.reject( new Error( 'wkParse:fail-cached' ) );
if ( wkParseInFlight.has( inFlightKey ) ) return wkParseInFlight.get( inFlightKey );
var p = new Promise( function ( resolve, reject ) {
wkParseQueue.push( {
inFlightKey: inFlightKey,
keyLocal: keyLocal,
bucket: bucket,
wikitext: wikitext,
resolve: resolve,
reject: reject
} );
wkParsePump();
} );
wkParseInFlight.set( inFlightKey, p );
p.finally( function () {
wkParseInFlight.delete( inFlightKey );
} );
return p;
}
function wkParseQueuePickNext() {
if ( !wkParseQueue.length ) return null;
var bestIdx = -1;
var bestPri = 999;
for ( var i = 0; i < wkParseQueue.length; i++ ) {
var job = wkParseQueue[ i ];
if ( !job ) continue;
var b = job.bucket || 'def';
var pri = ( typeof WK_PARSE_PRIORITY[ b ] === 'number' ) ? WK_PARSE_PRIORITY[ b ] : WK_PARSE_PRIORITY.def;
if ( pri < bestPri ) {
bestPri = pri;
bestIdx = i;
if ( bestPri === 0 ) break;
}
}
if ( bestIdx < 0 ) return null;
return wkParseQueue.splice( bestIdx, 1 )[ 0 ];
}
function wkParsePump() {
while ( wkParseActive < WK_PARSE_CONCURRENCY && wkParseQueue.length ) {
var job = wkParseQueuePickNext();
if ( !job ) return;
wkParseActive++;
wkGetApi().post( {
action: 'parse',
contentmodel: 'wikitext',
text: job.wikitext,
formatversion: 2,
disablelimitreport: 1,
disableeditsection: 1,
disabletoc: 1,
redirects: 1
} ).done( function ( data ) {
var html = data && data.parse && data.parse.text
? ( typeof data.parse.text === 'string' ? data.parse.text : ( data.parse.text[ '*' ] || '' ) )
: '';
if ( html ) html = html.replace( /<!--[\S\s]*?-->/gm, '' );
var cache2 = wkGetBucketCache( job.bucket );
var max = WK_PARSE_CACHE_MAX[ job.bucket ];
if ( typeof max !== 'number' ) max = WK_PARSE_CACHE_MAX.def;
wkCacheSetLRU( cache2, max, job.keyLocal, html );
job.resolve( html );
} ).fail( function ( err ) {
wkFailTouch( job.bucket, job.keyLocal );
job.reject( err );
} ).always( function () {
wkParseActive--;
wkParsePump();
} );
}
}
/* ==========================================================
fr-collapsible — bind idempotent (root-scoped)
========================================================== */
function bindFrCollapsible( $root ) {
$root.find( '.fr-collapsible' ).each( function () {
var $box = $( this );
if ( $box.data( 'fr-collapsible-bound' ) ) return;
$box.data( 'fr-collapsible-bound', true );
var $toggle = $box.children( '.fr-collapsible-toggle' ).first();
var $content = $box.children( '.fr-collapsible-content' ).first();
if ( !$toggle.length || !$content.length ) return;
$toggle.attr( { role: 'button', tabindex: 0 } );
$content.removeAttr( 'hidden' )[ 0 ].style.display = 'block';
var reduce = W.matchMedia && W.matchMedia( '(prefers-reduced-motion: reduce)' ).matches;
function openPanel( instant ) {
$box.removeClass( 'fr-collapsed' ).addClass( 'fr-expanded' );
$toggle.attr( 'aria-expanded', 'true' )
.removeClass( 'fr-collapsible-toggle-collapsed' )
.addClass( 'fr-collapsible-toggle-expanded' );
$content.attr( 'aria-hidden', 'false' );
if ( instant || reduce ) {
$content.stop( true, true );
$content[ 0 ].style.transition = 'none';
$content[ 0 ].style.height = 'auto';
$content[ 0 ].style.opacity = '1';
void $content[ 0 ].offsetHeight;
$content[ 0 ].style.transition = '';
return;
}
$content.stop( true, true );
$content[ 0 ].style.display = 'block';
$content[ 0 ].style.height = '0px';
$content[ 0 ].style.opacity = '0';
requestAnimationFrame( function () {
var h = $content[ 0 ].scrollHeight;
$content[ 0 ].style.height = h + 'px';
$content[ 0 ].style.opacity = '1';
} );
$content.one( 'transitionend', function ( e ) {
if ( e.target !== $content[ 0 ] ) return;
$content[ 0 ].style.height = 'auto';
} );
}
function closePanel( instant ) {
$box.removeClass( 'fr-expanded' ).addClass( 'fr-collapsed' );
$toggle.attr( 'aria-expanded', 'false' )
.removeClass( 'fr-collapsible-toggle-expanded' )
.addClass( 'fr-collapsible-toggle-collapsed' );
$content.attr( 'aria-hidden', 'true' );
if ( instant || reduce ) {
$content.stop( true, true );
$content[ 0 ].style.transition = 'none';
$content[ 0 ].style.height = '0px';
$content[ 0 ].style.opacity = '0';
void $content[ 0 ].offsetHeight;
$content[ 0 ].style.transition = '';
return;
}
$content.stop( true, true );
$content[ 0 ].style.display = 'block';
$content[ 0 ].style.height = $content[ 0 ].scrollHeight + 'px';
$content[ 0 ].style.opacity = '1';
requestAnimationFrame( function () {
$content[ 0 ].style.height = '0px';
$content[ 0 ].style.opacity = '0';
} );
}
function setState( expanded, instant ) {
if ( expanded ) openPanel( instant );
else closePanel( instant );
}
$toggle.on( 'click', function ( e ) {
if ( $( e.target ).closest( 'a,button,input,select,textarea,label' ).length ) return;
e.preventDefault();
setState( $box.hasClass( 'fr-collapsed' ), false );
} );
$toggle.on( 'keydown', function ( e ) {
if ( e.key === 'Enter' || e.key === ' ' || e.keyCode === 13 || e.keyCode === 32 ) {
e.preventDefault();
setState( $box.hasClass( 'fr-collapsed' ), false );
}
} );
setState( !$box.hasClass( 'fr-collapsed' ), true );
} );
}
/* ==========================================================
Autogrow — PF events + scan initial + batching idle
========================================================== */
var wkAutoGrowIdleScheduled = 0;
var wkAutoGrowPendingRoot = null;
function wkAutoGrowTextareasScan( $root ) {
$root.find( '#pfForm textarea.autoGrow' ).each( function () {
if ( this.dataset && this.dataset.wkAutogrow === '1' ) return;
if ( this.dataset ) this.dataset.wkAutogrow = '1';
this.rows = 1;
this.style.height = 'auto';
this.style.height = this.scrollHeight + 'px';
} );
}
function wkAutoGrowSchedule( root ) {
wkAutoGrowPendingRoot = root || wkAutoGrowPendingRoot || D;
if ( wkAutoGrowIdleScheduled ) return;
wkAutoGrowIdleScheduled = 1;
wkIdle( function () {
wkAutoGrowIdleScheduled = 0;
var r = wkAutoGrowPendingRoot || D;
wkAutoGrowPendingRoot = null;
wkAutoGrowTextareasScan( $( r ) );
} );
}
function wkBindAutoGrow() {
if ( !wkOnce( 'wkAutogrowInit' ) ) return;
$D.on( 'pfaddinstance pfafterrebuild pfcreateinput', function ( e ) {
var root = e && e.target ? e.target : D;
wkAutoGrowSchedule( root );
} );
}
/* ==========================================================
Espace insécable avant " ?"
========================================================== */
function wkFixTitleSpace() {
if ( !wkOnce( 'wkTitleSpaceInit' ) ) return;
function fixTitleSpace() {
var el = D.querySelector( '#firstHeading .mw-page-title-main' ) || D.querySelector( '#firstHeading' );
if ( !el ) return;
var walker = D.createTreeWalker( el, NodeFilter.SHOW_TEXT );
var t, last = null;
while ( ( t = walker.nextNode() ) ) last = t;
if ( !last ) return;
var s = last.nodeValue;
if ( /\u00A0\?$/.test( s ) || /\u202F\?$/.test( s ) ) return;
var r = s.replace( / (?=\?$)/, '\u00A0' );
if ( r !== s ) last.nodeValue = r;
}
mw.hook( 'wikipage.ready' ).add( fixTitleSpace );
var h = D.getElementById( 'firstHeading' );
if ( h && W.MutationObserver ) {
new MutationObserver( fixTitleSpace ).observe( h, { childList: true, subtree: true, characterData: true } );
}
}
/* ==========================================================
Onglet externe
========================================================== */
$( document ).on( 'click', '.onglet-externe a', function () {
var a = this;
if ( a.getAttribute( 'target' ) !== '_blank' ) {
a.setAttribute( 'target', '_blank' );
}
if ( a.relList && a.relList.add ) {
a.relList.add( 'noopener' );
} else {
var rel = ( a.getAttribute( 'rel' ) || '' );
if ( !/\bnoopener\b/.test( rel ) ) {
a.setAttribute( 'rel', ( rel ? rel + ' ' : '' ) + 'noopener' );
}
}
} );
/* ==========================================================
DÉPLACEMENTS BOUTONS — NS0 uniquement
========================================================== */
function wkMoveRenameButton() {
if ( !wkIsNs( 0 ) || !wkIsView() ) return;
var span = D.getElementById( 'bouton-renommer' );
if ( !span ) return;
var heading = D.querySelector( '.firstHeading' ) || D.getElementById( 'firstHeading' );
if ( !heading ) return;
span.style.display = 'inline';
if ( span.parentNode !== heading ) heading.appendChild( span );
var a = span.querySelector( 'a' );
if ( a ) a.textContent = '';
}
function wkMoveTopicButton() {
if ( !wkIsNs( 0 ) || !wkIsView() ) return;
var bouton = D.getElementById( 'bouton-modifier-sujet' );
var contentSub = D.getElementById( 'contentSub' );
if ( bouton && contentSub ) {
if ( bouton.parentNode !== contentSub ) contentSub.appendChild( bouton );
contentSub.style.display = 'flex';
bouton.style.display = 'flex';
}
}
function wkMoveCategoriesButton() {
if ( !wkIsNs( 0 ) || !wkIsView() ) return;
var bouton = D.getElementById( 'bouton-modifier-categories' );
var categories = D.getElementById( 'mw-normal-catlinks' );
if ( !bouton || !categories ) return;
var ul = categories.querySelector( 'ul' );
if ( !ul ) return;
var lastLi = ul.querySelector( 'li:last-child' );
if ( !lastLi ) return;
if ( bouton.parentElement !== lastLi ) lastLi.appendChild( bouton );
bouton.style.display = 'inline';
}
function wkMoveInterlanguageButton() {
if ( !wkIsNs( 0 ) || !wkIsView() ) return;
var MARKER_SELECTOR = '#bouton-modifier-interlangue';
var PORTLET_SELECTOR = '#p-lang-btn .vector-dropdown-content';
var NEW_ID = 'modifier-langues-lien';
var marker = D.querySelector( MARKER_SELECTOR );
if ( !marker ) return;
var container = D.querySelector( PORTLET_SELECTOR );
if ( !container ) return;
if ( D.getElementById( NEW_ID ) ) return;
var sourceLink = marker.querySelector( 'a' );
if ( !sourceLink || !sourceLink.href ) return;
var wantedTooltip = ( marker.getAttribute( 'data-wk-tooltip' ) || '' ).trim();
var newLink = D.createElement( 'a' );
newLink.id = NEW_ID;
newLink.href = sourceLink.href;
newLink.textContent = ( sourceLink.textContent || '' ).trim() || 'Modifier';
newLink.className = ( ( sourceLink.getAttribute( 'class' ) || '' ).trim() + ' interlanguage-edit-link' ).trim();
newLink.setAttribute( 'rel', 'nofollow' );
if ( wantedTooltip ) {
newLink.setAttribute( 'title', wantedTooltip );
newLink.setAttribute( 'data-tooltip', wantedTooltip );
newLink.setAttribute( 'aria-label', wantedTooltip );
}
var wrap = D.createElement( 'div' );
wrap.className = 'modifier-langues';
wrap.appendChild( newLink );
container.appendChild( wrap );
marker.remove();
}
function wkInitHeaderButtons() {
if ( !wkIsNs( 0 ) || !wkIsView() ) return;
wkMoveRenameButton();
wkMoveTopicButton();
wkMoveCategoriesButton();
wkMoveInterlanguageButton();
}
/* ==========================================================
TOOLTIPS formulaires + renommer (root-scoped)
========================================================== */
function wkFixAddDataAndRenameTooltipsOn( root ) {
var el = wkRootNode( root );
if ( !el || !el.querySelectorAll ) return;
var nodes = el.querySelectorAll( 'span.wk-adddata-link[data-wk-tooltip]' );
for ( var i = 0; i < nodes.length; i++ ) {
var wrap = nodes[ i ];
var tt = wrap.getAttribute( 'data-wk-tooltip' );
if ( !tt ) continue;
var a = wrap.querySelector( 'a' );
if ( !a ) continue;
if ( a.getAttribute( 'title' ) !== tt ) a.setAttribute( 'title', tt );
if ( a.getAttribute( 'data-tooltip' ) !== tt ) a.setAttribute( 'data-tooltip', tt );
if ( wrap.hasAttribute( 'title' ) ) wrap.removeAttribute( 'title' );
}
var a2 = D.querySelector( '#bouton-renommer a' );
if ( a2 ) {
var RENAME_KEY = 'wk-rename-page';
var tt2 = ( typeof wkMsg === 'function' ) ? wkMsg( RENAME_KEY ) : RENAME_KEY;
if ( a2.getAttribute( 'title' ) !== tt2 ) a2.setAttribute( 'title', tt2 );
if ( a2.getAttribute( 'data-tooltip' ) !== tt2 ) a2.setAttribute( 'data-tooltip', tt2 );
if ( a2.getAttribute( 'aria-label' ) !== tt2 ) a2.setAttribute( 'aria-label', tt2 );
}
}
/* ==========================================================
More / Latest — via wkParseWikitext (pool + dédup + priorité)
========================================================== */
function moreContentCall() {
if ( !wkOnce( 'wkMoreInit' ) ) return;
$D.on( 'click.wkMore', '.more-content-button', function () {
$( this ).hide();
wkWarmI18nCaches();
var ds = this.dataset || null;
var page = ds && ds.page ? ds.page : $( this ).data( 'page' );
var $wrapper = $( this ).parent().find( '.more-content-wrapper' );
var query = WK_OPEN + WK_T.more + WK_SEP + WK_P.page + ' = ' + page + WK_CLOSE;
wkParseWikitext( query, 'more' ).then( function ( html ) {
wkReplaceHtml( $wrapper, '<div class="more-content-wrapper"><div class="more-content-drop show"></div>' + html + '</div>' );
} ).catch( function () {} );
} );
}
function latestChangesCall() {
if ( !wkOnce( 'wkLatestInit' ) ) return;
$D.on( 'click.wkLatest', '.ns-0 .latest-changes-button.mw-ui-button', function () {
$( this ).hide();
wkWarmI18nCaches();
var ds = this.dataset || null;
var page = ds && ds.page ? ds.page : $( this ).data( 'page' );
var $wrapper = $( this ).parent().find( '.latest-changes-wrapper' );
var query = WK_OPEN + WK_T.latest + WK_SEP + WK_P.page + ' = ' + page + WK_CLOSE;
wkParseWikitext( query, 'latest' ).then( function ( html ) {
wkReplaceHtml( $wrapper, '<div class="latest-changes-wrapper"><div class="latest-changes-drop show"></div>' + html + '</div>' );
} ).catch( function () {} );
} );
}
/* ==========================================================
Hover — WeakMap cache + skip hidden + annulation queue
========================================================== */
var wkHoverTip = null;
var wkHoverTipContent = null;
var wkHoverCurrent = null;
var wkHoverTimer = 0;
var wkHoverToken = 0;
var wkHoverStore = ( typeof WeakMap !== 'undefined' ) ? new WeakMap() : null;
/* “global scroll/resize hub” (safe) */
var wkGlobalScrollHubBound = false;
var wkGlobalScrollHub = null;
var wkHoverNeedsReposition = false;
function wkEnsureGlobalScrollHub() {
if ( wkGlobalScrollHubBound ) return;
wkGlobalScrollHubBound = true;
wkGlobalScrollHub = wkRafThrottle( function () {
/* Hover reposition si tooltip visible */
if ( wkHoverNeedsReposition && wkHoverCurrent && wkHoverCurrent.length && wkHoverTip && wkHoverTip.is( ':visible' ) ) {
var el = wkHoverCurrent[ 0 ];
var ds = el && el.dataset ? el.dataset : null;
var pos = ( ds && ds.position ) ? ds.position : ( wkHoverCurrent.data( 'position' ) || 'bottom' );
wkPositionHoverTooltip( wkHoverCurrent, pos );
}
} );
W.addEventListener( 'scroll', wkGlobalScrollHub, { passive: true } );
W.addEventListener( 'resize', wkGlobalScrollHub, { passive: true } );
if ( W.visualViewport ) {
visualViewport.addEventListener( 'resize', wkGlobalScrollHub, { passive: true } );
visualViewport.addEventListener( 'scroll', wkGlobalScrollHub, { passive: true } );
}
}
function wkEnsureHoverTooltip() {
if ( wkHoverTip ) return;
wkHoverTip = $( '<div class="wk-hover-tooltip" aria-hidden="true">\n' +
'\t<div class="wk-hover-tooltip__content"></div>\n' +
'</div>' ).appendTo( $B ).hide();
wkHoverTipContent = wkHoverTip.find( '.wk-hover-tooltip__content' );
wkHoverTip.on( 'click', function ( e ) {
e.stopPropagation();
} );
wkHoverNeedsReposition = true;
wkEnsureGlobalScrollHub();
}
function wkPositionHoverTooltip( $anchor, position ) {
if ( !$anchor || !$anchor.length || !wkHoverTip ) return;
var rect = $anchor[ 0 ].getBoundingClientRect();
var winW = W.innerWidth || D.documentElement.clientWidth || 0;
var scrollX = W.pageXOffset || D.documentElement.scrollLeft || 0;
var scrollY = W.pageYOffset || D.documentElement.scrollTop || 0;
wkHoverTip.removeClass( 'pos-left pos-right pos-top pos-bottom' );
if ( position ) wkHoverTip.addClass( 'pos-' + position );
wkHoverTip.css( { left: -9999, top: -9999, right: '' } ).show();
var tipW = wkHoverTip.outerWidth();
var tipH = wkHoverTip.outerHeight();
var margin = 10;
var top = rect.bottom + scrollY + margin;
if ( position === 'top' ) top = rect.top + scrollY - tipH - margin;
var left = rect.left + scrollX + ( rect.width / 2 ) - ( tipW / 2 );
left = Math.max( scrollX + 6, Math.min( scrollX + winW - tipW - 6, left ) );
wkHoverTip.css( { left: Math.round( left ), top: Math.round( top ) } );
}
function wkHideHoverTooltip() {
if ( wkHoverTip ) wkHoverTip.hide().attr( 'aria-hidden', 'true' );
if ( wkHoverTipContent ) wkHoverTipContent.empty();
wkHoverCurrent = null;
}
function wkSetLocalHoverWrapper( $el, html, position ) {
var $w = $el.find( '.hover-wrapper' ).first();
if ( !$w.length ) {
$el.append( '<div class="hover-wrapper"></div>' );
$w = $el.find( '.hover-wrapper' ).first();
}
var pos = ( position || '' ).trim();
var cls = 'hover-wrapper show' + ( pos ? ( ' ' + pos ) : '' );
$w.replaceWith( '<div class="' + cls + '">' + html + '</div>' );
}
function wkClearLocalHoverWrapper( $el ) {
var $w = $el.find( '.hover-wrapper' ).first();
if ( $w.length ) {
$w.replaceWith( '<div class="hover-wrapper"></div>' );
}
}
function wkHoverQueryKey( el, $el ) {
var ds = el && el.dataset ? el.dataset : null;
var template = ( ds && ds.template ) ? ds.template : $el.data( 'template' );
var p1 = ( ds && ds.parameter1 ) ? ds.parameter1 : $el.data( 'parameter1' );
var p2 = ( ds && ds.parameter2 ) ? ds.parameter2 : $el.data( 'parameter2' );
var p3 = ( ds && ds.parameter3 ) ? ds.parameter3 : $el.data( 'parameter3' );
var pos = ( ds && ds.position ) ? ds.position : ( $el.data( 'position' ) || 'bottom' );
return String( template || '' ) + '|' + String( p1 || '' ) + '|' + String( p2 || '' ) + '|' + String( p3 || '' ) + '|' + String( pos || '' );
}
function hoverContentCall() {
if ( !wkOnce( 'wkHoverInit' ) ) return;
function wkGetHoverTypeAndTpl( $wrap ) {
if ( $wrap.hasClass( 'hover-map' ) ) {
return { type: 'map', template: WK_T.hoverMap };
}
if ( $wrap.hasClass( 'hover-wikipedia' ) ) {
return { type: 'wikipedia', template: WK_T.hoverWP };
}
return null;
}
function wkEnsureLocalHoverWrapper( $wrap ) {
var $w = $wrap.find( '.hover-wrapper' );
if ( !$w.length ) {
$w = $( '<div class="hover-wrapper" aria-hidden="true"></div>' );
$wrap.append( $w );
}
return $w;
}
function wkGetLinkNode( $wrap ) {
var $a = $wrap.find( 'a' ).first();
return $a.length ? $a : null;
}
function wkDecodeWikiTitleFromHref( href ) {
if ( !href ) return '';
try {
var m = href.match( /\/wiki\/([^#?]+)/ );
if ( !m || !m[ 1 ] ) return '';
var t = m[ 1 ].replace( /_/g, ' ' );
return decodeURIComponent( t );
} catch ( e ) {}
return '';
}
function wkGetParamForMap( $a ) {
var t = ( $a.attr( 'title' ) || '' ).trim();
if ( t ) return t;
var href = $a.attr( 'href' ) || '';
return wkDecodeWikiTitleFromHref( href );
}
function wkGetParamForWikipedia( $a ) {
var href = $a.attr( 'href' ) || '';
if ( !href ) return '';
try {
var m = href.match( /\/\/[^/]+\/wiki\/([^#?]+)/ );
if ( m && m[ 1 ] ) {
var t = m[ 1 ].replace( /_/g, ' ' );
return decodeURIComponent( t );
}
} catch ( e ) {}
return ( $a.text() || '' ).replace( /\s+/g, ' ' ).trim();
}
function wkBuildHoverQuery( info, el, $wrap, $a ) {
// Retourne { query, key } ou null
if ( !info || !info.template ) return null;
var ds = ( el && el.dataset ) ? el.dataset : null;
if ( info.type === 'wikipedia' ) {
var p1 = wkGetParamForWikipedia( $a );
if ( !p1 ) return null;
return {
query: WK_OPEN + info.template + WK_SEP + p1 + WK_SEP + WK_SEP + WK_CLOSE,
key: 'wikipedia|' + p1
};
}
// map
var p1m = wkGetParamForMap( $a );
if ( !p1m ) return null;
var p2 = '';
var p3 = '';
// Priorité : data-debate
if ( ds && ds.debate ) {
p2 = ds.debate;
p3 = 'debate';
} else if ( ds && ds.argument ) {
p2 = ds.argument;
}
return {
query: WK_OPEN + info.template + WK_SEP + p1m + WK_SEP + ( p2 || '' ) + WK_SEP + ( p3 || '' ) + WK_CLOSE,
key: 'map|' + p1m + '|' + ( p2 || '' ) + '|' + ( p3 || '' )
};
}
$D.on( 'mouseenter.wkHover', '.hover-map, .hover-wikipedia', function () {
var el = this;
var $wrap = $( el );
wkHoverCurrent = $wrap;
if ( wkHoverTimer ) clearTimeout( wkHoverTimer );
var myToken = ++wkHoverToken;
wkHoverTimer = setTimeout( function () {
wkHoverTimer = 0;
if ( myToken !== wkHoverToken ) return;
if ( !wkHoverCurrent || wkHoverCurrent[ 0 ] !== el ) return;
if ( $wrap.is( ':hidden' ) ) return;
if ( el && el.offsetParent === null ) return;
try {
var r = el.getBoundingClientRect();
var vh = W.innerHeight || D.documentElement.clientHeight || 0;
if ( r.bottom < 0 || r.top > vh ) return;
} catch ( e ) {}
var info = wkGetHoverTypeAndTpl( $wrap );
if ( !info || !info.template ) return;
var $a = wkGetLinkNode( $wrap );
if ( !$a ) return;
var built = wkBuildHoverQuery( info, el, $wrap, $a );
if ( !built || !built.query || !built.key ) return;
var $local = wkEnsureLocalHoverWrapper( $wrap );
$local.attr( 'aria-hidden', 'false' ).show();
// Cache
var stored = wkHoverStore ? wkHoverStore.get( el ) : null;
if ( stored && stored.key === built.key && stored.html ) {
$local.html( stored.html );
return;
}
// Pas de texte d’attente
$local.empty();
wkParseWikitext( built.query, 'hover' ).then( function ( html ) {
if ( myToken !== wkHoverToken ) return;
if ( !wkHoverCurrent || wkHoverCurrent[ 0 ] !== el ) return;
if ( wkHoverStore ) wkHoverStore.set( el, { key: built.key, html: html } );
$local.html( html );
} ).catch( function () {} );
}, 140 );
} );
$D.on( 'mouseleave.wkHover', '.hover-map, .hover-wikipedia', function () {
var el = this;
var $wrap = $( el );
if ( wkHoverTimer ) clearTimeout( wkHoverTimer );
wkHoverTimer = 0;
wkHoverToken++;
try {
var info = wkGetHoverTypeAndTpl( $wrap );
var $a = wkGetLinkNode( $wrap );
if ( info && $a && info.template ) {
var built = wkBuildHoverQuery( info, el, $wrap, $a );
if ( built && built.query ) {
wkParseCancel( 'hover', built.query );
}
}
} catch ( e ) {}
var $local = $wrap.find( '.hover-wrapper' );
if ( $local.length ) {
$local.attr( 'aria-hidden', 'true' ).hide().empty();
}
} );
}
/* ==========================================================
FIL D'ARIANE — observer robuste + fallback scroll si pas IO
========================================================== */
var filArianeObserver = null;
var filArianeLock = false;
var wkObservedSentinel = null;
var wkObserverRaf = 0;
var wkFallbackBound = false;
var wkFallbackRecompute = null;
function installOrUpdateObserver() {
var sentinel = getOrCreateLeftNavSentinel();
if ( !sentinel ) return;
var needReinstall = false;
if ( wkObservedSentinel !== sentinel ) needReinstall = true;
wkObservedSentinel = sentinel;
if ( !( 'IntersectionObserver' in W ) ) {
wkBindFallbackObserverOnce();
applyFilArianeVisibilityNow( 0, sentinel );
return;
}
if ( filArianeObserver && !needReinstall ) {
applyFilArianeVisibilityNow( 0, sentinel );
return;
}
if ( filArianeObserver ) {
try { filArianeObserver.disconnect(); } catch ( e ) {}
}
filArianeObserver = new IntersectionObserver( function ( entries ) {
var entry = entries[ 0 ];
if ( entry && entry.isIntersecting ) hideFilAriane();
else showFilAriane();
}, {
root: null,
rootMargin: '0px 0px 0px 0px',
threshold: 0
} );
filArianeObserver.observe( sentinel );
applyFilArianeVisibilityNow( 0, sentinel );
}
var installOrUpdateObserverRaf = wkRafThrottle( installOrUpdateObserver );
function pauseFilArianeObserver() {
if ( filArianeObserver ) {
try { filArianeObserver.disconnect(); } catch ( e ) {}
}
filArianeObserver = null;
wkObservedSentinel = null;
}
function resumeFilArianeObserver() {
installOrUpdateObserver();
}
function showFilAriane() {
if ( filArianeLock ) return;
var fil = D.getElementById( 'fil-ariane' );
if ( !fil ) return;
fil.classList.add( 'is-visible' );
fil.classList.remove( 'is-hidden' );
fil.setAttribute( 'aria-hidden', 'false' );
}
function hideFilAriane() {
if ( filArianeLock ) return;
var fil = D.getElementById( 'fil-ariane' );
if ( !fil ) return;
fil.classList.add( 'is-hidden' );
fil.classList.remove( 'is-visible' );
fil.setAttribute( 'aria-hidden', 'true' );
}
function measureFilArianeHeight() {
var fil = D.getElementById( 'fil-ariane' );
if ( !fil ) return 0;
if ( fil.classList.contains( 'is-visible' ) ) return fil.offsetHeight || 0;
var hadVisible = fil.classList.contains( 'is-visible' );
var hadHidden = fil.classList.contains( 'is-hidden' );
fil.classList.add( 'is-visible' );
fil.classList.remove( 'is-hidden' );
var h = fil.offsetHeight || 0;
if ( !hadVisible ) fil.classList.remove( 'is-visible' );
if ( hadHidden ) fil.classList.add( 'is-hidden' );
return h;
}
function getOrCreateLeftNavSentinel() {
var leftNav = D.querySelector( '#left-navigation' );
if ( !leftNav ) return null;
var next = leftNav.nextElementSibling;
if ( next && next.id === 'fil-ariane-sentinel' ) return next;
var sent = D.createElement( 'div' );
sent.id = 'fil-ariane-sentinel';
sent.setAttribute( 'aria-hidden', 'true' );
sent.style.cssText = 'position:relative;height:1px;pointer-events:none;';
leftNav.parentNode.insertBefore( sent, leftNav.nextSibling );
return sent;
}
function applyFilArianeVisibilityNow( headerOffset, sentinel ) {
if ( !sentinel ) return;
var rect = sentinel.getBoundingClientRect();
if ( rect.top >= headerOffset ) hideFilAriane();
else showFilAriane();
}
function wkBindFallbackObserverOnce() {
if ( wkFallbackBound ) return;
wkFallbackBound = true;
wkFallbackRecompute = wkRafThrottle( function () {
var sentinel = D.getElementById( 'fil-ariane-sentinel' ) || getOrCreateLeftNavSentinel();
if ( !sentinel ) return;
applyFilArianeVisibilityNow( 0, sentinel );
} );
W.addEventListener( 'scroll', wkFallbackRecompute, { passive: true } );
W.addEventListener( 'resize', wkFallbackRecompute, { passive: true } );
if ( W.visualViewport ) {
visualViewport.addEventListener( 'resize', wkFallbackRecompute, { passive: true } );
visualViewport.addEventListener( 'scroll', wkFallbackRecompute, { passive: true } );
}
}
function wkHtmlSig( html ) {
var s = String( html || '' );
var len = s.length;
var c0 = len ? s.charCodeAt( 0 ) : 0;
var c1 = len ? s.charCodeAt( len - 1 ) : 0;
var c2 = len ? s.charCodeAt( ( len / 2 ) | 0 ) : 0;
var c3 = len ? s.charCodeAt( ( len / 4 ) | 0 ) : 0;
var c4 = len ? s.charCodeAt( ( ( len * 3 ) / 4 ) | 0 ) : 0;
var limit = Math.min( 200, len );
var h = 2166136261;
for ( var i = 0; i < limit; i++ ) {
h ^= s.charCodeAt( i );
h = ( h + ( h << 1 ) + ( h << 4 ) + ( h << 7 ) + ( h << 8 ) + ( h << 24 ) ) >>> 0;
}
return len + '|' + c0 + '|' + c1 + '|' + c2 + '|' + c3 + '|' + c4 + '|' + h;
}
function wkGetOrCreateBreadcrumbNav() {
var fil = D.getElementById( 'fil-ariane' );
if ( fil ) return fil;
var nav = D.createElement( 'nav' );
nav.id = 'fil-ariane';
nav.className = 'zone-ariane fil-ariane--sticky is-hidden';
nav.setAttribute( 'role', 'navigation' );
nav.setAttribute( 'aria-label', wkMsg( 'wk-breadcrumb-aria-label' ) );
nav.setAttribute( 'aria-hidden', 'true' );
var main = D.querySelector( 'main#content.mw-body' ) || D.querySelector( '#content, .mw-body' );
if ( !main ) return null;
var anchor = main.querySelector( '.mw-body-header.vector-page-titlebar' );
if ( anchor && anchor.parentNode ) {
anchor.parentNode.insertBefore( nav, anchor );
} else {
main.insertBefore( nav, main.firstChild );
}
return nav;
}
function wkSetNavInnerHtml( nav, html ) {
if ( !nav ) return;
var prevVisible = nav.classList.contains( 'is-visible' );
var prevHidden = nav.classList.contains( 'is-hidden' );
var prevNoAnim = nav.classList.contains( 'no-anim' );
var prevAria = nav.getAttribute( 'aria-hidden' );
var tmp = D.createElement( 'div' );
tmp.innerHTML = html;
while ( nav.firstChild ) nav.removeChild( nav.firstChild );
while ( tmp.firstChild ) nav.appendChild( tmp.firstChild );
if ( prevVisible ) nav.classList.add( 'is-visible' ); else nav.classList.remove( 'is-visible' );
if ( prevHidden ) nav.classList.add( 'is-hidden' ); else nav.classList.remove( 'is-hidden' );
if ( prevNoAnim ) nav.classList.add( 'no-anim' ); else nav.classList.remove( 'no-anim' );
if ( prevAria !== null ) nav.setAttribute( 'aria-hidden', prevAria );
}
function injectFilAriane( html, meta ) {
var nav = wkGetOrCreateBreadcrumbNav();
if ( !nav ) return;
if ( meta && meta.currentKey ) nav.setAttribute( 'data-current-key', meta.currentKey );
if ( meta && meta.currentPath ) nav.setAttribute( 'data-current-path', meta.currentPath );
if ( meta && meta.currentPage ) nav.setAttribute( 'data-current-page', meta.currentPage );
var lastSig = nav.getAttribute( 'data-wk-html-sig' ) || '';
var sig = wkHtmlSig( html );
if ( lastSig !== sig ) {
nav.setAttribute( 'data-wk-html-sig', sig );
wkSetNavInnerHtml( nav, html );
}
installOrUpdateObserverRaf();
}
( function () {
var _pendingKey = null;
function normalizePath( path ) {
if ( typeof path !== 'string' ) return '';
var s = path.replace( /\+/g, ' ' );
try { s = decodeURIComponent( s ); } catch ( e ) {}
return s.replace( /\s+/g, ' ' ).trim().toLowerCase();
}
W.breadcrumbGeneration = function breadcrumbGeneration( titleElement ) {
if ( typeof titleElement === 'undefined' || !titleElement ) return;
if ( titleElement.jquery && titleElement.length ) titleElement = titleElement[ 0 ];
wkWarmI18nCaches();
var wrap = titleElement.nextElementSibling;
if ( !wrap || !wrap.classList || !wrap.classList.contains( 'argument-wrapper' ) ) {
// si jamais le wrapper n'existe pas encore, on laisse tomber proprement
return;
}
var ds = wrap.dataset || null;
var rawPath = ( ds && ds.path ) ? ds.path : '';
var page = ( ds && ds.page ) ? ds.page : '';
if ( !rawPath ) {
var fil = D.getElementById( 'fil-ariane' );
if ( fil && fil.parentNode ) fil.parentNode.removeChild( fil );
return;
}
var normPath = normalizePath( String( rawPath ) );
var normPage = String( page || '' );
var newKey = normPath + '||' + normPage;
var filNow = D.getElementById( 'fil-ariane' );
var currentKey = filNow ? ( filNow.getAttribute( 'data-current-key' ) || '' ) : '';
if ( currentKey === newKey ) return;
_pendingKey = newKey;
var query = WK_OPEN + WK_T.breadcrumbMenu +
WK_SEP + WK_P.path + ' = ' + rawPath +
WK_SEP + WK_P.page + ' = ' + page +
WK_CLOSE;
wkParseWikitext( query, 'bc' ).then( function ( html ) {
if ( _pendingKey !== newKey ) return;
injectFilAriane( html, {
currentKey: newKey,
currentPath: normPath,
currentPage: normPage
} );
} ).catch( function () {} );
};
} )();
var wkBreadcrumbScrollTimer = 0;
function breadcrumbMenu( titleElement, opts ) {
opts = opts || {};
if ( typeof titleElement === 'undefined' || !titleElement ) return;
if ( titleElement.jquery && titleElement.length ) titleElement = titleElement[ 0 ];
if ( typeof W.breadcrumbGeneration === 'function' ) {
W.breadcrumbGeneration( titleElement );
}
var recompute = wkRafThrottle( function () {
installOrUpdateObserverRaf();
} );
function scrollToTitle() {
var $el = $( titleElement );
if ( !$el.length ) return;
var fil = D.getElementById( 'fil-ariane' );
if ( !fil ) { setTimeout( scrollToTitle, 100 ); return; }
var headerOffset = 0;
var safeGap = 12;
var forceShow = !!opts.fromMapClick;
if ( forceShow ) showFilAriane();
var sentinel = D.querySelector( '#fil-ariane-sentinel' ) || getOrCreateLeftNavSentinel();
var willShowFil = true;
if ( sentinel ) {
var rect = sentinel.getBoundingClientRect();
willShowFil = ( rect.top <= headerOffset );
}
var filH = willShowFil ? ( measureFilArianeHeight() || 0 ) : 0;
if ( forceShow ) { willShowFil = true; filH = measureFilArianeHeight() || 0; }
var offset = headerOffset + filH + safeGap;
var targetY = $el.offset().top - offset;
targetY = Math.max( 0, targetY );
filArianeLock = true;
pauseFilArianeObserver();
fil.classList.add( 'no-anim' );
$( 'html, body' ).stop( true, false ).animate( { scrollTop: targetY }, 120, function () {
fil.classList.remove( 'no-anim' );
filArianeLock = false;
requestAnimationFrame( function () {
resumeFilArianeObserver();
} );
} );
}
if ( wkOnce( 'wkBreadcrumbListeners' ) ) {
W.addEventListener( 'resize', recompute, { passive: true } );
if ( W.visualViewport ) {
visualViewport.addEventListener( 'resize', recompute, { passive: true } );
visualViewport.addEventListener( 'scroll', recompute, { passive: true } );
}
}
recompute();
if ( wkBreadcrumbScrollTimer ) clearTimeout( wkBreadcrumbScrollTimer );
wkBreadcrumbScrollTimer = setTimeout( function () {
wkBreadcrumbScrollTimer = 0;
scrollToTitle();
}, 150 );
}
/* ==========================================================
Handlers Fil d’Ariane + TOC en GLOBAL (document)
========================================================== */
function wkIsVectorStickyEnabled() {
var root = D.documentElement;
return !!( root && root.classList && root.classList.contains( 'vector-sticky-header-enabled' ) );
}
function wkHideVectorStickyHeader() {
if ( !wkIsVectorStickyEnabled() ) return;
D.documentElement.classList.add( 'wk-hide-vector-sticky' );
}
function wkShowVectorStickyHeader() {
D.documentElement.classList.remove( 'wk-hide-vector-sticky' );
}
function wkBindBreadcrumbHandlers() {
if ( !wkOnce( 'wkBreadcrumbHandlersInit' ) ) return;
$D.on( 'click.wkBreadcrumbLink', '#fil-ariane .lien-ariane', function () {
var ds = this.dataset || null;
var titleId = ( ds && ds.anchor ) ? ds.anchor : $( this ).data( 'anchor' );
var targetEl = titleId ? D.getElementById( titleId ) : null;
if ( !targetEl ) return;
var level = ( ds && ds.level ) ? parseInt( ds.level, 10 ) : parseInt( $( this ).data( 'level' ), 10 );
level = isNaN( level ) ? 0 : level;
// Fermer tous les arguments enfants ouverts sous cet argument
var wrap = targetEl.nextElementSibling;
if ( wrap && wrap.classList && wrap.classList.contains( 'argument-wrapper' ) ) {
var opened = wrap.querySelectorAll( '.argument-title.is-expanded' );
for ( var i = 0; i < opened.length; i++ ) {
wkCollapseTitleEl( opened[ i ] );
}
}
var parentElement = $( targetEl ).closest( '.argument' );
var inlineElement = parentElement.find( '.colonnes.inline' );
inlineElement.removeClass( 'inline' );
if ( !parentElement.length ) $( '.colonnes' ).removeClass( 'inline' );
breadcrumbMenu( targetEl );
} );
$D.on( 'click.wkBreadcrumbDelete', '.supprimer-ariane', function ( e ) {
e.preventDefault();
var fil = D.getElementById( 'fil-ariane' );
if ( fil && fil.parentNode ) fil.parentNode.removeChild( fil );
wkShowVectorStickyHeader();
} );
}
function wkBindTocRemoveBreadcrumb() {
if ( !wkOnce( 'wkTocRemoveBreadcrumbInit' ) ) return;
$D.on( 'click.wkTocRemoveBreadcrumb', '#mw-panel-toc .vector-toc-list-item', function () {
var fil = D.getElementById( 'fil-ariane' );
if ( fil && fil.parentNode ) fil.parentNode.removeChild( fil );
} );
}
/* ==========================================================
ARGUMENTS — Set des éléments expanded (évite gros scans)
+ TokenMap + Abort (schéma Minerva) — SAFE
========================================================== */
var wkExpandedSet = ( typeof Set !== 'undefined' ) ? new Set() : null;
function wkExpandedAdd( el ) {
if ( !wkExpandedSet || !el ) return;
wkExpandedSet.add( el );
}
function wkExpandedDel( el ) {
if ( !wkExpandedSet || !el ) return;
wkExpandedSet.delete( el );
}
function wkExpandedForEach( fn ) {
if ( !wkExpandedSet ) return;
wkExpandedSet.forEach( function ( el ) {
if ( !el || !D.documentElement.contains( el ) ) {
wkExpandedSet.delete( el );
return;
}
fn( el );
} );
}
/* Token/abort par wrapper (comme Minerva) */
var wkArgTokenByWrapper = new WeakMap();
var wkArgXhrByWrapper = new WeakMap();
/* Meta calculée (params modèle) par titre d’argument */
var wkArgMetaStore = ( typeof WeakMap !== 'undefined' ) ? new WeakMap() : null;
function wkAbortWrapperXhr( wrapperEl, xhrMap ) {
if ( !wrapperEl || !xhrMap ) return;
var prev = xhrMap.get( wrapperEl );
if ( prev && typeof prev.abort === 'function' ) {
try { prev.abort(); } catch ( e ) {}
}
xhrMap.delete( wrapperEl );
}
function wkBumpWrapperToken( wrapperEl, tokenMap, xhrMap ) {
if ( !wrapperEl || !tokenMap ) return 0;
var tok = ( tokenMap.get( wrapperEl ) || 0 ) + 1;
tokenMap.set( wrapperEl, tok );
if ( xhrMap ) wkAbortWrapperXhr( wrapperEl, xhrMap );
return tok;
}
function wkParseWikitextAbortable( wikitext, bucket, wrapperEl, tokenMap, xhrMap ) {
var myTok = 0;
if ( wrapperEl && tokenMap ) {
myTok = wkBumpWrapperToken( wrapperEl, tokenMap, xhrMap );
}
var p = wkParseWikitext( wikitext, bucket );
/* NOTE: mw.Api().post retourne jqXHR, mais ici on est dans un pool -> pas d’abort natif
=> “safe”: tokenMap suffit pour ignorer les réponses tardives.
(Si tu veux abort réel, il faut une branche “direct xhr” comme Minerva.)
*/
return { token: myTok, promise: p };
}
function wkCollapseTitleEl( el ) {
if ( !el ) return;
var $t = $( el );
$t.removeClass( 'is-expanded' ).addClass( 'visited' );
var $w = $t.next( '.argument-wrapper' );
if ( $w.length ) {
var wEl = $w.get( 0 );
wkBumpWrapperToken( wEl, wkArgTokenByWrapper, wkArgXhrByWrapper );
$w.empty();
}
wkExpandedDel( el );
}
function wkDsGetAny( el, key, $el ) {
if ( el && el.dataset && typeof el.dataset[ key ] !== 'undefined' && el.dataset[ key ] !== '' ) {
return el.dataset[ key ];
}
if ( $el && $el.length ) {
var v = $el.data( key );
if ( typeof v !== 'undefined' && v !== null && String( v ) !== '' ) return v;
}
return '';
}
function wkEncodePlus( s ) {
if ( !s ) return '';
try {
return encodeURIComponent( s ).replace( /%20/g, '+' );
} catch ( e ) {}
return '';
}
function wkGetDebateTitleFromHeading() {
var el = D.querySelector( '#firstHeading .mw-page-title-main' ) || D.querySelector( '#firstHeading' );
if ( !el ) return '';
return ( el.textContent || '' ).replace( /\s+/g, ' ' ).trim();
}
function wkGetDebateBaseForPath() {
var t = wkGetDebateTitleFromHeading();
if ( !t ) {
try { t = mw.config.get( 'wgTitle' ) || ''; } catch ( e ) { t = ''; }
}
return wkEncodePlus( t );
}
function wkGetArgumentTitleFromNode( titleEl ) {
if ( !titleEl ) return '';
var a = titleEl.querySelector( 'a' );
if ( !a ) return '';
return ( a.textContent || '' )
.replace( /\s+/g, ' ' )
.trim();
}
function wkEnsureArgWrapperAfterTitle( titleEl ) {
if ( !titleEl ) return null;
var next = titleEl.nextElementSibling;
if ( next && next.classList && next.classList.contains( 'argument-wrapper' ) ) return next;
var w = D.createElement( 'div' );
w.className = 'argument-wrapper';
titleEl.insertAdjacentElement( 'afterend', w );
return w;
}
$D.on( 'click.wkArgTitleLink', '.argument-title > a', function ( e ) {
// Laisser passer les intentions de navigation (nouvel onglet, etc.)
if ( e.ctrlKey || e.metaKey || e.shiftKey || e.altKey || e.button === 1 ) return;
// Empêche la navigation, mais laisse le clic remonter vers .argument-title (ouverture)
e.preventDefault();
} );
/* ==========================================================
MODE LECTURE — pile sticky + contenu injecté dans #bodyContent
========================================================== */
var WK_READING = {
enabled: true,
state: {
chain: [] // [{ page, title, type }]
returnTo: null // { titleId, scrollY }
}
};
var WK_READING_UI = {
rootId: 'wk-reading-mode',
stackId: 'wk-reading-stack',
contentId: 'wk-reading-content',
closeId: 'wk-reading-close',
startId: 'wk-reading-sentinel-start',
endId: 'wk-reading-sentinel-end'
};
function wkReadingEnsureCss() {
if ( D.getElementById( 'wk-reading-css' ) ) return;
var css = [
'#' + WK_READING_UI.rootId + '{',
' box-sizing:border-box;',
' max-width:100%;',
' margin:0 0 12px 0;',
'}',
'#' + WK_READING_UI.stackId + '{',
' position:sticky;',
' top: var(--wk-reading-top, 0px);',
' z-index:50;',
' margin:0 0 10px 0;',
'}',
'.wk-reading__item{',
' position:static;',
' margin:0 0 8px 0;',
' max-width:100%;',
' box-sizing:border-box;',
'}',
'.wk-reading__inner{',
' background:#fff;',
' border:1px solid #c8ccd1;',
' border-radius:10px;',
' box-shadow:0 2px 10px rgba(0,0,0,.10);',
' padding:10px 12px;',
' box-sizing:border-box;',
' max-width:100%;',
'}',
'.wk-reading__item.is-pro .wk-reading__inner{',
' border-left:4px solid #14866d;',
'}',
'.wk-reading__item.is-con .wk-reading__inner{',
' border-left:4px solid #b32424;',
'}',
'.wk-reading__meta{',
' font-size:12px;',
' color:#54595d;',
' margin:0 0 4px 0;',
'}',
'.wk-reading__title{',
' font-weight:600;',
' line-height:1.35;',
' word-break:break-word;',
'}',
'#' + WK_READING_UI.closeId + '{',
' display:inline-block;',
' margin:0 0 8px 0;',
' cursor:pointer;',
' color:#3366cc;',
'}',
'#' + WK_READING_UI.contentId + '{',
' box-sizing:border-box;',
' max-width:100%;',
'}'
].join( '\n' );
var style = D.createElement( 'style' );
style.id = 'wk-reading-css';
style.textContent = css;
D.head.appendChild( style );
}
function wkReadingEnsureUiIn( parentEl ) {
wkReadingEnsureCss();
if ( !parentEl || !parentEl.appendChild ) return null;
var root = D.getElementById( WK_READING_UI.rootId );
if ( !root ) {
root = D.createElement( 'div' );
root.id = WK_READING_UI.rootId;
var close = D.createElement( 'div' );
close.id = WK_READING_UI.closeId;
close.textContent = '← ' + wkMsg( 'wk-reading-back' );
var stack = D.createElement( 'div' );
stack.id = WK_READING_UI.stackId;
var start = D.createElement( 'div' );
start.id = WK_READING_UI.startId;
start.setAttribute( 'aria-hidden', 'true' );
var end = D.createElement( 'div' );
end.id = WK_READING_UI.endId;
end.setAttribute( 'aria-hidden', 'true' );
var content = D.createElement( 'div' );
content.id = WK_READING_UI.contentId;
content.className = 'mw-parser-output';
root.appendChild( close );
root.appendChild( stack );
root.appendChild( start );
root.appendChild( content );
root.appendChild( end );
}
// ✅ Injection AU BON ENDROIT : sous l’argument cliqué (appendChild déplace si déjà existant)
if ( root.parentNode !== parentEl ) {
parentEl.appendChild( root );
}
return {
root: root,
stack: D.getElementById( WK_READING_UI.stackId ),
content: D.getElementById( WK_READING_UI.contentId )
};
}
function wkReadingIsClickInsideReading( target ) {
if ( !target ) return false;
var root = D.getElementById( WK_READING_UI.rootId );
return !!( root && root.contains( target ) );
}
function wkReadingGetTypeFromTitleEl( titleEl ) {
var ul = titleEl ? titleEl.closest( 'ul.argument-list' ) : null;
if ( !ul ) return '';
return ul.classList.contains( 'is-con' ) ? 'contre' : 'pour';
}
function wkReadingBuildChainFromDom( titleEl ) {
// Chaîne basée sur les wrappers réellement présents (donc uniquement la descendance ouverte)
var chain = [];
var curTitle = titleEl;
while ( curTitle ) {
var page = wkReadingGetArgPageFromTitleEl( curTitle );
var title = wkGetArgumentTitleFromNode( curTitle ) || ( curTitle.textContent || '' ).trim();
var type = wkReadingGetTypeFromTitleEl( curTitle );
chain.push( { page: page, title: title, type: type } );
var parentWrap = null;
// parent = wrapper qui contient la UL courante
var ul = curTitle.closest( 'ul.argument-list' );
parentWrap = ul ? ul.closest( '.argument-wrapper' ) : null;
// parent title = previousElementSibling du wrapper parent (si présent)
if ( parentWrap ) {
var prev = parentWrap.previousElementSibling;
if ( prev && prev.classList && prev.classList.contains( 'argument-title' ) ) {
curTitle = prev;
continue;
}
}
break;
}
chain.reverse();
return chain;
}
function wkReadingGetArgPageFromTitleEl( titleEl ) {
var a = titleEl ? titleEl.querySelector( 'a[href]' ) : null;
if ( !a ) return '';
var href = a.getAttribute( 'href' ) || '';
if ( !href ) return '';
return hrefToPageTitle( href );
}
function wkReadingSetTopOffset() {
var root = D.getElementById( WK_READING_UI.rootId );
if ( !root ) return;
// Si le sticky header Vector est masqué → top = 0
if ( D.documentElement.classList.contains( 'wk-hide-vector-sticky' ) ) {
root.style.setProperty( '--wk-reading-top', '0px' );
return;
}
// Hauteur du header sticky Vector (si présent)
var vh = D.querySelector( '.vector-sticky-header' );
var h = vh ? ( vh.getBoundingClientRect().height || 0 ) : 0;
root.style.setProperty( '--wk-reading-top', Math.round( h ) + 'px' );
}
function wkReadingRenderStack( ui, chain ) {
ui.stack.textContent = '';
for ( var i = 0; i < chain.length; i++ ) {
var it = chain[ i ];
var item = D.createElement( 'div' );
item.className = 'wk-reading__item';
if ( it.type === 'contre' ) item.classList.add( 'is-con' );
else item.classList.add( 'is-pro' );
item.dataset.page = it.page || '';
var inner = D.createElement( 'div' );
inner.className = 'wk-reading__inner';
var meta = D.createElement( 'div' );
meta.className = 'wk-reading__meta';
meta.textContent = 'Niveau ' + ( i + 1 );
var title = D.createElement( 'div' );
title.className = 'wk-reading__title';
title.textContent = it.title || '';
inner.appendChild( meta );
inner.appendChild( title );
item.appendChild( inner );
// Clic sur une carte => ouvrir ce niveau (recharge contenu)
( function ( page ) {
item.addEventListener( 'click', function () {
if ( !page ) return;
wkOpenReadingModeFromPageTitle( page, chain.slice( 0, i + 1 ) );
} );
} )( it.page );
ui.stack.appendChild( item );
}
wkReadingUpdateStickyOffsets( ui );
wkReadingSetTopOffset();
}
function wkReadingUpdateStickyOffsets( ui ) {
var top = 0;
var gap = 8;
var items = ui.stack.querySelectorAll( '.wk-reading__item' );
for ( var i = 0; i < items.length; i++ ) {
items[ i ].style.top = top + 'px';
top += ( items[ i ].offsetHeight || 0 ) + gap;
}
}
var wkReadingExitBound = false;
function wkReadingBindExitOnScroll( ui ) {
if ( wkReadingExitBound ) return;
wkReadingExitBound = true;
var onScroll = wkRafThrottle( function () {
var root = D.getElementById( WK_READING_UI.rootId );
if ( !root ) return;
var start = D.getElementById( WK_READING_UI.startId );
var end = D.getElementById( WK_READING_UI.endId );
if ( !start || !end ) return;
var vh = W.innerHeight || D.documentElement.clientHeight || 0;
var rr = root.getBoundingClientRect();
// ✅ Si tout le bloc "mode lecture" est sorti du viewport (en haut OU en bas) => on ferme
if ( rr.bottom < 0 || rr.top > vh ) {
wkCloseReadingMode();
return;
}
// Dépassé par le bas : la sentinelle du bas est passée au-dessus du viewport
if ( re.bottom < 0 ) {
wkCloseReadingMode();
return;
}
} );
W.addEventListener( 'scroll', onScroll, { passive: true } );
W.addEventListener( 'resize', onScroll, { passive: true } );
if ( W.visualViewport ) {
visualViewport.addEventListener( 'scroll', onScroll, { passive: true } );
visualViewport.addEventListener( 'resize', onScroll, { passive: true } );
}
}
function wkReadingExtractFragment( html ) {
// Réutilise ton extraction Summary → Parent_debates
function wkFindHeadingStartById( html2, id ) {
var key = 'id="' + id + '"';
var p = html2.indexOf( key );
if ( p === -1 ) return -1;
return html2.lastIndexOf( '<h2', p );
}
function wkExtractBetweenHeadingIds( html2, startId, endId ) {
var a = wkFindHeadingStartById( html2, startId );
if ( a === -1 ) return '';
var key = 'id="' + endId + '"';
var p = html2.indexOf( key, a + 1 );
if ( p === -1 ) return '';
var b = html2.lastIndexOf( '<h2', p );
if ( b === -1 ) b = html2.lastIndexOf( '<div', p );
if ( b === -1 || b <= a ) return '';
return html2.slice( a, b );
}
return wkExtractBetweenHeadingIds( html, 'Summary', 'Parent_debates' );
}
function wkOpenReadingModeFromPageTitle( argPage, chainOpt, ui ) {
if ( !WK_READING.enabled ) return;
if ( !ui ) return;
// Remplacer la chaîne (si fournie)
if ( chainOpt && chainOpt.length ) {
WK_READING.state.chain = chainOpt.slice();
}
// Cacher le fil d’ariane “linéaire” si présent (optionnel)
var fil = D.getElementById( 'fil-ariane' );
if ( fil ) fil.style.display = 'none';
ui.content.innerHTML = '<p>' + wkMsg( 'wk-loading' ) + '</p>';
// Cache fragment
if ( wkArgEmbedCache.has( argPage ) ) {
var cached = wkArgEmbedCache.get( argPage ) || '';
if ( cached ) {
ui.content.innerHTML = cached;
wkOnContent( ui.content );
wkReadingUpdateStickyOffsets( ui );
wkReadingSetTopOffset();
}
return;
}
wkGetApi().get( {
action: 'parse',
formatversion: 2,
page: argPage,
prop: 'text',
disableeditsection: 1,
redirects: 1
} ).then( function ( data ) {
var html = ( data && data.parse && data.parse.text ) ? data.parse.text : '';
if ( !html ) return;
var fragment = wkReadingExtractFragment( html );
if ( !fragment ) return;
wkArgEmbedCache.set( argPage, fragment );
ui.content.innerHTML = fragment;
wkOnContent( ui.content );
wkReadingUpdateStickyOffsets( ui );
wkReadingSetTopOffset();
} ).catch( function () {} );
}
function wkOpenReadingModeFromTitleEl( titleEl ) {
if ( !titleEl ) return;
if ( !WK_READING.enabled ) return;
// ✅ Point de retour
WK_READING.state.returnTo = {
titleId: titleEl.id || '',
scrollY: W.pageYOffset || D.documentElement.scrollTop || 0
};
var argPage = wkReadingGetArgPageFromTitleEl( titleEl );
if ( !argPage ) return;
// ✅ Wrapper de l’argument cliqué (c’est LA cible d’injection)
var wrapperEl = wkEnsureArgWrapperAfterTitle( titleEl );
if ( !wrapperEl ) return;
// ✅ Créer / déplacer l’UI DANS ce wrapper
var ui = wkReadingEnsureUiIn( wrapperEl );
if ( !ui ) return;
wkReadingBindExitOnScroll( ui );
// Chaîne : clic depuis le mode lecture => on append
if ( wkReadingIsClickInsideReading( titleEl ) && WK_READING.state.chain.length ) {
var next = {
page: argPage,
title: wkGetArgumentTitleFromNode( titleEl ) || ( titleEl.textContent || '' ).trim(),
type: wkReadingGetTypeFromTitleEl( titleEl )
};
var chain2 = WK_READING.state.chain.slice();
chain2.push( next );
WK_READING.state.chain = chain2;
wkReadingRenderStack( ui, chain2 );
wkOpenReadingModeFromPageTitle( argPage, chain2, ui );
return;
}
// Sinon : reconstruire depuis le DOM (descendance ouverte)
var chain = wkReadingBuildChainFromDom( titleEl );
WK_READING.state.chain = chain;
wkReadingRenderStack( ui, chain );
wkOpenReadingModeFromPageTitle( argPage, chain, ui );
}
function wkCloseReadingMode() {
var ret = WK_READING.state.returnTo;
var root = D.getElementById( WK_READING_UI.rootId );
if ( root ) root.parentNode.removeChild( root );
var fil = D.getElementById( 'fil-ariane' );
if ( fil ) fil.style.display = '';
// Revenir à l’endroit d’où on vient + ré-ouvrir l’argument si possible
if ( ret && ret.titleId ) {
var titleEl = D.getElementById( ret.titleId );
if ( titleEl ) {
// Option A : scroll direct sur le titre
titleEl.scrollIntoView( { block: 'start' } );
// Option B : ré-ouvrir le contenu sous le titre (si tu veux)
var $t = $( titleEl );
if ( $t.length && typeof W.loadContentFromTitle === 'function' ) {
if ( !$t.hasClass( 'is-expanded' ) ) {
W.loadContentFromTitle( $t );
}
}
} else if ( typeof ret.scrollY === 'number' ) {
W.scrollTo( 0, ret.scrollY );
}
}
WK_READING.state.returnTo = null;
}
function argumentContentCall() {
if ( !wkOnce( 'wkArgOpenInit' ) ) return;
$D.on( 'click.wkArgOpen', '.argument-title:not(.is-expanded)', function () {
wkHideVectorStickyHeader();
wkWarmI18nCaches();
var $clicked = $( this );
var clickedElement = this;
// Fermer les arguments ouverts au même niveau (sans data-level)
var ul = clickedElement.closest( 'ul.argument-list' );
var scope = ul ? ul.closest( '.argument-wrapper' ) : null;
if ( scope ) {
// Niveau > 1 : fermer les siblings (pro + con) du même parent
var opened = scope.querySelectorAll( 'ul.argument-list > li.argument > .argument-title.is-expanded' );
for ( var i = 0; i < opened.length; i++ ) {
if ( opened[ i ] !== clickedElement ) {
wkCollapseTitleEl( opened[ i ] );
}
}
} else {
// Niveau 1 : fermer les autres niveau 1 (évite closest() en boucle)
var openedTop = D.querySelectorAll( 'li.argument.level-1 > .argument-title.is-expanded' );
for ( var j = 0; j < openedTop.length; j++ ) {
if ( openedTop[ j ] !== clickedElement ) {
wkCollapseTitleEl( openedTop[ j ] );
}
}
}
wkOpenReadingModeFromTitleEl( clickedElement );
var col = clickedElement.closest( '.colonnes' );
if ( col ) col.classList.add( 'inline' );
} );
$D.on( 'click.wkArgStop', '.ns-0 a.modifier-argument-lien', function ( event ) {
event.stopPropagation();
} );
}
function wkApplyArgMetaFromTitleToWrapper( titleEl, $title, wrapperEl ) {
if ( titleEl && titleEl.jquery && titleEl.length ) titleEl = titleEl[ 0 ];
if ( !titleEl || !wrapperEl ) return;
// Type (pour/contre) via la liste courante
var ul = titleEl.closest( 'ul.argument-list' );
if ( !ul ) return;
var argType = ul.classList.contains( 'is-con' ) ? 'contre' : 'pour';
// Titre “propre”
var argTitle = wkGetArgumentTitleFromNode( titleEl );
if ( !argTitle ) return;
// Parent wrapper = wrapper qui contient cette UL (niveau parent)
var parentWrap = ul.closest( '.argument-wrapper' );
var level = 1;
var path = '';
if ( parentWrap && parentWrap.dataset && parentWrap.dataset.path ) {
var parentLevel = parseInt( parentWrap.dataset.level, 10 );
parentLevel = isNaN( parentLevel ) ? 0 : parentLevel;
level = parentLevel + 1;
var typeParent = parentWrap.classList.contains( 'is-pro' ) ? 'pour' : 'contre';
var argIcon = ( argType === typeParent ) ? 'pour' : 'contre';
path = parentWrap.dataset.path + '⟭' + argIcon + '⟬' + argTitle;
} else {
path = wkGetDebateBaseForPath() + '⟭' + argType + '⟬' + argTitle;
}
wrapperEl.classList.remove( 'is-pro', 'is-con' );
wrapperEl.classList.add( argType === 'contre' ? 'is-con' : 'is-pro' );
wrapperEl.dataset.level = String( level );
wrapperEl.dataset.path = String( path );
}
function loadContentFromTitle( $title ) {
// Mode lecture : on n’injecte plus jamais sous le titre
if ( W.WK_READING && W.WK_READING.enabled && typeof W.wkOpenReadingModeFromTitleEl === 'function' ) {
var el = $title && $title.length ? $title[ 0 ] : null;
if ( el ) W.wkOpenReadingModeFromTitleEl( el );
return;
}
wkWarmI18nCaches();
$title.addClass( 'is-expanded' ).removeClass( 'visited' );
var el = $title[ 0 ];
wkExpandedAdd( el );
var wrapperEl = wkEnsureArgWrapperAfterTitle( el );
if ( !wrapperEl ) return;
// Vider vite (plus rapide que $wrapper.empty() ici)
wrapperEl.textContent = '';
wkApplyArgMetaFromTitleToWrapper( el, $title, wrapperEl );
// Lien => argPage
var a = el.querySelector( 'a[href]' );
if ( !a ) return;
var href = a.getAttribute( 'href' ) || '';
if ( !href ) return;
var argPage = hrefToPageTitle( href );
if ( !argPage ) return;
// Helper local : injection ultra rapide via fragment
function appendFragment( html ) {
if ( !html ) return;
wrapperEl.insertAdjacentHTML( 'beforeend', html );
}
// Retourne l’index du début du bloc heading (mw-heading ou h2) pour un id donné
function wkFindHeadingStartById( html, id ) {
var key = 'id="' + id + '"';
var p = html.indexOf( key );
if ( p === -1 ) return -1;
return html.lastIndexOf( '<h2', p );
}
// Extraction start inclus / end exclu (ultra rapide)
function wkExtractBetweenHeadingIds( html, startId, endId ) {
var a = wkFindHeadingStartById( html, startId );
if ( a === -1 ) return '';
var key = 'id="' + endId + '"';
var p = html.indexOf( key, a + 1 );
if ( p === -1 ) return '';
var b = html.lastIndexOf( '<h2', p );
if ( b === -1 ) {
b = html.lastIndexOf( '<div', p );
}
if ( b === -1 || b <= a ) return '';
return html.slice( a, b );
}
// ✅ Cache HIT (has() = robuste même si valeur falsy)
if ( wkArgEmbedCache.has( argPage ) ) {
var cachedFrag = wkArgEmbedCache.get( argPage ) || '';
if ( cachedFrag ) {
appendFragment( cachedFrag );
wkOnContent( wrapperEl );
}
return;
}
// Token anti-réponse tardive
var token = wkBumpWrapperToken(
wrapperEl,
wkArgTokenByWrapper,
wkArgXhrByWrapper
);
// ❌ Cache MISS → parse(page)
wkGetApi().get( {
action: 'parse',
formatversion: 2,
page: argPage,
prop: 'text',
disableeditsection: 1,
redirects: 1
} ).then( function ( data ) {
// Ignore si un autre chargement a été lancé depuis
if ( wrapperEl && wkArgTokenByWrapper.get( wrapperEl ) !== token ) return;
var html = ( data && data.parse && data.parse.text ) ? data.parse.text : '';
if ( !html ) return;
// Optionnel : virer les commentaires HTML (parfois petit gain)
// html = html.replace( /<!--[\S\s]*?-->/gm, '' );
// Extraction ultra rapide : #Summary inclus → #Parent_debates non inclus
var fragment = wkExtractBetweenHeadingIds( html, 'Summary', 'Parent_debates' );
if ( !fragment ) return;
// 🧠 Cache (fragment HTML)
wkArgEmbedCache.set( argPage, fragment );
// Injection via DocumentFragment
appendFragment( fragment );
wkOnContent( wrapperEl );
} ).catch( function () {} );
}
function argumentContentDrop() {
if ( !wkOnce( 'wkArgDropInit' ) ) return;
$D.on( 'click.wkArgDrop', '.argument-title.is-expanded', function ( e ) {
if ( $( e.target ).closest( '.modifier-dropdown' ).length ) return;
wkCollapseTitleEl( this );
} );
}
function closeArgument( level, clickedElement ) {
clickedElement = clickedElement || null;
if ( wkExpandedSet ) {
wkExpandedForEach( function ( el ) {
if ( clickedElement && el === clickedElement ) return;
var lvlRaw = wkDsGetAny( el, 'level', $( el ) );
var lvl = parseInt( lvlRaw, 10 );
lvl = isNaN( lvl ) ? 1 : lvl;
if ( lvl === level ) wkCollapseTitleEl( el );
} );
return;
}
$( '.argument-title.is-expanded' ).each( function () {
var lvl2Raw = wkDsGetAny( this, 'level', $( this ) );
var lvl2 = parseInt( lvl2Raw, 10 );
lvl2 = isNaN( lvl2 ) ? 1 : lvl2;
if ( lvl2 === level && ( !clickedElement || this !== clickedElement ) ) {
wkCollapseTitleEl( this );
}
} );
}
/* ==========================================================
Carte des arguments en tête de débat
========================================================== */
function argumentMapContentCall() {
if ( !wkOnce( 'wkMapOpenInit' ) ) return;
$D.on( 'click.wkMapOpen', '.ns-0 #Argument_map .argument-title--map', function () {
wkHideVectorStickyHeader();
wkWarmI18nCaches();
closeArgument( 1 );
var id = $( this ).attr( 'id' );
id = id ? id.slice( 0, -4 ) : '';
if ( !id ) return;
var raw = D.getElementById( id );
if ( !raw ) return;
var titleEl = null;
if ( raw.classList && raw.classList.contains( 'argument-title' ) ) {
titleEl = raw;
} else {
titleEl = raw.querySelector( '.argument-title' ) || raw.querySelector( 'div.argument-title' );
}
if ( !titleEl || !titleEl.id ) return;
var $title = $( '#' + CSS.escape( titleEl.id ) );
wkEnsureModifierArgumentButton( $title );
if ( !$title.hasClass( 'is-expanded' ) ) {
loadContentFromTitle( $title );
}
breadcrumbMenu( $title[ 0 ], { fromMapClick: true } );
$( this ).addClass( 'visited' );
} );
}
function argumentMapColor() {
if ( !wkOnce( 'wkMapColorInit' ) ) return;
$D.on( 'click.wkMapColor', '.ns-0 .argument.level-1:not(.is-expanded)', function () {
var id = this.getAttribute( 'id' ) || '';
if ( !id ) return;
$( '#' + CSS.escape( id ) + '_map' ).addClass( 'visited' );
} );
}
/* ==========================================================
Lazy-bind NS0 view
========================================================== */
function wkLazyBindForArgumentsView( root ) {
if ( !( wkIsNs( 0 ) || wkIsNs( 3100 ) ) || !wkIsView() ) return;
var el = wkRootNode( root );
if ( !el || !el.querySelector ) return;
if ( el.querySelector( '.argument-title' ) ) {
argumentContentCall();
argumentContentDrop();
wkBindBreadcrumbHandlers();
wkBindTocRemoveBreadcrumb();
}
if ( el.querySelector( '#Argument_map .argument-title--map, #Argument_map' ) ) {
argumentMapContentCall();
argumentMapColor();
}
}
/* ==========================================================
RESTE (FormEdit / SMW / Tooltips / Dropdown etc.)
========================================================== */
function wkHideTitlebarOnAutoEval() {
if ( !wkIsNs( -1 ) ) return;
if ( !D.body.classList.contains( 'mw-special-FormEdit' ) ) return;
if ( !D.body.classList.contains( 'action-view' ) ) return;
if ( !D.querySelector( '#accepte-autoevaluation' ) ) return;
var titlebar = D.querySelector( '.mw-body-header.vector-page-titlebar' );
if ( titlebar ) titlebar.style.display = 'none';
}
function wkGetPfScope() {
var pf = D.getElementById( 'pfForm' );
return pf ? $( pf ) : $D;
}
function fillEditSummary( message ) {
if ( typeof message === 'undefined' || message === null ) return;
var $input = $( 'input[name=wpSummary]' );
if ( !$input.length ) return;
var summary = $input.val() || '';
if ( summary ) {
var condition = summary.substr( -3 );
if ( condition === '*/ ' ) summary += message;
else summary += ' + ' + message;
} else {
summary = message;
}
$input.val( summary );
}
function fillEditSummaryForCheckbox( $object, addingMessage, removingMessage ) {
if ( !$object || !$object.length ) return;
var $input = $( 'input[name=wpSummary]' );
if ( !$input.length ) return;
var checked = $object.prop( 'checked' );
var bannerName = $object.parent();
bannerName = $( bannerName ).next();
bannerName = $( bannerName ).text() + ' »';
var actionDone = checked ? ( addingMessage + ' «' ) : ( removingMessage + ' «' );
var message = actionDone + bannerName;
fillEditSummary( message );
}
function wkInitEditSummaries() {
if ( !wkIsFormEdit() ) return;
if ( !wkOnce( 'wkEditSummariesInit' ) ) return;
var $scope = wkGetPfScope();
if ( $( '.mw-special-FormEdit' ).length > 0 ) {
( function () {
var sectionValue = $( '#formName' ).data( 'section' );
var $summaryField = $( 'input[name="wpSummary"]' );
if ( $summaryField.length && ( $summaryField.val() || '' ).trim() === '' && sectionValue ) {
$summaryField.val( '/* ' + sectionValue + ' */ ' );
}
} )();
( function () {
var zones = [
{ selector: '.zone-arguments-pour', labelReorgKey: 'wk-summary-reorg-arguments', labelRenomKey: 'wk-summary-rename-argument', labelSuppKey: 'wk-summary-delete-argument', labelAjoutKey: 'wk-summary-add-argument-existing' },
{ selector: '.zone-arguments-contre', labelReorgKey: 'wk-summary-reorg-arguments', labelRenomKey: 'wk-summary-rename-argument', labelSuppKey: 'wk-summary-delete-argument', labelAjoutKey: 'wk-summary-add-argument-existing' },
{ selector: '.zone-justifications', labelReorgKey: 'wk-summary-reorg-arguments', labelRenomKey: 'wk-summary-rename-argument', labelSuppKey: 'wk-summary-delete-argument', labelAjoutKey: 'wk-summary-add-argument-existing' },
{ selector: '.zone-objections', labelReorgKey: 'wk-summary-reorg-arguments', labelRenomKey: 'wk-summary-rename-objection', labelSuppKey: 'wk-summary-delete-objection', labelAjoutKey: 'wk-summary-add-argument-existing' },
{ selector: '.zone-introduction', labelReorgKey: 'wk-summary-reorg-sections', labelRenomKey: 'wk-summary-rename-section', labelSuppKey: 'wk-summary-delete-section', labelSuppBisKey: 'wk-summary-delete-section-untitled', labelAjoutKey: 'wk-summary-add-section' },
{ selector: '.zone-voir-Wikipedia', labelReorgKey: 'wk-summary-reorg-articles', labelRenomKey: 'wk-summary-rename-article', labelSuppKey: 'wk-summary-delete-article', labelAjoutKey: 'wk-summary-add-wikipedia-article' },
{ selector: '.zone-debats-connexes', labelReorgKey: 'wk-summary-reorg-debats', labelRenomKey: 'wk-summary-rename-debat', labelSuppKey: 'wk-summary-delete-debat', labelAjoutKey: 'wk-summary-add-debat' },
{ selector: '.zone-interlangue', labelReorgKey: 'wk-summary-reorg-interlang', labelSuppKey: 'wk-summary-delete-interlang', labelAjoutKey: 'wk-summary-add-interlang' },
{ selector: '.zone-citations', labelReorgKey: 'wk-summary-reorg-citations', labelSuppKey: 'wk-summary-delete-citation', labelSuppBisKey: 'wk-summary-delete-citation-generic', labelAjoutKey: 'wk-summary-add-citation' },
{ selector: '.zone-references', labelReorgKey: 'wk-summary-reorg-references', labelSuppKey: 'wk-summary-delete-reference', labelSuppBisKey: 'wk-summary-delete-reference-generic', labelAjoutKey: 'wk-summary-add-reference' }
];
W.ajoutInstance = false;
W.ajoutInstanceZone = null;
function wkBindZoneSummaryHandlers( root ) {
var scope = root && root.nodeType ? root : D;
var pfRoot = scope.querySelector( '#pfForm' ) || scope;
zones.forEach( function ( zone ) {
var selRemove = zone.selector + ' .instanceRemove a';
var selAdd = zone.selector + ' .instanceAddAbove a, ' + zone.selector + ' .multipleTemplateAdder';
var selRename = zone.selector + ' .parametre-important';
var removeNodes = pfRoot.querySelectorAll( selRemove );
for ( var i = 0; i < removeNodes.length; i++ ) {
var element = removeNodes[ i ];
if ( element.dataset.wkSumRemoveBound === '1' ) continue;
element.dataset.wkSumRemoveBound = '1';
element.addEventListener( 'click', function ( e ) {
e.preventDefault();
var row = this.closest( 'tr' );
var titreInput = row ? row.querySelector( '.parametre-important' ) : null;
var isBis = false;
if ( !titreInput ) {
titreInput = row ? row.querySelector( '.parametre-important-bis' ) : null;
isBis = !!titreInput;
}
var titre = ( titreInput && titreInput.value ) ? titreInput.value : null;
var key;
if ( titre ) {
key = isBis ? ( zone.labelSuppBisKey || zone.labelSuppKey ) : zone.labelSuppKey;
fillEditSummary( wkMsg( key, titre ) );
} else {
key = zone.labelSuppBisKey || zone.labelSuppKey;
fillEditSummary( wkMsg( key ) );
}
} );
}
var addNodes = pfRoot.querySelectorAll( selAdd );
for ( var j = 0; j < addNodes.length; j++ ) {
var elementAdd = addNodes[ j ];
if ( elementAdd.dataset.wkSumAddBound === '1' ) continue;
elementAdd.dataset.wkSumAddBound = '1';
elementAdd.addEventListener( 'click', function ( e ) {
e.preventDefault();
if (
zone.selector === '.zone-introduction' ||
zone.selector === '.zone-citations' ||
zone.selector === '.zone-references'
) {
fillEditSummary( wkMsg( zone.labelAjoutKey ) );
} else {
W.ajoutInstance = true;
W.ajoutInstanceZone = zone.selector;
}
} );
}
var renameNodes = pfRoot.querySelectorAll( selRename );
for ( var k = 0; k < renameNodes.length; k++ ) {
var input = renameNodes[ k ];
if ( input.dataset.wkSumRenameBound === '1' ) continue;
input.dataset.wkSumRenameBound = '1';
input.addEventListener( 'blur', function ( e ) {
var value = e && e.target ? e.target.value : '';
if ( value && value.trim() !== '' ) {
fillEditSummary( wkMsg( zone.labelRenomKey, value ) );
}
} );
}
} );
}
W.ajoutInstance = false;
W.ajoutInstanceZone = null;
wkBindZoneSummaryHandlers( D );
$D.on( 'pfaddinstance pfafterrebuild pfcreateinput', function ( e ) {
wkBindZoneSummaryHandlers( ( e && e.target ) ? e.target : D );
} );
$scope.on( 'select2:select.wkSumSelect2', 'select', function ( e ) {
var match = ( e && e.params && e.params.data && e.params.data.text ) ? ( e.params.data.text || '' ).trim() : '';
try {
var selectedId = e.params.data && e.params.data._resultId;
var $option = selectedId ? $( D.getElementById( selectedId ) ) : null;
if ( $option && $option.length && $option.find( '.select2-match-entire' ).length ) {
match = $option.find( '.select2-match-entire' ).text().trim();
}
} catch ( err ) {}
var message;
if ( W.ajoutInstance && W.ajoutInstanceZone ) {
var matchedZone = zones.find( function ( z ) { return z.selector === W.ajoutInstanceZone; } );
if ( matchedZone ) message = wkMsg( matchedZone.labelAjoutKey, match );
else message = wkMsg( 'wk-summary-add-generic', match );
W.ajoutInstance = false;
W.ajoutInstanceZone = null;
} else {
message = wkMsg( 'wk-summary-add-generic', match );
}
fillEditSummary( message );
} );
} )();
$scope.on( 'click.wkWarnCb', '.checkboxesSpan .oo-ui-inputWidget-input', function () {
if ( $( this ).closest( '.zone-rubriques' ).length === 0 ) {
fillEditSummaryForCheckbox( $( this ), wkMsg( 'wk-summary-warning-add' ), wkMsg( 'wk-summary-warning-remove' ) );
}
} );
$scope.on( 'click.wkRubCb', '.zone-rubriques .oo-ui-inputWidget-input', function () {
fillEditSummaryForCheckbox( $( this ), wkMsg( 'wk-summary-rubrique-add' ), wkMsg( 'wk-summary-rubrique-remove' ) );
} );
$scope.on( 'change.wkProgress', '.mw-special-FormEdit .zone-bandeaux .mandatoryField', function () {
var bannerName = $( '.zone-bandeaux select.mandatoryField option:selected' ).val();
fillEditSummary( wkMsg( 'wk-summary-progress-change', bannerName ) );
} );
$scope.on( 'click.wkKeywordRemove', '.select2-selection__choice__remove', function () {
var $li = $( this ).closest( '.select2-selection__choice' );
var keyword = $li.find( '.select2-match-entire' ).text();
fillEditSummary( wkMsg( 'wk-summary-keyword-remove', keyword ) );
} );
( function () {
var $summary = $( 'input[name=wpSummary]' );
var sujetCompletInitial = $( '.zone-sujet-complet' ).val() || '';
$scope.on( 'change.wkSubjectFull1', '.zone-sujet-complet', function () {
var sujetCompletActuel = $( this ).val() || '';
var ajoutOuModification = '';
if ( sujetCompletInitial === '' && sujetCompletActuel !== '' ) {
ajoutOuModification = wkMsg( 'wk-summary-subject-add', sujetCompletActuel );
} else if ( sujetCompletInitial !== '' && sujetCompletActuel !== '' && sujetCompletInitial !== sujetCompletActuel ) {
ajoutOuModification = wkMsg( 'wk-summary-subject-mod', sujetCompletActuel );
}
if ( ajoutOuModification ) {
$summary.val( '/* Sujet du débat */ ' + ajoutOuModification );
}
} );
} )();
$scope.on( 'click.wkResumeOps', '.resume-modifications', function () {
var $summary = $( 'input[name=wpSummary]' );
if ( !$summary.length ) return;
var summary = $summary.val() || '';
var newSummary = ( $( this ).text() || '' ).trim();
if ( summary ) {
var condition = summary.substr( -3 );
if ( condition === '*/ ' ) summary += newSummary;
else summary += ' + ' + newSummary;
} else {
summary = newSummary;
}
$summary.val( summary );
} );
}
}
function wkReinitSMWTooltips() {
if ( !wkOnce( 'wkSmwTooltipInit' ) ) return;
mw.loader.using( 'ext.smw.tooltip' ).then( function () {
function reinitSMWTooltips( $root ) {
try {
if ( W.smw && smw.tooltip && smw.tooltip.init ) smw.tooltip.init( $root || $D );
} catch ( e ) {}
}
reinitSMWTooltips( $D );
$D.on( 'pfaddinstance pfafterrebuild pfcreateinput', function ( e ) {
reinitSMWTooltips( $( e && e.target ? e.target : D ) );
} );
} );
}
function wkRemoveSomeTooltipsOn( root ) {
var el = wkRootNode( root );
if ( !el || !el.querySelectorAll ) return;
var nodes = el.querySelectorAll( '.masquer-infobulle a[title]' );
for ( var i = 0; i < nodes.length; i++ ) {
nodes[ i ].removeAttribute( 'title' );
}
}
function wkRemoveSomeTooltips() {
if ( !wkOnce( 'wkRemoveSomeTooltipsInit' ) ) return;
$D.on( 'mouseenter.wkRmTip', '.hover-wikipedia a[title], .hover-map a[title]', function () {
this.removeAttribute( 'title' );
} );
}
function wkRefTooltips() {
( function ( mwLocal, $ ) {
'use strict';
if ( !wkOnce( 'wkRefTooltipInit' ) ) return;
var $tooltip = null;
var $content = null;
var currentTrigger = null;
function ensureTooltip() {
if ( $tooltip ) return;
$tooltip = $( '<div class="wk-ref-tooltip" role="dialog" aria-hidden="true">\n' +
'\t<div class="wk-ref-tooltip__content"></div>\n' +
'</div>' ).appendTo( $B ).hide();
$tooltip.css( { position: 'absolute', top: -9999, left: -9999 } );
$content = $tooltip.find( '.wk-ref-tooltip__content' );
$tooltip.on( 'click', function ( e ) {
e.stopPropagation();
} );
}
function getNoteHtmlFromLink( $a ) {
var href = $a.attr( 'href' );
if ( !href || href.charAt( 0 ) !== '#' ) return '';
var id = href.slice( 1 );
var $note = $( '#' + $.escapeSelector( id ) );
if ( !$note.length ) return '';
var $clone = $note.clone();
$clone.find( '.mw-cite-backlink' ).remove();
return $clone.html() || '';
}
function positionTooltip( $trigger ) {
if ( !$trigger || !$trigger.length ) return;
var rect = $trigger[ 0 ].getBoundingClientRect();
$tooltip.css( { top: -9999, left: -9999, right: '' } ).show();
var tipW = $tooltip.outerWidth();
var tipH = $tooltip.outerHeight();
var scrollX = $W.scrollLeft();
var scrollY = $W.scrollTop();
var margin = 8;
var top = rect.top + scrollY - tipH - margin;
var below = false;
if ( top < scrollY ) {
top = rect.bottom + scrollY + margin;
below = true;
}
var left = rect.left + scrollX + ( rect.width / 2 ) - ( tipW / 2 );
var minLeft = scrollX + 4;
var maxLeft = scrollX + $W.width() - tipW - 4;
left = Math.max( minLeft, Math.min( maxLeft, left ) );
$tooltip
.toggleClass( 'wk-ref-tooltip--below', below )
.css( { top: Math.round( top ), left: Math.round( left ) } );
}
function hideNow() {
if ( !$tooltip ) return;
$tooltip.hide().attr( 'aria-hidden', 'true' );
$content.empty();
currentTrigger = null;
$W.off( 'scroll.refhover resize.refhover keydown.refhover' );
$B.off( 'click.refhover' );
}
function showFor( $a ) {
ensureTooltip();
var html = getNoteHtmlFromLink( $a );
if ( !html ) return;
$content.html( html );
$tooltip.attr( 'aria-hidden', 'false' ).show();
positionTooltip( $a );
currentTrigger = $a;
$W.on( 'scroll.refhover resize.refhover', function () {
if ( currentTrigger ) positionTooltip( currentTrigger );
} ).on( 'keydown.refhover', function ( e ) {
if ( e.key === 'Escape' || e.key === 'Esc' ) hideNow();
} );
$B.on( 'click.refhover', function () {
hideNow();
} );
}
function toggleFor( $a ) {
if ( currentTrigger && currentTrigger[ 0 ] === $a[ 0 ] ) hideNow();
else showFor( $a );
}
function bindOn( $root ) {
var $ctx = $root && $root.jquery ? $root : $( $root || D );
if ( $ctx.data( 'wk-ref-tooltip-delegated' ) === 1 ) return;
$ctx.data( 'wk-ref-tooltip-delegated', 1 );
$ctx.on( 'click.refhover', 'sup.reference[id^="cite_ref"] > a, a[href^="#cite_note-"]', function ( e ) {
e.preventDefault();
e.stopPropagation();
e.stopImmediatePropagation();
toggleFor( $( this ) );
} );
$ctx.on( 'keydown.refhover', 'sup.reference[id^="cite_ref"] > a, a[href^="#cite_note-"]', function ( e ) {
if ( e.key === 'Enter' || e.key === ' ' || e.code === 'Space' ) {
e.preventDefault();
e.stopPropagation();
e.stopImmediatePropagation();
toggleFor( $( this ) );
}
} );
}
W.wkBindRefTooltipsOn = function ( root ) {
bindOn( $( root || D ) );
};
bindOn( $D );
} )( mediaWiki, jQuery );
}
/* ==========================================================
Bouton “modifier-argument” — insertion centralisée
========================================================== */
function wkEnsureModifierArgumentButton( $argumentTitle ) {
if ( !$argumentTitle || !$argumentTitle.length ) return;
if ( $argumentTitle.find( '.modifier-argument' ).length ) return;
$argumentTitle.append(
'<span class="modifier-argument">' +
'<a href="#" class="modifier-argument-lien" title="' + wkMsg( 'wk-edit-argument-title' ) + '">' +
wkMsg( 'wk-edit' ) +
'</a>' +
'</span>'
);
}
/* ---- Dropdown “modifier argument” ---- */
function wkInitArgumentDropdown() {
if ( !wkIsNs( 0 ) ) return;
$( document ).on( 'click.wkDropAddBtn', '.ns-0 div.argument-title:not(.is-expanded)', function () {
wkEnsureModifierArgumentButton( $( this ) );
} );
if ( !wkOnce( 'wkArgumentDropdownInit' ) ) return;
$D.on( 'click.wkDropToggle', '.ns-0 a.modifier-argument-lien', function ( e ) {
e.preventDefault();
wkWarmI18nCaches();
var $argumentTitle = $( this ).closest( '.argument-title' );
if ( !$argumentTitle.length ) return;
var $a = $argumentTitle.find( 'a' ).first();
var hrefArg = $a.attr( 'href' ) || '';
var identifiant = wkGetWikiTitleFromHrefRaw( hrefArg );
if ( !identifiant ) return;
var $modifierArgument = $argumentTitle.find( '.modifier-argument' );
var $dropdown = $argumentTitle.find( '.modifier-dropdown' );
if ( $dropdown.length ) {
$dropdown.toggle();
return;
}
var $menu = $( '<div class="modifier-dropdown"></div>' )
.attr( 'data-parent', $argumentTitle.attr( 'id' ) || '' );
$modifierArgument.append( $menu );
var lienModifierTitre = '#';
var ancestor = $argumentTitle.closest( '.NavFramex' );
if ( ancestor.length ) {
var navHead = ancestor.find( '.NavHead' ).first();
if ( navHead.length ) {
var modifierSection = navHead.find( '.modifier-section' ).first();
if ( modifierSection.length ) {
var lienHref = modifierSection.find( 'a' ).attr( 'href' );
if ( lienHref ) lienModifierTitre = lienHref;
}
}
} else {
var ulListe = $argumentTitle.closest( 'ul.argument-list' );
var precedent = ulListe.prev();
while ( precedent.length && precedent.prop( 'tagName' ) !== 'H2' ) {
precedent = precedent.prev();
}
if ( precedent.length ) {
var modifierSectionLink = precedent.find( '.modifier-section a' ).first();
if ( modifierSectionLink.length ) {
lienModifierTitre = modifierSectionLink.attr( 'href' );
}
}
}
var $lienTitre = $( '<span><a></a></span>' );
var $iconeTitre = $( '<img>' )
.attr( 'src', '/w/images/fr/b/ba/Modifier.svg' )
.attr( 'alt', '' )
.attr( 'class', 'picto-dropdown' );
var $wrapTitre = $( '<span class="picto-dropdown-wrap"></span>' )
.append( $iconeTitre );
$lienTitre.find( 'a' )
.attr( 'href', lienModifierTitre )
.attr( 'target', '_self' )
.append( $wrapTitre )
.append( wkMsg( 'wk-dropdown-edit-display-title' ) );
$menu.append( $lienTitre );
var formulaireTexte = [
{
formulaire: WK_F.summary,
texte: wkMsg( 'wk-dropdown-edit-summary' ),
icone: '/w/images/fr/c/c6/Contributions.svg'
},
{
formulaire: WK_F.citations,
texte: wkMsg( 'wk-dropdown-edit-citations' ),
icone: '/w/images/fr/6/6e/Citation.svg'
},
{
formulaire: WK_F.references,
texte: wkMsg( 'wk-dropdown-edit-references' ),
icone: '/w/images/fr/9/9e/Bibliographie.svg'
}
];
$.each( formulaireTexte, function ( index, item ) {
var $lien = $( '<span><a></a></span>' );
var $icone = $( '<img>' )
.attr( 'src', item.icone )
.attr( 'class', 'picto-dropdown' )
.attr( 'alt', '' );
var $wrap = $( '<span class="picto-dropdown-wrap"></span>' )
.append( $icone );
$lien.find( 'a' )
.attr( 'href', '/wiki/Special:AddData/' + item.formulaire + '/' + identifiant )
.attr( 'target', '_self' )
.append( $wrap )
.append( item.texte );
$menu.append( $lien );
} );
var $lienExterne = $( '<span class="onglet-externe"><a></a></span>' );
var $iconeExterne = $( '<img>' )
.attr( 'src', '/w/images/fr/7/74/Loupe-noire.svg' )
.attr( 'alt', '' )
.attr( 'class', 'picto-dropdown' );
var $wrapExterne = $( '<span class="picto-dropdown-wrap"></span>' )
.append( $iconeExterne );
$lienExterne.find( 'a' )
.attr( 'href', '/wiki/' + identifiant )
.attr( 'target', '_self' )
.append( $wrapExterne )
.append( wkMsg( 'wk-dropdown-view-detail' ) );
$menu.append( $lienExterne );
$menu.show();
} );
$D.on( 'click.wkDropClose', '.ns-0', function ( e ) {
if ( !$( e.target ).closest( '.modifier-dropdown, .modifier-argument' ).length ) {
$( '.modifier-dropdown' ).hide();
}
} );
}
/* ---- NS-3100 scroll top ---- */
function wkBindNs3100ScrollHandlers() {
if ( !wkOnce( 'wkNs3100ScrollInit' ) ) return;
$D.on( 'click.wkEvalTop', '.ns-3100 .bouton-argument-suivant', function () {
$( 'html, body' ).animate( { scrollTop: 0 }, 'slow' );
} );
$D.on( 'click.wkAutoEvalTop', '.ns-3100 .remonter-autoevaluation, .ns-3100 .titre-ariane', function ( event ) {
event.preventDefault();
$( '.colonnes' ).removeClass( 'inline' );
$( 'html, body' ).animate( { scrollTop: 0 }, 'slow' );
closeArgument( 2 );
} );
}
/* ---- Fil d’Ariane extras ---- */
function wkBindBreadcrumbExtras() {
if ( !wkOnce( 'wkBreadcrumbExtrasInit' ) ) return;
( function ( mwLocal, $ ) {
$D.on( 'click.wkBackToTop', '.remonter-fil, .remonter-carte, .remonter-haut, .titre-ariane', function ( e ) {
e.preventDefault();
// 1) Cacher / supprimer le fil d'Ariane
var fil = D.getElementById( 'fil-ariane' );
if ( fil && fil.parentNode ) {
fil.parentNode.removeChild( fil );
}
// (optionnel) réafficher le header sticky Vector si tu l'avais masqué
if ( typeof wkShowVectorStickyHeader === 'function' ) {
wkShowVectorStickyHeader();
}
// 2) Fermer les arguments
if ( typeof W.closeArgument === 'function' ) {
W.closeArgument( 1 );
}
// 3) Remonter en haut
$( 'html, body' ).stop( true ).animate( { scrollTop: 0 }, 120 );
} );
} )( mw, jQuery );
}
/* ==========================================================
SCAN DOM + BOOT — pré-checks pour limiter les rescans
(optim “safe”: getElementsByClassName quand possible)
========================================================== */
function wkHasClassIn( el, cls ) {
try {
return !!( el && el.getElementsByClassName && el.getElementsByClassName( cls ).length );
} catch ( e ) {}
return false;
}
function wkOnContent( root ) {
var el = wkRootNode( root );
if ( !el ) return;
var $root = root && root.jquery ? root : $( el );
/* Collapsibles */
if ( wkHasClassIn( el, 'fr-collapsible' ) ) bindFrCollapsible( $root );
/* Tooltips à retirer */
if ( el.querySelector && el.querySelector( '.masquer-infobulle a[title]' ) ) wkRemoveSomeTooltipsOn( el );
/* Tooltips AddData + renommer */
if ( ( el.querySelector && el.querySelector( 'span.wk-adddata-link[data-wk-tooltip]' ) ) || D.querySelector( '#bouton-renommer a' ) ) {
wkFixAddDataAndRenameTooltipsOn( el );
}
/* Ref tooltips */
if ( typeof W.wkBindRefTooltipsOn === 'function' && ( ( el.querySelector && el.querySelector( 'sup.reference > a, a[href^="#cite_note-"]' ) ) || el === D ) ) {
W.wkBindRefTooltipsOn( el );
}
/* NS0 + NS3100 view : arguments */
if ( wkIsView() && ( wkIsNs( 0 ) || wkIsNs( 3100 ) ) ) {
if ( el.querySelector && el.querySelector( '.argument-title' ) ) {
wkLazyBindForArgumentsView( el );
}
/* Déplacements boutons : NS0 uniquement */
if ( wkIsNs( 0 ) ) {
wkIdle( function () {
wkInitHeaderButtons();
} );
}
}
/* PF autogrow */
if ( el.querySelector && ( el.querySelector( '#pfForm textarea.autoGrow' ) || el.querySelector( '#pfForm' ) ) ) {
wkAutoGrowSchedule( el );
}
}
/* ==========================================================
Boot global — regroupement safe
(“safe”: certaines init en idle)
========================================================== */
function wkBindGlobalDelegations() {
wkRemoveSomeTooltips();
wkRefTooltips();
moreContentCall();
latestChangesCall();
hoverContentCall();
wkBindBreadcrumbHandlers();
wkBindTocRemoveBreadcrumb();
wkInitArgumentDropdown();
wkBindNs3100ScrollHandlers();
wkBindBreadcrumbExtras();
$D.on( 'click.wkReadingClose', '#' + WK_READING_UI.closeId, function ( e ) {
e.preventDefault();
wkCloseReadingMode();
} );
W.addEventListener( 'resize', function () {
wkReadingSetTopOffset();
} );
if ( W.visualViewport ) {
visualViewport.addEventListener( 'resize', function () {
wkReadingSetTopOffset();
}, { passive: true } );
visualViewport.addEventListener( 'scroll', function () {
wkReadingSetTopOffset();
}, { passive: true } );
}
}
function wkGlobalBindAll() {
/* i18n warm-up immédiat (safe) */
wkWarmI18nCaches();
/* Les trucs “non-urgents” en idle */
wkIdle( function () {
wkFixTitleSpace();
wkBindAutoGrow();
wkReinitSMWTooltips();
} );
wkInitEditSummaries();
wkHideTitlebarOnAutoEval();
wkBindGlobalDelegations();
}
function boot() {
if ( !wkOnce( 'wkBooted' ) ) return;
wkLoadI18n().catch( function () {} ).finally( function () {
wkGlobalBindAll();
wkOnContent( D );
} );
}
if ( D.readyState === 'loading' ) {
D.addEventListener( 'DOMContentLoaded', boot, { once: true } );
} else {
boot();
}
mw.hook( 'wikipage.content' ).add( function ( $content ) {
wkOnContent( $content && $content[ 0 ] ? $content[ 0 ] : D );
} );
/* ==========================================================
Expose (si besoin ailleurs)
========================================================== */
W.wkLoadI18n = wkLoadI18n;
W.wkMsg = wkMsg;
W.wkMsgD = wkMsgD;
W.wkTpl = wkTpl;
W.wkParam = wkParam;
W.wkForm = wkForm;
W.wkParamFast = wkParamFast;
W.wkTplFast = wkTplFast;
W.wkFormFast = wkFormFast;
W.wkGetApi = wkGetApi;
W.wkParseWikitext = wkParseWikitext;
W.wkParseCancel = wkParseCancel;
W.loadContentFromTitle = loadContentFromTitle;
W.closeArgument = closeArgument;
W.breadcrumbMenu = breadcrumbMenu;
W.breadcrumbGeneration = W.breadcrumbGeneration;
// --- Mode lecture (exposé) ---
W.WK_READING = WK_READING;
W.wkOpenReadingModeFromTitleEl = wkOpenReadingModeFromTitleEl;
W.wkOpenReadingModeFromPageTitle = wkOpenReadingModeFromPageTitle;
W.wkCloseReadingMode = wkCloseReadingMode;
}() );
mw.hook( 'wikipage.content' ).add( function ( $content ) {
if ( typeof wkIsNs === 'function' && !wkIsNs( 0 ) ) return;
$content.on( 'click', 'a.wk-js-nav', function ( e ) {
e.preventDefault();
var url = this.getAttribute( 'data-href' );
if ( !url ) return;
window.location.assign( url );
} );
} );
(function () {
'use strict';
if ( typeof wkIsNs === 'function' && !wkIsNs( 0 ) ) return;
if ( !document.querySelector( '.wk-auto-id' ) ) return;
function pad2(n) { return (n < 10 ? "0" : "") + n; }
function makeId() {
const d = new Date();
return (
d.getFullYear().toString() +
pad2(d.getMonth() + 1) +
pad2(d.getDate()) +
pad2(d.getHours()) +
pad2(d.getMinutes()) +
pad2(d.getSeconds())
);
}
function hasPlaceholder(href) {
return href && (href.indexOf("(ID)") !== -1 || href.indexOf("%28ID%29") !== -1);
}
function replacePlaceholder(href, id) {
// (ID) non encodé
href = href.replace("(ID)", "(" + id + ")");
// (ID) encodé : %28ID%29
href = href.replace("%28ID%29", "%28" + id + "%29");
return href;
}
// Capture = on passe avant la navigation et avant d'autres handlers
document.addEventListener("click", function (e) {
const wrap = e.target.closest(".wk-auto-id");
if (!wrap) return;
// On prend le premier lien à l’intérieur du bouton
const a = wrap.querySelector("a[href]");
if (!a) return;
// getAttribute peut contenir & etc, a.href donne l'URL résolue
const rawHref = a.getAttribute("href") || "";
const resolvedHref = a.href || rawHref;
const hrefToCheck = rawHref || resolvedHref;
if (!hasPlaceholder(hrefToCheck)) return;
e.preventDefault();
e.stopPropagation();
const id = makeId();
// On remplace sur la version "raw" si possible, sinon sur la résolue
const newHref = replacePlaceholder(rawHref || resolvedHref, id);
// Mettre à jour le lien + naviguer (clic sur div ou sur lien : les 2 marchent)
a.setAttribute("href", newHref);
try { a.href = newHref; } catch (err) {}
// Respecter target=_blank et les gestes "nouvel onglet"
const wantsNewTab =
(a.target && a.target.toLowerCase() === "_blank") ||
e.ctrlKey || e.metaKey || e.button === 1;
if (wantsNewTab) {
window.open(a.href, "_blank", "noopener");
} else {
window.location.href = a.href;
}
}, true);
})();