Jump to content

MediaWiki:Common.js

From Elite Dangerous Wiki
Revision as of 00:25, 1 November 2026 by Talondri (talk | contribs) (Improve Main Page browsing, article search, featured article links and independent-wiki information)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Note: After publishing, 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)
  • Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5.
/* Any JavaScript here will be loaded for all users on every page load. */

window.AjaxRCRefreshText = 'Auto-refresh';
window.AjaxRCRefreshHoverText = 'Automatically refresh the page';
window.ajaxPages = [
    "Special:RecentChanges",
    "Special:WikiActivity",
    "Special:Watchlist",
    "Special:Log",
    "Special:Contributions"
];

/* START - switching images for the main page navigation buttons */

$("#ShipsButton img").hover(function() {$(this).attr("src", "https://images.wikia.nocookie.net/elite-dangerous/images/9/9b/Ships_Selected.png");}, function() {$(this).attr("src", "https://images.wikia.nocookie.net/elite-dangerous/images/1/19/Ships_Default.png");});

$("#OutfittingButton img").hover(function() {$(this).attr("src", "https://images.wikia.nocookie.net/elite-dangerous/images/7/76/Outfitting_Selected.png");}, function() {$(this).attr("src", "https://images.wikia.nocookie.net/elite-dangerous/images/f/fc/Outfitting_Default.png");});

$("#EngineersButton img").hover(function() {$(this).attr("src", "https://vignette.wikia.nocookie.net/elite-dangerous/images/d/da/Engineers_Selected.png");}, function() {$(this).attr("src", "https://vignette.wikia.nocookie.net/elite-dangerous/images/9/96/Engineers_Default.png");});

$("#RanksButton img").hover(function() {$(this).attr("src", "https://vignette.wikia.nocookie.net/elite-dangerous/images/8/80/Ranks_Selected.png");}, function() {$(this).attr("src", "https://vignette.wikia.nocookie.net/elite-dangerous/images/f/f3/Ranks_Default.png");});

$("#FactionsButton img").hover(function() {$(this).attr("src", "https://images.wikia.nocookie.net/elite-dangerous/images/d/de/Factions_Selected.png");}, function() {$(this).attr("src", "https://images.wikia.nocookie.net/elite-dangerous/images/b/bc/Factions_Default.png");});

$("#StarsButton img").hover(function() {$(this).attr("src", "https://vignette.wikia.nocookie.net/elite-dangerous/images/9/9b/Stars_Selected.png");}, function() {$(this).attr("src", "https://vignette.wikia.nocookie.net/elite-dangerous/images/9/90/Stars_Default.png");});

$("#PlanetsButton img").hover(function() {$(this).attr("src", "https://vignette.wikia.nocookie.net/elite-dangerous/images/8/8d/Planets_Selected.png");}, function() {$(this).attr("src", "https://vignette.wikia.nocookie.net/elite-dangerous/images/a/a3/Planets_Default.png");});

$("#RolesButton img").hover(function() {$(this).attr("src", "https://images.wikia.nocookie.net/elite-dangerous/images/0/01/Roles_Selected.png");}, function() {$(this).attr("src", "https://images.wikia.nocookie.net/elite-dangerous/images/4/4d/Roles_Default.png");});

/* END - switching images for the main page navigation buttons */

