User:ST77/TScripts/Helper.js

/* */ // ============================================================== // Available functions: // * JSON - [Object].toJSONString // * Global Error Handling Support // * [XMLDOM] // * assignToEditForm // * [Array].indexOf // * [Array].every // * [Array].toSource // * addTab // * addToolboxLink // * getPname // * getSelText // * getSelTextArea (Firefox only) // * getParamValue // * getUploader // * qid_getFileHistory (required for getUploader) // * SetCaretTo // * openInNewWindow // * isIPAddress // * userIsInGroup // * [String].trim // * [String.replaceAll // * htmlNode // * [Status] // * [QueryString] // ==============================================================

// ===== JSON (2007-02-18) Public Domain ==== if(!Object.prototype.toJSONString){Array.prototype.toJSONString=function{var a=['['],b,i,l=this.length,v;function p(s){if(b){a.push(',');} a.push(s);b=true;} for(i=0;i<l;i+=1){v=this[i];switch(typeof v){case'undefined':case'function':case'unknown':break;case'object':if(v){if(typeof v.toJSONString==='function'){p(v.toJSONString);}}else{p("null");} break;default:p(v.toJSONString);}} a.push(']');return a.join('');};Boolean.prototype.toJSONString=function{return String(this);};Date.prototype.toJSONString=function{function f(n){return n<10?'0'+n:n;} return'"'+this.getFullYear+'-'+ f(this.getMonth+1)+'-'+ f(this.getDate)+'T'+ f(this.getHours)+':'+ f(this.getMinutes)+':'+ f(this.getSeconds)+'"';};Number.prototype.toJSONString=function{return isFinite(this)?String(this):"null";};Object.prototype.toJSONString=function{var a=['{'],b,k,v;function p(s){if(b){a.push(',');} a.push(k.toJSONString,':',s);b=true;} for(k in this){if(this.hasOwnProperty(k)){v=this[k];switch(typeof v){case'undefined':case'function':case'unknown':break;case'object':if(v){if(typeof v.toJSONString==='function'){p(v.toJSONString);}}else{p("null");} break;default:p(v.toJSONString);}}} a.push('}');return a.join();};(function(s){var m={'\b':'\\b','\t':'\\t','\n':'\\n','\f':'\\f','\r':'\\r','"':'\\"','\\':'\\\\'};s.parseJSON=function(filter){try{if(/^("(\\.|[^"\\\n\r])*?"|[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t])+?$/.test(this)){var j=eval('('+this+')');if(typeof filter==='function'){function walk(k,v){if(v&&typeof v==='object'){for(var i in v){if(v.hasOwnProperty(i)){v[i]=walk(i,v[i]);}}} return filter(k,v);} walk(,j);} return j;}}catch(e){} throw new SyntaxError("parseJSON");};s.toJSONString=function{if(/["\\\x00-\x1f]/.test(this)){return'"'+this.replace(/([\x00-\x1f\\"])/g,function(a,b){var c=m[b];if(c){return c;} c=b.charCodeAt;return'\\u00'+ Math.floor(c/16).toString(16)+ (c%16).toString(16);})+'"';} return'"'+this+'"';};})(String.prototype);}

// ========== Error Handling Support ========== function errorHandler(message, url, line) { Status.error("Sorry, found eror: " + message + " line: " + line + " in: " + url + ". Please report this problem at User:ST77"); return true; }

//Install the global error-handler window.onerror = errorHandler;

//Simple exception handling Exception = function( str ) { this.str = str || ''; };

Exception.prototype.what = function { return this.str; };

// ========== XMLDOM ========== window.XMLDOM = function window$XMLDOM(markup) { if (!window.DOMParser) { var progIDs = [ 'Msxml2.DOMDocument.3.0', 'Msxml2.DOMDocument' ]; for (var i = 0; i < progIDs.length; i++) { try { var xmlDOM = new ActiveXObject(progIDs[i]); xmlDOM.async = false; xmlDOM.loadXML(markup); xmlDOM.setProperty('SelectionLanguage', 'XPath'); return xmlDOM; }           catch (ex) { }       }        return null; }       else { try { var domParser = new window.DOMParser; return domParser.parseFromString(markup, 'text/xml'); } catch (ex) { return null; }   }    return null; };

// ========== assignToEditForm designed for iScript ========== function assignToEditForm(iScriptAction) { //edit page var title = encodeURIComponent(mw.config.get('wgPageName')); location.assign("/w/index.php?title=" + title + "&action=edit&iScriptAction=" + iScriptAction); }

