User:The Transhumanist/SearchSuite.js
Appearance
Code that you insert on this page could contain malicious content capable of compromising your account. If you import a script from another page with "importScript", "mw.loader.load", "iusc", or "lusc", take note that this causes you to dynamically load a remote script, which could be changed by others. Editors are responsible for all edits and actions they perform, including by scripts. User scripts are not centrally supported and may malfunction or become inoperable due to software changes. A guide to help you find broken scripts is available. If you are unsure whether code you are adding to this page is safe, you can ask at the appropriate village pump. This code will be executed when previewing this page. |
This user script seems to have a documentation page at User:The Transhumanist/SearchSuite. |
// <syntaxhighlight lang="javascript">
/*
Installation instructions and the user's manual are located on this script's
talk page.
SearchSuite.js: this script provides menu items for the following suite of
search features:
Hide/show details
Hide/show sister results
Hide/show redirecteds/category-members
Sort/unsort
Show/hide list item wiki formatting, like this: * [[]]
(For easy copying/pasting)
The script also includes TrueMatch, a work-around for the "intitle:" bug.
This script was forked on 2018/02/13 from [[User:The_Transhumanist/StripSearchSorted.js]] (see:
https://en.wikipedia.org/w/index.php?title=User:The_Transhumanist/StripSearchSorted.js&oldid=821420973 ),
which was in turn derived from [[User:The Transhumanist/OutlineViewAnnotationToggler.js]]:
https://en.wikipedia.org/w/index.php?title=User:The_Transhumanist/OutlineViewAnnotationToggler.js&oldid=807301505
Brief comments are provided within the sourcecode below. For extensive explanatory
notes on what the source code does and how it works, see the Script's workshop on
the talk page. (Only partially done so far).
*/
// ============== Set up ==============
// Start off with a bodyguard function to reserve the aliases mw and $ within
// the scope of this function, so that we can rely on them meaning "mediaWiki"
// and "jQuery", respectively: these alias definitions follow this function's
// closing curly bracket at the end of the script.
( function ( mw, $ ) {
// ============== Load dependencies ==============
// For support of mw.util.addPortletLink
mw.loader.using( ['mediawiki.util'], function () {
// ============== ready() event listener/handler ==============
// below is jQuery short-hand for $(document).ready(function() { ... });
// it makes the rest of the script wait until the page's DOM is loaded and ready
$(function() {
// ============== deactivation filters (guard clauses) ==============
// End the script if " - Search results - Wikipedia" is not in the page title
if (document.title.indexOf(" - Search results - Wikipedia") == -1) {
// use a return statement to end the local function and hence the program's body
// important: this approach does not work outside of a function
return;
}
// End of set up
// =================== Prep work =====================
// Variable declarations, etc., go here
var SRSisterSwitch;
var SRRedirectedSwitch;
var SRDetailSwitch;
var SRWikifySwitch;
var SRSortSwitch;
var elems0;
var elems1;
var elems2;
// get the values of our status variables from memory
// (this tells us what modes to start in)
// "SR" stands for "search results"
var SRSisterStatus = localStorage.getItem('SRSisterStatus');
var SRRedirectedStatus = localStorage.getItem('SRRedirectedStatus');
var SRDetailStatus = localStorage.getItem('SRDetailStatus');
var SRWikifyStatus = localStorage.getItem('SRWikifyStatus');
var SRSortStatus = localStorage.getItem('SRSortStatus');
// ================== Core program ===================
// True match = make "intitle:" work the way it is supposed to
// Call TrueMatch function - see in Subroutines at program's end
TrueMatch();
// Tag each entry with numerical ids, to record their original order.
elems0 = $('.mw-search-results li').detach().attr( "id", function( arr ) {
return arr;
});
$('.mw-search-results').append(elems0);
// Wrap mw-search-result-heading's <a> element in wikilink delimiters
// which are in turn wrapped in classed span tags. Prefix with li asterisk.
// Wrap step 1: Make the first link in entry targettable by adding a class to them
$( ".mw-search-result-heading" ).children( "a" ).addClass( "sr-a" );
// Wrap step 2: wrap those page links in classed list item wikiformatting (* [[]]),
// with the class called "wikibrackets"
var searchResultAElements = document.getElementsByClassName("sr-a");
var i;
for (i = 0; i < searchResultAElements.length; i++) {
searchResultAElements[i].outerHTML = searchResultAElements[i].outerHTML.replace(/(<a.*?(<\/a>))/g,'<span class=wikibrackets>* [[</span>$1<span class=wikibrackets>]]</span>');
}
// run the appropriate wikify function based on stored status
// SRWikify must be first, so that the wrapping link wikicodes (above) don't show by default
SRWikify();
// run the appropriate sort function based on stored status
SRSort();
// run the appropriate sisters function based on stored status
SRSister();
// run the appropriate redirecteds function based on stored status
SRRedirected();
// run the appropriate detail function based on stored status
SRDetail();
// run the filter function for honing down search results
if(typeof SRFilter !== 'undefined') SRFilter();
// ======================== Subroutines ===========================
// Functions (aka subroutines) are activated only when they are called.
// Below are the functions called in the core of the program above.
// They are placed here at the end of the program, so that the script's
// flow is easier to follow.
// ============ TrueMatch function to make intitle work right =============
function TrueMatch() {
// The purpose of this function is to make the intitle search
// feature actually work, by filtering out the entries that do
// not contain the intitle search string in their titles.
// Activation filter:
// Run this function only if 'intitle:"' is in the page title
// Notice the lone " after intitle:
if (document.title.indexOf('intitle:"') != -1) {
// Body of function
// Create variable with page title
var docTitle = document.title;
// Extract the intitle search string from the page title
// We want the part between the quotation marks
// var regexIntitle = new RegExp('intitle:"(.+?)(")(.*)','i'); //case-insensitve version
var regexIntitle = new RegExp('.*?intitle:"(.+?)(")(.*)');
var intitle;
intitle = docTitle.replace(regexIntitle,"$1");
// Filter out search results that do not match the intitle search string
// First, mark true results with a class
$('.mw-search-results').find('li').has( 'div > a:contains("' + intitle + '")' ).addClass('truematch');
// Now remove the other results
$('.mw-search-results').find('li').not('.truematch').remove();
}
}
// =============== Function for Wikify control contruct =================
function SRWikify() {
// run the appropriate wikify function based on stored status
// starts "off" by default, if no status is stored (i.e., when script is used
// for the first time)
if ( SRWikifyStatus === "on" ) {
SRWikifyOn();
} else {
SRWikifyOff();
}
}
// =============== Function for Sort control contruct =================
function SRSort() {
// run the appropriate sort function based on stored status
// starts "off" by default, if no status is stored (i.e., when script is used
// for the first time)
if ( SRSortStatus === "on" ) {
SRSortOn();
} else {
SRSortOff();
}
}
// =============== Function for Sister control contruct =================
function SRSister() {
// run the appropriate sisters function based on stored status
// starts "on" by default, if no status is stored (i.e., when script is used
// for the first time)
if ( SRSisterStatus === "off" ) {
SRSisterOff();
} else {
SRSisterOn();
}
}
// =============== Function for Redirected control contruct =================
function SRRedirected() {
// run the appropriate redirecteds function based on stored status
// starts "on" by default, if no status is stored (i.e., when script is used
// for the first time)
if ( SRRedirectedStatus === "off" ) {
SRRedirectedOff();
} else {
SRRedirectedOn();
}
}
// =============== Function for Detail control contruct =================
function SRDetail() {
// run the appropriate detail function based on stored status
// starts "on" by default, if no status is stored (i.e., when script is used
// for the first time)
if ( SRDetailStatus === "off" ) {
SRDetailOff();
} else {
SRDetailOn();
}
}
// ============ Function to hide sister search results (turn sister off) ==============
function SRSisterOff() {
// store status so it persists across page loads
localStorage.setItem("SRSisterStatus", "off");
// Hide interwiki results (per http://api.jquery.com/hide)
$('#mw-interwiki-results').hide();
// now we have to update the menu item
// (referred to in this script as "SRSisterSwitch").
// To do that, first we remove it (if it exists):
if ( SRSisterSwitch ) {
SRSisterSwitch.parentNode.removeChild(SRSisterSwitch);
}
// and then we create it (or its replacement) from scratch:
SRSisterSwitch = mw.util.addPortletLink( 'p-tb', '', 'SR sisters \(turn on\)', 'tb-Sister', 'Show sister projects search results', '', '#tb-Sort' );
// make the menu item clickable by binding it to a click handler
// (which activates the actions between the curly brackets when clicked):
$( SRSisterSwitch ).click( function ( e ) {
e.preventDefault(); // prevents any default action -- we want only the following action to run:
SRSisterOn();
} );
}
// ============ Function to show sister search results (turn sister on) ==============
function SRSisterOn() {
// store status so it persists across page loads
localStorage.setItem("SRSisterStatus", "on");
// Show interwiki results (per http://api.jquery.com/show)
$('#mw-interwiki-results').show();
// now we have to update the menu item
// (referred to in this script as "SRSisterSwitch").
// To do that, first we remove it (if it exists):
if ( SRSisterSwitch ) {
SRSisterSwitch.parentNode.removeChild(SRSisterSwitch);
}
// and then we create it (or its replacement) from scratch:
SRSisterSwitch = mw.util.addPortletLink( 'p-tb', '', 'SR sisters \(turn off\)', 'tb-Sister', 'Hide sister projects search results', '', '#tb-Sort' );
// make the menu item clickable by binding it to a click handler
// (which activates the actions between the curly brackets when clicked):
$( SRSisterSwitch ).click( function ( e ) {
e.preventDefault(); // prevents any default action -- we want only the following action to run:
SRSisterOff();
} );
}
// ====== Function to hide redirecteds and category-based search results (turn redirected off) ======
function SRRedirectedOff() {
// store status so it persists across page loads
localStorage.setItem("SRRedirectedStatus", "off");
// Hide redirected entries, and entries from matching categories (per http://api.jquery.com/hide)
$("li").has(".searchalttitle").hide();
// now we have to update the menu item
// (referred to in this script as "SRRedirectedSwitch").
// To do that, first we remove it (if it exists):
if ( SRRedirectedSwitch ) {
SRRedirectedSwitch.parentNode.removeChild(SRRedirectedSwitch);
}
// and then we create it (or its replacement) from scratch:
SRRedirectedSwitch = mw.util.addPortletLink( 'p-tb', '', 'SR redirecteds \(turn on\)', 'tb-Redirecteds', 'Show redirected entries and entries from matching categories', '', '#tb-Sister' );
// make the menu item clickable by binding it to a click handler
// (which activates the actions between the curly brackets when clicked):
$( SRRedirectedSwitch ).click( function ( e ) {
e.preventDefault(); // prevents any default action -- we want only the following action to run:
SRRedirectedOn();
} );
}
// ====== Function to show redirecteds and category-based search results (turn redirected on) ======
function SRRedirectedOn() {
// store status so it persists across page loads
localStorage.setItem("SRRedirectedStatus", "on");
// Show redirected entries, and entries from matching categories (per http://api.jquery.com/hide)
$("li").has(".searchalttitle").show();
// now we have to update the menu item
// (referred to in this script as "SRRedirectedSwitch").
// To do that, first we remove it (if it exists):
if ( SRRedirectedSwitch ) {
SRRedirectedSwitch.parentNode.removeChild(SRRedirectedSwitch);
}
// and then we create it (or its replacement) from scratch:
SRRedirectedSwitch = mw.util.addPortletLink( 'p-tb', '', 'SR redirecteds \(turn off\)', 'tb-Redirecteds', 'Hide redirected entries and entries from matching categories', '', '#tb-Sister' );
// make the menu item clickable by binding it to a click handler
// (which activates the actions between the curly brackets when clicked):
$( SRRedirectedSwitch ).click( function ( e ) {
e.preventDefault(); // prevents any default action -- we want only the following action to run:
SRRedirectedOff();
} );
}
// ============ Function to hide details (turn detail off) ==============
function SRDetailOff() {
// store status so it persists across page loads
localStorage.setItem("SRDetailStatus", "off");
// Hide details (per http://api.jquery.com/hide)
$('.searchresult').hide();
$('.mw-search-result-data').hide();
// Remove extra whitespace by changing element from a block to inline
$( ".mw-search-results" ).find( 'li' ).css( 'display', 'inline' );
// Accessing children elements above may be affecting display of list items with .searchalttitle
// Therefore, make sure redirecteds remain hidden or shown based on their status:
if ( SRRedirectedStatus === "off" ) {
$("li").has(".searchalttitle").hide();
} else {
$("li").has(".searchalttitle").show();
}
// now we have to update the menu item
// (referred to in this script as "SRDetailSwitch").
// To do that, first we remove it (if it exists):
if ( SRDetailSwitch ) {
SRDetailSwitch.parentNode.removeChild(SRDetailSwitch);
}
// and then we create it (or its replacement) from scratch:
SRDetailSwitch = mw.util.addPortletLink( 'p-tb', '', 'SR details \(turn on\)', 'tb-Detail', 'Show the details', '', '#tb-Redirecteds' );
// make the menu item clickable by binding it to a click handler
// (which activates the actions between the curly brackets when clicked):
$( SRDetailSwitch ).click( function ( e ) {
e.preventDefault(); // prevents any default action -- we want only the following action to run:
SRDetailOn();
} );
}
// ============ Function to show details (turn detail on) ==============
function SRDetailOn() {
// store status so it persists across page loads
localStorage.setItem("SRDetailStatus", "on");
// Show details (per http://api.jquery.com/show)
$('.searchresult').show();
$('.mw-search-result-data').show();
// Add the original extra whitespace back in by changing element from inline to a block
$( ".mw-search-results" ).find( 'li' ).css( 'display', 'block' );
// Accessing children elements above may be affecting display of list items with .searchalttitle
// Therefore, make sure redirecteds remain hidden or shown based on their status:
if ( SRRedirectedStatus === "off" ) {
$("li").has(".searchalttitle").hide();
} else {
$("li").has(".searchalttitle").show();
}
// now we have to update the menu item
// (referred to in this script as "SRDetailSwitch").
// To do that, first we remove it (if it exists):
if ( SRDetailSwitch ) {
SRDetailSwitch.parentNode.removeChild(SRDetailSwitch);
}
// and then we create it (or its replacement) from scratch:
SRDetailSwitch = mw.util.addPortletLink( 'p-tb', '', 'SR details \(turn off\)', 'tb-Detail', 'Hide the details', '', '#tb-Redirecteds' );
// make the menu item clickable by binding it to a click handler
// (which activates the actions between the curly brackets when clicked):
$( SRDetailSwitch ).click( function ( e ) {
e.preventDefault(); // prevents any default action -- we want only the following action to run:
SRDetailOff();
} );
}
// ============ Function to hide wikibrackets (turn wikify off) ==============
function SRWikifyOff() {
// store status so it persists across page loads
localStorage.setItem("SRWikifyStatus", "off");
// Hide wikibrackets (per http://api.jquery.com/hide)
$('.wikibrackets').hide();
// now we have to update the menu item
// (referred to in this script as "SRWikifySwitch").
// To do that, first we remove it (if it exists):
if ( SRWikifySwitch ) {
SRWikifySwitch.parentNode.removeChild(SRWikifySwitch);
}
// and then we create it (or its replacement) from scratch:
SRWikifySwitch = mw.util.addPortletLink( 'p-tb', '', 'SR wikify \(turn on\)', 'tb-Wikify', 'Show wiki brackets around links for easy copy and paste', '', '#t-specialpages' );
// make the menu item clickable by binding it to a click handler
// (which activates the actions between the curly brackets when clicked):
$( SRWikifySwitch ).click( function ( e ) {
e.preventDefault(); // prevents any default action -- we want only the following action to run:
SRWikifyOn();
} );
}
// ============ Function to show wikibrackets (turn wikify on) ==============
function SRWikifyOn() {
// store status so it persists across page loads
localStorage.setItem("SRWikifyStatus", "on");
// Show interwiki results (per http://api.jquery.com/show)
$( '.wikibrackets' ).show();
// now we have to update the menu item
// (referred to in this script as "SRWikifySwitch").
// To do that, first we remove it (if it exists):
if ( SRWikifySwitch ) {
SRWikifySwitch.parentNode.removeChild(SRWikifySwitch);
}
// and then we create it (or its replacement) from scratch:
SRWikifySwitch = mw.util.addPortletLink( 'p-tb', '', 'SR wikify \(turn off\)', 'tb-Wikify', 'Hide wiki brackets around links', '', '#t-specialpages' );
// make the menu item clickable by binding it to a click handler
// (which activates the actions between the curly brackets when clicked):
$( SRWikifySwitch ).click( function ( e ) {
e.preventDefault(); // prevents any default action -- we want only the following action to run:
SRWikifyOff();
} );
}
// ============ Function to sort the search results ==============
function SRSortOn() {
// store status so it persists across page loads
localStorage.setItem("SRSortStatus", "on");
// detach the the search resulsts, sort them, then put them back
elems1 = $('.mw-search-results li').detach().sort(function (a, b) {
return ($(a).text() < $(b).text() ? -1
: $(a).text() > $(b).text() ? 1 : 0);
});
$('.mw-search-results').append(elems1);
// now we have to update the menu item
// (referred to in this script as "SRSortSwitch").
// To do that, first we remove it (if it exists):
if ( SRSortSwitch ) {
SRSortSwitch.parentNode.removeChild(SRSortSwitch);
}
// and then we create it (or its replacement) from scratch:
SRSortSwitch = mw.util.addPortletLink( 'p-tb', '', 'SR sort \(turn off\)', 'tb-Sort', 'Show search results in original order', '', '#tb-Wikify' );
// make the menu item clickable by binding it to a click handler
// (which activates the actions between the curly brackets when clicked):
$( SRSortSwitch ).click( function ( e ) {
e.preventDefault(); // prevents any default action -- we want only the following action to run:
SRSortOff();
} );
}
// ============ Function to sort search results to original order ==============
function SRSortOff() {
// store status so it persists across page loads
localStorage.setItem("SRSortStatus", "off");
// Development note: It would be best not to sort them to original order
// if they are already in original order, such as when sort is off when
// the page is generalted. A code inserted on the page itself could
// identify the page as alphabetically sorted. Therefore, this function
// should run only if that code (class = SRsorted) does not exist.
// Sort search results by id, to return them to original order
elems2 = $('.mw-search-results li').detach().sort(function (a, b) {
return (parseInt(a.id) < parseInt(b.id) ? -1
: parseInt(a.id) > parseInt(b.id) ? 1 : 0);
});
$('.mw-search-results').append(elems2);
// now we have to update the menu item
// (referred to in this script as "SRSortSwitch").
// To do that, first we remove it (if it exists):
if ( SRSortSwitch ) {
SRSortSwitch.parentNode.removeChild(SRSortSwitch);
}
// and then we create it (or its replacement) from scratch:
SRSortSwitch = mw.util.addPortletLink( 'p-tb', '', 'SR sort \(turn on\)', 'tb-Sort', 'Sort search results', '', '#tb-Wikify' );
$( SRSortSwitch ).click( function ( e ) {
e.preventDefault(); // prevents any default action -- we want only the following action to run:
SRSortOn();
} );
}
} );
} );
}( mediaWiki, jQuery ) );
// </syntaxhighlight>