Jump to content

MediaWiki:Common.js: Difference between revisions

From Yusupov's House
No edit summary
No edit summary
Line 1: Line 1:
/* Promote infobox image to a 10:7 hero above the title (touch devices only) */
/* 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) {
  // Only on touch devices
   if (!window.matchMedia || !window.matchMedia('(pointer: coarse)').matches) return;
   if (!window.matchMedia || !window.matchMedia('(pointer: coarse)').matches) return;
  // Avoid duplicates
   if (document.querySelector('.article-hero')) return;
   if (document.querySelector('.article-hero')) return;


Line 11: Line 8:
   if (!$img.length) return;
   if (!$img.length) return;


   // Page title (Vector 2022 still uses #firstHeading)
   // Prefer the largest candidate from srcset
   var $heading = $('#firstHeading');
  var src = $img.attr('src') || '';
   if (!$heading.length) return;
   var srcset = $img.attr('srcset') || '';
   if (srcset) {
    var last = srcset.split(',').pop().trim().split(/\s+/)[0];
    if (last) src = last;
  }


   // Build hero container and clone the image
   // 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: $img.attr('src'),
     src: src,
    srcset: $img.attr('srcset') || '',
     alt: '',                        // decorative hero; keep real alt on the infobox image
    sizes: '100vw',
    decoding: 'async',
     alt: '',                        // decorative hero; real alt stays in infobox
     loading: 'eager',
     loading: 'eager',
     decoding: 'async',
     fetchpriority: 'high',
     fetchpriority: 'high'
     sizes: '100vw'
   });
   });
  $hero.append($clone);


   $hero.append($clone);
   // Insert hero just before the .mw-body-header (Vector 2022)
   $hero.insertBefore($heading);
  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 on touch devices (via CSS class)
   // 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);
});