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.

// newNode from [[wikt:Mediawiki:Common.js]], JsMwApi from [[wikt:WT:EDIT]].

// Previous version (works without enhanced RC) at [[User:Yair rand/interwikiwatchlist.js]].

// To enable, turn on "Enhanced recent changes (requires JavaScript)" 

// in [[Special:Preferences#mw-prefsection-rc]], and add 

// importScript ("User:Yair rand/interwikiwatchlist2.js"); 

// to [[Special:MyPage/common.js]].



// NOTE: this script is buggy and does not work on certain browsers.

function newNode(tagname){

 

  var node = document.createElement(tagname);

 

  for( var i=1;i<arguments.length;i++ ){

 

    if(typeof argumentsi == 'string'){ //Text

      node.appendChild( document.createTextNode(argumentsi]) );

 

    }else if(typeof argumentsi == 'object'){ 

 

      if(argumentsi].nodeName){ //If it is a DOM Node

        node.appendChild(argumentsi]);

 

      }else{ //Attributes (hopefully)

        for(var j in argumentsi]){

          if(j == 'class'){ //Classname different because...

            node.className = argumentsi][j];

 

          }else if(j == 'style'){ //Style is special

            node.style.cssText = argumentsi][j];

 

          }else if(typeof argumentsi][j == 'function'){ //Basic event handlers

            try{ node.addEventListener(j,argumentsi][j],false); //W3C

            }catch(e){try{ node.attachEvent('on'+j,argumentsi][j],"Language"); //MSIE

            }catch(e){ node'on'+j=argumentsi][j]; }}; //Legacy

 

          }else{

            node.setAttribute(j,argumentsi][j]); //Normal attributes

 

          }

        }

      }

    }

  }

 

  return node;

}



//JsMwApi documentation is at http://en.wiktionary.org/wiki/User_talk:Conrad.Irwin/Api.js

function JsMwApi (api_url, request_type) {

 

	if (!api_url) 

	{

		if (typeof(true) === 'undefined' || true == false)

			throw "Local API is not usable.";

 

		api_url = mw.config.get('wgScriptPath') + "/api.php";

	}

 

	if (!request_type)

	{

		if (api_url.indexOf('http://') == 0 || api_url.indexOf('https://') == 0)

			request_type = "remote";

		else

			request_type = "local";

	}

	function call_api (query, callback)

	{

		if(!query || !callback)

			throw "Insufficient parameters for API call";

 

		query = serialise_query(query);

 

		if(request_type == "remote")

			request_remote(api_url, query, callback, call_api.on_error || default_on_error);

		else

			request_local(api_url, query, callback, call_api.on_error || default_on_error);

 

	}

 

	var default_on_error = JsMwApi.prototype.on_error || function (xhr, callback, res)

	{

		if (typeof(console) != 'undefined')

			console.log([xhr, res]);

 

		callback(null);

	}

 

	function get_xhr () 

	{

		try{

			return new XMLHttpRequest();

		}catch(e){ try {

			return new ActiveXObject("Msxml2.XMLHTTP");

		}catch(e){ try {

			return new ActiveXObject("Microsoft.XMLHTTP");

		}catch(e){

			throw "Could not create an XmlHttpRequest";

		}}}

	}

 

	function request_local (url, query, callback, on_error)

	{

		var xhr = get_xhr();

 

		xhr.open('POST', url + '?format=json', true);

		xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");                  

		xhr.send(query);

		xhr.onreadystatechange = function ()

		{

			if (xhr.readyState == 4)

			{

				var res;

				if (xhr.status != 200)

					res = {error: {

						code: '_badresponse', 

						info: xhr.status + " " + xhr.statusText

					}};

				else

				{

					try

					{

						res = JSON.parse("("+xhr.responseText+")");

					}

					catch(e)

					{

						res = {error: {

							code: '_badresult',

							info: "The server returned an incorrectly formatted response"

						}};

					}

				}

				if (!res || res.error || res.warnings)

					on_error(xhr, callback, res);

				else

					callback(res);

			}

		}

	}

 

	function request_remote (url, query, callback, on_error)

	{

		if(! window.__JsMwApi__counter)

			window.__JsMwApi__counter = 0;

 

		var cbname = '__JsMwApi__callback' + window.__JsMwApi__counter++; 

 

		windowcbname = function (res)

		{

			if (res.error || res.warnings)

				on_error(null, callback, res);

			else

				callback(res);

		}

 

		var script = document.createElement('script');

		script.setAttribute('type', 'text/javascript');

		script.setAttribute('src', url + '?format=json&callback=window.' + cbname + '&' + query);

		document.getElementsByTagName('head')[0].appendChild(script);

	}

 

	function serialise_query (obj)

	{

		var amp = "";

		var out = "";

		if (String(obj) === obj)

		{

			out = obj;

		}

		else if (obj instanceof Array)

		{

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

			{

				out += amp + serialise_query(obji]);

				amp = (out == '' || out.charAt(out.length-1) == '&') ? '' : '&';

			}

		}

		else if (obj instanceof Object)

		{

			for (var k in obj)

			{

				if (objk === true)

					out += amp + encodeURIComponent(k) + '=1';

				else if (objk === false)

					continue;

				else if (objk instanceof Array)

					out += amp + encodeURIComponent(k) + '=' + encodeURIComponent(objk].join('|'));

				else if (objk instanceof Object)

					throw "API parameters may not be objects";

				else

					out += amp + encodeURIComponent(k) + '=' + encodeURIComponent(objk]);

				amp = '&';

			}

		}

		else if (typeof(obj) !== 'undefined' && obj !== null)

		{

			throw "An API query can only be a string or an object";

		}

		return out;

	}

 

	// Make JSON.parse work

	var JSON = (typeof JSON == 'undefined' ? new Object() : JSON);

 

	if (typeof JSON.parse != 'function')

		JSON.parse = function (json) { return eval('(' + json + ')'); };

 

	// Allow .prototype. extensions

	if (JsMwApi.prototype)

	{

		for (var i in JsMwApi.prototype)

		{

			call_apii = JsMwApi.prototypei];

		}

	}

	return call_api;

}



