User:DavidHOzAu/votescript/code.js

/*

Code
*/ //-- // GLOBAL VARIABLES //-- var vs_data = new Array(3);	// persistent data : { users, votes, headings }

//-- // voteProcessor - process an entire dom, extract users & votes //-- function voteProcessor(dom) { var lists = dom.getElementsByTagName("ol"); var votes = new Array; var users = new Array; for (i = 0; list = lists[i]; i++) { var ret = processList(list, users, votes, (lists.length - i) - 1); if (ret) { // checksafe users = ret[0]; votes = ret[1]; }   }    vs_data[0] = users; vs_data[1] = votes; }

//-- // getAllHeadings - Detect all headings in the DOM //-- function getAllHeadings(dom, headings) { for (var i = 0; n = dom.childNodes[i]; i++) { if (n.nodeName.length == 2            && !isNaN(n.nodeName.substr(1,1))             && n.nodeName.toLowerCase.substr(0,1) == "h") { headings[headings.length] = getHeading(n); }        if (n.childNodes.length > 0) { headings = getAllHeadings(n, headings); // recurse }   }    return headings; }

//-- // getHeading - Detect the heading text in a node //-- function getHeading(n) { for (var i = 0; el = n.getElementsByTagName("span")[i]; i++) { if (el.className == "mw-headline") { return el.innerHTML; }   }    return "unknown"; }

//-- // processList - extract users and votes from an option's list //-- function processList(list, users, votes, choice) { if (!list) { return; } // failsafe for (var i = 0; el = list.getElementsByTagName("li")[i]; i++) { var uname = getUserFromLiElement(el); if (uname == "") { uname = getUnknownUser(el); if (uname == "") { return; }       }        var uid = wasUserRead(uname, users); if (uid < 0) { uid=users.length; votes[uid] = 0; }       users[uid] = uname; votes[uid] += Math.pow(2, choice); // binary store }   ret = new Array; // pass back by array ret[0] = users; ret[1] = votes; return ret; }

//-- // getUserFromLiElement - auto-magically detect user name //-- function getUserFromLiElement(lielem) { for (var i = 0; link = lielem.getElementsByTagName("a")[i]; i++) { if (link.title.substr(0, 4) == "User") { return link.title.substr(5, link.title.length); }   }    return ""; }

//-- // getUnknownUser - user intervention for weird entries //-- function getUnknownUser(el) { var text = getInnerText(el); var msg = "Couldn't identify user. Please extract the user's name from the following text."; var reply = prompt(msg, text); if (reply == null) { return ""; } return reply; }

//-- // getInnerText - get innerHTML without the HTML tags //-- function getInnerText(el) { var re, text = el.innerHTML; // remove XML tags do { a = text; text = text.replace(/<[^>\/]*\/>/gi, ""); } while (a != text); // strip HTML tags do { a = text; text = text.replace(/<[^>]*>([^<]*)<\/[^>]*>/gi, "$1"); } while (a != text); // remove leading and trailing spaces text = text.replace(/^\s/gi, ""); text = text.replace(/\s$/gi, ""); return text; }

//-- // wasUserRead - O(n) search for user name presence //-- function wasUserRead(username, users) { for (var i = 0; i < users.length; i++) { if (users[i] == username) { return i; } }   return -1; }

//-- // gen_table - make HTML table preview of results //-- function gen_table { var users = vs_data[0]; var votes = vs_data[1]; var headings = vs_data[2];

var totals = new Array; var str = ' ";   str += " " + users.length + " editors voted in this survey. "    return str; }

//-- // gen_wiki - generate results as wikicode //-- function gen_wiki { var users = vs_data[0]; var votes = vs_data[1]; var headings = vs_data[2];