// ========== [Array].indexOf ========== // NOTE: This is included in Javascript 1.6 which is not yet available in IE or ECMAScript // Taken from http://www.dustindiaz.com/basement/sugar-arrays.html if (!Array.prototype.indexOf) { Array.prototype.indexOf = function(el, start) { var start = start || 0; for (var i = start; i < this.length; ++i) { if (this[i] === el) { return i;     } }   return -1; }; }

// ========== [Array].every ========== // NOTE: This is included in Javascript 1.6 which is not yet available in IE or ECMAScript // Taken from http://www.dustindiaz.com/basement/sugar-arrays.html if (!Array.prototype.every) { Array.prototype.every = function(fn, thisObj) { var scope = thisObj || window; for ( var i=0, j=this.length; i < j; ++i ) { if ( !fn.call(scope, this[i], i, this) ) { return false; }     }      return true; }; }

// ========== [Array].toSource ========== if (!Array.prototype.toSource) { Array.prototype.toSource = function { var L = this.length,s = '[',t,i; for (i = 0; i < L; i++) { if (i > 0) s += ','; if (this[i].constructor == Array) s += this[i].toSource; else switch (typeof this[i]) { case "number" : s += this[i]; break; case "boolean" : s += this[i]; break; default : s += '"' + this[i].toString.split('"').join('\\"') + '"'; }   }    return s + ']'; }; }

function addTab(url, name, id, title, key) { return addPortletLink('p-cactions', url, name, id, title, key); }

function addTab(url, name, id, title, key, after) { return addPortletLink('p-cactions', url, name, id, title, key, after); }

//WARNING: This function requires iScript sidebox function addToolboxLink(url, name, id, key) {

return addPortletLink('p-mScripts', url, name, id, key); }

//Returns the name of the page. For example, if you were browsing the "foo" WP page, getPname would return "foo" function getPname { if (typeof wgPageName != 'undefined' && wgPageName != null) { return wgPageName.replace(/_/g, ' '); } else { return document.getElementsByTagName('h1')[0].firstChild.nodeValue; //return document.title.substr(0, document.title.lastIndexOf(' - Wikipedia')); /*   z=document.getElementById("content").childNodes; for (var n=0;n<z.length;n++) { if (z[n].className=="firstHeading") return URLEncoding(z[n].innerHTML); }   */  } }

//Return selected text if any function getSelText { var text;

if (window.getSelection) { text = window.getSelection;

} else if (document.getSelection) { text = document.getSelection;

} else if (document.selection) { text = document.selection.createRange.text;

} else { return; } return text.toString; }

//Get selected text in textbox. in This function is designed for Firefox. Use normal getSelText for other browsers function getSelTextArea { var txtArea = document.editform.wpTextbox1; if (txtArea.selectionStart || txtArea.selectionStart == '0') { var startPos = txtArea.selectionStart; var endPos = txtArea.selectionEnd; return (txtArea.value).substring(startPos, endPos); } }

//===== Get QueryString ParamValue ===== function getParamValue(paramName) { var cmdRe=RegExp('[&?]'+paramName+'=([^&]*)'); var h=document.location; var m=cmdRe.exec(h); if (m) { try { return decodeURIComponent(m[1]); } catch (someError) {} } return null; }

//===== getUploader ===== //Source: en:User:Howcheng/quickimgdelete.js, adapted & further modified by user:Jutiphan //NOTE: DO NOT UPGRADE TO NEWER VER WITHOUT MERGE. This is custom, include sysop fix. See below. /* * Current version: 1.10.4 * ======================================= * Created by Howard Cheng * Released under the GNU Public License (GPL) * Full documentation at User talk:Howcheng/quickimgdelete.js * ======================================= */ //NOTE: DOES NOT work in Edit page // Get uploader from first point in the list under "File history" // Uploader is stored in second A tag in UL tag under "File history" // Returns title of user page (without name space) in URL form function getUploader { // Returns title of user page (without name space) in URL form var trs = qid_getFileHistory; var els = new Array; var tr = trs[0]; // skip first one because it's the header do { tr = tr.nextSibling; var tds = tr.childNodes; if(userIsInGroup("sysop")) { var td = tds[3]; } else { var td = tds[2];// uploader info in 3rd cell if not sysop }   els[els.length] = td; } while (tr.nextSibling);

var uploaders = new Array; var re1 = new RegExp(('/wiki/').replace(/\./g, '\\.') + 'User:(.*)$'); var re2 = new RegExp((wgServer + '/w/index.php').replace(/\./g, '\\.') + '\\?title=User:([^&]*)'); var re3 = /(User)?talk:(.*)$/; // this is for IE and handling Unicode characters

