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.

// customWatchlists.js

// version 0.1.3

$(function() {

	$("head").append(mw.loader.load( 'https://en.wikipedia.org/?title=User:MusikAnimal/customWatchlists.css&action=raw&ctype=text/css', 'text/css' ));

	

	var addCwLinkListener = function() {

		$(".cw-add").click(function() {

			if($("#cw-overlay")[0]) return false;

			var pageName = new mw.Title($(this).siblings(".mw-title").text());

			pageName = pageName.getNamespacePrefix()+pageName.getMain();

			getCustomWatchlists().then(setupCactionInterface.bind(this, pageName),setupCactionInterface.bind(this, null));

		});

	};

	

	var getCustomWatchlists = function() {

		return Promise.resolve($.get("/wiki/User:"+mw.config.get('wgUserName')+"/watchlists?action=raw"));

	};

	

	var formatDate = function(dateObj) {

		// TODO: replace monthNames with wgMonthNames

		var monthNames =  "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ];

		return (dateObj.getHours()+100).toString().slice(-2)+":"+(dateObj.getMinutes()+100).toString().slice(-2)+", "+(dateObj.getUTCDate()+100).toString().slice(-2)+" "+monthNamesdateObj.getUTCMonth()]+" "+dateObj.getUTCFullYear();

	};

	

	var generateListItem = function(data) {

		var mwName = new mw.Title(data.title);

		var pageUrl = "/?title="+mwName.getNamespacePrefix()+mwName.getMain().replace(/'/g, "%27"),

			editDate = new Date(data.timestamp);

		if(data.newlen) {

			var lengthDiff = data.newlen - data.oldlen;

			var diffClass = lengthDiff >= 0 ? "mw-plusminus-pos" : "mw-plusminus-neg";

		}

		return "<li class='mw-line-even mw-changeslist-line-not-watched'>" +

			"("+

				"<a href='"+pageUrl+"&diff=prev&oldid="+data.revid+"' class='nonimage'>diff</a>&nbsp;| " +

				"<a href='"+pageUrl+"&action=history' class='nonimage'>hist</a>&nbsp;| " +

				"<a href='javascript:' class='cw-add'>cw</a>" +

			")&nbsp;" +

			"<span class='mw-changeslist-separator'>. .</span>&nbsp;" +

			"<span class='mw-changeslist-date'>"+formatDate(editDate)+"</span>&nbsp;" +

			"<span class='mw-title'><a href='/wiki/"+encodeURI(data.title).replace(/'/g, "%27")+"' class='mw-changeslist-title nonimage'>"+data.title+"</a></span>&nbsp;" +

			(data.newlen ? "<span class='mw-changeslist-separator'>. .</span>&nbsp;<span dir='ltr' class='"+diffClass+"'>("+(lengthDiff > 0 ? "+" : "")+lengthDiff+")</span> " : "") +

			"<span class='mw-changeslist-separator'>. .</span>&nbsp;" +

			"<a href='/wiki/User:"+data.user+"' class='mw-userlink nonimage'>"+data.user+"</a> " +

			"(<a href='/wiki/User talk:"+data.user+"'>talk</a> | <a href='/wiki/Special:Contributions/"+data.user+"'>contribs</a>)" +

			(data.parsedcomment ? "&nbsp;<span style='font-style:italic'>(" + data.parsedcomment + ")</span>" : "") +

		"</li>";

	};

	

	var showCustomWatchlist = function(type,lists,target,limit,allrev) {

		var apiRoot = "/w/api.php?action=query";

		var pages = JSON.parse(JSON.stringify(liststarget]));

		var pagesLength = pages.length;

		for(var i=0; i<pagesLength; i++) {

			var mwPageName = new mw.Title(pagesi]);

			if(mwPageName.namespace % 2 === 0) {

				pages.push(mwPageName.getNamespacePrefix().slice(0,-1) + (mwPageName.namespace === 0 ? "Talk:" : "_talk:") + mwPageName.getMain());

			}

		}

		$(".mw-changeslist").html("Loading...");

		

		var newHtml = "";

		if(type === "rc") {

			$.get(apiRoot+"&list=watchlist&wlprop=user|parsedcomment|timestamp|sizes|title|ids&wltype=edit&wllimit="+limit+(allrev === true ? "&wlallrev=true" : "")+"&format=json", function(data) {

				var matches = $.grep(data.query.watchlist, function(el){

					var mwName = new mw.Title(el.title);

					return pages.indexOf(mwName.getNamespacePrefix()+mwName.getMain()) >= 0;

				});

				for(var i=0; i<matches.length; i++) {

					newHtml += generateListItem(matchesi]);

				}

				$(".mw-changeslist").html(newHtml);

				addCwLinkListener();

				mw.hook( 'wikipage.content' ).fire($('.mw-changeslist'));

			});

		} else {

			var queryablePages = $.map(pages,function(p,i){return encodeURIComponent(p).replace(/'/g, "%27")}).join("|");

			$.get(apiRoot+"&prop=revisions&rvprop=ids|timestamp|user|parsedcomment&titles="+queryablePages+"&format=json", function(data) {

				var sortedData = [];

				for(var pageId in data.query.pages) {

					if(parseInt(pageId) > 0) {

						var pageData = data.query.pagespageId];

						sortedData.push({

							parsedcomment : pageData.revisions0].parsedcomment,

							revid: pageData.revisions0].revid,

							timestamp: pageData.revisions0].timestamp,

							title: pageData.title,

							user: pageData.revisions0].user

						});

					}

				}

				$.each(sortedData.sort(function(x,y) {

					if($("#cw-rw-options input:checked").val() === "timestamp") {

						return new Date(y.timestamp).getTime() - new Date(x.timestamp).getTime();

					} else {

						return x.title.localeCompare(y.title);

					}

				}), function(i,v) {

					newHtml += generateListItem(v);

				});

				$(".mw-changeslist").html(newHtml);

				addCwLinkListener();

				mw.hook( 'wikipage.content' ).fire($('.mw-changeslist'));

			});

		}

	};

	

	var showCustomWatchlistsForm = function(appendHtml) {

		console.log("testing");

		var html = "<form id='custom_watchlist_form'><fieldset>" +

				"<legend>Custom watchlists (<a href='//en.wikipedia.org/?title=User:MusikAnimal/customWatchlists'>documentation</a>)</legend>" + appendHtml;

		$("#mw-watchlist-form").after(html);

	};

	

	var setupCactionInterface = function(data, argName) {

		if(argName) {

			pageName = data;

			data = argName;

		} else {

			pageName = mw.config.get('wgPageName');

		}

		var customWatchlists = data ? JSON.parse(data.split("\n")[0]) : {};

		var customWatchlistNames = Object.keys(customWatchlists),

			inWatchlists = [];

		

		for(var wl in customWatchlists) {

			

			if(customWatchlistswl].indexOf(pageName.replace("_talk:",":").replace("Talk:","")) !== -1) {

				inWatchlists.push(wl);

			}

		}

		

		var html = "<div id='cw-overlay'>" +

			"<div class='header'>" +

				"Add/remove page to custom watchlists" +

				"<span class='closer-x' onclick=\"$('#cw-overlay').remove();\"></span>" +

			"</div>" +

			"<div id='cw-overlay-body'>" +

				(argName ? "<p style='margin-top:0'>Page name: <i>"+pageName.replace(/_/g, " ")+"</i></p>" : "");

		

		for(var i=0; i < customWatchlistNames.length; i++) {

			var listName = customWatchlistNamesi];

			html += "<span><input class='cw-option' type='checkbox' value='"+i+"' "+(inWatchlists.indexOf(listName) !== -1 ? "checked data-index='"+customWatchlistslistName].indexOf(pageName)+"'" : "")+" id='cw-option-"+i+"' /><label for='cw-option-"+i+"'>"+listName+"</label> (<a class='cw-delete' href='javascript:' data-id='"+i+"'>del</a>)</span>";

		}

		

		html += "<div id='cw-overlay-new-watchlist'>" +

				"<input class='cw-option' type='checkbox' value='-1' id='cw-new-option' "+(data ? "" : "checked")+" /><label for='cw-new-option'>New watchlist</label>" +

				"<input type='text' id='cw-overlay-new-watchlist-input' placeholder='Enter watchlist name' "+(data ? "" : "style='display:inline-block'")+" />" +

			"</div><button id='cw-overlay-selector-submit'>Save changes</button></div></div>";

		

		$("body").append(html);

		

		if(!data) $("#cw-overlay-new-watchlist-input").focus();

		

		$("#cw-new-option").change(function() {

			if($(this).is(":checked")) {

				$("#cw-overlay-new-watchlist-input").show().focus();

			} else {

				$("#cw-overlay-new-watchlist-input").hide();

			}

		});

		

		$(".cw-delete").click(function() {

			if($(this).text() === "undel") {

				$("#cw-option-"+$(this).data('id')).prop('checked',false).siblings("label").removeClass("disabled");

				$("#cw-option-"+$(this).data('id')).data('delete',null);

				$(this).text("del");

			} else {

				var name = customWatchlistNames$(this).data('id')];

				var cwToDelete = customWatchlistsname];

				if(confirm("Mark the watchlist \""+name+"\" and all it's "+cwToDelete.length+" entries for deletion?")) {

					$(this).text("undel");

					$("#cw-option-"+$(this).data('id')).data('delete',true);

					$("#cw-option-"+$(this).data('id')).prop('checked',true).one("click", function() {

						$(this).siblings("a").trigger("click");

					}).siblings("label").addClass("disabled");

				}

			}

		});

		

		$("#cw-overlay-selector-submit").click({

			customWatchlistNames: customWatchlistNames,

			customWatchlists: customWatchlists,

			inWatchlists: inWatchlists,

			pageName : pageName

		}, function(e) {

			$("#cw-overlay-selector-submit").replaceWith("Saving...");

			var cw = e.data.customWatchlists,

				iw = e.data.inWatchlists,

				pageName = e.data.pageName.replace("_talk:",":").replace("Talk:",":"),

				toWatch = false,

				updateStr = "";



			$.each($(".cw-option"), function(i) {

				var id = parseInt($(this).val());

				var key = id < 0 ? $("#cw-overlay-new-watchlist-input").val().replace(/[^\w\s]/gi, '') : customWatchlistNamesid];

				var exists = iw.indexOf(key) >= 0;

				

				if($(this).is(":checked")) {

					if($(this).data("delete")) {

						updateStr = "Deleted the custom watchlist <b>"+key+"</b>.";

						delete cwkey];

					} else {

						toWatch = true;

						if(id < 0) {

							updateStr = "Created the custom watchlist <b>"+key+"</b> with <b>"+pageName+"</b>";

							cwkey = pageName];

						} else {

							updateStr = "Added <b>"+pageName+"</b> to the custom watchlist <b>"+key+"</b>";

							cwkey].push(pageName);

						}

					}

				} else if(exists) {

					updateStr = "Removed <b>"+pageName+"</b> from the custom watchlist <b>"+key+"</b>";

					cwkey].splice($(this).data('index'),1);

				}

			});

			

			var stringifiedCw = JSON.stringify(cw)+"\nBacklink: [[User:MusikAnimal/customWatchlists]]";



			var api = new mw.Api();

			api.watch(pageName).done(function(watchResult) {

				api.postWithToken( "edit", {

					action: "edit",

					title: "User:"+mw.config.get('wgUserName')+"/watchlists",

					summary: "updating [[User:MusikAnimal/customWatchlists|custom watchlists]]",

					text: stringifiedCw

				}).done(function(result, jqXHR) {

					$("#cw-overlay-body").html("Success!");

					mw.notify($("<div>"+updateStr+"</div"));

					setTimeout(function() {

						$("#cw-overlay").remove();

					},3000);

				}).fail(function(code, result) {

					if ( code === "http" ) {

						mw.log( "HTTP error: " + result.textStatus ); // result.xhr contains the jqXHR object

					} else if ( code === "ok-but-empty" ) {

						mw.log( "Got an empty response from the server" );

					} else {

						mw.log( "API error: " + code );

					}

				});

			}).fail(function(code, result) {

				if ( code === "http" ) {

					mw.log( "HTTP error: " + result.textStatus ); // result.xhr contains the jqXHR object

				} else if ( code === "ok-but-empty" ) {

					mw.log( "Got an empty response from the server" );

				} else {

					mw.log( "API error: " + code );

				}

			});

		});

	};

	

	if(mw.config.get('wgRelevantPageName') === "Special:Watchlist") {

		getCustomWatchlists().then(function(data) {

			var customWatchlists = JSON.parse(data.split("\n")[0]);

			var customWatchlistNames = Object.keys(customWatchlists);

			var html = "<p><label for='custom_watchlist_selector'>Custom list:</label>&nbsp;<select id='custom_watchlist_selector'>";



			for(var i=0; i < customWatchlistNames.length; i++) {

				var listName = customWatchlistNamesi];

				html += "<option value='"+i+"'>"+listName+"</option>";

			}

			

			html += "</select></p>"+

				"<p id='cw-list-type'>Show:&nbsp;<label><input type='radio' name='cw-display-type' value='rc' checked /> Recent changes</label>&nbsp;<label><input type='radio' name='cw-display-type' value='rw' /> Raw watchlist</label></p>" +

				"<p id='cw-rw-options' style='display:none'>Sorting:&nbsp;<label><input type='radio' name='cw-rw-sorting' value='timestamp' checked /> Last edited</label>&nbsp;<label><input type='radio' name='cw-rw-sorting' value='title' />Alphabetical</label></p>" +

				"<p id='cw-rc-options'><label for='custom_watchlist_limit'>Search limit (from base watchlist):</label>&nbsp;<select id='custom_watchlist_limit'>";

			var limitArr = 50,100,250,500,1000,2500,5000];

			for(var j=0; j<limitArr.length; j++) {	

				html += "<option val='"+limitArrj+"'>"+limitArrj+"</option>";

			}



			html += "</select><br/>" +

				"<input type='checkbox' id='custom_watchlist_all_rev' value='wlallrev' /><label for='custom_watchlist_all_rev'>Include multiple revisions to same page</label></p>" +

				"<p><button id='custom_watchlist_submit'>Go</button></fieldset></p></form>";



			showCustomWatchlistsForm(html);

			

			$("#custom_watchlist_submit").click(function(e) {

				e.preventDefault();

				showCustomWatchlist($("#cw-list-type input[type=radio]:checked").val(),customWatchlists,customWatchlistNamesparseInt($("#custom_watchlist_selector").val())],$("#custom_watchlist_limit").val(),$("#custom_watchlist_all_rev").is(":checked"));

			});

			$("#custom_watchlist_form input[type=radio]").click(function() {

				if($(this).val() === "rc") {

					$("#cw-rc-options").show();

					$("#cw-rw-options").hide();

				} else {

					$("#cw-rc-options").hide();

					$("#cw-rw-options").show();

				}

			});

		}, function() {

			showCustomWatchlistsForm("<p>No <a href='/info/en/?search=User:MusikAnimal/customWatchlists'>custom watchlists</a> yet! Go to a <a href='/wiki/Special:Random'>page</a> and create a custom watchlist by selecting the \"Custom Watchlists&hellip;\" item from the More menu.</p>");

		});

		$(".mw-changeslist .special li").each(function() {

			$anchor = $(this).find("a").eq(1);

			if($anchor.text() === "hist" && !$anchor.siblings(".wikibase-edit").length) {

				$anchor.after("&nbsp;| <a class='cw-add' href='javascript:'>cw</a>");

			}

		});

		addCwLinkListener();

	} else if(mw.config.get('wgNamespaceNumber') >= 0) {

		mw.util.addPortletLink(

			'p-cactions',

			'javascript:',

			'Custom watchlist…',

			'ca-add-to-cw'

		);

		$("#ca-add-to-cw").click(function() {

			if($("#cw-overlay")[0]) return false;

			getCustomWatchlists().then(setupCactionInterface,setupCactionInterface.bind(this, null, null));

		});

	}

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

