User:Evad37/Watchlist-openUnread.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 = '

'+

' '+

'(Options: pages max / '+

' '+

')

';

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

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

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");

});

});

});