var m; var uploader; var uploaderList = ""; var count = 0; for (var i = 0; i < els.length; i++) { var el = els[i]; if (!el) continue; var as = el.childNodes; if (!as) continue; for (var k=0; k 0) uploaderList += "; "; uploaderList += count + " - " + uploader; uploaders[uploaders.length] = uploader; count += 1; } }

if (!uploaders || uploaders.length == 0) { alert("getUploader: ไม่สามารถดึงชื่อผู้ใช้ที่อัปโหลดได้ กรุณาแจ้งผู้ใช้:Jutiphan"); return null; } if (uploaders.length == 1) return uploaders[0];

var which = parseInt(window.prompt("กรุณาเลือกชื่อผู้ใช้ที่ต้องการจะแจ้ง: " + uploaderList, "")); if (isNaN(which) || which < 0 || which >= uploaders.length) { alert("getUploader: ไม่มีชื่อผู้ใช้ที่เลือก หยุดการดำเนินการ"); return null; } return uploaders[which]; }

//===== qid_getFileHistory ===== //Part of getUploader. See above. function qid_getFileHistory { var el = document.getElementById('filehistory'); if (!el) { alert("getUploader: ไม่พบประวัติไฟล์ หยุดการดำเนินงาน กรุณาแจ้งผู้ใช้:Jutiphan"); return null; } while (el.nextSibling) { el = el.nextSibling; if (el.tagName && el.tagName.toLowerCase == 'table') break; } if (!el) { alert("getUploader: ไม่พบป้าย TABLE หยุดการทำงาน กรุณาแจ้งผู้ใช้:Jutiphan"); return null; }

var trs = el.getElementsByTagName('tr'); if (!trs) { alert("getUploader: ไม่พบป้าย TR หยุดการทำงาน กรุณาแจ้งผู้ใช้:Jutiphan"); return null; } return trs; }

//===== Set Cursor Position in given Textbox ===== //Source: http://parentnode.org/javascript/working-with-the-cursor-position/ function setCaretTo(obj, pos) { if (obj.createTextRange) { /* Create a TextRange, set the internal pointer to      a specified position and show the cursor at this position */   var range = obj.createTextRange; range.move("character", pos); range.select; } else if (obj.selectionStart) { /* Gecko is a little bit shorter on that. Simply focus the element and set the selection to a      specified position */   obj.focus; obj.setSelectionRange(pos, pos); } }

// ========== Open In New Window ========== function openInNewWindow(website, windowName, isFocus) { if(!windowName) { windowName = '_blank'; } var newWindow = window.open(website, windowName); if(isFocus) { newWindow.focus; } }

// ========== Check if the user is an IP Address ========== /* Returns true if given string contains a valid IP-address, that is, from 0.0.0.0 to 255.255.255.255*/ function isIPAddress(string) { var res = /(\d{1,4})\.(\d{1,3})\.(\d{1,3})\.(\d{1,4})/.exec(string); return res != null && res.slice(1, 5).every(function(e) {   return e < 256;  }); }

// ========== Check if the user belongs to the given group ========== function userIsInGroup(groupName) { for (var i = 0; i < wgUserGroups.length; i++) { if (wgUserGroups[i] == groupName) return true; } return false; }

// ========== Replace string ========== // Javascript from http://www.irt.org/script/242.htm function replace(string, text, by) { // Replaces text with by in string var strLength = string.length, txtLength = text.length; if ((strLength == 0) || (txtLength == 0)) return string;

var i = string.indexOf(text); if ((!i) && (text != string.substring(0, txtLength))) return string; if (i == -1) return string;

var newstr = string.substring(0, i) + by;

if (i + txtLength < strLength) newstr += replace(string.substring(i + txtLength, strLength), text, by);

return newstr; }

// ========== [String].trim ========== String.prototype.trim = function { return this.replace(/^\s+|\s+$/, ''); };

// Replaces all instances of the given substring. String.prototype.replaceAll = function(   strTarget, // The substring you want to replace    strSubString // The string you want to replace in.    ) { var strText = this; var intIndexOfMatch = strText.indexOf(strTarget);

// Keep looping while an instance of the target string // still exists in the string. while (intIndexOfMatch != -1) { // Relace out the current instance. strText = strText.replace(strTarget, strSubString);

// Get the index of any next matching substring. intIndexOfMatch = strText.indexOf(strTarget); }

// Return the updated string with ALL the target strings // replaced out with the new substring. return( strText ); };

// Simple helper function to create a simple node function htmlNode(type, content, color) { var node = document.createElement(type); if (color) { node.style.color = color; } node.appendChild(document.createTextNode(content)); return node; }

// ========== Status class ========== Status = function {};

