Jump to content

User:Dead.rabbit/duplinks.js

From Wikipedia, the free encyclopedia
Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
// I took help from the following sources:
// - https://en.wikipedia.org/wiki/User:Ucucha/duplinks.js
// - https://commons.wikimedia.org/wiki/MediaWiki:Gadget-HotCat.js 

	var conf = window.mw ? mw.config.values : window;	
	
	function make (arg, literal) {
		if (!arg) return null;
		return literal ? document.createTextNode (arg) : document.createElement (arg);
	}
	
	function currentTimestamp () {
		var now = new Date();
		var ts  = "" + now.getUTCFullYear();
		function two (s) { return s.substr (s.length - 2); }
		ts = ts
			+ two ('0' + (now.getUTCMonth() + 1))
			+ two ('0' + now.getUTCDate())
			+ two ('00' + now.getUTCHours())
			+ two ('00' + now.getUTCMinutes())
			+ two ('00' + now.getUTCSeconds());
		return ts;
	}
	
	var getJSON = (function () {
		function getRequest () {
			var request = null;
			try {
				request = new window.XMLHttpRequest();
			} catch (anything) {
				if (window.ActiveXObject) {
					try {
						request = new window.ActiveXObject('Microsoft.XMLHTTP');
					} catch (any) {
					}
				} // end if IE
			} // end try-catch
			return request;
		}
		
		function armorUri (uri) {
			// Avoid protocol-relative URIs, IE7 has a bug with them in Ajax calls
			if (uri.length >= 2 && uri.substring(0, 2) == '//') return document.location.protocol + uri;
			return uri;
		}
		
		return function (settings) {
			var req = getRequest();
			if (!req && settings && settings.error) settings.error (req);
			if (!req || !settings || !settings.uri) return req;
			var uri = armorUri (settings.uri);
			var args = settings.data || null;
			var method;
			if (args && uri.length + args.length + 1 > 2000) {
				// We lose caching, but at least we can make the request
				method = 'POST';
				req.setRequestHeader ('Content-Type', 'application/x-www-form-urlencoded');
			} else {
				method = 'GET';
				if (args) uri += '?' + args;
				args = null;
			}
			req.open (method, uri, true);
			req.onreadystatechange = function () {
				if (req.readyState != 4) return;
				if (req.status != 200 || !req.responseText || !(/^\s*[\{\[]/.test(req.responseText))) {
					if (settings.error) settings.error (req);
				} else {
					if (settings.success) settings.success (eval ('(' + req.responseText + ')'));
				}
			};
			req.setRequestHeader ('Pragma', 'cache=yes');
			req.setRequestHeader ('Cache-Control', 'no-transform');
			req.send (args);
			return req;
		};
	})();
	
	function passInfoBox(wikitext) {
		var i = -1;
		if((i=wikitext.search(/infobox/i)) != -1){
			
			var s = wikitext.indexOf("{{", i);
			var e = wikitext.indexOf("}}", i);

			while ( s != -1 && e > s) {
				s = wikitext.indexOf("{{", s+2);
				e = wikitext.indexOf("}}", e+2);
			}
			
			return e;
		}
		return -1;
	}
	
	function getlinktext(str){
		
		if ((bar=str.indexOf("|")) != -1) {	
			link = str.substring(2, bar);
			text = str.substring(bar+1, str.length-2);
		} else {
			link = text = str.substring(2, str.length-2);
		}
		
		return [link, text];		
	}
	
	function removedups(wikitext){
		var s = passInfoBox(wikitext);
		var i;
		
		var seen = [];
		
		while((i=wikitext.indexOf("[[", s)) != -1) {
			e = wikitext.indexOf("]]", i);
			
			var ahref = wikitext.substring(i, e+2);
			
			var res = getlinktext(ahref);
			var link = res[0];
			var text = res[1];
			
			if(seen[link]) {
				wikitext = wikitext.substring(0, i) + text + wikitext.substring(e+2);
			} else {
				seen[link] = true;
			}
			s = e;
		}
		
		return wikitext;
	}
	
	function setPage (json) {
		var startTime = null;
		if (json && json.query) {
			if (json.query.pages) {
				var page = json.query.pages[conf.wgArticleId === 0 ? "-1" : "" + conf.wgArticleId];
				if (page) {
					if (page.revisions && page.revisions.length > 0) {
						// Revisions are sorted by revision ID, hence [0] is the one we asked for, and possibly there's a [1] if we're
						// not on the latest revision (edit conflicts and such).
						var pageText = page.revisions[0]['*'];
						var replacedText = removedups(pageText);
						if (pageText != replacedText) {
							createCommitForm (replacedText);
						}
					}
				}
			}
		}
	}

	function getPage(){
		getJSON ({
			uri : conf.wgServer + conf.wgScriptPath + '/api.php',
			data : 'format=json&action=query&rawcontinue=&titles=' + encodeURIComponent (conf.wgPageName)
				+ '&prop=info%7Crevisions%7Clanglinks&inprop=watched&intoken=edit'
				+ '&rvprop=content%7Ctimestamp%7Cids%7Cuser&lllimit=500'
				+ '&rvlimit=2&rvdir=newer&rvstartid=' + conf.wgCurRevisionId
				+ '&meta=siteinfo%7Cuserinfo&uiprop=options',
			success : function (json) { setPage (json); },
			error : function (req) { window.alert("fail" + req.status + ' ' + req.statusText); }
		});
	}
	
	function createCommitForm (wikitext) {
		var formContainer = make ('div');
		formContainer.style.display = 'none';
		document.body.appendChild (formContainer);
		formContainer.innerHTML =
			'<form id="hotcatCommitForm" method="post" enctype="multipart/form-data" action="'
			+ conf.wgScript + '?title=' + encodeURIComponent (conf.wgPageName)
			+ '&action=edit">'
			+ '<input type="hidden" name="wpTextbox1" />'
			+ '<input type="hidden" name="model" value="wikitext" />'
			+ '<input type="hidden" name="format" value="text/x-wiki" />'
			+ '<input type="hidden" name="wpSummary" value="" />'
			+ '<input type="checkbox" name="wpMinoredit" value="1" />'
			+ '<input type="checkbox" name="wpWatchthis" value="1" />'
			+ '<input type="hidden" name="wpAutoSummary" value="" />'
			+ '<input type="hidden" name="wpEdittime" />'
			+ '<input type="hidden" name="wpStarttime" />'
			+ '<input type="hidden" name="wpDiff" value="wpDiff" />'
			+ '<input type="hidden" name="oldid" value="0" />'
			+ '<input type="submit" name="hcCommit" value="hcCommit" />'
			+ '<input type="hidden" name="wpEditToken" />'
			+ '<input type="hidden" name="wpUltimateParam" value="1" />'
			+ '</form>';
		
		var commitForm = document.getElementById ('hotcatCommitForm');
		
		commitForm.wpAutoSummary.value = 'd41d8cd98f00b204e9800998ecf8427e'; // MD5 hash of the empty string
		commitForm.wpMinoredit.checked = true;
		commitForm.wpWatchthis.checked = true;
		commitForm.wpSummary.value = "removed overlinking as per ''[[Wikipedia:Tutorial/Wikipedia_links#When to link|When To Link]]''";
		commitForm.wpTextbox1.value = wikitext;
		commitForm.wpEdittime.value = commitForm.wpStarttime.value =  currentTimestamp ();

		commitForm.hcCommit.click();
		
	}
$( function($) {
    if((wgNamespaceNumber !== 0) && (wgNamespaceNumber != 2)) {
        // only check links in mainspace and userspace (for userspace drafts)
        return;
    }
    var portletlink = mw.util.addPortletLink('p-tb', '#', 'Highlight duplicates', 'ca-findduplicatelinks');
    $(portletlink).click( function(e) {
        e.preventDefault();
        				
        mw.util.addCSS(".duplicate-link { border: 3px solid red; }");
        
        // detect duplicate links
        var finddups = function() {
            var href = $(this).attr('href');
            if(href !== undefined && href.indexOf('#') !== 0) {
                if(seen[href]) {
                    $(this).addClass("duplicate-link");
                }
                else {
                    seen[href] = true;
                }
            }
            return true;
        };
        // array to keep track of whether we've seen a link before
        var seen = [];
        var content = ".mw-content-ltr";

        mw.util.$content.find('a').not('.infobox *, .navbox *').each(finddups);
    });
    
    var fixlink = mw.util.addPortletLink('p-tb', '#', 'Remove duplicates', 'ca-renduplicatelinks');
    $(fixlink).click( function(e) {
        e.preventDefault();
    	getPage();
    });
});