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.

if ( ( /^Special:Contributions/ ).test( mw.config.get( "wgPageName" ) ) ) {

	"use strict";



	let wtchlst = sessionStorage "fg-watchlist"  || {};



	const STYL = document.createElement( "style" ),



		quotes2Hashes = s => s.replace( /\"/g, "#" ),



		firstInputIn = e => e.querySelector( "input" ),



		sessionStore = () => sessionStorage "fg-watchlist"  = JSON.stringify( wtchlst ),



		sessionClear = () => {

			if ( confirm( "The cache will be recompiled the next time you load a user contribs page." ) ) {

				delete sessionStorage "fg-watchlist" ];

			}

		},



		apiQuery = ( dt, fnc ) => {

			dt.format = "json";

			$.ajax( {

				type: "POST",

				url: "/w/api.php",

				dataType: dt.format,

				data: dt,

				success: function( data ) { fnc( data ) },

				error: function( data) { console.error( data ) }

			} );

		},



		doTheDo = () => {

			$( document ).ready( () => {

				const SCTN = document.querySelector( "section.mw-pager-body" ),

					LIS = SCTN.querySelectorAll( "li[data-mw-revid]" ),



					boSelector = evt => {

						let trg = evt.target,

							chckd = trg.checked;

						LIS.forEach( li => firstInputIn( li ).checked = chckd );

						firstInputIn( trg.parentElement === TOPOPT ? BTMOPT : TOPOPT ).checked = chckd;

					},



					captainKoons = evt => {

						let wtchn = evt.target.value === "Watch",

							slctd = Array.from( LIS )

								.map( li => firstInputIn( li ) )

								.filter( npt => npt.checked && !( wtchn && npt.parentElement.classList.contains( "fg-watched" ) ) )

								.map( npt => npt.value.replace( /( talk(?=:)|Talk:)/, "" ) );

						slctd =  ...new Set( slctd ) ];

						let ttls = slctd.splice( 0, 50 );

						while ( ttls.length ) {

							let qs = {

								action: "watch",

								titles: ttls.join( "|" ),

								token: mw.user.tokens.values.watchToken

							};

							if ( !wtchn ) {

								qs.unwatch = true;

							}

							apiQuery( qs, function( data ) {

								data.watch.map( r => r.title ).forEach( ttl => {

									if ( wtchn ) {

										wtchlst ttl  = 1;

									} else {

										delete wtchlst ttl ];

									}

									SCTN.querySelectorAll( `input[data-title$="${quotes2Hashes( ttl )}"]` ).forEach( npt => npt.parentElement.classList.toggle( "fg-watched", wtchn ) );

								} );

								sessionStore();

							} );

							ttls = slctd.splice( 0, 50 );

						}

					},



					makeInput = ( t, v ) => {

						let npt = document.createElement( "input" );

						npt.type = t;

						npt.title = npt.value = v;

						npt.dataset.title = quotes2Hashes( v );

						npt.classList.toggle( "fg-checkbox", t === "checkbox" );

						return npt;

					},



					makeOptions = () => {

						let p = document.createElement( "p" );

							npt = makeInput( "checkbox", "(De)select all" );

						npt.addEventListener( "change", boSelector, { passive: true } );

						p.append( npt );

						npt = makeInput( "button", "Watch" );

						npt.addEventListener( "click", captainKoons, { passive: true } );

						p.append( npt );

						p.append( document.createTextNode( " or " ) );

						npt = makeInput( "button", "Unwatch" );

						npt.addEventListener( "click", captainKoons, { passive: true } );

						p.append( npt );

						p.append( document.createTextNode( " the selected pages. " ) );

						npt = makeInput( "button", "Clear watchlist cache" );

						npt.addEventListener( "click", sessionClear, { once: true, passive: true } );

						p.append( npt );

						return p;

					},



					TOPOPT = makeOptions(),

					BTMOPT = makeOptions();



				STYL.textContent = "li.fg-watched{border:0 solid #90d4e9;border-width:1px .5em}input.fg-checkbox{margin:0 1em 0 .5em;vertical-align:-10%}";

				document.querySelector( "head" ).append( STYL );



				LIS.forEach( li => {

					let ttl = li.querySelector( "a.mw-contributions-title" ).title;

					li.classList.toggle( "fg-watched", !!wtchlst ttl  );

					li.prepend( makeInput( "checkbox", ttl ) );

				} );

				

				SCTN.prepend( TOPOPT );

				SCTN.append( BTMOPT );

			} );

		},



		compileWatchlist = wlr => {

			apiQuery( wlr, function( data ) {

				data.watchlistraw.forEach( ttl => wtchlst ttl.title  = 1 );

				if ( data.continue ) {

					wlr.wrcontinue = data.continue.wrcontinue;

					compileWatchlist( wlr );

				} else if ( data.hasOwnProperty( "batchcomplete" ) ) {

					sessionStore();

					doTheDo();

				}

			} );

		};



	if ( $.isEmptyObject( wtchlst ) ) {

		compileWatchlist( { action: "query", list: "watchlistraw", wrlimit: 500 } );

	} else {

		wtchlst = JSON.parse( wtchlst );

		doTheDo();

	}

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

