User:Dtrebbien/Sandbox/newPagesTool.js

function addlimenu(tabs, name, id, href, position) { var na, mn; var li; if (!id) id = name; if (!href) href = '#'; na = document.createElement("a"); na.appendChild(document.createTextNode(name)); na.href = href; mn = document.createElement("ul"); li = document.createElement("li"); li.appendChild(na); li.appendChild(mn); if (id) li.id = id; li.className = 'tabmenu'; if (position) { tabs.insertBefore(li, position); } else { tabs.appendChild(li); }

return mn; // useful because it gives us the  to add s to }

var wgPreferences = wgPreferences || new Object; var wgMessages = wgMessages || new Object;

/** * Date Format 1.2.2 * (c) 2007-2008 Steven Levithan  * MIT license * Includes enhancements by Scott Trenda  and Kris Kowal  * Includes modifications by D. Trebbien to remove localized day names (`ddd` and `dddd`) and to use `wgMessages.monthNames` instead of `dateFormat.i18n.monthNames`. Also `mmm` was removed and `mmmm` altered so that the 'january' message would be at `wgMessages.monthNames[0]`. * * Accepts a date, a mask, or a date and a mask. * Returns a formatted version of the given date. * The date defaults to the current date/time. * The mask defaults to dateFormat.masks.default. * * @see http://blog.stevenlevithan.com/archives/date-time-format */ var dateFormat = function { var token = /d{1,4}|m{1,4}|yy(?:yy)?|([HhMsTt])\1?|[LloSZ]|"[^"]*"|'[^']*'/g,     timezone = /\b(?:[PMCEA][SDP]T|(?:Pacific|Mountain|Central|Eastern|Atlantic) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC)(?:[-+]\d{4})?)\b/g,      timezoneClip = /[^-+\dA-Z]/g,      pad = function(val, len) {         val = String(val);         len = len || 2;         while(val.length < len) val = "0" + val;         return val;      };

// regexes and supporting functions are cached through closure return function(date, mask, utc) { var dF = dateFormat;

// you can't provide utc if you skip other args (use the "UTC:" mask prefix) if(arguments.length == 1 && (typeof date == "string" || date instanceof String) && !/\d/.test(date)) {        mask = date; date = undefined; }

// passing date through Date applies Date.parse, if necessary date = date ? new Date(date) : new Date; if(isNaN(date)) throw new SyntaxError("invalid date");

mask = String(dF.masks[mask] || mask || dF.masks["default"]);

// allow setting the utc argument via the mask if(mask.slice(0, 4) == "UTC:") {        mask = mask.slice(4); utc = true; }

var _ = utc ? "getUTC" : "get", d = date[_ + "Date"], D = date[_ + "Day"], m = date[_ + "Month"], y = date[_ + "FullYear"], H = date[_ + "Hours"], M = date[_ + "Minutes"], s = date[_ + "Seconds"], L = date[_ + "Milliseconds"], o = utc ? 0 : date.getTimezoneOffset, flags = { d:   d,            dd:   pad(d), //ddd: dF.i18n.dayNames[D], //dddd: dF.i18n.dayNames[D + 7], m:   m + 1, mm:  pad(m + 1), //mmm: dF.i18n.monthNames[m], mmmm: wgMessages.monthNames[m], yy:  String(y).slice(2), yyyy: y,           h:    H % 12 || 12, hh:  pad(H % 12 || 12), H:   H,            HH:   pad(H), M:   M,            MM:   pad(M), s:   s,            ss:   pad(s), l:   pad(L, 3), L:   pad(L > 99 ? Math.round(L / 10) : L), t:   H < 12 ? "a" : "p", tt:  H < 12 ? "am" : "pm", T:   H < 12 ? "A" : "P", TT:  H < 12 ? "AM" : "PM", Z:   utc ? "UTC" : (String(date).match(timezone) || [""]).pop.replace(timezoneClip, ""), o:   (o > 0 ? "-" : "+") + pad(Math.floor(Math.abs(o) / 60) * 100 + Math.abs(o) % 60, 4), S:   ["th", "st", "nd", "rd"][d % 10 > 3 ? 0 : (d % 100 - d % 10 != 10) * d % 10] };

return mask.replace(token, function($0) {        return $0 in flags ? flags[$0] : $0.slice(1, $0.length - 1);      }); }; };

