הערה: לאחר הפרסום, ייתכן שיהיה צורך לנקות את זיכרון המטמון (cache) של הדפדפן כדי להבחין בשינויים.

  • פיירפוקס / ספארי: להחזיק את המקש Shift בעת לחיצה על טעינה מחדש (Reload) או ללחוץ על צירוף המקשים Ctrl-F5 או Ctrl-R (במחשב מק: ⌘-R).
  • גוגל כרום: ללחוץ על צירוף המקשים Ctrl-Shift-R (במחשב מק: ⌘-Shift-R).
  • אדג': להחזיק את המקש Ctrl בעת לחיצה על רענן (Refresh) או ללחוץ על צירוף המקשים Ctrl-F5.
mw.loader.using( ['mediawiki.api', 'mediawiki.user', 'mediawiki.util'] , function() {  	const storageKeyName = 'watchlistwatcher-newestclicked'; 	var api = new mw.Api( { cache: false } ), 		titles, 		items, 		newest = 0, 		watchButton,  		watchwButtonAnchor, 		timer, 		storage = window.localStorage; 	 	function i18n( key ) { 		switch ( mw.user.options.get( 'language' ) ) { 			case 'he': 				switch ( key ) { 					case 'title' : return 'רשימת המעקב שלך'; 				} 				break; 			case 'en': 				switch ( key ) { 					case 'title': return 'Your watchlist'; 				} 				break; 		} 		return key; 	} 	 	function updateStorageAndRefresh() { 		storage.setItem( storageKeyName, newest ); // remember the click: only items newer than latest click will trigger coloring the bubble. 		triggerQuery( 0 );	// initiate click, so when it returns we can color the icon accordingly 	} 	 	function showWatchlistDialog( e ) { 		e.stopImmediatePropagation(); 		e.preventDefault();  		updateStorageAndRefresh();		  		var $this = $( this ), 			width60 = $( 'body' ).width() * 0.6, 			height60 = $( 'body' ).height() * 0.6; 		 		$.ajax( { url: mw.util.getUrl( 'Special:Watchlist' ) } ) 			.done( function( data ) { 				mw.loader.using( 'jquery.ui' ).done ( function() { 					var content = $( data ).find( '.mw-changeslist' ), 						cl = ''; 					 					content 						.parents() 						.each( function() {  							if ( $( this ).length )  								cl += $this.attr( 'class' ) + ' ';  						} ); 					 					$( '<div>' ) 						.addClass( 'mw-changeslist ' + cl ) 						.dialog( { 							position: { 								my: "center top", 								at: "center bottom", 								of: $this 							}, 							width: width60, 							height: height60, 							close: function() { $( this ).remove(); } 						} ) 						.css( { overflow: 'auto' } ) 						.append( content ); 				} ); 			} ); 	} 	 	function announce() { 		const new_id = 'pt-notifications-watchlist'; 		var count = titles.length; 		if ( ! watchButton ) { 			var url, 				notif = $( '#pt-notifications-notice, #pt-notifications-alert' ).eq(-1); 				 			if ( ! notif.length ) 				return;  			watchButton = notif.clone() 				.attr( { id: new_id } ) 				.insertAfter( notif ); 			watchwButtonAnchor = watchButton.find( 'a' ) 				.removeClass('oo-ui-icon-tray') 				.click( showWatchlistDialog ) 				.attr( { href: mw.util.getUrl( 'Special:Watchlist' ), title: i18n( 'title' ) } ); 		} 		var lastClicked = parseInt( storage.getItem( storageKeyName ) ) || 0, 			toColor = newest > lastClicked; 			 		watchwButtonAnchor 			.toggleClass( 'mw-echo-notifications-badge-unseen', toColor ) 			.toggleClass( 'mw-echo-notifications-badge-all-read', count === 0 ) 			.attr( { 'data-counter-text': count || '', 'data-counter-num': count } ); 	}  	function calcParams() { 		var  			opts = { 				/* watchlisthideown: we do not care about this one, since "unread" will never have own edits anyway */ 				watchlisthideanons: '!anon', 				watchlisthidebots:	'!bot', 				watchlisthideliu: 	'anon',  /* this strangely named option means "hide regitered users", IOW, show anons */ 				watchlisthideminor:	'!minor', 				watchlisthidepatrolled: '!patrolled' 			}, 			show = Object.keys( opts ) 				.filter( function( k ) {return mw.user.options.get( k ); } ) 				.map( function( k ) { return opts[k]; } ) 				.concat( 'unread' ) 				.join( '|' ); 		return {  			list: 'watchlist',  			wlprop: 'ids|user|title|timestamp|notificationtimestamp',  			wlshow: show,  			wltype: mw.user.options.get( 'watchlisthidecategorization' ) ? 'edit|new|log' : 'edit|new|log|categorize', 			wllimit: window.script88limit || 50  		}; 	} 	 	function triggerQuery( timeout ) { 		clearTimeout( timer ); 		if ( typeof(timeout) != 'number') 			timeout = 1000; 		timer = setTimeout( queryAndUpdate, timeout );		 	} 	 	function queryAndUpdate() { 		api.get( calcParams() ) 			.done( function(data) { 				var counts = {}; 				if ( data && data.query && data.query.watchlist ) { 					items = data.query.watchlist; 					items.forEach( function( item ) { counts[item.title] = ( counts[item.title] || 0 ) + 1; } ); 					newest = items.map( function( item ) { return new Date( item.timestamp ).getTime(); } ).sort().pop(); 					titles = Object.keys( counts );  					announce(); 					triggerQuery( 60000 ); 				} 			} ); // done 	} // queryandupdate  	//load css page. would do it locally, but javascript does not support multiline strings, and putting all the CSS locally is just too much.  	mw.loader.load( '//he.wikipedia.org/w/index.php?title=מדיה_ויקי:סקריפטים/88.css&action=raw&ctype=text/css', 'text/css' ); 	queryAndUpdate(); 	$('#mw-watchlist-resetbutton').submit( triggerQuery ); 	$( 'body ').on( 'script-88-refresh', triggerQuery ); 	mw.hook('wikipage.content').add( triggerQuery ); 	$('.oo-ui-buttonElement-button').click( triggerQuery ); 	$( 'body ').on( 'script-88-pretend-clicked', updateStorageAndRefresh ); } );