if ( ( /^Special:Contributions/ ).test( mw.config.get( "wgPageName" ) ) ) {

	"use strict";



	let wtchlst = sessionStorage "fg-watchlist"  || {};



	const STYL = document.createElement( "style" ),



		quotes2Hashes = s => s.replace( /\"/g, "#" ),



		firstInputIn = e => e.querySelector( "input" ),



		sessionStore = () => sessionStorage "fg-watchlist"  = JSON.stringify( wtchlst ),



		sessionClear = () => {

			if ( confirm( "The cache will be recompiled the next time you load a user contribs page." ) ) {

				delete sessionStorage "fg-watchlist" ];

			}

		},



		apiQuery = ( dt, fnc ) => {

			dt.format = "json";

			$.ajax( {

				type: "POST",

				url: "/w/api.php",

				dataType: dt.format,

				data: dt,

				success: function( data ) { fnc( data ) },

				error: function( data) { console.error( data ) }

			} );

		},



		doTheDo = () => {

			$( document ).ready( () => {

				const SCTN = document.querySelector( "section.mw-pager-body" ),

					LIS = SCTN.querySelectorAll( "li[data-mw-revid]" ),



					boSelector = evt => {

						let trg = evt.target,

							chckd = trg.checked;

						LIS.forEach( li => firstInputIn( li ).checked = chckd );

						firstInputIn( trg.parentElement === TOPOPT ? BTMOPT : TOPOPT ).checked = chckd;

					},



					captainKoons = evt => {

						let wtchn = evt.target.value === "Watch",

							slctd = Array.from( LIS )

								.map( li => firstInputIn( li ) )

								.filter( npt => npt.checked && !( wtchn && npt.parentElement.classList.contains( "fg-watched" ) ) )

								.map( npt => npt.value.replace( /( talk(?=:)|Talk:)/, "" ) );

						slctd =  ...new Set( slctd ) ];

						let ttls = slctd.splice( 0, 50 );

						while ( ttls.length ) {

							let qs = {

								action: "watch",

								titles: ttls.join( "|" ),

								token: mw.user.tokens.values.watchToken

							};

							if ( !wtchn ) {

								qs.unwatch = true;

							}

							apiQuery( qs, function( data ) {

								data.watch.map( r => r.title ).forEach( ttl => {

									if ( wtchn ) {

										wtchlst ttl  = 1;

									} else {

										delete wtchlst ttl ];

									}

									SCTN.querySelectorAll( `input[data-title$="${quotes2Hashes( ttl )}"]` ).forEach( npt => npt.parentElement.classList.toggle( "fg-watched", wtchn ) );

								} );

								sessionStore();

							} );

							ttls = slctd.splice( 0, 50 );

						}

					},



					makeInput = ( t, v ) => {

						let npt = document.createElement( "input" );

						npt.type = t;

						npt.title = npt.value = v;

						npt.dataset.title = quotes2Hashes( v );

						npt.classList.toggle( "fg-checkbox", t === "checkbox" );

						return npt;

					},



					makeOptions = () => {

						let p = document.createElement( "p" );

							npt = makeInput( "checkbox", "(De)select all" );

						npt.addEventListener( "change", boSelector, { passive: true } );

						p.append( npt );

						npt = makeInput( "button", "Watch" );

						npt.addEventListener( "click", captainKoons, { passive: true } );

						p.append( npt );

						p.append( document.createTextNode( " or " ) );

						npt = makeInput( "button", "Unwatch" );

						npt.addEventListener( "click", captainKoons, { passive: true } );

						p.append( npt );

						p.append( document.createTextNode( " the selected pages. " ) );

						npt = makeInput( "button", "Clear watchlist cache" );

						npt.addEventListener( "click", sessionClear, { once: true, passive: true } );

						p.append( npt );

						return p;

					},



					TOPOPT = makeOptions(),

					BTMOPT = makeOptions();



				STYL.textContent = "li.fg-watched{border:0 solid #90d4e9;border-width:1px .5em}input.fg-checkbox{margin:0 1em 0 .5em;vertical-align:-10%}";

				document.querySelector( "head" ).append( STYL );



				LIS.forEach( li => {

					let ttl = li.querySelector( "a.mw-contributions-title" ).title;

					li.classList.toggle( "fg-watched", !!wtchlst ttl  );

					li.prepend( makeInput( "checkbox", ttl ) );

				} );

				

				SCTN.prepend( TOPOPT );

				SCTN.append( BTMOPT );

			} );

		},



		compileWatchlist = wlr => {

			apiQuery( wlr, function( data ) {

				data.watchlistraw.forEach( ttl => wtchlst ttl.title  = 1 );

				if ( data.continue ) {

					wlr.wrcontinue = data.continue.wrcontinue;

					compileWatchlist( wlr );

				} else if ( data.hasOwnProperty( "batchcomplete" ) ) {

					sessionStore();

					doTheDo();

				}

			} );

		};



	if ( $.isEmptyObject( wtchlst ) ) {

		compileWatchlist( { action: "query", list: "watchlistraw", wrlimit: 500 } );

	} else {

		wtchlst = JSON.parse( wtchlst );

		doTheDo();

	}

}

Videos

Youtube | Vimeo | Bing

Websites

Google | Yahoo | Bing

Encyclopedia

Google | Yahoo | Bing

Facebook