User:Evad37/Watchlist-openUnread/sandbox.js

/* Add any or all of these lines after the importScript line to set various options (the default values are shown):

var openUnread_maxnum = "10"; // Preset value for max number of pages var openUnread_oldest = false; // Preset state of checkbox "oldest first". Set to true  for checked, or  false  for unchecked var openUnread_showAbove = false; // If set to true  the "Open unread pages" button appears above the above the "Watchlist options" box, instead of below it

mw.loader.using( ['mediawiki.util', 'mediawiki.api'], function { $(document).ready( function  { if( mw.config.get('wgCanonicalSpecialPageName') != 'Watchlist' ) { // only operate in Special: namespace, on Special:Watchlist return; }

// Set default options for any that haven't been set if ( window.openUnread_maxnum === undefined ) { window.openUnread_maxnum = "10"; } if ( window.openUnread_oldest === undefined ) { window.openUnread_oldest = true; } if ( window.openUnread_showAbove === undefined ) { window.openUnread_showAbove = false; }

//Add a form to open multiple unread pages var openUnread_form = ' '+ 'Open unread pages '+ '(Options:  pages max / '+		'  oldest first '+		') '; if (openUnread_showAbove) { $("form#mw-watchlist-form").before(openUnread_form); $("#openUnread-input").css("margin-top","5px"); $("fieldset#mw-watchlist-options").css("margin-top", "0"); } else { $("form#mw-watchlist-form").after(openUnread_form + ' '); $("#openUnread-input").css("margin","5px 0"); $("fieldset#mw-watchlist-options").css("margin-bottom", "0"); }

if (openUnread_oldest) { $("#openUnread-order").prop( "checked", "true" ); }

//Seen is reused for each button click to account for itmes which have already been opened var seen = {}; var count = 0; // var increment on each button click iteration // Start processing on button click $("#openUnread-go").click(function {		// get max number from input		var maxnum = parseInt( $('#openUnread-number').val );		if (isNaN(maxnum) || maxnum < 1) {			msg = "\Error: \"" + $('#openUnread-number').val + "\" is zero, negative, or not a number";			mw.notify( msg, { autoHide: false, tag: "WatchlistOpenUnread", title: "Watchlist-openUnread says:" } );			return;		// error - zero, negative, or not a number		}		count++;		// get unread title links as array		var unread = $("li.mw-changeslist-line-watched, table.mw-changeslist-line-watched")			.find("a.mw-changeslist-title")			.map(function { return $(this).text; })			.get;

// reverse order if oldest first option selected if ( $('#openUnread-order').prop('checked') ) { unread.reverse; }		//remove duplicates var unique_unread = []; var len = unread.length; var j = 0; for (var i = 0; i < len; i++) { var item = unread[i]; if( !(seen[item] >= count) ) { // because (undefined < number) is false seen[item] = count; unique_unread[j++] = item; }		}

// reduce to the max number to open if (unique_unread.length > maxnum) { unique_unread = unique_unread.slice(0, maxnum); }

// Mark each unique unread item as already seen for the next iterations for (var u = 0; u < len; u++) { seen[unique_unread[u]] = seen[unique_unread[u]]+1000; }

// Callback for api errors apiFailedCallback = function(code, result) { var msg = ""; if ( code === "http" ) { msg = "HTTP error: " + result.textStatus; // api_result contains the jqXHR object } else if ( code === "ok-but-empty" ) { msg = "Error: Got an empty response from the server "; } else { msg = "API error: " + code; }			mw.notify( msg, { autoHide: false, tag: "WatchlistOpenUnread", title: "Watchlist-openUnread says:" } ); };		// Callback for getRevId: get old revision id for diff link apiCallback_getRevId = function(result) { var page_id = result.query.pageids[0]; var diff_oldid = result.query.pages[page_id].revisions && result.query.pages[page_id].revisions[1] && result.query.pages[page_id].revisions[1].revid; var diff_title = mw.util.wikiUrlencode(result.query.pages[page_id].title);

if (!diff_oldid) { window.open("https:" + mw.config.get('wgServer') + mw.config.get('wgScriptPath') +				"/index.php?title=" + diff_title, "_blank"); console.log("Could not find old revision for page "+ result.query.pages[page_id].title); return; }			window.open("https:" + mw.config.get('wgServer') + mw.config.get('wgScriptPath') +			"/index.php?title=" + diff_title +"&diff=cur&oldid=" + diff_oldid, "_blank"); };		// Function to get revision id of a page as of a particular timestamp getRevId = function(pageid, timestamp) { new mw.Api.get( {				action: 'query',				pageids: pageid,				prop: 'revisions',				rvprop: 'ids',				rvstart: timestamp,				rvlimit: '2',				indexpageids: 1,				rawcontinue: ''			} ).done( apiCallback_getRevId ) .fail( apiFailedCallback ); };		// Callback for getTimestamps: get timestamps/pageids to pass through to getRevId function apiCallback_getTimestamps = function(result) { var page_ids = result.query.pageids; for (var k=0; k<page_ids.length; k++) { var nts = result.query.pages[ page_ids[k] ].notificationtimestamp; getRevId(page_ids[k], nts); }		};		// Function to get timestamps from the api getTimestamps = function(pagetitles) { new mw.Api.get( {				action: 'query',				titles: pagetitles,				prop: 'info',				inprop: 'notificationtimestamp',				indexpageids: 1,				rawcontinue: ''			} ).done( apiCallback_getTimestamps ) .fail( apiFailedCallback ); };		// Split into lists of 50 (max number for api) for (var ii=0; ii<unique_unread.length; ii+=50) { getTimestamps(unique_unread.slice(ii, ii+49).join("|")); }

// show pages as read on watchlist $("li.mw-changeslist-line-watched, table.mw-changeslist-line-watched") .find("a.mw-changeslist-title") .filter(":contains('" + unique_unread.join("'), :contains('") + "')") .closest(".mw-changeslist-line-watched") .removeClass("mw-changeslist-line-watched") .addClass("mw-changeslist-line-not-watched"); });

}); });