mw.config.get('wgPageName') == "Special:Watchlist" && 'localStorage' in window && jQuery(document).ready(function(){

  function doubledigits(n){return (+n)<10?'0'+n:''+n}

  var v = document.getElementById("mw-watchlist-options") || $(".mw-specialpage-summary")[ 0 ];

  var qw, er='Wikipedia','Wiktionary','Wikibooks','Wikisource','Wikiquote','Wikiversity','Wikinews','Meta-Wiki','Commons','Wikispecies','Mediawiki'], cv, bn, sd;

  var wspan;

  v.appendChild(newNode('hr'));

  v.appendChild(newNode('span', 'Interwiki watchlists: ', wspan = newNode('span'), newNode('a','(+new watchlist)',{href:"#",click:function(){

    v.lastChild.lastChild.style.display='none';

    v.appendChild(newNode('form',

      'Language: ',cv=newNode('input',{size:3}),

      ' Project: ', qw=newNode('select'), newNode('br'), 

      'Watchlist token ',newNode('small','(can be found be found at ',sd=newNode('a','Special:Preferences',{'href':'/wiki/Special:Preferences#mw-prefsection-watchlist'}),' in the Watchlist section)'),': ',bn=newNode('input'),

      newNode('input',{'type':'submit','value':'Import watchlist'}),newNode('span',{style:'color:red;'}))).onsubmit = function(){

        if(!/^[a-z]{2,3}(-?[a-z]{2,3})?$/.test(cv.value) && qw.value <=6 || !bn.value){

          bn.parentNode.lastChild.innerHTML = bn.value?"Choose a valid language code.":"Enter watchlist token.";

          return false;

          }

        var importedurl=(qw.value > 6?(qw.value==7?"meta.wikimedia":qw.value==8?'commons.wikimedia':qw.value==9?'species.wikimedia':'mediawiki'):cv.value+'.'+erqw.value].toLowerCase());

        localStorage'importedwatchlists'+mw.config.get('wgUserName')] = (localStorage'importedwatchlists'+mw.config.get('wgUserName')]?localStorage'importedwatchlists'+mw.config.get('wgUserName')]+"|":"")+importedurl;

        localStorage'importedwatchlist'+mw.config.get('wgUserName')+importedurl+'token'=bn.value;

        location.reload();

        return false}

    for(var i = 0; i < er.length; i++){qw.appendChild(newNode('option',{'value':i},eri]))};

    function df(){

      if(/^[a-z]{2,3}(-?[a-z]{2,3})?$/.test(cv.value) || qw.value >6){

        sd.href = "//"+(qw.value > 6?(qw.value==7?"meta.wikimedia":qw.value==8?'commons.wikimedia':qw.value==9?'species.wikimedia':'mediawiki'):cv.value+'.'+erqw.value].toLowerCase())+".org/wiki/Special:Preferences#mw-prefsection-watchlist";

        }

      }

    cv.onchange=qw.onchange=df;

    }})));

  for(var k = localStorage'importedwatchlists'+mw.config.get('wgUserName')]?localStorage'importedwatchlists'+mw.config.get('wgUserName')].split("|"):[], ii=0; ii < k.length; ii++){

    function st(rt){

      var tkn = localStorage'importedwatchlist'+mw.config.get('wgUserName')+rt+'token'], project = location.protocol+"//"+rt+".org/";

      wspan.appendChild(newNode('span',project, ' ', newNode('a','(remove)',{click:function(){

        localStorage.removeItem('importedwatchlist'+mw.config.get('wgUserName')+rt+'token');

        localStorage.removeItem('importedwatchlist'+mw.config.get('wgUserName')+rt+'hidden');

        localStorage'importedwatchlists'+mw.config.get('wgUserName')] = localStorage'importedwatchlists'+mw.config.get('wgUserName')].replace(rt,'').replace(/(^\||\|\||\|$)/,'');

        location.reload()

        }}),', '))

      var d = new Date(+new Date()+new Date().getTimezoneOffset()*60000-mw.user.options.get('watchlistdays')*24*60*60*1000); d = d.getFullYear()+'-'+doubledigits(d.getMonth()+1)+'-'+doubledigits(d.getDate())+"T"+doubledigits(d.getHours())+":"+doubledigits(d.getMinutes())+":"+doubledigits(d.getSeconds())+"Z";

      JsMwApi(project + "w/api.php")({action:'query',list:'watchlist',wlowner:mw.config.get('wgUserName'),wltoken:tkn,

       wlexcludeuser:mw.user.options.get('watchlisthideown')?mw.config.get('wgUserName'):'Example',wlprop:'title|flags|user|parsedcomment|timestamp|ids|sizes',wllimit:500,wlend:d},function(r){

/*

        var b=newNode('div',{'style':'display:'+

          (localStorage['importedwatchlist'+mw.config.get('wgUserName')+rt+'hidden']?'none;':'block;')

          });

*/

        var g = r && r.query && r.query.watchlist;

        if(!g) g = [];

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

          var zx = newNode('span',{class:'comment'}); zx.innerHTML = gi].parsedcomment && ' ('+gi].parsedcomment.replace(/\ href\=\"\//g,' href="'+project)+')';

          var date = (new Date(+new Date(gi].timestamp)+new Date().getTimezoneOffset()*60000)), day = date.getDate(), month = date.getMonth(), time = gi].timestamp.match(/\d\d\:\d\d/);time=time&&time0];

          var sizediff = gi].newlen-gi].oldlen;

          var table = newNode('table',{'class':'mw-enhanced-rc'},newNode('tbody',newNode('tr',newNode('td',{'class':"mw-enhanced-rc"},newNode('span',{"class":"mw-enhancedchanges-arrow-space"}),

            ("new" in gi?newNode("abbr",{class:"newpage"},"N"):" "),

            ("bot" in gi?newNode("abbr",{class:"botedit"},"b"):"minor" in gi?newNode("abbr",{class:"minoredit"},"m"):" "),

            "       "+time+" "),newNode('td',

            newNode('a',gi].title,{class:'extiw',href:project+"wiki/"+gi].title}),

            ' (',

            newNode('a','diff',{href:project+"w/index.php?title="+gi].title+"&curid="+gi].pageid+"&diff="+gi].revid}),

            ' | ',

            newNode('a','hist',{href:project+"w/index.php?title="+gi].title+"&curid="+gi].pageid+"&action=history"}),

            ') . . ',

            newNode(Math.abs(sizediff)>500?'strong':'span',{class:'mw-plusminus-'+(sizediff>0?'pos':'neg')},'('+(sizediff>0?"+":"")+sizediff+")"),

            ' . . ',

            newNode('a',{class:'extiw',href:project+"wiki/User:"+gi].user},gi].user),

            ' (',

            newNode('a',{class:'extiw',href:project+"wiki/User talk:"+gi].user},'Talk'),

            ' | ',

            newNode('a',{class:'extiw',href:project+"wiki/Special:Contributions/"+gi].user},'contribs'),

            ') ',

            zx

            ))));

          for(var ii = $(".mw-changeslist")[ 0 ].firstChild; ii; ii = ii.nextSibling){

            if(ii.nodeName == "H4"){

              var hdate = new Date(ii.innerText || ii.textContent);

              if(hdate.getMonth() == month && hdate.getDate() == day){

                for(;ii && ii.nodeName != "DIV"; ii = ii.nextSibling);

                for(var trs = $(ii).find('tr:first-child'), iii = 0; true; iii++){

                  if(iii >= trs.length){

                    trsiii-1].parentNode.parentNode.parentNode.appendChild(table);

                    break;

                    }

                  var tds = trsiii].getElementsByTagName('td'),

                	td = tds2&&tds2].className=='mw-enhanced-rc'?tds2:tds1];

                  //if( +(((td.innerText || td.textContent).match(/\d/g)||[]).join("")) < time){

                  try{

                  	var match = (td.innerText || td.textContent).match(/\d\d\:\d\d/g);

                  	if( match && match0 < time){

	                    trsiii].parentNode.parentNode.parentNode.insertBefore(table, trsiii].parentNode.parentNode);

	                    break;

                    }}catch(a){

                    	throw new Error( 22, a, trsiii].parentNode.parentNode );

                	}

                  }

                break;

                }

              }

            if(ii.className == 'printfooter'){

              ii.parentNode.insertBefore(newNode("h4", date.getDate()+' '+'January','February','March','April','May','June','July','August','September','October','November','December'][date.getMonth()]+' '+date.getFullYear()), ii);

              ii.parentNode.insertBefore(newNode('div', table), ii);

              }

            }

          }catch(err){window.console&&console.log(err.stack)}}

        });

      }

    st(kii]);

    }

  })