// some common format strings dateFormat.masks = {  "default":      "ddd mmm dd yyyy HH:MM:ss", shortDate:     "m/d/yy", mediumDate:    "mmm d, yyyy", longDate:      "mmmm d, yyyy", fullDate:      "dddd, mmmm d, yyyy", shortTime:     "h:MM TT", mediumTime:    "h:MM:ss TT", longTime:      "h:MM:ss TT Z", isoDate:       "yyyy-mm-dd", isoTime:       "HH:MM:ss", isoDateTime:   "yyyy-mm-dd'T'HH:MM:ss", isoUtcDateTime: "UTC:yyyy-mm-dd'T'HH:MM:ss'Z'" };

// for convenience... Date.prototype.format = function(mask, utc) { return dateFormat(this, mask, utc); };

/** * Takes a given timestamp, as generated by the API, and formats it per the user's Date & Time preferences. * * Note that the API timestamp "2008-08-22T21:37:39Z" means "Mon, 22 Sep 2008 21:37:39 GMT". */ var formatTimestamp = function(timestamp) { timestamp = timestamp.split(/-0?|:0?|T|Z/); var date = new Date(Date.UTC(parseInt(timestamp[0]), parseInt(timestamp[1]), parseInt(timestamp[2]), parseInt(timestamp[3]), parseInt(timestamp[4]), parseInt(timestamp[5]))); var timeCorrection = wgPreferences.timecorrection.split(/:0?/); date.setUTCHours(date.getUTCHours + parseInt(timeCorrection[0])); date.setUTCMinutes(date.getUTCMinutes + parseInt(timeCorrection[1])); var format = "HH:MM, d mmmm yyyy"; switch(wgPreferences.date) {     case "ISO 8601": format = "isoDateTime"; break; case "ymd": format = "HH:MM, yyyy mmmm d"; break; case "mdy": format = "HH:MM, mmmm d, yyyy"; break; default: case "default": case "dmy": break; }  return date.format("UTC:" + format); };

if(!Object.prototype.join) {  /**    * Joins together the keys of an object, separating them by `separator`. *   * The effect should be no different than creating an array `arr` of all of the object's keys, * and calling `join(separator)` on that. */  Object.prototype.join = function(separator) { var result = ""; for(var k in this) {        if(result != "") result += separator; result += k;     } return result; }; }

