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 title (touch devices only) */ | ||
(function () { | |||
if (!window.matchMedia || ! | if (!window.matchMedia || !matchMedia('(pointer: coarse)').matches) return; | ||
if (document.querySelector('.article-hero')) return; | if (document.querySelector('.article-hero')) return; | ||
// | function run() { | ||
// Find the infobox image cell | |||
var imgCell = document.querySelector('table.infobox .infobox-image-cell'); | |||
if (!imgCell) return; | |||
// What we'll move: prefer a wrapper (span/a/figure) so we keep the link | |||
var moveNode = | |||
imgCell.querySelector('span, figure, a, picture, img') || imgCell.firstElementChild; | |||
if (!moveNode) return; | |||
var | |||
// Where to put the hero | |||
var header = document.querySelector('.mw-body-header') || document.getElementById('firstHeading'); | |||
if (!header) return; | |||
// Create the hero *first* so space is reserved immediately | |||
var hero = document.createElement('div'); | |||
hero.className = 'article-hero'; | |||
header.parentNode.insertBefore(hero, header); | |||
// Batch DOM mutation in the next frame to avoid extra reflows | |||
requestAnimationFrame(function () { | |||
// Move (not clone) the existing node — avoids a second download/decoding | |||
hero.appendChild(moveNode); | |||
// Optional: mark infobox for any extra styling you might want later | |||
var infobox = imgCell.closest('table.infobox'); | |||
if (infobox) infobox.classList.add('infobox--image-promoted'); | |||
}); | |||
} | } | ||
if (document.readyState === 'loading') { | |||
document.addEventListener('DOMContentLoaded', run, { once: true }); | |||
} else { | } else { | ||
run(); | |||
} | } | ||
})(); | |||
Revision as of 19:15, 2 October 2025
/* Promote infobox image to a 10:7 hero above the title (touch devices only) */
(function () {
if (!window.matchMedia || !matchMedia('(pointer: coarse)').matches) return;
if (document.querySelector('.article-hero')) return;
function run() {
// Find the infobox image cell
var imgCell = document.querySelector('table.infobox .infobox-image-cell');
if (!imgCell) return;
// What we'll move: prefer a wrapper (span/a/figure) so we keep the link
var moveNode =
imgCell.querySelector('span, figure, a, picture, img') || imgCell.firstElementChild;
if (!moveNode) return;
// Where to put the hero
var header = document.querySelector('.mw-body-header') || document.getElementById('firstHeading');
if (!header) return;
// Create the hero *first* so space is reserved immediately
var hero = document.createElement('div');
hero.className = 'article-hero';
header.parentNode.insertBefore(hero, header);
// Batch DOM mutation in the next frame to avoid extra reflows
requestAnimationFrame(function () {
// Move (not clone) the existing node — avoids a second download/decoding
hero.appendChild(moveNode);
// Optional: mark infobox for any extra styling you might want later
var infobox = imgCell.closest('table.infobox');
if (infobox) infobox.classList.add('infobox--image-promoted');
});
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', run, { once: true });
} else {
run();
}
})();
/* 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);
});