// customWatchlists.js

// version 0.1.3

$(function() {

	$("head").append(mw.loader.load( 'https://en.wikipedia.org/?title=User:MusikAnimal/customWatchlists.css&action=raw&ctype=text/css', 'text/css' ));

	

	var addCwLinkListener = function() {

		$(".cw-add").click(function() {

			if($("#cw-overlay")[0]) return false;

			var pageName = new mw.Title($(this).siblings(".mw-title").text());

			pageName = pageName.getNamespacePrefix()+pageName.getMain();

			getCustomWatchlists().then(setupCactionInterface.bind(this, pageName),setupCactionInterface.bind(this, null));

		});

	};

	

	var getCustomWatchlists = function() {

		return Promise.resolve($.get("/wiki/User:"+mw.config.get('wgUserName')+"/watchlists?action=raw"));

	};

	

	var formatDate = function(dateObj) {

		// TODO: replace monthNames with wgMonthNames

		var monthNames =  "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ];

		return (dateObj.getHours()+100).toString().slice(-2)+":"+(dateObj.getMinutes()+100).toString().slice(-2)+", "+(dateObj.getUTCDate()+100).toString().slice(-2)+" "+monthNamesdateObj.getUTCMonth()]+" "+dateObj.getUTCFullYear();

	};

	

	var generateListItem = function(data) {

		var mwName = new mw.Title(data.title);

		var pageUrl = "/?title="+mwName.getNamespacePrefix()+mwName.getMain().replace(/'/g, "%27"),

			editDate = new Date(data.timestamp);

		if(data.newlen) {

			var lengthDiff = data.newlen - data.oldlen;

			var diffClass = lengthDiff >= 0 ? "mw-plusminus-pos" : "mw-plusminus-neg";

		}

		return "<li class='mw-line-even mw-changeslist-line-not-watched'>" +

			"("+

				"<a href='"+pageUrl+"&diff=prev&oldid="+data.revid+"' class='nonimage'>diff</a>&nbsp;| " +

				"<a href='"+pageUrl+"&action=history' class='nonimage'>hist</a>&nbsp;| " +

				"<a href='javascript:' class='cw-add'>cw</a>" +

			")&nbsp;" +

			"<span class='mw-changeslist-separator'>. .</span>&nbsp;" +

			"<span class='mw-changeslist-date'>"+formatDate(editDate)+"</span>&nbsp;" +

			"<span class='mw-title'><a href='/wiki/"+encodeURI(data.title).replace(/'/g, "%27")+"' class='mw-changeslist-title nonimage'>"+data.title+"</a></span>&nbsp;" +

			(data.newlen ? "<span class='mw-changeslist-separator'>. .</span>&nbsp;<span dir='ltr' class='"+diffClass+"'>("+(lengthDiff > 0 ? "+" : "")+lengthDiff+")</span> " : "") +

			"<span class='mw-changeslist-separator'>. .</span>&nbsp;" +

			"<a href='/wiki/User:"+data.user+"' class='mw-userlink nonimage'>"+data.user+"</a> " +

			"(<a href='/wiki/User talk:"+data.user+"'>talk</a> | <a href='/wiki/Special:Contributions/"+data.user+"'>contribs</a>)" +

			(data.parsedcomment ? "&nbsp;<span style='font-style:italic'>(" + data.parsedcomment + ")</span>" : "") +

		"</li>";

	};

	

	var showCustomWatchlist = function(type,lists,target,limit,allrev) {

		var apiRoot = "/w/api.php?action=query";

		var pages = JSON.parse(JSON.stringify(liststarget]));

		var pagesLength = pages.length;

		for(var i=0; i<pagesLength; i++) {

			var mwPageName = new mw.Title(pagesi]);

			if(mwPageName.namespace % 2 === 0) {

				pages.push(mwPageName.getNamespacePrefix().slice(0,-1) + (mwPageName.namespace === 0 ? "Talk:" : "_talk:") + mwPageName.getMain());

			}

		}

		$(".mw-changeslist").html("Loading...");

		

		var newHtml = "";

		if(type === "rc") {

			$.get(apiRoot+"&list=watchlist&wlprop=user|parsedcomment|timestamp|sizes|title|ids&wltype=edit&wllimit="+limit+(allrev === true ? "&wlallrev=true" : "")+"&format=json", function(data) {

				var matches = $.grep(data.query.watchlist, function(el){

					var mwName = new mw.Title(el.title);

					return pages.indexOf(mwName.getNamespacePrefix()+mwName.getMain()) >= 0;

				});

				for(var i=0; i<matches.length; i++) {

					newHtml += generateListItem(matchesi]);

				}

				$(".mw-changeslist").html(newHtml);

				addCwLinkListener();

				mw.hook( 'wikipage.content' ).fire($('.mw-changeslist'));

			});

		} else {

			var queryablePages = $.map(pages,function(p,i){return encodeURIComponent(p).replace(/'/g, "%27")}).join("|");

			$.get(apiRoot+"&prop=revisions&rvprop=ids|timestamp|user|parsedcomment&titles="+queryablePages+"&format=json", function(data) {

				var sortedData = [];

				for(var pageId in data.query.pages) {

					if(parseInt(pageId) > 0) {

						var pageData = data.query.pagespageId];

						sortedData.push({

							parsedcomment : pageData.revisions0].parsedcomment,

							revid: pageData.revisions0].revid,

							timestamp: pageData.revisions0].timestamp,

							title: pageData.title,

							user: pageData.revisions0].user

						});

					}

				}

				$.each(sortedData.sort(function(x,y) {

					if($("#cw-rw-options input:checked").val() === "timestamp") {

						return new Date(y.timestamp).getTime() - new Date(x.timestamp).getTime();

					} else {

						return x.title.localeCompare(y.title);

					}

				}), function(i,v) {

					newHtml += generateListItem(v);

				});

				$(".mw-changeslist").html(newHtml);

				addCwLinkListener();

				mw.hook( 'wikipage.content' ).fire($('.mw-changeslist'));

			});

		}

	};

	

	var showCustomWatchlistsForm = function(appendHtml) {

		console.log("testing");

		var html = "<form id='custom_watchlist_form'><fieldset>" +

				"<legend>Custom watchlists (<a href='//en.wikipedia.org/?title=User:MusikAnimal/customWatchlists'>documentation</a>)</legend>" + appendHtml;

		$("#mw-watchlist-form").after(html);

	};

	

	var setupCactionInterface = function(data, argName) {

		if(argName) {

			pageName = data;

			data = argName;

		} else {

			pageName = mw.config.get('wgPageName');

		}

		var customWatchlists = data ? JSON.parse(data.split("\n")[0]) : {};

		var customWatchlistNames = Object.keys(customWatchlists),

			inWatchlists = [];

		

		for(var wl in customWatchlists) {

			

			if(customWatchlistswl].indexOf(pageName.replace("_talk:",":").replace("Talk:","")) !== -1) {

				inWatchlists.push(wl);

			}

		}

		

		var html = "<div id='cw-overlay'>" +

			"<div class='header'>" +

				"Add/remove page to custom watchlists" +

				"<span class='closer-x' onclick=\"$('#cw-overlay').remove();\"></span>" +

			"</div>" +

			"<div id='cw-overlay-body'>" +

				(argName ? "<p style='margin-top:0'>Page name: <i>"+pageName.replace(/_/g, " ")+"</i></p>" : "");

		

		for(var i=0; i < customWatchlistNames.length; i++) {

			var listName = customWatchlistNamesi];

			html += "<span><input class='cw-option' type='checkbox' value='"+i+"' "+(inWatchlists.indexOf(listName) !== -1 ? "checked data-index='"+customWatchlistslistName].indexOf(pageName)+"'" : "")+" id='cw-option-"+i+"' /><label for='cw-option-"+i+"'>"+listName+"</label> (<a class='cw-delete' href='javascript:' data-id='"+i+"'>del</a>)</span>";

		}

		

		html += "<div id='cw-overlay-new-watchlist'>" +

				"<input class='cw-option' type='checkbox' value='-1' id='cw-new-option' "+(data ? "" : "checked")+" /><label for='cw-new-option'>New watchlist</label>" +

				"<input type='text' id='cw-overlay-new-watchlist-input' placeholder='Enter watchlist name' "+(data ? "" : "style='display:inline-block'")+" />" +

			"</div><button id='cw-overlay-selector-submit'>Save changes</button></div></div>";

		

		$("body").append(html);

		

		if(!data) $("#cw-overlay-new-watchlist-input").focus();

		

		$("#cw-new-option").change(function() {

			if($(this).is(":checked")) {

				$("#cw-overlay-new-watchlist-input").show().focus();

			} else {

				$("#cw-overlay-new-watchlist-input").hide();

			}

		});

		

		$(".cw-delete").click(function() {

			if($(this).text() === "undel") {

				$("#cw-option-"+$(this).data('id')).prop('checked',false).siblings("label").removeClass("disabled");

				$("#cw-option-"+$(this).data('id')).data('delete',null);

				$(this).text("del");

			} else {

				var name = customWatchlistNames$(this).data('id')];

				var cwToDelete = customWatchlistsname];

				if(confirm("Mark the watchlist \""+name+"\" and all it's "+cwToDelete.length+" entries for deletion?")) {

					$(this).text("undel");

					$("#cw-option-"+$(this).data('id')).data('delete',true);

					$("#cw-option-"+$(this).data('id')).prop('checked',true).one("click", function() {

						$(this).siblings("a").trigger("click");

					}).siblings("label").addClass("disabled");

				}

			}

		});

		

		$("#cw-overlay-selector-submit").click({

			customWatchlistNames: customWatchlistNames,

			customWatchlists: customWatchlists,

			inWatchlists: inWatchlists,

			pageName : pageName

		}, function(e) {

			$("#cw-overlay-selector-submit").replaceWith("Saving...");

			var cw = e.data.customWatchlists,

				iw = e.data.inWatchlists,

				pageName = e.data.pageName.replace("_talk:",":").replace("Talk:",":"),

				toWatch = false,

				updateStr = "";



			$.each($(".cw-option"), function(i) {

				var id = parseInt($(this).val());

				var key = id < 0 ? $("#cw-overlay-new-watchlist-input").val().replace(/[^\w\s]/gi, '') : customWatchlistNamesid];

				var exists = iw.indexOf(key) >= 0;

				

				if($(this).is(":checked")) {

					if($(this).data("delete")) {

						updateStr = "Deleted the custom watchlist <b>"+key+"</b>.";

						delete cwkey];

					} else {

						toWatch = true;

						if(id < 0) {

							updateStr = "Created the custom watchlist <b>"+key+"</b> with <b>"+pageName+"</b>";

							cwkey = pageName];

						} else {

							updateStr = "Added <b>"+pageName+"</b> to the custom watchlist <b>"+key+"</b>";

							cwkey].push(pageName);

						}

					}

				} else if(exists) {

					updateStr = "Removed <b>"+pageName+"</b> from the custom watchlist <b>"+key+"</b>";

					cwkey].splice($(this).data('index'),1);

				}

			});

			

			var stringifiedCw = JSON.stringify(cw)+"\nBacklink: [[User:MusikAnimal/customWatchlists]]";



			var api = new mw.Api();

			api.watch(pageName).done(function(watchResult) {

				api.postWithToken( "edit", {

					action: "edit",

					title: "User:"+mw.config.get('wgUserName')+"/watchlists",

					summary: "updating [[User:MusikAnimal/customWatchlists|custom watchlists]]",

					text: stringifiedCw

				}).done(function(result, jqXHR) {

					$("#cw-overlay-body").html("Success!");

					mw.notify($("<div>"+updateStr+"</div"));

					setTimeout(function() {

						$("#cw-overlay").remove();

					},3000);

				}).fail(function(code, result) {

					if ( code === "http" ) {

						mw.log( "HTTP error: " + result.textStatus ); // result.xhr contains the jqXHR object

					} else if ( code === "ok-but-empty" ) {

						mw.log( "Got an empty response from the server" );

					} else {

						mw.log( "API error: " + code );

					}

				});

			}).fail(function(code, result) {

				if ( code === "http" ) {

					mw.log( "HTTP error: " + result.textStatus ); // result.xhr contains the jqXHR object

				} else if ( code === "ok-but-empty" ) {

					mw.log( "Got an empty response from the server" );

				} else {

					mw.log( "API error: " + code );

				}

			});

		});

	};

	

	if(mw.config.get('wgRelevantPageName') === "Special:Watchlist") {

		getCustomWatchlists().then(function(data) {

			var customWatchlists = JSON.parse(data.split("\n")[0]);

			var customWatchlistNames = Object.keys(customWatchlists);

			var html = "<p><label for='custom_watchlist_selector'>Custom list:</label>&nbsp;<select id='custom_watchlist_selector'>";



			for(var i=0; i < customWatchlistNames.length; i++) {

				var listName = customWatchlistNamesi];

				html += "<option value='"+i+"'>"+listName+"</option>";

			}

			

			html += "</select></p>"+

				"<p id='cw-list-type'>Show:&nbsp;<label><input type='radio' name='cw-display-type' value='rc' checked /> Recent changes</label>&nbsp;<label><input type='radio' name='cw-display-type' value='rw' /> Raw watchlist</label></p>" +

				"<p id='cw-rw-options' style='display:none'>Sorting:&nbsp;<label><input type='radio' name='cw-rw-sorting' value='timestamp' checked /> Last edited</label>&nbsp;<label><input type='radio' name='cw-rw-sorting' value='title' />Alphabetical</label></p>" +

				"<p id='cw-rc-options'><label for='custom_watchlist_limit'>Search limit (from base watchlist):</label>&nbsp;<select id='custom_watchlist_limit'>";

			var limitArr = 50,100,250,500,1000,2500,5000];

			for(var j=0; j<limitArr.length; j++) {	

				html += "<option val='"+limitArrj+"'>"+limitArrj+"</option>";

			}



			html += "</select><br/>" +

				"<input type='checkbox' id='custom_watchlist_all_rev' value='wlallrev' /><label for='custom_watchlist_all_rev'>Include multiple revisions to same page</label></p>" +

				"<p><button id='custom_watchlist_submit'>Go</button></fieldset></p></form>";



			showCustomWatchlistsForm(html);

			

			$("#custom_watchlist_submit").click(function(e) {

				e.preventDefault();

				showCustomWatchlist($("#cw-list-type input[type=radio]:checked").val(),customWatchlists,customWatchlistNamesparseInt($("#custom_watchlist_selector").val())],$("#custom_watchlist_limit").val(),$("#custom_watchlist_all_rev").is(":checked"));

			});

			$("#custom_watchlist_form input[type=radio]").click(function() {

				if($(this).val() === "rc") {

					$("#cw-rc-options").show();

					$("#cw-rw-options").hide();

				} else {

					$("#cw-rc-options").hide();

					$("#cw-rw-options").show();

				}

			});

		}, function() {

			showCustomWatchlistsForm("<p>No <a href='/info/en/?search=User:MusikAnimal/customWatchlists'>custom watchlists</a> yet! Go to a <a href='/wiki/Special:Random'>page</a> and create a custom watchlist by selecting the \"Custom Watchlists&hellip;\" item from the More menu.</p>");

		});

		$(".mw-changeslist .special li").each(function() {

			$anchor = $(this).find("a").eq(1);

			if($anchor.text() === "hist" && !$anchor.siblings(".wikibase-edit").length) {

				$anchor.after("&nbsp;| <a class='cw-add' href='javascript:'>cw</a>");

			}

		});

		addCwLinkListener();

	} else if(mw.config.get('wgNamespaceNumber') >= 0) {

		mw.util.addPortletLink(

			'p-cactions',

			'javascript:',

			'Custom watchlist…',

			'ca-add-to-cw'

		);

		$("#ca-add-to-cw").click(function() {

			if($("#cw-overlay")[0]) return false;

			getCustomWatchlists().then(setupCactionInterface,setupCactionInterface.bind(this, null, null));

		});

	}

});

Videos

Youtube | Vimeo | Bing

Websites

Google | Yahoo | Bing

Encyclopedia

Google | Yahoo | Bing

Facebook