Difference between revisions of "MediaWiki:Common.js"

From Summertime Saga Wiki
Jump to: navigation, search
 
(16 intermediate revisions by the same user not shown)
Line 26: Line 26:
  
 
mw.hook('wikipage.content').add(function ($content) {
 
mw.hook('wikipage.content').add(function ($content) {
   const tabs = ['current', 'legacy'];
+
   // Manage the Preview / Stable tabs
  const [hint, frag] = window.location.hash.slice(1).split('#');
 
  
   const pref = localStorage.getItem('preferredVersion') || 'current';
+
   const $tabs = $content.find('ul.version-tabs');
  
   //if (hint && frag && tabs.indexOf(hint) !== -1) {
+
   if (!$tabs) return;
   //  pref = hint;
+
 
  //  location.hash = frag;
+
  const allow = ['21', '0.20.16'];
  //}
+
 
 +
   const pref = location.hash
 +
            ? location.hash.endsWith('-0.20.16') ? '0.20.16' : '21'
 +
            : localStorage.getItem('preferredVersion') || '21';
  
 
   function activateTab(tab) {
 
   function activateTab(tab) {
     if (tabs.indexOf(tab) === -1) return;
+
     if (allow.indexOf(tab) === -1) return;
  
 
     $content.find('div.vt-content').hide();
 
     $content.find('div.vt-content').hide();
     $content.find('div.vt-' + tab).show();
+
     $content.find('div.vt-' + tab.replaceAll('.', '-')).show();
  
     $content.find('ul.version-tabs li').removeClass('active');
+
     $tabs.find('li').removeClass('active');
     $content.find('ul.version-tabs li[data-tab="' + tab + '"]').addClass('active');
+
     $tabs.find('li[data-tab="' + tab + '"]').addClass('active');
  
 
     localStorage.setItem('preferredVersion', tab);
 
     localStorage.setItem('preferredVersion', tab);
 
   }
 
   }
  
   $content.find('ul.version-tabs li').click(function (e) {
+
   function rewriteAnchors(scopeSelector, suffix) {
 +
    const $scope = $(scopeSelector);
 +
    const idMap = {};
 +
    const baselines = {}; // lowest index seen
 +
 
 +
    // Regex to parse base and numeric suffix
 +
    const headingIdRegex = /^(.*?)(?:_(\d+))?$/;
 +
 
 +
    function getBaseAndIndex(id) {
 +
      const match = id.match(headingIdRegex);
 +
      return {base: match[1], index: match[2] ? parseInt(match[2], 10) : 1};
 +
    }
 +
 
 +
    // Determine baseline MediaWiki suffixes
 +
    $scope.find('[id]').each(function () {
 +
      const o = getBaseAndIndex(this.id);
 +
      if (!(o.base in baselines) || o.index < baselines[o.base]) {
 +
        baselines[o.base] = o.index;
 +
      }
 +
    });
 +
 
 +
    // Rewrite all elements with 'id'
 +
    $scope.find('[id]').each(function () {
 +
      const $el = $(this);
 +
      const oldId = $el.attr('id');
 +
      const o = getBaseAndIndex(oldId);
 +
      const baseline = baselines[o.base];
 +
 
 +
      const newIndex = o.index - baseline + 1;
 +
 
 +
      const newId = newIndex === 1 ? o.base + suffix : o.base + '_' + newIndex + suffix;
 +
      $el.attr('id', newId);
 +
      idMap[oldId] = newId;
 +
    });
 +
 
 +
    // Rewrite links
 +
    $scope.find('a[href^="#"]').each(function () {
 +
      const $a = $(this);
 +
      const href = $a.attr('href').substring(1); // strip leading #
 +
      if (idMap[href]) {
 +
        $a.attr('href', '#' + idMap[href]);
 +
      }
 +
    });
 +
 
 +
    // Rewrite labels
 +
    $scope.find('label[for]').each(function () {
 +
      const $label = $(this);
 +
      const forId = $label.attr('for');
 +
      if (idMap[forId]) {
 +
        $label.attr('for', idMap[forId]);
 +
      }
 +
    });
 +
  }
 +
 
 +
  $tabs.find('li').click(function (e) {
 
     e.preventDefault();
 
     e.preventDefault();
 
     const selected = this.dataset.tab;
 
     const selected = this.dataset.tab;
Line 55: Line 111:
  
 
   activateTab(pref);
 
   activateTab(pref);
 +
  rewriteAnchors('div.vt-0-20-16', '-0.20.16');
 +
 +
  if (location.hash) {
 +
    location.hash = location.hash;
 +
  }
 
});
 
});

Latest revision as of 17:28, 11 October 2025

/* Any JavaScript here will be loaded for all users on every page load. */

// Wait for document ready
$(function() {
	var htmle = function(str) {
		return String(str).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
	};

	if ($('body').hasClass('page-Summertime_Saga_Wiki') && $('body').hasClass('action-view') && $('body').hasClass('skin-vector') && $('#ajax-posts').length && $('#ajax-version').length) {
		var maxPosts = 5;

		$.getJSON('/ssdata.json', function(data) {
			$('#ajax-version').text(data.version);
			$('#ajax-posts').html('');

			data.posts.forEach(function(post, i) {
				if (i >= maxPosts) {
					return;
				}

				$('#ajax-posts').append('<dd><b>▪ ' + htmle(post.date) + ':</b> <a rel="nofollow" class="external text" href="https://www.patreon.com' + htmle(post.url) + '">' + htmle(post.title) + '</a></dd>');
			});
		});
	}
}());

mw.hook('wikipage.content').add(function ($content) {
  // Manage the Preview / Stable tabs

  const $tabs = $content.find('ul.version-tabs');

  if (!$tabs) return;

  const allow = ['21', '0.20.16'];

  const pref = location.hash
             ? location.hash.endsWith('-0.20.16') ? '0.20.16' : '21'
             : localStorage.getItem('preferredVersion') || '21';

  function activateTab(tab) {
    if (allow.indexOf(tab) === -1) return;

    $content.find('div.vt-content').hide();
    $content.find('div.vt-' + tab.replaceAll('.', '-')).show();

    $tabs.find('li').removeClass('active');
    $tabs.find('li[data-tab="' + tab + '"]').addClass('active');

    localStorage.setItem('preferredVersion', tab);
  }

  function rewriteAnchors(scopeSelector, suffix) {
    const $scope = $(scopeSelector);
    const idMap = {};
    const baselines = {}; // lowest index seen

    // Regex to parse base and numeric suffix
    const headingIdRegex = /^(.*?)(?:_(\d+))?$/;

    function getBaseAndIndex(id) {
      const match = id.match(headingIdRegex);
      return {base: match[1], index: match[2] ? parseInt(match[2], 10) : 1};
    }

    // Determine baseline MediaWiki suffixes
    $scope.find('[id]').each(function () {
      const o = getBaseAndIndex(this.id);
      if (!(o.base in baselines) || o.index < baselines[o.base]) {
        baselines[o.base] = o.index;
      }
    });

    // Rewrite all elements with 'id'
    $scope.find('[id]').each(function () {
      const $el = $(this);
      const oldId = $el.attr('id');
      const o = getBaseAndIndex(oldId);
      const baseline = baselines[o.base];

      const newIndex = o.index - baseline + 1;

      const newId = newIndex === 1 ? o.base + suffix : o.base + '_' + newIndex + suffix;
      $el.attr('id', newId);
      idMap[oldId] = newId;
    });

    // Rewrite links
    $scope.find('a[href^="#"]').each(function () {
      const $a = $(this);
      const href = $a.attr('href').substring(1); // strip leading #
      if (idMap[href]) {
        $a.attr('href', '#' + idMap[href]);
      }
    });

    // Rewrite labels
    $scope.find('label[for]').each(function () {
      const $label = $(this);
      const forId = $label.attr('for');
      if (idMap[forId]) {
        $label.attr('for', idMap[forId]);
      }
    });
  }

  $tabs.find('li').click(function (e) {
    e.preventDefault();
    const selected = this.dataset.tab;
    activateTab(selected);
  });

  activateTab(pref);
  rewriteAnchors('div.vt-0-20-16', '-0.20.16');

  if (location.hash) {
    location.hash = location.hash;
  }
});