/* Initiate an element to be a status window, it will remove all it's childs Status.init = function(elem) {

if (elem.nodeType != 1) { throw new Exception('object not an instance of Element'); }

Status.elem = elem; Status.currentNode = null;

while (elem.hasChildNodes) { elem.removeChild(elem.firstChild); } };

// Private function Status.append = function(obj, node) {

if (Status.elem == null) { throw new Exception('no initialized object found'); }

if (! ( obj instanceof Array )) { obj = [ obj ]; }

node = node || Status.currentNode;

for (var i in obj) { if (typeof obj[i] == 'string') { node.appendChild(document.createTextNode(obj[i]));

} else if (obj[i].nodeType == 1) { node.appendChild(obj[i]); } } };

Status.error = function(obj) { Status.currentNode = document.createElement('div'); Status.currentNode.style.color = 'OrangeRed'; Status.currentNode.style.fontWeight = '900'; Status.append(obj); Status.elem.appendChild(Status.currentNode); return Status.currentNode; };

Status.warn = function(obj) { Status.currentNode = document.createElement('div'); Status.currentNode.style.color = 'OrangeRed'; Status.append(obj); Status.elem.appendChild(Status.currentNode); return Status.currentNode; };

Status.info = function(obj) { Status.currentNode = document.createElement('div'); Status.currentNode.style.color = 'ForestGreen'; Status.append(obj); Status.elem.appendChild(Status.currentNode); return Status.currentNode; };

Status.debug = function(obj, level) { level = level || 1; if (iScriptConfig.debugMode >= level) { Status.currentNode = document.createElement('div'); Status.currentNode.style.color = 'DimGray'; Status.append("Debug (" + level + "): "); Status.append(obj); Status.elem.appendChild(Status.currentNode); return Status.currentNode; } else { return null; } };

Status.status = function(obj) { Status.currentNode = document.createElement('div'); Status.currentNode.style.color = 'SteelBlue'; Status.append(obj); Status.elem.appendChild(Status.currentNode); return Status.currentNode; };

Status.progress = function (obj, node) { Status.append(obj, node); };

// ================================================================= // Maps the querystring to an object // // Functions: // // QueryString.exists(key) //    returns true if the particular key is set // QueryString.get(key) //    returns the value associated to the key // QueryString.equals(key, value) //    returns true if the value associated with given key equals given value // QueryString.toString //    returns the query string as a string // // Optional parameter to exists, get and equals, can define another query string, but remember that that string wont be cached. // ===================================================================== function QueryString { }

QueryString.init = function(str) { var params = {};

if (QueryString.params != null && !str) { return; } if (!str) { QueryString.params = {}; } var queryString = str || location.search.substring(1);

if (queryString.length == 0) { return; }

if (!str) { QueryString.str = queryString; }

queryString.replace(/\+/, ' ');

var args = queryString.split('&');

for (var i in args) { if (typeof( args[i] ) != 'string') { continue; }   var pair = args[i].split('='); var key = decodeURIComponent(pair[0]), value = key;

if (pair.length == 2) { value = decodeURIComponent(pair[1]); }

params[key] = value; }

if (!str) { QueryString.params = params; }

return params; };

QueryString.get = function(key, str) { if (str) { var val = QueryString.init(str)[key]; return val ? val : null; } else if (QueryString.params == null) { QueryString.init; } return QueryString.params[key] ? QueryString.params[key] : null; };

QueryString.exists = function(key, str) { if (str) { return QueryString.init(str)[key] ? true : false; } else if (QueryString.params == null) { QueryString.init; }

return QueryString.params[key] ? true : false; };

QueryString.equals = function(key, value, str) { if (str) { return QueryString.init(str)[key] == value ? true : false; } else if (QueryString.params == null) { QueryString.init; } return QueryString.params[key] == value ? true : false; };

QueryString.toString = function { if (QueryString.str == null) { QueryString.init; } return QueryString.str ? QueryString.str : null; };

QueryString.create = function(arr) { var resarr = Array; for (var i in arr) { if (typeof arr[i] == 'object') { var v = Array; for (var j in arr[i]) { //alert("1: " + j + " A*A " + arr[i][j]); if(j == 0 || Number(j)) { v[j] = encodeURIComponent(arr[i][j]); resarr.push(encodeURIComponent(i) + '=' + v.join('|')); }     }    } else { //alert("2: " + i + " A*A " + arr[i]); if(i.indexOf("toJSONString") != 0) { resarr.push(encodeURIComponent(i) + '=' + encodeURIComponent(arr[i])); }   }  }

return resarr.join('&'); };

QueryString.params = null; QueryString.str = null;

/* */