var totals = new Array; var str = '<' + 'pre style="border-style: none; padding: 0; margin: 0"' + '>{|class="wikitable"\n!Users'; var i, j, k;   for (i = 0; i < headings.length; i++) { str += "!!" + headings[i]; totals[i] = 0; }   for (i = 0; i < users.length; i++) { str += "\n|-\n|" + users[i]; k = votes[i]; for (j = headings.length-1; j >= 0; j--) { // MSB to LSB if (k - Math.pow(2, j) >= 0) { // is bit set? k -= Math.pow(2, j);      // turn it off str += "|| X "; totals[j]++; } else { str += "|| - "; }       }    }    str += "\n|-\n!Total"; for (i = headings.length-1; i >= 0; i--) { // Reverse order str += "!!" + totals[i]; }

str += "\n|}"; str += "\n\n" + users.length + " editors voted in this survey.<" + "/pre" + ">"; return str; }

//-- // Adapt code for MediaWiki use //-- var votescript_url = "User:DavidHOzAu/votescript/ui"; var vs_path_len = document.location.pathname.length; if (document.location.pathname.substring(vs_path_len - votescript_url.length, vs_path_len) == votescript_url) { hookDOMEvent(window, "load", uiSetup); }

//-- // hookDOMEvent - useful for hooking events in any element //-- function hookDOMEvent(dom, hookName, hookFunct) { if (dom.addEventListener) dom.addEventListener(hookName, hookFunct, false); else if (dom.attachEvent) dom.attachEvent("on" + hookName, hookFunct); }

//-- // uiHandler - UI setup code //-- function uiSetup { // blank the inner contents of the page var bodyContent = document.getElementById("bodyContent"); while (bodyContent.childNodes.length > 0) bodyContent.removeChild(bodyContent.lastChild);

bodyContent.innerHTML = '' + uiLabel("Survey page") + uiWrap("2em", uiButton("fetch", "Fetch", "button") + uiInput("page", "Wikipedia:Village_pump_(proposals)/Sidebar_redesign/Final_draft_vote")) + uiLabel("Headers") + uiTextArea("headers", "") + uiLabel("Preview") + uiOutput("preview", "") + uiLabel("Wikitable") + uiOutput("wiki", "") + ' ' + uiHiddenText("hidden");

document.getElementById("vs-page").style.position = "absolute"; document.getElementById("vs-page").style.left = "0em"; document.getElementById("vs-page").style.width = "32em"; document.getElementById("vs-fetch").style.position = "absolute"; document.getElementById("vs-fetch").style.right = "0em"; document.getElementById("vs-fetch").style.width = "5.5em";

hookDOMEvent(document.getElementById("vs-fetch"), "click", fetchVotes); hookDOMEvent(document.getElementById("vs-headers"), "change", uiUpdater); }

//-- // UI Helper functions //-- function uiLabel(label) { return(' '   + '' + label    + '   '); }

function uiWrap(h, text) { return('' + text + ' '); }

function uiInput(id, text) { return(''); }

function uiButton(id, text, type) { return(''); }

function uiTextArea(id, text) { return uiWrap("auto", '' + text + ' '); }

function uiOutput(id, text) { return uiWrap("auto", '' + text + ' '); }

function uiHiddenText(id) { return(' '); }

//-- // uiUpdater - update contents when heading text changes //-- function uiUpdater { vs_data[2] = document.getElementById("vs-headers").value.split(/[\n\r]+/); document.getElementById("vs-preview").innerHTML = gen_table; document.getElementById("vs-wiki").innerHTML = gen_wiki; }

//-- // fetchVotes - fetch DOM of requested page //-- function fetchVotes(event) { document.getElementById("vs-preview").innerHTML = "Loading..."; x = sajax_init_object; if (!x) { alert("AJAX not supported"); return false; }   var url = document.getElementById("vs-page").value; x.onreadystatechange = function { voteFetcher(x); }; url = wgScriptPath + "/index.php?title=" + escape(url) + "&action=render"; x.open("GET", url, true); x.send(null); }

//-- // voteFetcher - handle XMLHttpRequest messages //-- function voteFetcher(x) { if (x.readyState == 3) { /* document.write(x.getAllResponseHeaders); */ } if (x.readyState != 4) { return; } if (x.status != 200) { document.getElementById("vs-preview").innerHTML = "Page not found or network error"; return; }   if (x.responseText) { var dom = document.createElement("div"); // placeholder dom.innerHTML = x.responseText; // hack vs_data[2] = getAllHeadings(dom, new Array);	// get _ALL_ headings voteProcessor(dom);		// process dom for votes for (head in vs_data[2]) { document.getElementById("vs-headers").value += vs_data[2][head] + '\r\n'; }       uiUpdater; } else { document.getElementById("vs-preview").innerHTML = "Response empty"; } } /* */