| Contenidos de Wikipedia en español bajo licencia CC BY-SA 4.0 ⇔ Mapas de OpenStreetMap bajo licencia ODbL |
MediaWiki:Common.js
De Hispanopedia
Nota: Después de publicar, quizás necesite actualizar la caché de su navegador para ver los cambios.
- Firefox/Safari: Mantenga presionada la tecla Shift mientras pulsa el botón Actualizar, o presiona Ctrl+F5 o Ctrl+R (⌘+R en Mac)
- Google Chrome: presione Ctrl+Shift+R (⌘+Shift+R en Mac)
- Edge: mantenga presionada Ctrl mientras pulsa Actualizar, o presione Ctrl+F5
// MediaWiki:Common.js
// Optimized for MediaWiki 1.43.3+ with Timeless skin exclusively.
// Features: skin redirects, URL parameter loading, collapsible templates, progressive image loading,
// interwiki highlighting, table sorting, map integration.
// Dependencies: mediawiki.util (always), jquery.tablesorter (conditional).
//
// Setup:
// 1. Host these pages in MediaWiki namespace:
// - MediaWiki:Wdsearch.js, MediaWiki:Wikiminiatlas.js, MediaWiki:OSM.js
// - MediaWiki:Edittools.js, MediaWiki:Common.js/seguimiento.js
// 2. Upload Erioll_world.svg to /images/Erioll_world.svg
// 3. Define message pages: MediaWiki:Commonjs-collapse, MediaWiki:Commonjs-expand,
// MediaWiki:Commonjs-invalid-withcss, MediaWiki:Commonjs-invalid-withcss-title,
// MediaWiki:Commonjs-invalid-withjs, MediaWiki:Commonjs-invalid-withjs-title,
// MediaWiki:Commonjs-featured-article, MediaWiki:Commonjs-good-article,
// MediaWiki:Commonjs-wikipedia-list, MediaWiki:Commonjs-wikipedia-list-tooltip
// 4. Add to MediaWiki:Common.css:
// .overflow-x-auto { overflow-x: auto; -webkit-overflow-scrolling: touch; margin: 1em 0; }
// #p-lang li.destacado::before { content: "★ "; color: #ffd700; }
// #p-lang li.bueno::before { content: "◆ "; color: #a3d977; }
( function ( $, mw ) {
'use strict';
// ===== IMMEDIATE EXECUTION =====
$( function () {
// Closeable messages
var $cierraPadre = $( '#cierraPadre' );
if ( $cierraPadre.length ) {
$cierraPadre.css( 'cursor', 'pointer' ).on( 'click', function ( e ) {
e.preventDefault();
$( this ).parent().hide();
} );
}
} );
// ===== DEFERRED INITIALIZATION =====
var deferredInit = window.requestIdleCallback || function ( cb ) {
setTimeout( cb, 1 );
};
deferredInit( function () {
mw.loader.using( 'mediawiki.util' ).then( function () {
// Cache frequently accessed config
var config = mw.config.get( [
'wgArticleId',
'wgNamespaceNumber',
'wgPageName',
'wgAction',
'wgCanonicalSpecialPageName',
'wgScriptPath'
] );
// ===== USER SKIN REDIRECT =====
// Redirect User:Name/skin.js → User:Name/timeless.js
if ( config.wgArticleId === 0 && config.wgNamespaceNumber === 2 ) {
var titleParts = config.wgPageName.split( '/' );
if ( titleParts.length === 2 ) {
var targetPage = titleParts[0] + '/timeless';
if ( titleParts[1] === 'skin.js' ) {
window.location.replace( mw.util.getUrl( targetPage + '.js' ) );
return;
} else if ( titleParts[1] === 'skin.css' ) {
window.location.replace( mw.util.getUrl( targetPage + '.css' ) );
return;
}
}
}
// ===== URL PARAMETER LOADING =====
var extraCSS = mw.util.getParamValue( 'withCSS' ),
extraJS = mw.util.getParamValue( 'withJS' );
if ( extraCSS ) {
if ( /^MediaWiki:[a-zA-Z0-9_-]+\.css$/.test( extraCSS ) ) {
mw.loader.load( mw.util.getUrl( extraCSS, { action: 'raw', ctype: 'text/css' } ), 'text/css' );
} else {
mw.notify(
mw.msg( 'commonjs-invalid-withcss' ) || 'Solo se pueden cargar páginas del espacio de nombres MediaWiki.',
{ title: mw.msg( 'commonjs-invalid-withcss-title' ) || 'Valor withCSS no permitido' }
);
}
}
if ( extraJS ) {
if ( /^MediaWiki:[a-zA-Z0-9_-]+\.js$/.test( extraJS ) ) {
mw.loader.load( mw.util.getUrl( extraJS, { action: 'raw', ctype: 'text/javascript' } ) );
} else {
mw.notify(
mw.msg( 'commonjs-invalid-withjs' ) || 'Solo se pueden cargar páginas del espacio de nombres MediaWiki.',
{ title: mw.msg( 'commonjs-invalid-withjs-title' ) || 'Valor withJS no permitido' }
);
}
}
// ===== CONDITIONAL PAGE-SPECIFIC SCRIPTS =====
// Wikidata search - Search pages or 404s
if ( config.wgCanonicalSpecialPageName === 'Search' ||
( config.wgArticleId === 0 && !config.wgCanonicalSpecialPageName ) ) {
mw.loader.load( mw.util.getUrl( 'MediaWiki:Wdsearch.js', { action: 'raw', ctype: 'text/javascript' } ) );
}
// Edit functionality
if ( config.wgAction === 'edit' || config.wgAction === 'submit' ) {
// Fix undo edit summary
if ( window.location.search.indexOf( 'undo=' ) !== -1 ) {
$( 'input[name="wpAutoSummary"]' ).val( '1' );
}
// Load edit tools
mw.loader.load( mw.util.getUrl( 'MediaWiki:Edittools.js', { action: 'raw', ctype: 'text/javascript' } ) );
}
// Seguimiento page
if ( config.wgPageName === 'Especial:Seguimiento' ) {
mw.loader.load( mw.util.getUrl( 'MediaWiki:Common.js/seguimiento.js', { action: 'raw', ctype: 'text/javascript' } ) );
}
// Main page - Add interwiki completelist link
if ( config.wgPageName === 'Hispanopedia:Portada' ) {
mw.util.addPortletLink(
'p-lang',
'//es.wikipedia.org/wiki/Anexo:Wikipedias',
mw.msg( 'commonjs-wikipedia-list' ) || 'Lista completa',
'interwiki-completelist',
mw.msg( 'commonjs-wikipedia-list-tooltip' ) || 'Lista completa de Wikipedias'
);
}
// Hide edit summary for specific preload pages
var preloadValue = mw.util.getParamValue( 'preload' );
if ( preloadValue && [
'Hispanopedia:Tablón_de_anuncios_de_los_bibliotecarios/Portal/Plantillas/Fusión_de_historiales/precarga',
'Hispanopedia:Tablón_de_anuncios_de_los_bibliotecarios/Portal/Plantillas/Permisos/precarga',
'Hispanopedia:Bot/Solicitudes/Precarga'
].indexOf( preloadValue ) !== -1 ) {
$( '#wpSummary, #wpSummaryLabel' ).hide();
}
// ===== LAZY MAP SCRIPT LOADING =====
deferredInit( function () {
if ( $( '.coordinates, [class*="coord"], #coordinates' ).length ) {
window.wma_settings = {
buttonImage: config.wgScriptPath + '/images/Erioll_world.svg'
};
mw.loader.load( mw.util.getUrl( 'MediaWiki:Wikiminiatlas.js', { action: 'raw', ctype: 'text/javascript' } ) );
mw.config.set( { osm_proj_map: 'mapa', osm_proj_lang: 'es' } );
mw.loader.load( mw.util.getUrl( 'MediaWiki:OSM.js', { action: 'raw', ctype: 'text/javascript' } ) );
}
} );
// ===== CONTENT ENHANCEMENT FUNCTIONS =====
// Collapsible templates
function initCollapsibleTemplates( $content ) {
var collapseText = mw.msg( 'commonjs-collapse' ) || 'ocultar',
expandText = mw.msg( 'commonjs-expand' ) || 'mostrar',
hideLabel = '[' + collapseText + ']',
showLabel = '[' + expandText + ']';
var indexNavigationBar = 0;
$content.find( 'div.NavFrame' ).each( function () {
indexNavigationBar++;
var $frame = $( this ),
isCollapsed = $frame.hasClass( 'collapsed' ) || $frame.find( '.NavPic, .NavContent' ).is( ':hidden' ),
frameId = 'NavFrame' + indexNavigationBar,
toggleId = 'NavToggle' + indexNavigationBar;
var $toggle = $( '<a>' )
.addClass( 'NavToggle' )
.attr( { id: toggleId, href: '#' } )
.text( isCollapsed ? showLabel : hideLabel )
.on( 'click', function ( e ) {
e.preventDefault();
var $tgl = $( '#' + toggleId ),
$frm = $( '#' + frameId );
if ( $tgl.text() === hideLabel ) {
$frm.find( '.NavContent, .NavPic' ).hide();
$tgl.text( showLabel );
} else {
$frm.find( '.NavContent, .NavPic' ).show();
$tgl.text( hideLabel );
}
} );
$frame.attr( 'id', frameId )
.find( '.NavHead' ).first().append( $toggle );
if ( isCollapsed ) {
$frame.find( '.NavPic, .NavContent' ).hide();
}
} );
}
// Progressive image loading
function initProgressiveImageLoading( $content ) {
var $images = $content.find( 'img[data-src]' );
if ( !$images.length ) return;
if ( !( 'IntersectionObserver' in window ) ) {
// Fallback: load immediately
$images.each( function () {
var $img = $( this );
$img.attr( 'src', $img.data( 'src' ) )
.removeAttr( 'data-src' )
.addClass( 'loaded' );
} );
return;
}
// Use IntersectionObserver for lazy loading
var imageObserver = new IntersectionObserver( function ( entries ) {
entries.forEach( function ( entry ) {
if ( entry.isIntersecting ) {
var $img = $( entry.target ),
dataSrc = $img.data( 'src' );
if ( dataSrc ) {
$img.attr( 'src', dataSrc )
.removeAttr( 'data-src' )
.addClass( 'loaded' );
}
imageObserver.unobserve( entry.target );
}
} );
}, {
rootMargin: '100px 0px',
threshold: 0.01
} );
$images.each( function () {
imageObserver.observe( this );
} );
}
// Wrap wide tables for horizontal scrolling
function wrapWideTables( $content ) {
var windowWidth = $( window ).width(),
maxWidth = windowWidth * 0.95;
$content.find( 'table.wikitable' ).each( function () {
var $table = $( this );
// Skip if already wrapped or marked as ok
if ( $table.hasClass( 'overflow-ok' ) || $table.parent().hasClass( 'overflow-x-auto' ) ) {
return;
}
if ( this.offsetWidth > maxWidth ) {
$table.wrap( '<div class="overflow-x-auto"></div>' );
}
} );
}
// Highlight featured/good articles in Timeless sidebar
function highlightInterwikiLinks() {
var $langLinks = $( '#p-lang li' );
if ( !$langLinks.length ) return;
$langLinks.each( function () {
var $li = $( this ),
className = $li.attr( 'class' );
if ( !className ) return;
var match = className.match( /interwiki-([\w-]+)/ );
if ( !match ) return;
var baseClass = match[0];
// Check for featured article marker
if ( $( '#' + baseClass + '-fa' ).length && !$li.hasClass( 'badge-featuredarticle' ) ) {
$li.addClass( 'destacado' )
.attr( 'title', mw.msg( 'commonjs-featured-article' ) ||
'Éste es un artículo destacado de Hispanopedia.' );
}
// Check for good article marker
else if ( $( '#' + baseClass + '-ga' ).length && !$li.hasClass( 'badge-goodarticle' ) ) {
$li.addClass( 'bueno' )
.attr( 'title', mw.msg( 'commonjs-good-article' ) ||
'Éste es un artículo bueno de Hispanopedia.' );
}
} );
}
// Add new section link to discussion pages
function addNewSectionLink() {
var $newSectionLink = $( '#ca-addsection a' );
if ( !$newSectionLink.length ) return;
var $link = $newSectionLink.clone()
.removeAttr( 'accesskey id' )
.removeClass()
.attr( 'title', function ( i, oldTitle ) {
return oldTitle ? oldTitle.replace( /\s*\[.*?\]\s*$/g, '' ) : '';
} )
.css( 'text-transform', 'lowercase' );
// Remove empty spans
$link.find( 'span' ).filter( function () {
return !$.trim( $( this ).text() );
} ).remove();
// Add to last edit section
var $lastEditSection = $( 'span.mw-editsection:last a:last' );
if ( $lastEditSection.length ) {
$lastEditSection.after( ' · ', $link );
}
}
// Main content enhancement function
function initContentEnhancements( $content ) {
$content = $content && $content.length ? $content : $( '#mw-content-text' );
var ns = config.wgNamespaceNumber;
// Collapsible templates - all namespaces
initCollapsibleTemplates( $content );
// Image loading and table wrapping - main/project namespaces only
if ( ns === 0 || ns === 104 ) {
initProgressiveImageLoading( $content );
wrapWideTables( $content );
}
}
// Global enhancements (run once per page load)
function initGlobalEnhancements() {
highlightInterwikiLinks();
addNewSectionLink();
}
// ===== TABLE SORTING =====
// Load jquery.tablesorter only if sortable tables exist
var $sortableTables = $( 'table.sortable' );
if ( $sortableTables.length ) {
mw.loader.using( 'jquery.tablesorter' ).then( function () {
var ts = $.tablesorter;
// Spanish month names
var monthNames = {
enero: 1, febrero: 2, marzo: 3, abril: 4, mayo: 5, junio: 6,
julio: 7, agosto: 8, septiembre: 9, octubre: 10, noviembre: 11, diciembre: 12,
ene: 1, feb: 2, mar: 3, abr: 4, may: 5, jun: 6,
jul: 7, ago: 8, sep: 9, oct: 10, nov: 11, dic: 12
};
ts.monthNames = monthNames;
// Spanish date pattern: "1 de enero de 2024"
ts.dateRegexCustom = /^(\d{1,2})\s+de\s+(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre|ene|feb|mar|abr|may|jun|jul|ago|sep|oct|nov|dic)\s+de\s+(\d{2,4})$/i;
// Add custom date parser
ts.addParser( {
id: 'dateCustom',
is: function ( s ) {
return ts.dateRegexCustom.test( $.trim( s ) );
},
format: function ( s ) {
var cleaned = $.trim( s.toLowerCase() ),
match = cleaned.match( ts.dateRegexCustom );
if ( !match ) return 99999999;
var day = match[1],
monthName = match[2],
year = parseInt( match[3], 10 ),
month = monthNames[monthName];
if ( !month ) return 99999999;
// Pad day and month
day = day.length === 1 ? '0' + day : day;
month = month < 10 ? '0' + month : '' + month;
// Handle 2-digit years
if ( year < 100 ) {
year = year < 30 ? 2000 + year : 1900 + year;
}
// Ensure 4-digit year
var yearStr = String( year );
while ( yearStr.length < 4 ) {
yearStr = '0' + yearStr;
}
return parseInt( yearStr + month + day, 10 );
},
type: 'numeric'
} );
// Custom collation for Spanish characters
var accentMap = {
á: 'a', à: 'a', â: 'a', ä: 'a', ã: 'a', ā: 'a', ă: 'a', å: 'a', ą: 'a',
æ: 'ae',
ć: 'c', ĉ: 'c', č: 'c', ç: 'c',
ď: 'd', ḑ: 'd', đ: 'd', ð: 'd',
é: 'e', è: 'e', ê: 'e', ë: 'e', ẽ: 'e', ě: 'e', ē: 'e', ĕ: 'e', ę: 'e',
ĝ: 'g', ḡ: 'g', ğ: 'g', ģ: 'g', ǥ: 'g',
ĥ: 'h', ḧ: 'h', ḩ: 'h', ħ: 'h',
í: 'i', ì: 'i', î: 'i', ï: 'i', ĩ: 'i', ī: 'i', ĭ: 'i', į: 'i', ı: 'i',
ĵ: 'j',
ķ: 'k',
ĺ: 'l', ľ: 'l', ļ: 'l', ł: 'l',
ń: 'n', ň: 'n', ņ: 'n',
ñ: 'n~',
ó: 'o', ò: 'o', ô: 'o', ö: 'o', õ: 'o', ō: 'o', ŏ: 'o', ǫ: 'o', ő: 'o', ø: 'o',
œ: 'oe',
ŕ: 'r', ř: 'r', ŗ: 'r',
ś: 's', ŝ: 's', š: 's', ş: 's',
ß: 'ss',
ť: 't', ţ: 't', ŧ: 't',
ú: 'u', ù: 'u', û: 'u', ü: 'u', ũ: 'u', ū: 'u', ŭ: 'u', ů: 'u', ų: 'u', ű: 'u',
ṽ: 'v',
ŵ: 'w', ẅ: 'w',
ẍ: 'x',
ý: 'y', ŷ: 'y', ÿ: 'y', ỹ: 'y',
ź: 'z', ẑ: 'z', ž: 'z', ƶ: 'z'
};
mw.config.set( 'tableSorterCollation', accentMap );
} );
}
// ===== INITIALIZATION =====
// Register hook for dynamic content changes (AJAX loads, VisualEditor, etc.)
mw.hook( 'wikipage.content' ).add( initContentEnhancements );
// Run on initial page load
initContentEnhancements();
initGlobalEnhancements();
} );
} );
}( jQuery, mediaWiki ) );