MediaWiki:Common.js

From Sea of Thieves Wiki
Jump to navigation Jump to search
In other languages: Deutsch • English • Español • Français • Português • 中文
Note: After saving, you may have to bypass your browser's cache to see the changes.
  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Internet Explorer: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Go to Menu → Settings (Opera → Preferences on a Mac) and then to Privacy & security → Clear browsing data → Cached images and files.
/* Any JavaScript here will be loaded for all users on every page load. */

/* global mw, $ */
/* jshint strict:false, browser:true */

(function() {
    'use strict';

// mp4 webm video autoplay/loop

var vids = document.getElementsByClassName("autoloop");
for (var i = 0; i < vids.length; i++){
    vids[i].autoplay = true;
    vids[i].loop = true;
    vids[i].muted = true;
}

var vids = document.getElementsByClassName("loop");
for (var i = 0; i < vids.length; i++){
    vids[i].loop = true;
    vids[i].muted = true;
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////

/**
 * Fix broken searchbox suggestions on mobile (by Anysite - source: https://phabricator.wikimedia.org/T219590#9067867)
 */
var $searchInput = $( '#searchInput,.mw-searchInput' );

		$searchInput.on('input',function(e){
			
			//trigger keydown with e object
			$(this).trigger(jQuery.Event('keydown', { 
				keyCode: e.keyCode,
				which: e.which, 
			}));
			$(this).trigger(jQuery.Event('keypress', { 
				keyCode: e.keyCode,
				which: e.which, 
			}));
		})

///////////////////////////////////////////////////////////////////////////////////////////////////////////////

/**
 * Make sidebar sections collapsible (from Terraria)
 */
$(function(){
	var $panel = $('#mw-panel');
	$("#mw-panel .portal").each(function(index, el){
		var $el = $(el);
		var $id = $el.attr("id");
		if(!$id){
			return;
		}
		// for < 1366px
		$el.removeClass('expanded');
		// for >= 1366px
		if(localStorage.getItem('sidebar_c_'+$id) === "y"){
			$el.addClass('collapsed').find('.body').slideUp(0);
		}
	});
	$("#mw-panel .portal").on("click", "h3", function(event){
		var $el = $(this).parent();
		var $id = $el.attr("id");
		if(!$id){
			return;
		}
		event.stopPropagation();
		if($panel.width() < 200){
			$el.toggleClass('collapsed');
			if($el.hasClass('collapsed')){ // more consistent between class and slide status.
				localStorage.setItem('sidebar_c_'+$id, "y");
				$el.find('.body').slideUp('fast');
			}
			else{
				localStorage.setItem('sidebar_c_'+$id, "n");
				$el.find('.body').slideDown('fast');
			}
		}
		else{
			$("#mw-panel .portal").not($el).removeClass('expanded');
			$el.toggleClass('expanded');
		}
	});
});

///////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
 * content width toggle (from Terraria)
 */
$(function(){
	var $body = $('body');
	$('<div id="nav-content-size-toggle"><span></span></div>')
	.prependTo($('#mw-head'))
	.on('click', function(){
		$body.toggleClass('content-size-expanded');
	});
});

///////////////////////////////////////////////////////////////////////////////////////////////////////////////
/*!
floating-scroll v3.2.0
https://amphiluke.github.io/floating-scroll/
(c) 2022 Amphiluke
*/
!function(t,i){"object"==typeof exports&&"undefined"!=typeof module?i(require("jquery")):"function"==typeof define&&define.amd?define(["jquery"],i):i((t="undefined"!=typeof globalThis?globalThis:t||self).jQuery)}(this,(function(t){"use strict";var i="horizontal",n="vertical",e={init:function(t,n){var e=this;e.orientationProps=function(t){var n=t===i;return{ORIENTATION:t,SIZE:n?"width":"height",X_SIZE:n?"height":"width",OFFSET_SIZE:n?"offsetWidth":"offsetHeight",OFFSET_X_SIZE:n?"offsetHeight":"offsetWidth",CLIENT_SIZE:n?"clientWidth":"clientHeight",CLIENT_X_SIZE:n?"clientHeight":"clientWidth",INNER_X_SIZE:n?"innerHeight":"innerWidth",SCROLL_SIZE:n?"scrollWidth":"scrollHeight",SCROLL_POS:n?"scrollLeft":"scrollTop",START:n?"left":"top",X_START:n?"top":"left",X_END:n?"bottom":"right"}}(n);var o=t.closest(".fl-scrolls-body");o.length&&(e.scrollBody=o),e.container=t[0],e.visible=!0,e.initWidget(),e.updateAPI(),e.addEventHandlers(),e.skipSyncContainer=e.skipSyncWidget=!1},initWidget:function(){var i=this,n=i.orientationProps,e=n.ORIENTATION,o=n.SIZE,r=n.SCROLL_SIZE,c=i.widget=t('<div class="fl-scrolls" data-orientation="'+e+'"></div>');t("<div></div>").appendTo(c)[o](i.container[r]),c.appendTo(i.container)},addEventHandlers:function(){var i=this;(i.eventHandlers=[{$el:t(window),handlers:{"destroyDetached.fscroll":function(t){"fscroll"===t.namespace&&i.destroyDetachedAPI()}}},{$el:i.scrollBody||t(window),handlers:{scroll:function(){i.updateAPI()},resize:function(){i.updateAPI()}}},{$el:i.widget,handlers:{scroll:function(){i.visible&&!i.skipSyncContainer&&i.syncContainer(),i.skipSyncContainer=!1}}},{$el:t(i.container),handlers:{scroll:function(){i.skipSyncWidget||i.syncWidget(),i.skipSyncWidget=!1},focusin:function(){setTimeout((function(){i.widget&&i.syncWidget()}),0)},"update.fscroll":function(t){"fscroll"===t.namespace&&i.updateAPI()},"destroy.fscroll":function(t){"fscroll"===t.namespace&&i.destroyAPI()}}}]).forEach((function(t){var i=t.$el,n=t.handlers;return i.bind(n)}))},checkVisibility:function(){var t=this,i=t.widget,n=t.container,e=t.scrollBody,o=t.orientationProps,r=o.SCROLL_SIZE,c=o.OFFSET_SIZE,l=o.X_START,s=o.X_END,d=o.INNER_X_SIZE,a=o.CLIENT_X_SIZE,f=i[0][r]<=i[0][c];if(!f){var h=n.getBoundingClientRect(),u=e?e[0].getBoundingClientRect()[s]:window[d]||document.documentElement[a];f=h[s]<=u||h[l]>u}t.visible===f&&(t.visible=!f,i.toggleClass("fl-scrolls-hidden"))},syncContainer:function(){var t=this,i=t.orientationProps.SCROLL_POS,n=t.widget[0][i];t.container[i]!==n&&(t.skipSyncWidget=!0,t.container[i]=n)},syncWidget:function(){var t=this,i=t.orientationProps.SCROLL_POS,n=t.container[i];t.widget[0][i]!==n&&(t.skipSyncContainer=!0,t.widget[0][i]=n)},updateAPI:function(){var i=this,n=i.orientationProps,e=n.SIZE,o=n.X_SIZE,r=n.OFFSET_X_SIZE,c=n.CLIENT_SIZE,l=n.CLIENT_X_SIZE,s=n.SCROLL_SIZE,d=n.START,a=i.widget,f=i.container,h=i.scrollBody,u=f[c],S=f[s];a[e](u),h||a.css(d,f.getBoundingClientRect()[d]+"px"),t("div",a)[e](S),S>u&&a[o](a[0][r]-a[0][l]+1),i.syncWidget(),i.checkVisibility()},destroyAPI:function(){var t=this;t.eventHandlers.forEach((function(t){var i=t.$el,n=t.handlers;return i.unbind(n)})),t.widget.remove(),t.eventHandlers=t.widget=t.container=t.scrollBody=null},destroyDetachedAPI:function(){t.contains(document.body,this.container)||this.destroyAPI()}};t.fn.floatingScroll=function(o,r){if(void 0===o&&(o="init"),void 0===r&&(r={}),"init"===o){var c=r.orientation,l=void 0===c?i:c;if(l!==i&&l!==n)throw new Error("Scrollbar orientation should be either “horizontal” or “vertical”");this.each((function(i,n){return Object.create(e).init(t(n),l)}))}else Object.prototype.hasOwnProperty.call(e,o+"API")&&this.trigger(o+".fscroll");return this},t((function(){t("body [data-fl-scrolls]").each((function(i,n){var e=t(n);e.floatingScroll("init",e.data("flScrolls")||{})}))}))}));

///////////////////////////////////////////////////////////////////////////////////////////////////////////////

/**
 * Handle wide tables (from Terraria)
 *
 * Display a horizontal floating scroll bar when the table width exceeds the page width.
 */
$.when($.ready, mw.loader.using(['mediawiki.util'])).then( function() {
	var TABLE_WIDE_CLASS = "table-wide";
	var TABLE_WIDE_INNER_CLASS = "table-wide-inner";

	var handleWideTables = function(tables) {
		var handler = mw.util.debounce(100, function() {
			if(!tables){
				return;
			}
			tables.forEach(function(table) {
				var $table = $(table);
				if(!$table.data('container')){
					$table.data('container', table.parentNode);
				}
				var container = $table.data('container');
				if(!container){
					return;
				}
				var $innerBox = $table.parent();
				var $outerBox = $innerBox.parent();
				var overwide = table.getBoundingClientRect().width > container.getBoundingClientRect().width;
				if($outerBox.hasClass(TABLE_WIDE_CLASS)){
					if(overwide){
						$innerBox.floatingScroll("update");
					}else{
						$outerBox.before($table).remove();
					}
				}else{
					if(overwide) {
						$('<div/>').addClass(TABLE_WIDE_INNER_CLASS).appendTo(
							$('<div/>').addClass(TABLE_WIDE_CLASS).insertBefore($table)
						).append($table).floatingScroll("init").floatingScroll("update");
					}
				}
			});
		});
		handler();
		window.addEventListener("resize", handler);
	};

	var isEditorActive  = function() {
		var e = new URLSearchParams(window.location.search);
		return "edit" === e.get("action") || "submit" === e.get("action") || ("edit" === e.get("veaction")
			|| "submit" === e.get("veaction") || "editsource" === e.get("veaction"));
	}

	mw.hook("wikipage.content").add(function() {
		if (!isEditorActive()) {
			var el = document.querySelector("#bodyContent");
			if (el) {
				handleWideTables(el.querySelectorAll("table"));
			}
		}
	});
});

///////////////////////////////////////////////////////////////////////////////////////////////////////////////

// #region I18n accessor factory borrowed from ARK wiki
// This takes in a module name and a localised string table (map[language -> map[name -> string]]),
// and returns a function to look-up a string by its name.
// Translations should either be put into the script's string table, or provided locally via
// [[MediaWiki:Common.js]].
// To provide a string locally, provide window.arkLocalI18n (map[module -> map[name -> string]]).
window.arkCreateI18nInterface = function(module, strings) {
    var lang = mw.config.get('wgPageContentLanguage');
    var localStrings = window.arkLocalI18n && window.arkLocalI18n[module];
    return function (key) {
        return ( // try from local store
                 (localStrings && localStrings[key])
                 // try from script store
                 || (strings[lang] && strings[lang][key] || strings['en'][key])
                 // fallback
                 || '<'+key+'>' );
    };
};

/**
 * Riddle Wrapper and Clue Wrapper Expand/Collapse Button
 */
var riddleToggleText = 'Expand/Collapse Riddle Section';
var clueToggleText = 'Expand/Collapse Clue Section';

$('div.riddlewrapper').each(function (i) {
    var $wrapper = $(this),
        $button = $('<div class="mw-ui-button mw-ui-primary toggleButton"><a href="#" class="toggleButton' + i + '">' + riddleToggleText + '</a></div>');
    $button.on('click', function (event) {
        $wrapper.find('> .mw-collapsible > span.mw-collapsible-toggle').click();
        event.preventDefault();
    });
    $wrapper.before($button);
});

$('div.cluewrapper').each(function (i) {
    var $wrapper = $(this),
        $button = $('<div class="mw-ui-button mw-ui-primary toggleButton"><a href="#" class="toggleButton' + i + '">' + clueToggleText + '</a></div>');
    $button.on('click', function (event) {
        $wrapper.find('> .mw-collapsible > span.mw-collapsible-toggle').click();
        event.preventDefault();
    });
    $wrapper.before($button);
});

/**
 * Hoverbox (from Path of Exile wiki @ https://www.poewiki.net/ )
 * @param  config  Object containing configuration
 */
function hoverbox(config) {
    const defaults = {
        mainClass: 'hoverbox',
        activatorClass: 'hoverbox__activator',
        displayClass: 'hoverbox__display'
    };
    config = Object.assign(defaults, config);
    var timestamp = Date.now(),
        $container = $('#hoverbox-displays-' + timestamp);
    if ( $container.length === 0 ) {
        $container = $('<div id="hoverbox-displays-' + timestamp + '" class="hoverbox-display-container"></div>');
    }
    $('body').append($container);
    var $hoverbox = $('.' + config.mainClass),
        idCounter = 0;
    $hoverbox.each(function() {
        var $this = $(this),
            $activator = $this.find('.' + config.activatorClass).first(),
            $display = $this.find('.' + config.displayClass).first(),
            id = $this.data('hoverbox-id') || idCounter++,
            $target = $container.find('[data-hoverbox-target="' + id + '"]');
        if ( $target.length === 0 ) {
            $container.append($display);
            $display.attr('data-hoverbox-target', id);
        } else {
            $display.remove();
            $display = $target;
        }
        $activator.hover(function() {
            var viewport = {},
                activator = {},
                display = {},
                position, // position relative to the activator
                location; // location relative to the viewport
            viewport.width = document.documentElement.clientWidth;
            viewport.height = document.documentElement.clientHeight;
            viewport.top = document.documentElement.scrollTop;
            viewport.left = document.documentElement.scrollLeft;
            viewport.bottom = viewport.top + viewport.height;
            viewport.right = viewport.left + viewport.width;
            activator.width = $activator.outerWidth();
            activator.height = $activator.outerHeight();
            activator.top = $activator.offset().top;
            activator.left = $activator.offset().left;
            activator.bottom = activator.top + activator.height;
            activator.right = activator.left + activator.width;
            display.width = $display.outerWidth();
            display.height = $display.outerHeight();
            if (viewport.width < display.width) { // Don't bother showing the hoverbox at all if the viewport is too small
                return false;
            }
            if (activator.left > viewport.width - activator.right) {
                location = 'right';
            } else {
                location = 'left';
            }
            if (activator.top - display.height > viewport.top) {
                position = 'above';
                display.top = activator.top - display.height;
                display.left = activator.left + (activator.width / 2) - (display.width / 2);
            } else if (activator.right + display.width < viewport.right) {
                position = 'right-of';
                display.top = activator.top + (activator.height / 2) - (display.height / 2);
                display.left = activator.right;
            } else if (activator.left - display.width > viewport.left) {
                position = 'left-of';
                display.top = activator.top + (activator.height / 2) - (display.height / 2);
                display.left = activator.left - display.width;
            } else {
                position = 'below';
                display.top = activator.bottom;
                display.left = activator.left + (activator.width / 2) - (display.width / 2);
            }
            display.top = Math.max(viewport.top, display.top);
            display.left = Math.max(viewport.left, Math.min(viewport.right - display.width, display.left));
            $display.addClass('is-visible is-' + position + '-activator is-' + location + '-side-of-viewport').offset(display);
        }, function() {
            $display.removeClass('is-visible is-above-activator is-below-activator is-left-of-activator is-right-of-activator is-left-side-of-viewport is-right-side-of-viewport');
        });
    });
}

/* Fires when DOM is ready */
$( function() {

    // Hoverbox
    hoverbox();

    // Item hoverbox
    hoverbox({
        mainClass: 'c-item-hoverbox',
        activatorClass: 'c-item-hoverbox__activator',
        displayClass: 'c-item-hoverbox__display'
    });

} );
/* End DOM ready */

/* DO NOT ADD CODE BELOW THIS LINE */
}() );