MediaWiki:Vector-2022.js
Note : après avoir publié vos modifications, il se peut que vous deviez forcer le rechargement complet du cache de votre navigateur pour voir les changements.
- Firefox / Safari : maintenez la touche Maj (Shift) en cliquant sur le bouton Actualiser ou appuyez sur Ctrl + F5 ou Ctrl + R (⌘ + R sur un Mac).
- Google Chrome : appuyez sur Ctrl + Maj + R (⌘ + Shift + R sur un Mac).
- Edge : maintenez la touche Ctrl en cliquant sur le bouton Actualiser ou pressez Ctrl + F5.
/* <Dynamic API call> */ $(function() { argumentMapContentCall(); argumentMapColor(); argumentContentCall(); argumentContentDrop(); closeArgument(); moreContentCall(); latestChangesCall(); hoverContentCall(); hoverContentLeave(); breadcrumbGeneration(); breadcrumbMenu(); fillEditSummary(); fillEditSummaryForCheckbox(); }); /* Pour afficher le contenu d'un argument ouvert et le fil d'Ariane correspondant */ function argumentContentCall() { $(document).on('click', '.argument-expandable-title:not(.expanded)', function() { // Récupérer la valeur de data-level de l'élément cliqué var level = $(this).data('level'); var clickedElement = $(this); // Stocker l'élément cliqué // Sélectionner tous les éléments qui ont la classe "argument-expandable-title", la classe "expanded", // et le même niveau (data-level égal à celui de l'élément cliqué) $('.argument-expandable-title.expanded').each(function() { // Vérifier que ce n'est pas l'élément cliqué en utilisant jQuery's is() pour comparer les objets if ($(this).data('level') === level && !$(this).is(clickedElement)) { // Supprimer la classe "expanded" et ajouter la classe "open" $(this).removeClass('expanded').addClass('open'); // Supprimer le contenu de l'élément suivant avec la classe "argument-content-wrapper" $(this).next('.argument-content-wrapper').empty(); } }); // Appeler les fonctions supplémentaires breadcrumbMenu(this); // Actualiser le fil d'Ariane loadContentFromTitle($(this)); // Charger le contenu associé à l'élément cliqué $(this).closest('.colonnes').addClass('inline'); // Ajouter une classe à l'élément parent $(this).addClass('actualiser-ariane'); // Ajouter une classe à l'élément cliqué }); } // Annule le script si clic sur le bouton modifier-argument $(document).on('click', '.ns-0 .modifier-argument a', function(event) { event.stopPropagation(); }); /* Pour afficher le contenu d'un argument ouvert */ function loadContentFromTitle(titleElement) { titleElement.addClass('expanded').removeClass('open'); var page = titleElement.data('page'); var template = titleElement.data('template'); var argument = titleElement.data('argument'); var type = titleElement.data('type'); var level = titleElement.data('level'); var root = titleElement.data('root'); var path = titleElement.data('path'); var warnings = titleElement.data('warnings'); var wrapper = titleElement.parent().find('.argument-content-wrapper'); var query = '{{' + template + '|page=' + page + '|argument=' + argument + '|type=' + type + '|niveau=' + level + '|racine=' + root + '|chemin=' + path + '|avertissements=' + warnings + '}}'; new mw.Api().post({ action: "parse", contentmodel: "wikitext", text: query }).done(function(data) { var text = data.parse.text['*'].replace(/<!--[\S\s]*?-->/gm, ''); wrapper.append(text); }); } /* Pour supprimer le contenu d'un argument fermé manuellement */ function argumentContentDrop() { $(document).on('click', '.ns-0 .argument-expandable-title.expanded', function() { if ($(event.target).closest('.modifier-dropdown').length) { return; // ignore le clic } $(this).removeClass('expanded').addClass('open'); var wrapper = $(this).parent().find('.argument-content-wrapper'); wrapper.empty(); }); } /* Pour afficher un argument de la carte des arguments sur lequel on clique */ function argumentMapContentCall() { $('.ns-0').on('click', '#Argument_map .titre-argument-carte', function() { $('.argument-expandable-title.expanded').each(function() { if ($(this).data('level') === 1) { $(this).removeClass('expanded').addClass('open'); $(this).next('.argument-content-wrapper').empty(); } }); var id = $(this).attr('id'); id = id.slice(0, -4); // Supprime "_map" var titleElement = $('#' + CSS.escape(document.getElementById(id).querySelector('div').id)); /* ⬇️ IMPORTANT : on indique que le scroll vient de la carte */ breadcrumbMenu(titleElement, { fromMapClick: true }); if (titleElement.find('.modifier-argument').length === 0) { titleElement.append('<span class="modifier-argument"><a href="#" title="Modifier cet argument">modifier</a></span>'); } if (!$(titleElement).hasClass('expanded')) { loadContentFromTitle(titleElement); } $(this).addClass('visited'); }); } /* Pour colorer dans la carte des arguments les arguments ouverts */ function argumentMapColor(){ $('.ns-0').on('click', '.liste-arguments .root-argument:not(.expanded)', function(){ var id = $(this).attr('id'); var element = $('#' + id + '_map'); element.addClass('visited'); }); } /*\ * * FIL D'ARIANE — sticky animé \*/ /* Hauteur du sticky header (0 si anonyme ou pas visible) */ function getVectorStickyHeaderHeight() { 'use strict'; var root = document.documentElement; /* A. Anonyme → 0 */ try { if (mw && mw.user && typeof mw.user.isAnon === 'function' && mw.user.isAnon()) { return 0; } } catch (e) {} /* B. Sticky pas activée → 0 */ if (!root.classList.contains('vector-sticky-header-enabled')) { return 0; } /* C. Sinon, mesure réelle (≈ 50px) */ var bar = document.querySelector('.vector-sticky-header'); var h = bar ? (bar.offsetHeight || 0) : 0; /* Filet de sécurité */ if (h <= 0) h = 50; return h; } /* Écrit la variable CSS top */ function setVectorStickyHeaderOffsetVar() { 'use strict'; var h = getVectorStickyHeaderHeight(); document.documentElement.style.setProperty('--vector-sticky-header-height', h + 'px'); return h; } /* Helpers état */ var filArianeObserver = null; var filArianeLock = false; function pauseFilArianeObserver() { if (filArianeObserver) { try { filArianeObserver.disconnect(); } catch (e) {} } } function resumeFilArianeObserver() { installOrUpdateObserver(); } function showFilAriane() { if (filArianeLock) return; var $fil = $('#fil-ariane'); if (!$fil.length) return; $fil.addClass('is-visible').removeClass('is-hidden').attr('aria-hidden','false'); } function hideFilAriane() { if (filArianeLock) return; var $fil = $('#fil-ariane'); if (!$fil.length) return; $fil.addClass('is-hidden').removeClass('is-visible').attr('aria-hidden','true'); } /* Mesure la hauteur réelle du fil (même si caché) */ function measureFilArianeHeight() { var $fil = $('#fil-ariane'); if (!$fil.length) return 0; if ($fil.hasClass('is-visible')) return $fil.outerHeight() || 0; var hadVisible = $fil.hasClass('is-visible'); var hadHidden = $fil.hasClass('is-hidden'); $fil.addClass('is-visible').removeClass('is-hidden'); var h = $fil.outerHeight() || 0; if (!hadVisible) $fil.removeClass('is-visible'); if (hadHidden) $fil.addClass('is-hidden'); return h; } /* Sentinel après #left-navigation */ function getOrCreateLeftNavSentinel() { var leftNav = document.querySelector('#left-navigation'); if (!leftNav) return null; var next = leftNav.nextElementSibling; if (next && next.id === 'fil-ariane-sentinel') return next; var sent = document.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; } /* Observer */ function installOrUpdateObserver() { var sentinel = getOrCreateLeftNavSentinel(); if (!sentinel) return; if (filArianeObserver) { try { filArianeObserver.disconnect(); } catch (e) {} } filArianeObserver = null; var headerOffset = setVectorStickyHeaderOffsetVar(); filArianeObserver = new IntersectionObserver(function(entries) { var entry = entries[0]; if (entry && entry.isIntersecting) { hideFilAriane(); } else { showFilAriane(); } }, { root: null, rootMargin: '-' + headerOffset + 'px 0px 0px 0px', threshold: 0 }); filArianeObserver.observe(sentinel); } /* Injection du fil */ function injectFilAriane(html) { var $nav = $('<nav>', { id: 'fil-ariane', class: 'zone-ariane fil-ariane--sticky is-hidden', role: 'navigation', 'aria-label': 'Fil d’Ariane', 'aria-hidden': 'true' }).append(html); var $main = $('main#content.mw-body').first(); if (!$main.length) $main = $('#content, .mw-body').first(); var $anchor = $main.children('.mw-body-header.vector-page-titlebar').first(); var $existing = $('#fil-ariane'); if ($existing.length) { $existing.replaceWith($nav); } else if ($anchor.length) { $anchor.before($nav); } else { $main.prepend($nav); } setVectorStickyHeaderOffsetVar(); installOrUpdateObserver(); } /* === Génération du fil d'Ariane (déduplication + anti-race) === */ (function () { // Remplace la fonction globale breadcrumbGeneration par une version dédupliquée var _xhr = null; // requête API en cours var _pendingKey = null; // clé de la requête en cours function normalizePath(path) { if (typeof path !== 'string') return ''; var s = path.replace(/\+/g, ' '); try { s = decodeURIComponent(s); } catch (e) { /* ignore si déjà décodé/partiel */ } return s.replace(/\s+/g, ' ').trim().toLowerCase(); } window.breadcrumbGeneration = function breadcrumbGeneration(titleElement) { if (typeof titleElement === 'undefined' || !titleElement) return; var $title = $(titleElement); var rawPath = $title.data('path'); var page = $title.data('page'); // Si pas de path → on supprime le fil if (!rawPath) { $('#fil-ariane').remove(); return; } // Clé normalisée pour comparer / mémoriser l’état var normPath = normalizePath(String(rawPath)); var normPage = String(page || ''); var newKey = normPath + '||' + normPage; var $bc = $('#fil-ariane'); var currentKey = $bc.attr('data-current-key') || ($bc.data('currentKey') || ''); // 1) Si le fil visible a déjà cette clé → rien à faire if (currentKey === newKey) return; // 2) Si une requête pour cette même clé est déjà en cours → inutile d’en relancer une if (_xhr && _pendingKey === newKey) return; // 3) On a une requête en cours mais pour une AUTRE clé → on l’annule (anti-race) if (_xhr) { try { _xhr.abort(); } catch (e) { /* noop */ } _xhr = null; _pendingKey = null; } // 4) Lancer la (seule) requête pour la nouvelle clé _pendingKey = newKey; var query = "{{Fil d'Ariane (menu) | chemin = " + rawPath + " | page = " + page + " }}"; _xhr = new mw.Api().post({ action: 'parse', contentmodel: 'wikitext', text: query }); _xhr.done(function (data) { // Si entre-temps une autre requête a pris la main, on ignore ce résultat if (_pendingKey !== newKey) return; var html = data && data.parse && data.parse.text && data.parse.text['*'] ? data.parse.text['*'].replace(/<!--[\S\s]*?-->/gm, '') : ''; injectFilAriane(html); // Après injection, on stocke la clé courante directement sur le conteneur var $bc2 = $('#fil-ariane'); if ($bc2.length) { $bc2 .attr('data-current-key', newKey) // pour CSS/devtools .data('currentKey', newKey) // pour lecture jQuery eventuelle .attr('data-current-path', normPath) .attr('data-current-page', normPage); } }).always(function () { // Libère l’état si c’était la requête active if (_pendingKey === newKey) { _xhr = null; _pendingKey = null; } }); }; })(); /* Menu */ function breadcrumbMenu(titleElement, opts) { opts = opts || {}; if (typeof titleElement === 'undefined') return; breadcrumbGeneration(titleElement); function recompute() { setVectorStickyHeaderOffsetVar(); installOrUpdateObserver(); } function scrollToTitle() { var $el = $(titleElement); if (!$el.length) return; var $fil = $('#fil-ariane'); if (!$fil.length) { setTimeout(scrollToTitle, 100); return; } var headerOffset = getVectorStickyHeaderHeight(); var safeGap = 12; var forceShow = !!opts.fromMapClick; if (forceShow) showFilAriane(); var sentinel = document.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.addClass('no-anim'); $('html, body').stop(true, false).animate({ scrollTop: targetY }, 120, function () { $fil.removeClass('no-anim'); filArianeLock = false; requestAnimationFrame(function () { resumeFilArianeObserver(); setVectorStickyHeaderOffsetVar(); }); }); } window.addEventListener('resize', recompute, { passive: true }); if (window.visualViewport) { visualViewport.addEventListener('resize', recompute, { passive: true }); visualViewport.addEventListener('scroll', recompute, { passive: true }); } if (window.MutationObserver) { new MutationObserver(recompute).observe(document.body, { attributes: true, attributeFilter: ['class'] }); } recompute(); setTimeout(scrollToTitle, 150); } /* === Survol dynamique arguments → mise à jour fil d'Ariane (anti-régénération via data-path) === */ (function () { // Empêche les doubles bindings si ce script est évalué plusieurs fois if (window._wikidebatsBreadcrumbHoverBound) return; window._wikidebatsBreadcrumbHoverBound = true; /* — Config — */ var NS_SCOPE = '.ns-0'; var SELECTOR_CONTENT = '.liste-arguments .contenu-argument, .liste-arguments .bouton-ajouter span, .liste-arguments span.remonter-argument'; var SELECTOR_TITLESPAN = '.liste-arguments .argument-expandable-title.level-sup span'; var DELAY_CONTENT_MS = 1500; var DELAY_TITLE_MS = 500; var BREADCRUMB_ROOT = '#fil-ariane'; var REQUIRE_INLINE_FOR_TITLES = false; // ⬅️ ancien comportement = true ; on passe à false par défaut var hoverTimeout = null; // timer différé unique var isHovered = false; // état courant var lastKey = null; // dernière clé comparée (data-path normalisé, sinon nœud DOM) /* — Helpers — */ function breadcrumbExists() { return !!$(BREADCRUMB_ROOT).length; } function normalizePath(path) { if (typeof path !== 'string') return ''; var s = path.replace(/\+/g, ' '); try { s = decodeURIComponent(s); } catch (e) { /* ignore */ } return s.replace(/\s+/g, ' ').trim().toLowerCase(); } function keyFromTitle($title) { if (!$title || !$title.length) return null; var raw = $title.attr('data-path'); if (raw) return normalizePath(raw); return $title.get(0) || null; // fallback par référence DOM } function getTitleFromContentTarget($t) { // structure : .argument-content-wrapper → prev() = .argument(...) return $t.closest('.argument-content-wrapper').prev('.argument'); } function getTitleFromTitleSpanTarget($t) { return $t.closest('.argument-expandable-title'); } function isInInlineColumns($title) { var $c = $title.closest('.colonnes'); return $c.length && $c.hasClass('inline'); } function maybeUpdateBreadcrumb($title) { if (!$title || !$title.length) return; var key = keyFromTitle($title); if (key == null) return; // ne régénérer que si la clé (path ou DOM) a changé if (key !== lastKey) { lastKey = key; breadcrumbGeneration($title); if (typeof installOrUpdateObserver === 'function') { installOrUpdateObserver(); } } } function scheduleUpdate($title, delayMs, extraCondition) { isHovered = true; clearTimeout(hoverTimeout); hoverTimeout = setTimeout(function () { if (!isHovered || !$title.length) return; if (typeof extraCondition === 'function' && !extraCondition($title)) return; maybeUpdateBreadcrumb($title); }, delayMs); } /* — Délégation d'événements — */ // 1) Survol des contenus (1500 ms) $(NS_SCOPE).on( 'mouseenter.wikidebatsBreadcrumbHover', SELECTOR_CONTENT, function () { var $title = getTitleFromContentTarget($(this)); scheduleUpdate($title, DELAY_CONTENT_MS, function () { return true; }); } ).on( 'mouseleave.wikidebatsBreadcrumbHover', SELECTOR_CONTENT, function () { isHovered = false; clearTimeout(hoverTimeout); } ); // 2) Survol des titres (500 ms) $(NS_SCOPE).on( 'mouseenter.wikidebatsBreadcrumbHoverTitle', SELECTOR_TITLESPAN, function () { // ⚠️ on NE s'appuie plus sur un $breadcrumb mis en cache // Si tu veux forcer l'existence du conteneur, dé-commente la ligne suivante : // if (!breadcrumbExists()) return; var $title = getTitleFromTitleSpanTarget($(this)); scheduleUpdate($title, DELAY_TITLE_MS, function ($t) { // Ancien comportement : seulement si parent .colonnes.inline return REQUIRE_INLINE_FOR_TITLES ? isInInlineColumns($t) : true; }); } ).on( 'mouseleave.wikidebatsBreadcrumbHoverTitle', SELECTOR_TITLESPAN, function () { isHovered = false; clearTimeout(hoverTimeout); } ).on( 'mousemove.wikidebatsBreadcrumbHoverTitle', SELECTOR_TITLESPAN, function () { isHovered = true; } ); /* — Si le fil est modifié ailleurs, on invalide la clé pour autoriser une future MAJ — */ if ('MutationObserver' in window) { var $bc = $(BREADCRUMB_ROOT); if ($bc.length) { var mo = new MutationObserver(function () { lastKey = null; }); mo.observe($bc.get(0), { childList: true, subtree: true, attributes: true, characterData: true }); } } })(); /* Pour réafficher le contenu d'un argument du fil d'Ariane */ $(document).on('click', '#fil-ariane .lien-ariane', function(){ var titleElement = $(this).data('anchor'); var escapedTitleElement = CSS.escape(titleElement); escapedTitleElement = document.getElementById(titleElement); var level = $(this).data('level'); closeArgument(level + 1); // Réafficher les justifications et objections en deux colonnes var parentElement = $(escapedTitleElement).closest('.argument-expandable'); var inlineElement = parentElement.find('.colonnes.inline'); inlineElement.removeClass('inline'); if (!parentElement.length) { $('.colonnes').removeClass('inline'); } // Régénérer le menu du fil d'Ariane breadcrumbMenu(escapedTitleElement); }); /* Pour supprimer le fil d'Ariane */ $(document).on('click', '.supprimer-ariane', function(event){ var nav = $(document).find('#fil-ariane'); nav.replaceWith('').show(); }); /* Pour vider le contenu du fil d'Ariane à la fermeture d'un argument de niveau 1 */ $('.ns-0').on('click', '.liste-arguments .argument-expandable-title.level-1.expanded', function(e){ // Vérifier si le clic vient de la zone de modification if ($(e.target).closest('.modifier-argument, .modifier-dropdown').length === 0) { // Si ce n'est pas un clic sur modifier, on vide le fil d'Ariane $('#fil-ariane .argument-ariane').remove(); } }); /* Pour remonter à la carte des arguments */ ( function ( mw, $ ) { 'use strict'; // Récupération robuste de la hauteur du sticky header : // - essaie d'abord la variable CSS --vector-sticky-header-height (si définie), // - sinon fallback 50px. function getStickyHeight () { try { var root = document.documentElement; var val = getComputedStyle( root ).getPropertyValue( '--vector-sticky-header-height' ).trim(); if ( val ) { // gère des valeurs comme "50px" var px = parseFloat( val ); if ( !isNaN( px ) ) return px; } } catch (e) {} return 50; } // Détermine si l'utilisateur est anonyme (pas de nom d'utilisateur) function isAnon () { try { return mw.config.get( 'wgUserName' ) === null; } catch (e) { return true; } } // Handler principal (délégué) $( document ).on( 'click', '.remonter-fil, .remonter-carte', function ( e ) { e.preventDefault(); var $map = $( '#Argument_map' ); if ( !$map.length ) return; var $fil = $( '#fil-ariane' ); var filExists = $fil.length > 0; var anon = isAnon(); var stickyEnabled = document.documentElement.classList.contains( 'vector-sticky-header-enabled' ); var targetScroll = 0; if ( anon ) { // 1) Utilisateur anonyme → retirer seulement l'argument courant, puis scroller sous le fil var filH1 = 0; if ( filExists ) { $fil.find( '.argument-ariane' ).remove(); filH1 = $fil.outerHeight( true ) || 0; } var mapTop1 = $map.offset().top; targetScroll = mapTop1 - filH1; } else if ( stickyEnabled ) { // 2) Sticky header activé → retirer complètement le fil, scroller sous le sticky if ( filExists ) $fil.remove(); var mapTop2 = $map.offset().top; targetScroll = mapTop2 - getStickyHeight(); } else { // 3) Connecté sans sticky → logique héritée (−35) var filH3 = 0; if ( filExists ) { filH3 = $fil.height() || 0; $fil.find( '.argument-ariane' ).remove(); } var mapTop3 = $map.offset().top; targetScroll = mapTop3 - filH3 - 35; } $( 'html, body' ).stop( true ).animate( { scrollTop: Math.max( 0, targetScroll ) }, 50 ); if ( typeof window.closeArgument === 'function' ) { window.closeArgument( 1 ); } } ); } )( mw, jQuery ); /* Pour remonter en tête de page dans les autoévaluations */ $('.ns-3100').on('click', '.remonter-autoevaluation, .titre-ariane', function(event) { event.preventDefault(); $('.colonnes').removeClass('inline'); $('html, body').animate({ scrollTop: 0 }, 'slow'); closeArgument(2); }); /* Pour fermer automatiquement un argument et retirer le gras pour indiquer qu'il a été ouvert */ function closeArgument(level, clickedElement) { // Si clickedElement n'est pas défini, on l'assigne à null clickedElement = clickedElement || null; // Sélectionner tous les éléments qui ont la classe "argument-expandable-title" et la classe "expanded" $('.argument-expandable-title.expanded').each(function() { // Vérifier si l'élément a le même niveau (data-level égal) et que ce n'est pas l'élément cliqué (si fourni) if ($(this).data('level') === level && (!clickedElement || !$(this).is(clickedElement))) { // Supprimer la classe "expanded" et ajouter la classe "open" $(this).removeClass('expanded').addClass('open'); // Supprimer le contenu de l'élément suivant avec la classe "argument-content-wrapper" $(this).next('.argument-content-wrapper').empty(); } }); } /* Pour afficher un contenu supplémentaire */ function moreContentCall() { $(document).on('click', '.more-content-button', function() { $(this).hide(); var page = $(this).data('page'); var wrapper = $(this).parent().find('.more-content-wrapper'); var query = '{{Contenu supplémentaire | page = ' + page + '}}'; new mw.Api().post({ action: "parse", contentmodel: "wikitext", text: query }).done(function(data) { var text = data.parse.text['*'].replace(/<!--[\S\s]*?-->/gm, ''); wrapper.replaceWith('<div class="more-content-wrapper"><div class="more-content-drop show"></div>' + text + '</div>'); }); }); } /* Pour afficher une infobulle au survol */ function hoverContentCall(){ $(document).on('mouseenter', '.hover-link', function(){ var template = $(this).data('template'); var parameter1 = $(this).data('parameter1'); var parameter2 = $(this).data('parameter2'); var parameter3 = $(this).data('parameter3'); var position = $(this).data('position'); var wrapper = $(this).find('.hover-content-wrapper'); var query = '{{ ' + template + ' | ' + parameter1 + ' | ' + parameter2 + ' | ' + parameter3 + ' }}'; new mw.Api().post({ action: "parse", contentmodel: "wikitext", text: query }).done( function( data ) { var text = data.parse.text['*'].replace(/<!--[\S\s]*?-->/gm, '' ); wrapper.replaceWith('<div class="hover-content-wrapper show ' + position + '">' + text + '</div>').show(); }); }); } /* Pour masquer l'infobulle */ function hoverContentLeave(){ $(document).on('mouseleave', '.hover-link', function(){ $(this).find('.hover-content-wrapper').replaceWith('<div class="hover-content-wrapper"></div>'); }); } /* Pour afficher les dernières modifications d'un débat */ function latestChangesCall(){ $('.ns-0').on('click', '.latest-changes-button.mw-ui-button', function(){ $(this).hide(); var page = $(this).data('page'); var wrapper = $(this).parent().find('.latest-changes-wrapper'); var query = '{{Dernières modifications | page = ' + page + '}}'; new mw.Api().post({ action: "parse", contentmodel: "wikitext", text: query }).done( function( data ) { var text = data.parse.text['*'].replace(/<!--[\S\s]*?-->/gm, '' ); wrapper.replaceWith('<div class="latest-changes-wrapper"><div class="latest-changes-drop show"></div>' + text + '</div>'); }); }); } /* Pour ouvrir certains liens dans un nouvel onglet */ $(document).on('click', '.onglet-externe a', function(event) { event.preventDefault(); var url = $(this).attr('href'); window.open(url, '_blank'); }); /* Pour remonter en début de page après chaque évaluation d'un argument */ $(document).on('click', '.ns-3100 .bouton-argument-suivant', function() { $('html, body').animate({ scrollTop: 0 }, 'slow'); // Fait défiler en douceur }); /* Pour déplacer le bouton Renommer après le titre de la page */ function renameButton( $content ) { var $span = $content.find( '#bouton-renommer' ); if ( $span.length ) { if (!document.body.classList.contains("action-view")) { clearInterval(waitForElements); return; } $span.css('display', 'inline'); $( '.firstHeading' ).append( $span ); $span.find('a').text(''); // Supprimer le texte à l'intérieur du lien } } mw.hook( 'wikipage.content' ).add( renameButton ); /* Pour déplacer le bouton Modifier le sujet du débat */ function moveTopicButton() { /* Vérifie qu’on est en mode lecture (action-view et pas action-submit) */ if (!document.body.classList.contains("action-view")) { clearInterval(waitForElements); return; } var bouton = document.getElementById("bouton-modifier-sujet"); var contentSub = document.getElementById("contentSub"); if (bouton && contentSub) { contentSub.appendChild(bouton); contentSub.style.display = "flex"; bouton.style.display = "flex"; clearInterval(waitForElements); // Stop checking } } var waitForElements = setInterval(moveTopicButton, 300); /* Pour déplacer le bouton Modifier les rubriques */ (function() { var boutonId = "bouton-modifier-categories"; var catId = "mw-normal-catlinks"; function tryMoveButton() { var bouton = document.getElementById(boutonId); var categories = document.getElementById(catId); if (!bouton || !categories) return false; var ul = categories.querySelector("ul"); if (!ul) return false; var lastLi = ul.querySelector("li:last-child"); if (!lastLi) return false; if (bouton.parentElement !== lastLi) { lastLi.appendChild(bouton); } bouton.style.display = "inline"; return true; } // Essaye immédiatement if (tryMoveButton()) return; // Sinon observe le DOM pour agir dès qu’ils apparaissent var observer = new MutationObserver(function() { if (tryMoveButton()) { observer.disconnect(); // Stopper l’observation } }); observer.observe(document.body, { childList: true, subtree: true }); })(); /* Pour déplacer le bouton Modifier des liens interlangues */ (function () { 'use strict'; var MARKER_SELECTOR = '#bouton-modifier-interlangue'; var PORTLET_SELECTOR = '#p-lang-btn .vector-dropdown-content'; var NEW_ID = 'modifier-langues-lien'; function buildEditLink() { var marker = document.querySelector(MARKER_SELECTOR); if (!marker) return false; var container = document.querySelector(PORTLET_SELECTOR); if (!container) return false; // Éviter les doublons if (document.getElementById(NEW_ID)) return true; // 1) Récupérer l'ancre var sourceLink = marker.tagName === 'A' ? marker : marker.querySelector('a'); if (!sourceLink || !sourceLink.href) return false; // 2) Cloner l'ancre et l’adapter var newLink = sourceLink.cloneNode(false); newLink.id = NEW_ID; newLink.textContent = 'Modifier'; newLink.setAttribute( 'class', (sourceLink.getAttribute('class') || '').trim() + ' interlanguage-edit-link' ); newLink.removeAttribute('target'); newLink.setAttribute('rel', 'nofollow'); // 3) L’envelopper dans un conteneur var wrap = document.createElement('div'); wrap.className = 'modifier-langues'; wrap.appendChild(newLink); // 4) Insérer à la fin du dropdown (après la liste des langues) container.appendChild(wrap); // 5) Supprimer le marqueur d’origine marker.remove(); return true; } // Tentative immédiate if (buildEditLink()) return; // Observation du DOM (injections tardives de Vector/ULS) var obs = new MutationObserver(function () { if (buildEditLink()) { obs.disconnect(); } }); obs.observe(document.documentElement, { childList: true, subtree: true }); // Sécurité après onload window.addEventListener('load', function () { buildEditLink(); }); })(); /* Pour compléter le résumé des modifications apportées selon la partie de la page modifiée */ function fillEditSummary(message) { if (typeof message === "undefined") { return; } var input = $('input[name=wpSummary]'); 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 (typeof object === "undefined") { return; } var summary = $('input[name=wpSummary]').val(); var checked = object.prop('checked'); var bannerName = object.parent(); var bannerName = $(bannerName).next(); var bannerName = $(bannerName).text() + ' »'; if (checked) { var actionDone = addingMessage + ' «'; } else { var actionDone = removingMessage + ' «'; } var message = actionDone + bannerName; fillEditSummary(message); } /* Pour compléter automatiquement les résumés de modification */ $(document).ready(function() { if ($('.mw-special-FormEdit').length > 0) { // Pour remplir automatiquement le résumé des modifications avec la section correspondante $(document).ready(function () { // Récupère la valeur de l'attribut data-section var sectionValue = $('#formName').data('section'); // Cible le champ input[name="wpSummary"] var summaryField = $('input[name="wpSummary"]'); // Vérifie que le champ est vide et que sectionValue existe if (summaryField.val().trim() === '' && sectionValue) { var section = '/* ' + sectionValue + ' */ '; summaryField.val(section); } }); // Pour les instances multiples $(document).ready(function() { var zones = [ { selector: '.zone-arguments-pour', labelReorg: 'Réorganisation des arguments', labelRenom: 'Renommage de l’argument : « ', labelSupp: 'Suppression de l’argument : « ', labelAjout: 'Ajout de l’argument existant : « ' }, { selector: '.zone-arguments-contre', labelReorg: 'Réorganisation des arguments', labelRenom: 'Renommage de l’argument : « ', labelSupp: 'Suppression de l’argument : « ', labelAjout: 'Ajout de l’argument existant : « ' }, { selector: '.zone-justifications', labelReorg: 'Réorganisation des arguments', labelRenom: 'Renommage de l’argument : « ', labelSupp: 'Suppression de l’argument : « ', labelAjout: 'Ajout de l’argument existant : « ' }, { selector: '.zone-objections', labelReorg: 'Réorganisation des arguments', labelRenom: 'Renommage de l’objection : « ', labelSupp: 'Suppression de l’objection : « ', labelAjout: 'Ajout de l’argument existant : « ' }, { selector: '.zone-introduction', labelReorg: 'Réorganisation des rubriques', labelRenom: 'Renommage de la rubrique : « ', labelSupp: 'Suppression de la rubrique : « ', labelSuppBis: 'Suppression d’une rubrique sans titre', labelAjout: 'Ajout d’une rubrique' }, { selector: '.zone-voir-Wikipedia', labelReorg: 'Réorganisation des articles', labelRenom: 'Renommage de l’article « ', labelSupp: 'Suppression de l’article « ', labelAjout: 'Ajout de l’article Wikipédia « ' }, { selector: '.zone-debats-connexes', labelReorg: 'Réorganisation des débats', labelRenom: 'Renommage du débat : « ', labelSupp: 'Suppression du débat : « ', labelAjout: 'Ajout du débat : « ' }, { selector: '.zone-interlangue', labelReorg: 'Réorganisation des liens interlangues', labelSupp: 'Suppression du lien vers « ', labelAjout: 'Ajout du lien interlangue vers : « ' }, { selector: '.zone-citations', labelReorg: 'Réorganisation des citations', labelSupp: 'Suppression de la citation de ', labelSuppBis: 'Suppression d’une citation', labelAjout: 'Ajout d’une citation' }, { selector: '.zone-references', labelReorg: 'Réorganisation des références', labelSupp: 'Suppression de la référence : « ', labelSuppBis: 'Suppression d’une référence', labelAjout: 'Ajout d’une référence' } ]; // Parcours des zones zones.forEach(function(zone) { // Suppression document.querySelectorAll(zone.selector + ' .instanceRemove a').forEach(function(element) { element.addEventListener('click', function(e) { e.preventDefault(); var row = element.closest('tr'); var titreInput = row ? row.querySelector('.parametre-important') : null; if (!titreInput) { titreInput = row ? row.querySelector('.parametre-important-bis') : null; } var titre = titreInput && titreInput.value ? titreInput.value : null; var message; if (titre) { if (zone.selector === '.zone-citations') { message = (titreInput ? zone.labelSupp : zone.labelSuppBis || zone.labelSupp) + titre; } else { message = (titreInput ? zone.labelSupp : zone.labelSuppBis || zone.labelSupp) + titre + ' »'; } } else { message = zone.labelSuppBis || zone.labelSupp; } fillEditSummary(message); }); }); // Ajout window.ajoutInstance = false; document.querySelectorAll(zone.selector + ' .instanceAddAbove a' + ', ' + zone.selector + ' .multipleTemplateAdder').forEach(function(element) { element.addEventListener('click', function(e) { e.preventDefault(); if ( zone.selector === '.zone-introduction' || zone.selector === '.zone-citations' || zone.selector === '.zone-references' ) { fillEditSummary(zone.labelAjout); } else { window.ajoutInstance = true; window.ajoutInstanceZone = zone.selector; } }); }); // Renommage var inputs = document.querySelectorAll(zone.selector + ' .parametre-important'); for (var i = 0; i < inputs.length; i++) { inputs[i].addEventListener('blur', function(e) { var value = e.target.value; if (value && value.trim() !== '') { if (typeof fillEditSummary === 'function') { // On remplace totalement le résumé pour éviter les répétitions fillEditSummary(zone.labelRenom + value + ' »'); } } }); } // Réorganisation var ordreInitial = []; var reorganisationDejaFaite = false; var clicEnCours = false; function getOrdre() { return Array.from(document.querySelectorAll(zone.selector + ' .multipleTemplateInstance')) .map(function(el) { var input = el.querySelector('select, input'); return input && input.value ? input.value : el.innerText.trim(); }); } // Étape 1 : clic sur un handle dans la zone document.querySelectorAll(zone.selector + ' .instanceRearranger').forEach(function(el) { el.addEventListener('mousedown', function() { ordreInitial = getOrdre(); clicEnCours = true; }); }); // Étape 2 : écoute du mouseup dans la même zone var zoneElement = document.querySelector(zone.selector); if (zoneElement) { // Vérifie si l'élément existe zoneElement.addEventListener('mouseup', function() { if (!clicEnCours || reorganisationDejaFaite) return; var ordreFinal = getOrdre(); if (JSON.stringify(ordreInitial) !== JSON.stringify(ordreFinal)) { fillEditSummary(zone.labelReorg); reorganisationDejaFaite = true; } clicEnCours = false; }); } // Ajout d'une instance de type token function attachHandler() { $('select').off('select2:select.fullListener').on('select2:select.fullListener', function (e) { var selectedId = e.params.data && e.params.data._resultId; var $option = selectedId ? $(document.getElementById(selectedId)) : null; // Texte de base depuis l'événement var match = e.params.data.text.trim(); // Si possible, extraire la version enrichie du DOM if ($option && $option.find('.select2-match-entire').length) { match = $option.find('.select2-match-entire').text().trim(); } var message; if (window.ajoutInstance && window.ajoutInstanceZone) { var matchedZone = zones.find(function(z) { return z.selector === window.ajoutInstanceZone; }); if (matchedZone) { message = matchedZone.labelAjout + match + ' »'; } else { message = 'Ajout de « ' + match + ' »'; } window.ajoutInstance = false; window.ajoutInstanceZone = null; } else { message = 'Ajout de « ' + match + ' »'; } fillEditSummary(message); }); } // MutationObserver pour chaque zone zones.forEach(function(zone) { var observer = new MutationObserver(attachHandler); observer.observe(document.body, { childList: true, subtree: true }); }); }); }); // Pour les cases à cocher d'avertissements $(document).on('click', '.checkboxesSpan .oo-ui-inputWidget-input', function() { if ($(this).closest('.zone-rubriques').length === 0) { fillEditSummaryForCheckbox($(this), 'Ajout du bandeau d’avertissement', 'Retrait du bandeau d’avertissement'); } }); // Pour les cases à cocher de rubriques $(document).ready(function() { $(document).on('click', '.zone-rubriques' + ' .oo-ui-inputWidget-input', function() { fillEditSummaryForCheckbox($(this), 'Ajout de la rubrique', 'Retrait de la rubrique'); }); }); // Pour le changement de l'état d'avancement du débat $(document).on('change', '.mw-special-FormEdit .zone-bandeaux .mandatoryField', function() { var summary = $('input[name=wpSummary]').val(); var bannerName = $('.zone-bandeaux select.mandatoryField option:selected').val() + ' »'; // Sélectionne le select dans la zone-bandeaux var actionDone = 'Niveau d’avancement du débat changé à « '; var message = actionDone + bannerName; fillEditSummary(message); }); // Pour la suppression de mots-clés $(document).on('click', '.select2-selection__choice__remove', function() { var $li = $(this).closest('.select2-selection__choice'); var keyword = $li.find('.select2-match-entire').text(); var message = 'Suppression de « ' + keyword + ' »'; fillEditSummary(message); }); // Pour le sujet du débat var $summary = $('input[name=wpSummary]'); var sujetCompletInitial = $('.zone-sujet-complet').val(); // Sauvegarder la valeur initiale au chargement $(document).on('change', '.zone-sujet-complet', function() { var sujetCompletActuel = $(this).val(); var summary = $summary.val(); var ajoutOuModification = ''; if (sujetCompletInitial === '' && sujetCompletActuel !== '') { ajoutOuModification = 'Ajout du sujet : « ' + sujetCompletActuel + ' »'; } else if ( sujetCompletInitial !== '' && sujetCompletActuel !== '' && sujetCompletInitial !== sujetCompletActuel ) { ajoutOuModification = 'Sujet modifié : « ' + sujetCompletActuel + ' »'; } if (ajoutOuModification) { summary = '/* Sujet du débat */ ' + ajoutOuModification; $summary.val(summary); } }); // Pour ajouter au résumé de modifications les opérations proposées $(document).on('click', '.resume-modifications', function() { var summary = $('input[name=wpSummary]').val(); var newSummary = $(this).text(); if (summary) { var condition = summary.substr(-3); if (condition == '*/ ') { summary = summary + newSummary; $('input[name=wpSummary]').val(summary); } else { summary = summary + ' + ' + newSummary; $('input[name=wpSummary]').val(summary); } } else { $('input[name=wpSummary]').val(newSummary); } }); // Pour copier automatiquement le titre de la page de l'argument dans le champ "Titre affiché" $(document).on('select2:select', '.zone-arguments .pfTokens', function (e) { // Récupérer le texte de l'option sélectionnée var selectedText = e.params.data.text; // Trouver l'élément d'entrée juste après le select2 var inputField = $(this).closest('tr').next('tr').find('.createboxInput'); // Copier le texte seulement si le champ est vide if (inputField.val() === '') { inputField.val(selectedText); } }); } }); $(document).ready(function() { if ($('.mw-editable.action-formedit').length > 0) { // Déclaration de la variable summary une seule fois var $summary = $('input[name=wpSummary]'); // Pour la modification ou l'ajout du sujet du débat var $selectSujet = $('select[name="Débat[sujet][]"]'); if ($selectSujet.length > 0) { var sujetInitial = $selectSujet.val() ? $selectSujet.val()[0] : ''; $selectSujet.on('change', function() { var sujetActuel = $(this).val() ? $(this).val()[0] : ''; if (!sujetActuel || sujetActuel === sujetInitial) return; var summary = $summary.val(); // Supprimer toute ancienne ligne de sujet principal summary = summary.replace(/Modification du sujet principal du débat\s?:\s?.+?( \+ |$)/, ''); // Construire la nouvelle ligne var ajoutSujet = 'Modification du sujet principal du débat : ' + sujetActuel; // Si le résumé n'est pas vide, on ajoute avec " + " if (summary.trim() !== '') { summary += ' + ' + ajoutSujet; } else { summary = ajoutSujet; } $summary.val(summary); }); } // Pour la modification ou l'ajout du sujet complet var sujetCompletInitial = $('.zone-sujet-complet').val(); // Sauvegarder la valeur initiale au chargement $(document).on('change', '.zone-sujet-complet', function() { var sujetCompletActuel = $(this).val(); var summary = $summary.val(); var ajoutOuModification = ''; if (sujetCompletInitial === '' && sujetCompletActuel !== '') { ajoutOuModification = 'Ajout du sujet complet'; } else if (sujetCompletInitial !== '' && sujetCompletActuel !== '' && sujetCompletInitial !== sujetCompletActuel) { ajoutOuModification = 'Modification du sujet complet'; } if (ajoutOuModification) { if (summary) { summary = summary + ' + ' + ajoutOuModification; } else { summary = ajoutOuModification; } $summary.val(summary); } }); // Pour l'ajout du débat détaillé var $zoneDebat = $('.zone-debat-detaille'); var debatDetailleInitial = ''; // Variable pour stocker le texte initial // Vérifier si la classe .select2-match-entire existe dans la structure attendue if ($zoneDebat.find('.select2-selection__choice .select2-match-entire').length > 0) { // Récupérer le texte initial du champ debatDetailleInitial = $zoneDebat.find('.select2-selection__choice .select2-match-entire').text().trim(); } // Sur changement dans .zone-debat-detaille $zoneDebat.on('change', function() { var debatDetailleActuel = $zoneDebat.find('.select2-selection__choice .select2-match-entire').text().trim(); // Si le champ est modifié et qu'il est non vide if (debatDetailleActuel !== '' && debatDetailleInitial !== debatDetailleActuel) { var summary = $summary.val(); // Ajouter "Ajout du débat détaillé" avec le titre du débat var ajoutDebat = 'Ajout du débat détaillé : ' + debatDetailleActuel; // Si le résumé n'est pas vide, on ajoute avec " + " if (summary.trim() !== '') { summary += ' + ' + ajoutDebat; } else { summary = ajoutDebat; } // Mettre à jour le résumé des modifications $summary.val(summary); // Mettre à jour la variable initiale pour éviter les ajouts multiples debatDetailleInitial = debatDetailleActuel; } // Si le champ débat est vidé, réinitialiser debatDetailleInitial if (debatDetailleActuel === '') { debatDetailleInitial = ''; } }); } }); /* Pour afficher les notes de bas de page au survol */ /** * For suppressing tooltips on interactive elements created with an API call * @example <> */ (function($,mw){ removeTooltips(); }(jQuery, mediaWiki)); function removeTooltips(){ $(document).on('mouseenter', '.hover-content-wrapper a', function(){ $(this).removeAttr('title'); }); $(document).on('mouseenter', '.hover-link a', function(){ $(this).removeAttr('title'); }); } /** * fork de jQuery makeCollapsible * * script initial : http://www.mediawiki.org/wiki/RL/DM#jQuery.makeCollapsible * auteur initial : Krinkle <[email protected]> * * modifications : http://fr.wikipedia.org/wiki/Utilisateur:Lgd * * Dual license: * @license CC-BY 3.0 <http://creativecommons.org/licenses/by/3.0> * @license GPL2 <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html> */ /*\ * * FONCTION DE SECTIONS DÉROULANTES \*/ 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; /* a11y + état de base (jamais display:none) */ $toggle.attr({role:'button', tabindex:0}); $content.removeAttr('hidden')[0].style.display = 'block'; var reduce = window.matchMedia && window.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){ expanded ? openPanel(instant) : 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); } }); /* état initial instantané */ setState(!$box.hasClass('fr-collapsed'), true); }); } mw.hook('wikipage.content').add(function($content){ bindFrCollapsible($content); }); /*\ * * REFERENCE TOOLTIPS \*/ // See [[mw:Reference Tooltips]] // Source https://en.wikipedia.org/wiki/MediaWiki:Gadget-ReferenceTooltips.js // Modifié par ChatGPT /* Infobulle de références — simplifié * - Survol d'un numéro de note -> affiche la note en infobulle * - Infobulle interactive (reste ouverte tant que la souris est dessus) * - Aucune autre option/paramètre */ /* Infobulle de références — ouverture au clic (MW 1.43) */ ( function ( mw, $ ) { 'use strict'; var $win = $( window ); var $body = $( document.body ); var $tooltip, $content, currentTrigger; 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( $body ).hide(); $content = $tooltip.find( '.wk-ref-tooltip__content' ); // garder ouvert quand on clique dedans $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( true ); $clone.find( '.mw-cite-backlink' ).remove(); return $clone.html() || ''; } function positionTooltip( $trigger ) { var rect = $trigger[0].getBoundingClientRect(); $tooltip.css( { top: -9999, left: -9999, right: '' } ).show(); var tipW = $tooltip.outerWidth(); var tipH = $tooltip.outerHeight(); var scrollX = $win.scrollLeft(); var scrollY = $win.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 + $win.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; $win.off( 'scroll.refhover resize.refhover keydown.refhover' ); $body.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; $win.on( 'scroll.refhover resize.refhover', function () { if ( currentTrigger ) positionTooltip( currentTrigger ); } ).on( 'keydown.refhover', function ( e ) { if ( e.key === 'Escape' || e.key === 'Esc' ) hideNow(); } ); // fermer au clic à l'extérieur (click, pas mousedown) $body.on( 'click.refhover', function () { hideNow(); } ); } function toggleFor( $a ) { if ( currentTrigger && currentTrigger[0] === $a[0] ) { hideNow(); } else { showFor( $a ); } } function bindOn( $root ) { var $links = $root .find( 'sup.reference[id^="cite_ref"] > a, a[href^="#cite_note-"]' ) .not( '.wk-ref-tooltip-bound' ) .addClass( 'wk-ref-tooltip-bound' ); $links.on( 'click.refhover', function ( e ) { // évite le défilement et bloque Cite (évite l’erreur dispatch) e.preventDefault(); e.stopPropagation(); e.stopImmediatePropagation(); toggleFor( $( this ) ); } ); $links.on( 'keydown.refhover', function ( e ) { if ( e.key === 'Enter' || e.key === ' ' || e.code === 'Space' ) { e.preventDefault(); e.stopPropagation(); e.stopImmediatePropagation(); toggleFor( $( this ) ); } } ); } mw.hook( 'wikipage.content' ).add( bindOn ); }( mediaWiki, jQuery ) ); /* Pour masquer certaines infobulles */ document.querySelectorAll('.masquer-infobulle a[title]').forEach(function(link) { link.removeAttribute('title'); // Supprime complètement l'attribut }); /* Pour créer un menu déroulant de modification des arguments */ $('.ns-0').ready(function() { // Au clic sur un div.argument-expandable-title (pas encore expanded) $('.ns-0').on('click', 'div.argument-expandable-title:not(.expanded)', function() { var $argumentTitle = $(this); // Ajoute le lien "modifier" s'il n'existe pas déjà if ($argumentTitle.find('.modifier-argument').length === 0) { $argumentTitle.append('<span class="modifier-argument"><a href="#" title="Modifier cet argument">modifier</a></span>'); } }); // Au clic sur "modifier", afficher ou masquer le menu déroulant $('.ns-0').on('click', '.modifier-argument a', function(e) { e.preventDefault(); var $argumentTitle = $(this).closest('.argument-expandable-title'); var identifiantEnc = $argumentTitle.attr('data-argument'); var identifiant = encodeURIComponent(decodeURIComponent(identifiantEnc.replace(/\+/g, ' '))).replace(/%20/g, '_'); var $dropdown = $argumentTitle.find('.modifier-dropdown'); // Si le menu existe déjà, toggle if ($dropdown.length) { $dropdown.toggle(); } else { // Crée le menu déroulant var menu = $('<div class="modifier-dropdown"></div>').attr('data-parent', $argumentTitle.attr('id')); // Cherche le lien "Modifier le titre affiché" var lienModifierTitre = '#'; // Premier cas : remonter jusqu'à .NavFramex 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 { // Deuxième cas : remonter jusqu'à <h2.section-modifiable> au-dessus du <section> parent var ulListe = $argumentTitle.closest("ul.liste-arguments"); 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'); } } } // Ajoute le premier lien "Modifier le titre affiché" var lienTitre = $('<span><a></a></span>'); var iconeTitre = $('<img>') .attr('src', '/w/images/fr/b/ba/Modifier.svg') .attr('alt', '') .attr('class', 'picto-dropdown'); lienTitre.find('a') .attr('href', lienModifierTitre) .attr('target', '_self') .append(iconeTitre) .append('Modifier le titre affiché'); menu.append(lienTitre); // Autres liens var formulaireTexte = [ { formulaire: 'Résumé', texte: 'Modifier le résumé', icone: '/w/images/fr/c/c6/Contributions.svg' }, { formulaire: 'Citations', texte: 'Modifier les citations', icone: '/w/images/fr/6/6e/Citation.svg' }, { formulaire: 'Références', texte: 'Modifier les références', 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', ''); lien.find('a') .attr('href', '/wiki/Sp%C3%A9cial:AjouterDonn%C3%A9es/' + item.formulaire + '/' + identifiant) .attr('target', '_self') .append(icone) .append(item.texte); menu.append(lien); }); // Ajoute le 4e lien "Voir la page détaillée" 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'); lienExterne.find('a') .attr('href', '/wiki/' + identifiant) .attr('target', '_self') .append(iconeExterne) .append('Voir la page détaillée'); menu.append(lienExterne); // Ajoute le menu déroulant au DOM et l'affiche $argumentTitle.append(menu); menu.show(); } }); // Ferme le menu si on clique ailleurs que sur le menu ou le bouton "modifier" $('.ns-0').on('click', function(e) { if (!$(e.target).closest('.modifier-dropdown, .modifier-argument').length) { $('.modifier-dropdown').hide(); } }); }); /* Réactive les infobulles dans les formulaires après chargement de la page */ mw.loader.using( 'ext.smw.tooltip' ).then( function () { function reinitSMWTooltips( $root ) { if ( window.smw && smw.tooltip && smw.tooltip.init ) { smw.tooltip.init( $root || $( document ) ); } } // 1) au premier affichage du formulaire reinitSMWTooltips( $( document ) ); // 2) après ajouts dynamiques (multi-instance, etc.) $( document ).on( 'pfaddinstance pfafterrebuild pfcreateinput', function ( e ) { reinitSMWTooltips( $( e.target ) ); } ); } );