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.
/* This script adds an "unwatch" link to each entry in your watchlist, using the new
* ajax watchlist thing.
*/

var wlUnwatch = {
	supported: true,
	onLoad: function () {
		var i, entries, links, page, a, span, div;
		
		entries = document.getElementsByClassName( 'mw-changeslist-line-inner' );
		for ( i = entries.length-1; i >= 0; i-- ) {
			page = entries[i].getAttribute( 'data-target-page' );
			if ( page === null ) {
				continue;
			}
			links = entries[i].getElementsByClassName( 'mw-changeslist-links' )[0];
			if ( !links ) {
				continue;
			}
			if ( links.nodeName === 'A' ) {
				// Log entries have mw-changeslist-links on the one link. Put it inside a div instead.
				div = document.createElement( 'DIV' );
				div.className = 'mw-changeslist-links';
				links.parentNode.insertBefore( div, links );
				span = document.createElement( 'SPAN' );
				div.appendChild( span );
				span.appendChild( links );
				links.classList.remove( 'mw-changeslist-links' );
				links = div;
			}

			a = document.createElement( 'A' );
			a.href = mw.util.wikiScript()   '?action=unwatch&title='   encodeURIComponent( page );
			a.title = 'Unwatch '   page;
			a.unwatchInProgress = false;
			a.onclick = wlUnwatch.onClick;
			a.appendChild( document.createTextNode( 'unw' ) );

			span = document.createElement( 'SPAN' );
			span.appendChild( a );
			links.appendChild( span );
		}
	},

	onClick: function () {
		if ( !wlUnwatch.supported ) {
			wlUnwatch.supported = false;
			return true;
		}
		var link = this;
		if ( link.unwatchInProgress ) {
			return false;
		}
		link.unwatchInProgress = true;
		link.style.color = 'red';
		var timeout = setTimeout( function() {
			timeout = null;
			link.unwatchInProgress = false;
			link.style.color = '';
		}, 10000 );
		var api = new mw.Api();
		api.postWithToken( 'watch', {
			action: 'watch',
			unwatch: 1,
			titles: decodeURIComponent( link.href.match( /&title=(. )/ )[ 1 ].replace( /_/g,' ' ) )
		} ).done( function( data ) {
			if ( timeout ) {
				clearTimeout( timeout );
			}
			timeout = null;
			link.unwatchInProgress = false;
			link.style.color = '';
			if ( data.watch[ 0 ].unwatched !== undefined ) {
				var li;
				for ( li = link; li && li.nodeName !== 'LI'; li = li.parentNode ); // Empty loop
				if ( li ) {
					var classes = li.className.split(' ');
					var i, len, cl, matches, ns, assocCl;
					for ( i = 0, len = classes.length; i < len; i   ) {
						cl = classes[i];
						matches = cl.match( /^watchlist-(\d )-(.*)/ );
						if ( matches ) {
							break;
						}
					}
					if ( matches ) {
						ns = Number( matches[ 1 ] );
						ns ^= 1; // use bitwise XOR to get the associated namespace number
						assocCl = 'watchlist-'   ns   '-'   matches[ 2 ];
						$( '.'   cl ).remove();
						$( '.'   assocCl ).remove();
					} else {
						li.parentNode.removeChild( li );
					}
				}
			}
		} ).fail( function ( error ) {
			if ( timeout ) {
				clearTimeout( timeout );
			}
			timeout = null;
			link.unwatchInProgress = false;
			link.style.color = '';
		} );
		return false;
	}
};

if ( mw.config.get( 'wgCanonicalSpecialPageName' ) === 'Watchlist' && mw.config.get( 'wgAction' ) === 'view' ) {
	mw.loader.using( [ 'mediawiki.util','mediawiki.api' ], function() {
		$( document ).ready( wlUnwatch.onLoad );
	} );
}