MediaWiki:Common.js: Difference between revisions
Appearance
No edit summary |
No edit summary |
||
| Line 1: | Line 1: | ||
/* Promote infobox image to a 10:7 hero | /* Promote infobox image to a 10:7 hero ABOVE the .mw-body-header (touch only) */ | ||
mw.hook('wikipage.content').add(function ($content) { | mw.hook('wikipage.content').add(function ($content) { | ||
if (!window.matchMedia || !window.matchMedia('(pointer: coarse)').matches) return; | if (!window.matchMedia || !window.matchMedia('(pointer: coarse)').matches) return; | ||
if (document.querySelector('.article-hero')) return; | if (document.querySelector('.article-hero')) return; | ||
| Line 11: | Line 8: | ||
if (!$img.length) return; | if (!$img.length) return; | ||
// | // Prefer the largest candidate from srcset | ||
var | var src = $img.attr('src') || ''; | ||
if ( | var srcset = $img.attr('srcset') || ''; | ||
if (srcset) { | |||
var last = srcset.split(',').pop().trim().split(/\s+/)[0]; | |||
if (last) src = last; | |||
} | |||
// Build hero | // Build hero and image | ||
var $hero = $('<div>', { 'class': 'article-hero', 'aria-hidden': 'true' }); | var $hero = $('<div>', { 'class': 'article-hero', 'aria-hidden': 'true' }); | ||
var $clone = $('<img>', { | var $clone = $('<img>', { | ||
src: | src: src, | ||
alt: '', // decorative hero; keep real alt on the infobox image | |||
decoding: 'async', | |||
alt: '', // decorative hero; real alt | |||
loading: 'eager', | loading: 'eager', | ||
fetchpriority: 'high', | |||
sizes: '100vw' | |||
}); | }); | ||
$hero.append($clone); | |||
// Insert hero just before the .mw-body-header (Vector 2022) | |||
$hero.insertBefore($ | var $header = $('.mw-body-header').first(); | ||
if ($header.length) { | |||
$hero.insertBefore($header); | |||
} else { | |||
// Fallback: before firstHeading if header not found | |||
$('#firstHeading').first().before($hero); | |||
} | |||
// Hide the original infobox image | // Hide the original infobox image when promoted | ||
$img.closest('table.infobox').addClass('infobox--image-promoted'); | $img.closest('table.infobox').addClass('infobox--image-promoted'); | ||
}); | }); | ||
/* Quick facts: collapse infobox under first paragraph on touch devices */ | /* Quick facts: collapse infobox under first paragraph on touch devices */ | ||
Revision as of 19:07, 2 October 2025
/* Promote infobox image to a 10:7 hero ABOVE the .mw-body-header (touch only) */
mw.hook('wikipage.content').add(function ($content) {
if (!window.matchMedia || !window.matchMedia('(pointer: coarse)').matches) return;
if (document.querySelector('.article-hero')) return;
// First infobox image
var $img = $content.find('table.infobox .infobox-image-cell img').first();
if (!$img.length) return;
// Prefer the largest candidate from srcset
var src = $img.attr('src') || '';
var srcset = $img.attr('srcset') || '';
if (srcset) {
var last = srcset.split(',').pop().trim().split(/\s+/)[0];
if (last) src = last;
}
// Build hero and image
var $hero = $('<div>', { 'class': 'article-hero', 'aria-hidden': 'true' });
var $clone = $('<img>', {
src: src,
alt: '', // decorative hero; keep real alt on the infobox image
decoding: 'async',
loading: 'eager',
fetchpriority: 'high',
sizes: '100vw'
});
$hero.append($clone);
// Insert hero just before the .mw-body-header (Vector 2022)
var $header = $('.mw-body-header').first();
if ($header.length) {
$hero.insertBefore($header);
} else {
// Fallback: before firstHeading if header not found
$('#firstHeading').first().before($hero);
}
// Hide the original infobox image when promoted
$img.closest('table.infobox').addClass('infobox--image-promoted');
});
/* Quick facts: collapse infobox under first paragraph on touch devices */
mw.hook('wikipage.content').add(function ($content) {
// Only on touch devices
if (!window.matchMedia || !window.matchMedia('(pointer: coarse)').matches) return;
var $ibox = $content.find('table.infobox').first();
if (!$ibox.length) return;
// First real paragraph in article content
var $firstP = $content
.find('.mw-parser-output > p')
.filter(function () { return $(this).text().trim().length > 0; })
.first();
if (!$firstP.length) return;
// Build <details> wrapper
var $details = $('<details>', { 'class': 'quickfacts', 'aria-label': 'Quick facts' });
var $summary = $('<summary>', { 'class': 'quickfacts-summary', text: 'Quick facts' });
$details.append($summary);
// Mark infobox so CSS can remove float/width inside quickfacts
$ibox.addClass('infobox--in-quickfacts');
// Move the infobox inside the details (not cloning; avoids duplicate content for SR)
$details.append($ibox);
// Insert directly after the first paragraph
$details.insertAfter($firstP);
});