/* BEGIN Elite Main Page search */
if ( mw.config.get( "wgIsMainPage" ) ) {
mw.loader.using( [ "mediawiki.searchSuggest", "mediawiki.util" ] ).then( function () {
/* Main Page InputBox enhancement. Load after:
 * mw.loader.using( [ 'mediawiki.searchSuggest', 'mediawiki.util' ] )
 * The first dependency supplies jquery.suggestions, mediawiki.api and user.options.
 * Keep the ordinary InputBox form: no-JS/error/short-query submission still works.
 */
( function ( mw, $ ) {

	'use strict';
	if ( !mw.config.get( 'wgIsMainPage' ) ) {
		return;
	}

	$( function () {
		// mediawiki.searchSuggest's ready callback runs first. Reconfigure its
		// existing widget, rather than attaching a competing autocomplete.
		mw.hook( 'wikipage.content' ).add( function () {
			$( '.ed-home-search input.mw-searchInput' ).each( function () {
				const input = this;
				const $input = $( input );
				if ( $input.data( 'elite-home-search' ) || !input.form ) {
					return;
				}
				if ( !$.fn.suggestions || !mw.searchSuggest || !mw.Api || !mw.util ) {
					return; // Leave the working form alone if dependencies are absent.
				}

				let request = null;
				let generation = 0;
				let composing = false;
				const api = new mw.Api(); // Configured local wiki only, never ForeignApi.
				// A stable per-input ID also permits more than one hero InputBox.
				const listId = 'elite-home-suggestions-' + $( '.ed-home-search input.mw-searchInput' ).index( input );
				let context;

				function cancel() {
					generation++;
					if ( request ) {
						const previous = request;
						request = null;
						previous.abort();
					}
				}

				function syncAria() {
					const container = context.data.$container[ 0 ];
					const results = container.querySelectorAll( '.suggestions-result' );
					const expanded = container.style.display !== 'none' && results.length > 0;
					input.setAttribute( 'aria-expanded', String( expanded ) );
					input.removeAttribute( 'aria-activedescendant' );
					results.forEach( function ( result, index ) {
						result.id = listId + '-' + index;
						result.setAttribute( 'role', 'option' );
						const selected = expanded && result.classList.contains( 'suggestions-result-current' );
						result.setAttribute( 'aria-selected', String( selected ) );
						if ( selected ) {
							input.setAttribute( 'aria-activedescendant', result.id );
						}
					} );
				}

				function hide() {
					context.data.$container.hide();
					syncAria();
				}

				function localUrl( title ) {
					// Ignore OpenSearch's URL array, deriving links through MediaWiki.
					const url = new URL( mw.util.getUrl( title ), window.location.href );
					return url.origin === window.location.origin ? url.href : null;
				}

				$input.suggestions( {
					$region: $input,
					delay: 250,
					maxRows: 6,
					maxExpandFactor: 1,
					cache: false,
					highlightInput: false,
					submitOnClick: false,
					special: {},
					fetch: function ( query, response ) {
						if ( !context ) {
							return; // Initial native construction may fetch synchronously.
						}
						cancel();
						const current = generation;
						if ( composing || query.trim().length < 2 || query.length > 200 ) {
							response( [] );
							hide();
							return;
						}
						// [0], not 0: native request() otherwise falls back to the
						// user's configured namespaces because zero is falsy.
						request = mw.searchSuggest.request( api, query, function ( titles ) {
							if ( current !== generation || query !== input.value ||
								document.activeElement !== input || !input.isConnected ) {
								return;
							}
							const safeTitles = Array.isArray( titles ) ? titles.filter( function ( title ) {
								return typeof title === 'string' && title.length > 0 &&
									!/[\u0000-\u001f\u007f]/.test( title ) && localUrl( title );
							} ).slice( 0, 6 ) : [];
							response( safeTitles );
							if ( safeTitles.length === 0 ) {
								hide();
							}
						}, 6, [ 0 ] );
						request.fail( function () {
							if ( current === generation ) {
								response( [] );
								hide();
							}
						} );
					},
					cancel: cancel,
					update: { after: function () { if ( context ) { syncAria(); } } },
					result: {
						render: function ( title ) {
							this[ 0 ].textContent = title;
							const link = document.createElement( 'a' );
							link.href = localUrl( title );
							link.tabIndex = -1; // Focus stays on the combobox.
							link.className = 'mw-searchSuggest-link';
							this.wrap( link );
						},
						select: function ( textbox, source ) {
							if ( source === 'keyboard' ) {
								const url = localUrl( this.data( 'text' ) );
								if ( url ) {
									cancel();
									window.location.assign( url );
									return false;
								}
							}
							return true; // Mouse uses the ordinary local anchor.
						}
					}
				} );
				context = $input.data( 'suggestions-context' );
				cancel(); // Abort any generic request started before reconfiguration.
				const genericRequest = $.data( input, 'request' );
				if ( genericRequest ) {
					genericRequest.abort();
					$.removeData( input, 'request' );
				}
				$input.data( 'elite-home-search', true );
				$input.attr( {
					role: 'combobox',
					'aria-autocomplete': 'list',
					'aria-haspopup': 'listbox',
					'aria-controls': listId,
					'aria-expanded': 'false'
				} ); // Preserve InputBox's existing accessible label.
				context.data.$container.addClass( 'ed-home-suggestions' );
				const results = context.data.$container[ 0 ].querySelector( '.suggestions-results' );
				results.id = listId;
				results.setAttribute( 'role', 'listbox' );
				results.setAttribute( 'aria-label', 'Suggested articles' );
				hide();

				// Native keyboard handling owns arrows/Enter/Escape. Input covers
				// paste, mobile keyboards and other edits without a keypress event.
				function changed() {
					cancel();
					hide();
					if ( !composing ) {
						context.data.keypressed = 0;
						$input.trigger( 'keypress' ); // Native 250 ms debounce + cancel.
					}
				}
				$input.on( 'input.eliteHomeSearch', changed )
					.on( 'compositionstart.eliteHomeSearch', function () {
						composing = true;
						cancel();
						hide();
					} )
					.on( 'compositionend.eliteHomeSearch', function () {
						composing = false;
						changed();
					} );
				$( input.form ).on( 'submit.eliteHomeSearch', function () { cancel(); hide(); } );
				const observer = new MutationObserver( syncAria );
				observer.observe( context.data.$container[ 0 ], {
					subtree: true, childList: true, attributes: true,
					attributeFilter: [ 'class', 'style' ]
				} );
				if ( document.activeElement === input && input.value.length >= 2 ) {
					changed();
				}
			} );
		} );
	} );
}( mediaWiki, jQuery ) );

} );
}
/* END Elite Main Page search */