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