if(!window.hasAttribute) {  if(window.HTMLElement && HTMLElement.prototype.hasAttribute && window.Element && Element.prototype.hasAttribute) // Firefox {     window.hasAttribute = function(e, attr) {        return e.hasAttribute(attr); }  }   else // IE, Chrome {     window.hasAttribute = function(e, attr) {        return e.getAttribute(attr) != null; }  } }

var wRclimit = wRclimit || 50; if(500 < wRclimit) wRclimit = 500; var wRcshow = wRcshow || "!bot|!redirect"; var wUpdateDelay = wUpdateDelay || 10000; if(wUpdateDelay < 3000) wUpdateDelay = 3000; if(!window.wUpdatesEnabledByDefault) window.wUpdatesEnabledByDefault = true;

// if this is updated, be sure to update the code @pared-processComment function processComment(comment) {  comment = comment.replace(/$+"); comment = comment.replace(/([^']*?)/g, "$1"); comment = comment.replace(/([^']*?)/g, "$1"); comment = comment.replace(/\{\{\s*([^|]*?)(\s*(\||&lt;!|\}))/g,     "{"+"{$1$2"); return comment; }

function finishDisablingUpdates {  var endiUpdates = document.getElementById("a-endiupdates"); endiUpdates.onclick = function { enableUpdates; };  endiUpdates.innerHTML = "Enable updates"; }

function enableUpdates(initialRun) {  if(!updateNewPages.updatesEnabled || initialRun) {     updateNewPages.updatesEnabled = true; var endiUpdates = document.getElementById("a-endiupdates"); endiUpdates.onclick = function { endiUpdates.innerHTML = "Disabling..."; updateNewPages.updatesEnabled = false; };     endiUpdates.innerHTML = "Disable updates"; setTimeout("updateNewPages", 1); } }

function updateNewPages {  if(updateNewPages.updatesEnabled) {     var bodyContent = document.getElementById("bodyContent"); var ul = bodyContent.getElementsByTagName("ul")[0]; var list = updateNewPages.list; var request = updateNewPages.request;

request.open("GET", wgServer + wgScriptPath + "/api.php?format=xml&action=query&list=recentchanges" +        "&rctype=new&rcnamespace=0&rcprop=user|comment|timestamp|title|ids|sizes|redirect|patrolled&rcshow=" + wRcshow + "&rclimit=" + wRclimit, // TO DO: handle the `offset` parameter of the URL         false); request.send(null); if(request.responseXML) {        var titles = new Array; var users = new Object; // this is a map between `User:...` and `User talk:...`s and arrays of  elements that link to the page var rcs = request.responseXML.getElementsByTagName("rc"); for(var i = 0; i < rcs.length; i++) {           var rc = rcs[i]; var title = rc.getAttribute("title"); titles.push(title); var li = null; for(var j = 0; j < list.length; j++) {              if(list[j].title == title) // TO CHECK: whether the `title` parameter of new pages, as generated by the Special:NewPages page, is escaped in the same way as the `title` parameter of s {                 li = list[j]; li.patrolled = hasAttribute(rc, "patrolled"); }           }            if(!li) {              if(wRclimit <= list.length) ul.removeChild(list.shift); li = document.createElement("li"); li.title = title; li.appendChild(document.createTextNode(formatTimestamp(rc.getAttribute("timestamp")) + " ")); var a = document.createElement("a"); // link to the article a.title = title; if(hasAttribute(rc, "patrolled")) {                 a.href = wgServer + "/wiki/" + encodeURIComponent(title) + "?easydb=1"; li.patrolled = true; }              else a.href = wgServer + "/w/index.php?title=" + encodeURIComponent(title) + "&rcid=" + rc.getAttribute("rcid") + "&easydb=1"; a.innerHTML = title; li.appendChild(a); li.appendChild(document.createTextNode(" ("));              a = document.createElement("a"); // hist               a.title = title;               a.href = wgServer + "/w/index.php?title=" + encodeURIComponent(title) + "&action=history";               a.innerHTML = "hist";               li.appendChild(a);               li.appendChild(document.createTextNode(") [" + rc.getAttribute("newlen") + " bytes] ")); // TO DO: format the number a = document.createElement("a"); // link to the user page var user = rc.getAttribute("user"); if(hasAttribute(rc, "anon")) {                 a.title = user; a.href = wgServer + "/wiki/Special:Contributions/" + user; }              else {                 a.title = "User:" + user; if(!users[a.title]) users[a.title] = new Array; users[a.title].push(a); a.href = wgServer + "/wiki/User:" + user; }              a.innerHTML = user; li.appendChild(a); li.appendChild(document.createTextNode(" ("));              a = document.createElement("a"); // link to user talk               a.title = "User talk:" + user;               if(!users[a.title])                  users[a.title] = new Array;               users[a.title].push(a);               a.href = wgServer + "/wiki/User talk:" + user;               a.innerHTML = "Talk";               li.appendChild(a);               if(!hasAttribute(rc, "anon"))               {                  li.appendChild(document.createTextNode(" | "));                  a = document.createElement("a"); // link to user contributions list                  a.title = "Special:Contributions/" + user;                  a.href = wgServer + "/wiki/Special:Contributions/" + user;                  a.innerHTML = "contribs";                  li.appendChild(a);               }               li.appendChild(document.createTextNode(") ")); var span = document.createElement("span"); span.className = "comment"; span.innerHTML = processComment(rc.getAttribute("comment")); li.appendChild(span); list.push(li); ul.insertBefore(li, ul.firstChild); }        }         // check if titles have been deleted, or if they are in `Category:Candidates for speedy deletion` or `Category:Possible copyright violations`, and set the class name request.abort; request.open("GET", wgServer + wgScriptPath + "/api.php?format=xml&action=query&prop=info|categories" +           "&cllimit=500&titles=" + encodeURIComponent(titles.join("|")),            false); request.send(null); if(request.responseXML) {           var pages = request.responseXML.getElementsByTagName("page"); outer: for(var i = 0; i < pages.length; i++) {              var page = pages[i]; var title = page.getAttribute("title"); for(var j = 0; j < list.length; j++) // find the corresponding  {                 if(list[j].title == title) // TO CHECK: whether the `title` parameter of new pages, as generated by the Special:NewPages page or as the attribute of an , is escaped in the same way as the `title` parameter of s                  { var li = list[j]; if(hasAttribute(page, "missing")) {                       if(li.style.display != "none") {                          li.style.display = "none"; // hide it for now. It will eventually be deleted. window.status = title + " was deleted."; //window.alert(title + " was deleted."); }                    }                     else {                       var categories = page.getElementsByTagName("cl"); for(var k = 0; k < categories.length; k++) {                          var title = categories[k].getAttribute("title"); if(title == "Category:Candidates for speedy deletion") {                             li.className = "plainlinks sdcandidate"; continue outer; }                          else if(title == "Category:Possible copyright violations") {                             li.className = "plainlinks possiblecopyvio"; continue outer; }                       }                        if(li.patrolled) {                          li.className = "plainlinks"; li.getElementsByTagName("a")[0].href = wgServer + "/wiki/" + encodeURIComponent(li.title) + "?easydb=1"; }                       else {                          li.className = "plainlinks not-patrolled"; li.getElementsByTagName("a")[0].href = wgServer + "/w/index.php?title=" + encodeURIComponent(li.title) + "&rcid=" + rc.getAttribute("rcid") + "&easydb=1"; }                    }                     continue outer; }              }            }         }         // go through `users`, performing existence checks request.abort; request.open("GET", wgServer + wgScriptPath + "/api.php?format=xml&action=query&prop=info" +           "&titles=" + encodeURIComponent(users.join("|")),            false); request.send(null); if(request.responseXML) {           var pages = request.responseXML.getElementsByTagName("page"); for(var i = 0; i < pages.length; i++) {              var page = pages[i]; if(hasAttribute(page, "missing")) {                 var arr = users[page.getAttribute("title")]; for(var j = 0; j < arr.length; j++) {                    arr[j].className = "new"; }              }            }         }      } // end `if(request.responseXML)` request.abort; setTimeout("updateNewPages", wUpdateDelay); }  else finishDisablingUpdates; }

updateNewPages.list = new Array; // from oldest to newest updateNewPages.request = sajax_init_object; updateNewPages.updatesEnabled = wUpdatesEnabledByDefault;

$(function {  var i = window.location.href.indexOf("?");   var queryString = (0 < i) ? window.location.href.substring(i+1) : "";

if(wgCanonicalNamespace == "Special" && wgCanonicalSpecialPageName == "Newpages") {     if(!wgPreferences.timecorrect || !wgPreferences.date || !wgPreferences.language) {        wgPreferences.language = wgUserLanguage; var request = sajax_init_object; request.open("GET", wgServer + wgScriptPath + "/api.php?format=xml&action=query" +           "&meta=userinfo&uiprop=options",            false); request.send(null); if(request.responseXML) {           var options = request.responseXML.getElementsByTagName("options")[0]; wgPreferences.timecorrection = options.getAttribute("timecorrection"); wgPreferences.date = options.getAttribute("date"); if(window.wAlertSource && wgPreferences.toSource) window.alert("var wgPreferences = " + wgPreferences.toSource + ";"); }        else {           wgPreferences.timecorrection = "0:00"; }     }      if(!wgMessages.monthNames) {        wgMessages.monthNames = new Array;

var request = sajax_init_object; request.open("GET", wgServer + wgScriptPath + "/api.php?format=xml&action=query" +           "&meta=allmessages&ammessages=january|february|march|april|may|june" +            "|july|august|september|october|november|december&amlang=" + wgPreferences.language,            false); request.send(null); if(request.responseXML) {           var messages = request.responseXML.getElementsByTagName("message"); for(var i = 0; i < messages.length; i++) {              var message = messages[i]; var name = message.getAttribute("name"); wgMessages[name] = message.innerText || message.textContent; wgMessages.monthNames.push(message.innerText || message.textContent); }           if(window.wgMessages && wgMessages.toSource) window.alert("var wgMessages = " + wgMessages.toSource + ";"); }        else {           window.wgMessages = ({monthNames:["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], january:"January", february:"February", march:"March", april:"April", may:"May", june:"June", july:"July", august:"August", september:"September", october:"October", november:"November", december:"December"}); }     }      var bodyContent = document.getElementById("bodyContent"); var ul = bodyContent.getElementsByTagName("ul")[0]; var lis = ul.getElementsByTagName("li"); // TO DO: trim to `wRclimit` for(var i = 0; i < lis.length; i++) {        var li = lis[i]; var title = li.getElementsByTagName("a")[0].title.replace("_", " "); li.title = title; var span = li.getElementsByTagName("span")[0]; var comment = span.innerHTML; // pared-processComment comment = comment.replace(/([^']*?)/g, "$1"); comment = comment.replace(/([^']*?)/g, "$1"); comment = comment.replace(/\{\{\s*([^|]*?)(\s*(\||&lt;!|\}))/g,           "{"+"{$1$2"); span.innerHTML = comment; updateNewPages.list.unshift(li); // the s go from newest to oldest, so we insert at 0 each time }     var endiUpdates = document.createElement("a"); endiUpdates.id = "a-endiupdates"; endiUpdates.href = "#"; endiUpdates.style.paddingLeft = "12px"; ul.parentNode.insertBefore(endiUpdates, ul); if(updateNewPages.updatesEnabled) enableUpdates(true); else finishDisablingUpdates; }  else if(0 <= queryString.search(/(?:^|&)easydb=/i)) {     // TO DO: http://matt.blissett.me.uk/web/authoring/css_menus/with_javascript/ //importScript('Wikipedia:WikiProject User scripts/Scripts/Add LI menu'); importStylesheet("Wikipedia:WikiProject User scripts/Scripts/Add LI menu/css"); var tabs = document.getElementById("p-cactions").getElementsByTagName("ul")[0]; addlimenu(tabs, "db", "ca-db", "#", document.getElementById("ca-edit")); mw.util.addPortletLink("ca-db", "javascript:db('attack')", "attack", "ca-db-attack", "Serves no purpose but to disparage or threaten its subject or some other entity"); mw.util.addPortletLink("ca-db", "javascript:db('band')", "band", "ca-db-band", "About a band, singer, musician, or musical ensemble that does not indicate the importance or significance of the subject"); mw.util.addPortletLink("ca-db", "javascript:db('bio')", "bio", "ca-db-bio", "About a real person that does not indicate the importance or significance of the subject"); mw.util.addPortletLink("ca-db", "javascript:db('blank')", "blank", "ca-db-blank", "Empty article, or one that consists only of external links, category tags and \"see also\" sections, a rephrasing of the title, attempts to correspond with the person or group named by its title, chat-like comments, template tags and/or images"); mw.util.addPortletLink("ca-db", "javascript:db('nocontext')", "nocontext", "ca-db-nocontext", "Very short and lacking sufficient context to identify the subject"); mw.util.addPortletLink("ca-db", "javascript:db('nonsense')", "nonsense", "ca-db-nonsense", "Unsalvageably incoherent with no meaningful content or history; patent nonsense"); mw.util.addPortletLink("ca-db", "javascript:db('spam')", "spam", "ca-db-spam", "Does nothing but promote some entity and would require a fundamental rewrite in order to become encyclopedic"); mw.util.addPortletLink("ca-db", "javascript:db('test')", "test", "ca-db-test", "Test page"); mw.util.addPortletLink("ca-db", "javascript:db('vandalism')", "vandalism", "ca-db-vandalism", "Pure vandalism"); }  else if(wgAction == "edit" && /&db=([^&]*)/.test(queryString)) {     var code = RegExp.$1; var wpTextbox1 = document.getElementById("wpTextbox1"); if(/\{\{\s*db-(\w*)\s*\}\}/.test(wpTextbox1.innerHTML)) {        window.alert("The article already has a speedy deletion template, `{"+"{db-" + RegExp.$1 + "}"+"}`, so `{"+"{db-" + code + "}"+"}` will not be added."); }     else {        wpTextbox1.style.display = "none"; wpTextbox1.innerHTML = "{"+"{db-" + code + "}"+"}\n" + wpTextbox1.innerHTML; document.getElementById("wpSummary").value = "db-" + code; document.getElementById("wpMinoredit").setAttribute("checked", "1"); document.getElementById("wpSave").click; }  } });

if(!window.wShowDBConfirmationDialog) window.wShowDBConfirmationDialog = true;

function db(code) {  if(!wShowDBConfirmationDialog) {     window.location = wgServer + "/w/index.php?action=edit&title=" + encodeURIComponent(wgTitle) + "&db=" + code; }  else if(!db.inUse) {     db.inUse = true; var request = sajax_init_object; request.open("GET", wgServer + wgScriptPath + "/api.php?format=xml&action=parse&text={"+"{db-" + code + "}"+"}", false); request.send(null); if(request.responseXML) {        var div = document.createElement("div"); div.id = "db-confirmation-dialog"; var text = request.responseXML.getElementsByTagName("text")[0]; div.innerHTML = text.innerText || text.textContent; div.style.position = "absolute"; div.style.zIndex = "10"; div.style.top = "170px"; div.style.right = "0"; document.getElementById("bodyContent").appendChild(div); var tbody = div.getElementsByTagName("tbody")[0]; var tr = document.createElement("tr"); var td = document.createElement("td"); td.style.border = "medium none"; td.style.padding = "0px"; td.style.width = "1px"; tr.appendChild(td); td = document.createElement("td"); td.align = "right";

var button = document.createElement("button"); button.innerHTML = "Confirm"; button.onclick = function { window.location = wgServer + "/w/index.php?action=edit&title=" + encodeURIComponent(wgTitle) + "&db=" + code; };        button.style.marginRight = "3px"; td.appendChild(button); button = document.createElement("button"); button.innerHTML = "Cancel"; button.onclick = function { var div = document.getElementById("db-confirmation-dialog"); div.parentNode.removeChild(div); db.inUse = false; };        td.appendChild(button); tr.appendChild(td); tbody.appendChild(tr); }     else {        window.alert("Failed to parse `{"+"{db-" + code + "}"+"}`"); }  } }