User:MastCell/el-search.js

/* * File: el-search.js * Author: MastCell * Language: Javascript * Dependencies: *	jQuery (bundled with MediaWiki) *	api.js (by Conrad Irwin; original at http://en.wiktionary.org/wiki/User:Conrad.Irwin/Api.js) * Other credits: *	Leverages code from a variety of sources, including ^demon's old CSD-rationale script * ================================================================================================= * Purpose: 	This script adds a drop-down selection box to restrict external-link searches to *		a specific namespace. Often, one is only interested in external links in *		articlespace, so it's useful to be able to filter these. The MediaWiki API *		has a handy option to restrict external-link queries by namespace, but *		for whatever reason, it doesn't have an associated UI gadget at *		Special:LinkSearch. This script is intended to fill that gap. * ================================================================================================= * Under the hood: *	Pretty straightforward. The script: *		1. Adds a namespace selection box to Special:LinkSearch. *		2. Intercepts the "Search" button *		3. Reroutes it to the API via AJAX *		4. Throws the results into human-readable form. *	Note that the script runs on the client side, so you won't be able to bookmark results. * ================================================================================================= * Usage: *	To use this gadget, go to your vector.js file (or, if you use a skin besides vector, go to *	the appropriate .js file). For me, it's at User:MastCell/vector.js. *		 *	Once you're in your vector.js file, simply add the following line: *		importScript('User:MastCell/el-search.js'); *	... then save and reload. After that, it should just work. You can go to *	Special:LinkSearch and try it out. You should see a drop-down box next to the *	"Search" button, with a list of namespaces. */ // Include local copy of api.js, which facilitates AJAX queries to the MediaWiki API // The original library is at http://en.wiktionary.org/wiki/User:Conrad.Irwin/Api.js importScript('User:MastCell/api.js'); /* * Function: fillSelect * Parameters: None * Return value: 	Returns a Select object filled in with Wikipedia's namespaces *			and corresponding numerical values * ================================================================================== * This is a helper function to fill in a drop-down box. The function creates a "select" * input, fills it with the relevant namespaces and corresponding numerical values, * and then returns the drop-down box, which can then be inserted into the DOM. * * The drop-down box is assigned the id "nsoptions", so that it can be * located easily later on. */ function fillSelect { var namespaceList = [ { "value" : "-99", "display" : "All namespaces" }, {		"value" : "0", "display" : "Article" }, {		"value" : "1", "display" : "Talk" }, {		"value" : "2", "display" : "User" }, {		"value" : "3", "display" : "User Talk" }, {		"value" : "4", "display" : "Wikipedia" }, {		"value" : "5", "display" : "Wikipedia Talk" }, {		"value" : "6", "display" : "Image" }, {		"value" : "7", "display" : "Image Talk" }, {		"value" : "8", "display" : "MediaWiki" }, {		"value" : "9", "display" : "MediaWiki Talk" }, {		"value" : "10", "display" : "Template" }, {		"value" : "11", "display" : "Template Talk" }, {		"value" : "12", "display" : "Help" }, {		"value" : "13", "display" : "Help Talk" }, {		"value" : "14", "display" : "Category" }, {		"value" : "15", "display" : "Category Talk" } ];	var sel = document.createElement("select"); sel.disabled = false; for (var i = 0; i < namespaceList.length; i++) { var opt = new Option(namespaceList[i].display, namespaceList[i].value); // catches stupid IE error if (opt.innerHTML != namespaceList[i].display) { opt.innerHTML = namespaceList[i].display; }		sel.appendChild(opt); }	sel.name = "nsoptions"; sel.id = "nsoptions"; sel.style.marginLeft = "10px"; return sel; } /* * Function: 	handleFormSubmission * Params:	None. * Returns:	Nothing. * ================================================================================================ * This function is called when the user clicks on the "Search" button on the HTML form. It calls the * MediaWiki API, using api.js, and then returns. The result is sent back asynchronously and dispatched * to processELresults for handling. * * This function sets the UI to a "busy" state; it disables the Search button (to prevent multiple * simultaneous queries) and shows a spinner while waiting for the results. Note that the AJAX * callback function (in this case, processELresults) is responsible for restoring the UI * to its functional state once the query is complete. */ function handleFormSubmission { // Set the "busy" UI... $("#mw-linksearch-form :submit").attr("value", "Searching..."); $("#mw-linksearch-form :submit").attr("disabled", "true"); if ($("#progress-spinner").length > 0) { // Show spinner $("#progress-spinner").show; } else { // Create and show spinner $("#mw-linksearch-form :submit").after('  '); }	// AJAX call to retrieve results... var targetLink = $("#target").val; var localAPI = JsMwApi; var namespaceOpt = $("#nsoptions").val; if (namespaceOpt == -99) { // Search all namespaces localAPI({action: "query", list: "exturlusage", euquery: targetLink, eulimit: "1000"}, processELresults); } else { // Search only the restricted namespace localAPI({action: "query", list: "exturlusage", euquery: targetLink, eulimit: "1000", eunamespace: namespaceOpt}, processELresults); } } /* * Function: 	processELresults * Params:	result (a query object returned by api.js, containing the results of the user request) * Returns:	Nothing * ==================================================================================================================================== * This function is called when the AJAX query returns with results from the MediaWiki database. It processes the results and * puts them in a user-friendly list, patterned after the result view from Special:LinkSearch. * * Note that this function is responsible for restoring the functional UI (from the "busy" state) once it is completed. */ function processELresults(result) { // Remove old list, if any if ($("#el-result-list").length > 0) { $("#el-result-list").remove; }	if (result.query.exturlusage.length == 0) { // No links were found var noneFound = ' No links to '; noneFound += $("#target").val; noneFound += " were found in the given namespace. "; $("#mw-linksearch-form").after(noneFound); } else { // Create a result list $("#mw-linksearch-form").after(''); // Populate the result list for (var i = 0; i < result.query.exturlusage.length; i++) { var listItem = ''; listItem += result.query.exturlusage[i].url; listItem += ' is linked from '; listItem += result.query.exturlusage[i].title; listItem += ""; $("#el-result-list").append(listItem); }	}	// Clear the "busy" UI... $("#mw-linksearch-form :submit").attr("value", "Search"); $("#mw-linksearch-form :submit").removeAttr("disabled"); $("#progress-spinner").hide; } // Adds a hook to check if we're on Special:LinkSearch. If so, // we create and place the drop-down box. Then we intercept clicks // on the "Search" button and re-route them to our handler. addOnloadHook(function {	if (mw.config.get('wgPageName') == "Special:LinkSearch") {		var sel = fillSelect;		$("#target").after(sel);		$("#mw-linksearch-form").submit(function(event) { event.preventDefault; handleFormSubmission; return false; });	} });