User:Whiteknight/gadgetscore.js

From Wikibooks, open books for an open world
Jump to navigation Jump to search
Note: After saving, changes may not occur immediately. Click here to learn how to bypass your browser's cache.
  • Mozilla / Firefox / Safari: hold down Shift while clicking Reload, or press Ctrl-Shift-R (Cmd-Shift-R on Apple Mac);
  • Internet Explorer: hold Ctrl while clicking Refresh, or press Ctrl-F5;
  • Konqueror: simply click the Reload button, or press F5;
  • Opera users may need to completely clear their cache in Tools→Preferences.
//Whiteknights Core javascript
//Maintained by [[User:Whiteknight]]
/*
  This is a javascript library for helping to automate and simplify some common JavaScript
  tasks, and expose special-purpose functionality for use with several other scripts. This
  core library contains special functions for dealing with common elements, and a number
  of AJAX-based functions for loading pages and text from the server and posting edits to
  the server. Documentation about this library is located at 
  [[User:Whiteknight/Gadgetscore]].
*/

wk = {
  _version: 2.81,

  testVersion: function(ver) { return ((ver == null)?(true):(wk._version >= ver)); },

  _getNode: function(elem) {
    if(elem == null) return null;
    if(typeof elem == "string") return document.getElementById(elem);
    return elem;
  },

  getDate: function() {
    var date = new Date();
    return (date.getMonth() + 1) + "/" + date.getDate() + "/" + date.getFullYear();
  }, 

  getQueryHash: function() {
    var qs = new Object();
    var query = location.search.substring(1);
    if(query == "") return qs;
    var pairs = query.split("&");
    for(var x = 0; x < pairs.length; x++) {
      var attrval = pairs[x].split("=");
      qs[attrval[0]] = attrval[1];
    }
    return qs;
  },

  _httpmethods: [
    function() { return new XMLHttpRequest(); },
    function() { return new ActiveXObject("msxml2.XMLHTTP"); },
    function() { return new ActiveXObject("Microsoft.XMLHTTP"); }
  ],

  _httpmethod: null,

  _initclient: function() {
    for(var i = 0; i < wk._httpmethods.length; i++) {
      try {
        var method = wk._httpmethods[i];
        var client = method();
        if(client != null) wk._httpmethod = method;
        return client;
      } catch(e) { continue; }
    }
    return null;
  },

  httpClient: function() {
    if(wk._httpmethod != null) return wk._httpmethod();
    if(wk._initclient() == null) return null;
    return wk._httpmethod();
  },

  _encodeData: function(dat) {
    var p = [];
    for(var name in dat) {
      var value = dat[name].toString();
      var pair = encodeURIComponent(name).replace(/%20/g, "+") + "=" +
                 encodeURIComponent(value).replace(/%20/g, "+");
      p.push(pair);
    }
    return p.join("&");
  },

  loadPage: function(url, callback, type) {
    if(callback == null || url == null) return false;
    var client = wk.httpClient();
    client.onreadystatechange = function() {
      if(client.readyState != 4) return;
      if(type == "text/xml" && client.overrideMimeType) callback(client.responseXML);
      else if(client.status == 200) callback(client.responseText);
      else callback('');
    }
    client.open("GET", url, true);
    if(type == "text/xml" && client.overrideMimeType) client.overrideMimeType(type);
    client.send(null);
    return true;
  },

  loadWikiPage: function(page, callback) { 
    page = page.replace(/ /g, "_");
    return wk.loadPage(wk._URLBase + page, callback, "text/xml");
  },

  loadEditPage: function(page, callback) {
    return wk.loadPage(wk._editURL(page), callback, "text/xml");
  },

  loadWikiText: function(page, callback) {
    return wk.loadPage(wk._rawURL(page), callback, "text/x-wiki");
  },

  loadWikiTextSection: function(page, section, callback) {
    return wk.loadPage(wk._rawURL(page) + "&section=" + section, callback, "text/x-wiki");
  },

  _URLBase: "http://en.wikibooks.org/w/index.php?title=",
  _rawURL: function(page) {
    return wk._URLBase + page.replace(/ /g, "_") + "&action=raw&ctype=text/x-wiki";
  },
  _editURL: function(page, section) {
    if(section == null)
      return wk._URLBase + page.replace(/ /g, "_") + "&action=edit&printable=yes";
    else
      return wk._URLBase + page.replace(/ /g, "_") + 
             "&section=" + section + 
             "&action=edit&printable=yes";
  },

  _ensureXML: function(text) {
    if(text.getElementsByTagName) return text;
    var xmldom = new ActiveXObject("Microsoft.XMLDOM");
    xmldom.async = false;
    xmldom.loadXML(text);
    return xmldom.documentElement;
  },

/*"opts" contains options pertinent to the edit:
opts.section
opts.minor
opts.watch
opts.filter
opts.callback
*/

  postEdit: function(page, text, summary, opts) {
    if(opts == null) opts = {};
    var client = wk.httpClient();
    client.onreadystatechange = function() {
      if(client.readyState != 4 || client.status != 200) return;
      if(client.overrideMimeType) 
        wk._postEdit2(client, client.responseXML, page, text, summary, opts);
      else 
        wk._postEdit2(client, wk._ensureXML(client.responseText), page, text, summary, opts);
    }
    var url = wk._editURL(page, (typeof opts.section != "undefined")?(opts.section):(null));
    client.open("GET", url, true);
    if(client.overrideMimeType) client.overrideMimeType("text/xml");
    client.send(null);
  },

  _postEdit2: function(client, xml, page, text, summary, opts) {
    var input = xml.getElementsByTagName("input");
    var data = [];
    var pagetext = xml.getElementsByTagName("textarea")[0].value;
    data["wpTextbox1"]  = (typeof text == "function")?(text(pagetext)):(text);
    data["wpRecreate"]  = true;
    data["wpSummary"]   = summary;
    if(typeof opts.minor != "undefined") data["wpMinoredit"] = "1";
    data["wpSection"]   = (typeof opts.section != "undefined")?(opts.section):("");
    data["wpSave"]      = "Save page";
    var watch = null;
    for(var i = 0; i < input.length; i++) {
      var attribs = input[i].attributes;
      var name = ""; var value = "";
      for(var j = 0; j < attribs.length; j++){
        if(attribs[j].name == "name") name = attribs[j].value;
        if(attribs[j].name == "value") value = attribs[j].value;
      }
      if(name == "wpStarttime") data["wpStarttime"] = value;
      if(name == "wpEdittime")  data["wpEdittime"]  = value;
      if(name == "wpEditToken") data["wpEditToken"] = value;
      if(name == "wpWatchthis") watch = value;
    }
    if(typeof opts.watch == "undefined") data["wpWatchthis"] = watch;
    else if(opts.watch == true) data["wpWatchthis"] = true;
    var url = wk._URLBase + page.replace(/ /g, "_") + "&action=submit";
    client.open("POST", url, true);
    client.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    client.onreadystatechange = function() {
      if(client.readyState != 4 || client.status != 200) return;
      if(opts.callback) opts.callback(page, pagetext, data);
    }
    client.send(wk._encodeData(data));
  },

  // Shows a basic edit window
  showEditWindow: function (xml, parent, text, summary) {
    if(parent == null) parent = wk.makeElement('div');
    if(typeof xml.getElementById == "function") {
      var form  = xml.getElementById('editform');
      form      = document.importNode(form, true);
      wk.spanText(parent, "").appendChild(form);
    } else {
      wk.spanText(parent, "");
      var i = xml.indexOf("<form");
      var j = xml.indexOf("</form>");
      xml   = xml.substring(i, j+7);
      wk.appendSpanText(parent, xml);
    }
    var ta    = document.getElementById('wpTextbox1');
    var sum   = document.getElementById('wpSummary');
    var time  = document.getElementById('wpStarttime');
    if(summary != null) sum.value = summary;
    if(typeof text == "string") ta.value = text;
    else if(typeof text == "function") ta.value = text(ta.value);
    return {form: form, text: ta, summary: sum, time: time, parent: parent};
  },

  // shows a small edit window with no descriptions or fancy tools.
  showEditWindowSmall: function (xml, parent, text, summary) {
    var editform = wk.showEditWindow(xml, parent, text, summary);
    editform.text.rows = 10;
    wk.spanText('editpage-copywarn', '');
    wk.spanText('editpage-specialchars', '');
    wk.spanText('specialchars', '')
    return editform;
  },

  // opens an edit page in a separate tab or window, with the given text and summary pre-loaded.
  showEditWindowExternal: function(page, text, summary) {
    var loadwin = function(win, newtext, newsummary) {
      var eb = win.document.getElementById('wpTextbox1');
      if(typeof newtext == "string") eb.value = newtext;
      else if(typeof newtext == "function") eb.value = newtext(eb.value);
      if(newsummary != null) win.document.getElementById('wpSummary').value = newsummary;
    }
    var w = window.open(wk._editURL(page));
    if (w.attachEvent) {
      w.attachEvent("onload", function() { loadwin(w, text, summary) });}
    else if (window.addEventListener) {
      w.addEventListener("load", function() { loadwin(w, text, summary) }, false);
    } else {
      w.document.addEventListener("load", function() { loadwin(w, out) }, false);
    }
  },

  makeElement: function(type, attr, children) {
    var elem = document.createElement(type);
    if(attr) for(var a in attr) elem.setAttribute(a, attr[a]);
    if(children == null) return elem;
    if(children instanceof Array) for(var i = 0; i < children.length; i++) {
      var child = children[i];
      if(typeof child == "string") child = document.createTextNode(child);
      elem.appendChild(child);
    }
    else if(typeof children == "string") elem.appendChild(document.createTextNode(children));
    else elem.appendChild(children);
    return elem;
  },

  elementBuilder: function(type) {
    return function(attr, children) { return wk.makeElement(type, attr, children); }
  },

  makeButton: function (name, value, onclick) {
    var elem = wk.makeElement("input", {type:"button", name:name, value:value}, null);
    elem.onclick = onclick;
    return elem;
  },

  makeInput: function (name, value){
    return wk.makeElement("input", {type:"text", name:name, value:value}, null);
  },

  spanText: function(spanid, text) {
    var res = wk._getNode(spanid);
    if(res) res.innerHTML = ((text == null)?(""):(text));
    return res; 
  },

  appendSpanText: function (spanid, text) {
    var res = wk._getNode(spanid);
    if(res) res.innerHTML = res.innerHTML + text;
    return res;
  },

  appendChildren: function(parent, children) {
    var res = wk._getNode(parent);
    if(res == null) return;
    if(children instanceof Array) {
      for(var i = 0; i < children.length; i++) {
        if(typeof children[i] == 'string') children[i] = document.createTextNode(children[i]);
        res.appendChild(children[i]);
      }
    } else {
      if(typeof children == 'string') children[i] = document.createTextNode(children);
      res.appendChild(children);
    }
  },

  spanEditor: function(spanid) {
    return function(text) { return wk.spanText(spanid, text); }
  },

  wikiLink: function(pagename, link, action) {
    if(pagename == null) pagename = "Main Page";
    if(link == null) link = pagename;
    var a = wk.makeElement("a");
    if(action == null) a.setAttribute("href", "/wiki/" + pagename.replace(/ /g, "_"));
    else a.setAttribute("href", "/w/index.php?title=" + pagename.replace(/ /g, "_") + "&" + action);
    a.innerHTML = link;
    return a;
  },

  wikiLinkText: function (pagename, link, action) {
    if(link == null) link = pagename;
    if(action == null) 
      return "<a href=\"/wiki/" + pagename.replace(/ /g, "_") + "\">" + link + "</a>";
    else 
      return "<a href=\"/w/index.php?title=" + pagename.replace(/ /g, "_") + "&" + action +
             "\">" + link + "</a>";
  },

  toggleDisplay: function (elem, disp) {
    var res = wk._getNode(elem);
    if(res == null) return;
    if(disp != null) res.style.display = disp;
    else res.style.display = ((res.style.display == "none")?("block"):("none"));
  },

  toggleDisable: function (elem, disa) {
    var res = wk._getNode(elem);
    if(res == null) return;
    if(disa != null) res.disabled = ((disa == true)?(true):(false));
    else res.disabled = !res.disabled;
  },

  getElementsByClass: function (c, type) {
    var elems = new Array();
    if(type == null) type = "*";
    var els = document.getElementsByTagName(type);
    var pattern = new RegExp("(^|\\s)" + c + "(\\s|$)");
    for (i = 0, j = 0; i < els.length; i++) {
      if (pattern.test(els[i].className)) elems[j++] = els[i];
    }
    return elems;
  },

  testUserPermissions: function(level) {
    for(var i = 0; i < wgUserGroups.length; i++) {
      if(wgUserGroups[i] == level) return true;
    }
    if(level == "administrator") return wk.testUserPermissions("bureaucrat");
    return false;
  }
};