// ==UserScript==
// @name HDRT Enhancer Alpha
// @namespace HDRT Alpha
// @include https://REDACTED
// @include https://REDACTED
// @version 1.1.3.0a
// @updateURL http://REDACTED
// @description Enhances HDRT by adding searchlinks, and highlighting RN/HD Queues
// ==/UserScript==
// Last updated - 2012-07-18
// GLOBAL CONSTANTS
const INSTALLED_RELEASE = "HDRT Enhancer: Release version installed successfully!\n\nPlease report any bugs to REDACTED@REDACTED";
const INSTALLED_BETA = "HDRT Enhancer: Beta installed successfully!\n\nPlease report any bugs to REDACTED@REDACTED";
const INSTALLED_ALPHA = "HDRT Enhancer: Alpha installed successfully!\n\nBe VERY careful!";
const DEFAULT_HDRT_TEXT = "Insert your HDRT comment here";
const FAILSAFE = 123;
const ERR = "ERROR";
const COMMENT_NOT_SAVED = "Data Not Saved Yet!";
const COMMENT_SAVED = "Saved!";
const NO_NETID_FOR_USER = "No NetID for this user";
// MacUpdate, NetworkSupport, Outage, Sups, RN CIRT, RUW CIRT, NB Virus, help@RN, help@RUW, RUWireless/RUWired
const RN_NUM_QUEUES = new Array(20, 22, 23, 24, 41, 42, 43, 52, 53, 60);
const HD_RN_NUM_QUEUES = new Array(20, 22, 41, 42, 43, 60); // RN queues that HD CTs can use - double check
const RN_OFC_ADDTL_NUM_QUEUES = new Array(23, 52, 53); // additional queues that RN OFC can use - double check
// Eden - Alumn/PWD/Ques, NetID - Activation/changes, RCI - PWD/QUES, SM - PWD/Ques
const HD_ACCT_NUM_QUEUES = new Array(29, 30, 31, 40, 45, 50, 51, 62, 63); // the eden, RCI, scarletmail, and netid queues
const HD_EOS_NUM_QUEUES = new Array(1, 30, 44, 50, 57); // general, eden pwd, vm, rci pwd, rias
const HD_ADDTL_NUM_QUEUES = new Array(1, 44); // additional HD queues that HD CT can use - double check
const LDAP_INITIAL_MESSAGE = 'Click in this box to retrieve LDAP information for [NETID] Note: If you are not currently logged in, you will receive a password prompt';
// GET URLs
const VARIABLE_TEXT = "VARIABLETEXT" // For linkifying
const HDRT_TICKET_URL = 'https://REDACTED' + VARIABLE_TEXT;
const RN_AUTH_URL = "https://REDACTED" + VARIABLE_TEXT;
const IPS_URL = "https://REDACTED" + VARIABLE_TEXT;
const COFFER_URL = "http://coffer.com/mac_find/?string=" + VARIABLE_TEXT;
const RUMAPS_URL = "http://REDACTED" + VARIABLE_TEXT; // linkify later
// POST URLs
const IEEE_URL = ''; //TODO - add MAC IEEE lookup - needs POST though (display on page?)
const LDAP_URL = "https://REDACTED"; // Does not support GET, needs POST
// Regexp Stuff
const LOGGEDIN_REGEXP = /logged in as (\w+)<\/b><\/font><\/td>/;
const NETID_FROM_USER_PAGE_REGEXP = /id="uid" value="([\w-]+)"/;
const HDRT_COOKIE_REGEXP = /PHPSESSID=\w+/; //gets HDRT cookies - not used anymore. Chrome doesn't like passing cookies and it is unnecessary afaik
// /ticket(?=\D{1,5})(\d{6})/gi;
const HDRT_TICKET_REGEXP_1 = /(?:[\s]{1,5})(\d{6})(?:\b)/gi;
const HDRT_TICKET_REGEXP_2 = /(?:\s[#])(\d{6})/gi; //for number signs, TODO - fix capturing # - have to use numVars=2
const IPV4_ADDRESS_REGEXP_1 = /[\s](\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/g;
const RN_IP_ADDRESS_REGEXP_1 = /(?:[\s])(172\.30\.\d{1,3}\.\d{1,3})/g;
const MAC_ADDRESS_REGEXP_1 = /(?:[\s])([a-z0-9][a-z0-9]:[a-z0-9][a-z0-9]:[a-z0-9][a-z0-9]:[a-z0-9][a-z0-9]:[a-z0-9][a-z0-9]:[a-z0-9][a-z0-9])/gi;
const MAC_ADDRESS_REGEXP_2 = /(?:[\s])([a-z0-9][a-z0-9]-[a-z0-9][a-z0-9]-[a-z0-9][a-z0-9]-[a-z0-9][a-z0-9]-[a-z0-9][a-z0-9]-[a-z0-9][a-z0-9])/gi; //separator character is dash (-) instead of colon (:), TODO - convert this to regular MAC for RN_AUTH
const MAC_ADDRESS_REGEXP_3 = /(?:[\s])([a-z0-9][a-z0-9][a-z0-9][a-z0-9]\.[a-z0-9][a-z0-9][a-z0-9][a-z0-9]\.[a-z0-9][a-z0-9][a-z0-9][a-z0-9])/gi; // Cisco IOS switches, TODO - convert this to regular MAC for RN_AUTH
// make sure it's not a link - [\s,>: -]
// Colors
const FATALERR_COLOR = '#f00';
const ERR_COLOR = '#f31';
const WARN_COLOR = '#ffaa00';
const INFO_COLOR = '#999';
// GLOBAL VARS
var allTables; // Xpath object with all the tables
var netid; // The person logged into HDRT
//TODO - set table nums based on regexp
var commentTableNum; // Which table is the comment table in allTables?
var commentTable, qTable; // The table holding all the comments
var fakeCommentForm; // The fake form to submit comments
var userTableNum; // Which table is the HDRT user info in? - i.e. name, email, phone
var box; // The textarea box which we're typing the comment in
var statusText, failSafeText, ownerField;
var debugDiv, ldapDiv, regexpDiv, infoDiv;
var tableOffsetNum = 0; // to account for extra elements on the page
// Debugging / Enabled Features variables
var version; // 0.5 - production, 1 - private release, 2 - RC, 3 - Beta, 4 - Alpha, 5 - Pre-Alpha
const GM_HDRT_VERSION = "HDRT_Version";
const GM_IS_RN_SUP = "HDRT_RN_SUP";
const GM_IS_HD_SUP = "HDRT_HD_SUP";
var firstRun;
var myFailSafe = 123; // If this matches FAILSAFE above, comments will be posted
var displayCommentBox = true;
var DBG = true;
var dbgp = true; // Enabled debugging for preview pane
var doScriptStatus = false; // Shows which script options are enabled. may break ticket/netid/name lookup
var doLDAP = false; // Do LDAP
var doRegexp = false; // Do RegExp, this breaks ticket/netid/name lookup
var doRegexpTest = false; // add Regexp pane
var doNetidAllQueues = true; // Retrieve netid for all queeus
var alertOnDebug = false; // don't use debugDiv and alert on all errors/warning/info if DBG true
var doCommentFakeForm = true; // make fake form and submit it
var doSmartHighlight; // smart highlight HDRT queues - works well - should be enabled
var doLDAPall; // do LDAP on all queues - should this be the default?
// Access controls
var isRNSup = true; // for RN SUP, RN FT, Abuse -> affects RTIR links
var isRNOfc = true; // RN OFC or higher, TODO - change queue highlighting for this later
var isHDSup = false; // for HD AS only -> affects HD AS colors
var workHDshifts = false; // to highlight HD queues (set to false to disabled HD queue highlighting)
// HD consultants don't really need queue highlight
window.addEventListener('load',
function(){
if (DBG) addDebugPane(); // start logging debug info immediately
version = GM_getValue(GM_HDRT_VERSION, null);
isRNSup = GM_getValue(GM_IS_RN_SUP);
isHDSup = GM_getValue(GM_IS_HD_SUP);
// ask if RN or HD Sup - backward compatible with old versions of the script
if (!GM_getValue(GM_IS_RN_SUP)) { // if RN SUP not set, prompt for it
isRNSup = confirm("Click 'OK' if you are a RN Supervisor. (i.e. do you fill out RN EOS and have RTIR access?).\n\nClick 'Cancel' otherwise.");
GM_setValue(GM_IS_RN_SUP, (isRNSup?'ISRNSUP':'ISNOTRNSUP'));
} else
isRNSup = (isRNSup == 'ISRNSUP') ? true : false; // set to T or F for later code
if (!GM_getValue(GM_IS_HD_SUP)) {
isHDSup = confirm("Click 'OK' if you are a HD Supervisor. (i.e. do you fill out HD EOS?).\n\nClick 'Cancel' otherwise.");
GM_setValue(GM_IS_HD_SUP, (isHDSup?'ISHDSUP':'ISNOTHDSUP'));
} else
isHDSup = (isHDSup == 'ISHDSUP') ? true : false; // set to T or F for later code
dbgInfol('you are: ' + (isRNSup?'[+RN,':'[-RN,') + (isHDSup?'-HD] sup':'-HD] sup'));
firstRun = !version;
// Adjust below for non-custom / custom versions of the script
processVersion(version, firstRun);
// worksHDshifts = true; // enable for release/beta versions
// Enable or disable certain features depending on what version the user want to use
function processVersion(version, firstRun) {
if ( firstRun ) { // If this variable is not set
userResp = prompt("HDRT Enhancer: Would you like to use the release version of this script?\n\n* Leave 1 below to use the release version. (RECOMMENDED)\n\n* Type 3 to use the beta. (Adds ticket/RNIP/MAC regexp. Some bugs)\n\n* Type 4 to use the alpha version. (WARNING: Use the alpha version at your own risk.)\n\n* Note: You can change versions easily on Firefox. It is much harder to do on Chrome so if you are using Chrome, it is highly recommended to use the release version.\n\n", "1");
if (userResp) {
setVersion(userResp, firstRun);
} else if (!userResp) { // if no user response, default to release
setVersion(1, firstRun);
}
} else { // NOT first run
firstRun = false;
if (version==1 || version==3 || version==4) setVersion(version, firstRun);
else setVersion(1, firstRun); // if the variable is anything besides the normal values, stick to the release just in case
}
} // end process version
// Set script version
function setVersion(v, firstRun) {
GM_setValue(GM_HDRT_VERSION, v);
if (v == 1) { // Set script to release version
myFailSafe = 123;
displayCommentBox = false;
DBG = false;
dbgp = false;
doScriptStatus = false;
doLDAP = true;
doRegexp = false;
doRegexpTest = false;
doNetidAllQueues = true;
alertOnDebug = false;
doCommentFakeForm = true;
doSmartHighlight = true;
doLDAPall = false;
if (firstRun) alert(INSTALLED_RELEASE);
} else if (v == 3) { // Set script to beta / use only somewhat tested features
myFailSafe = 123;
displayCommentBox = false;
DBG = false;
dbgp = false;
doScriptStatus = false;
doLDAP = true;
doRegexp = true;
doRegexpTest = false;
doNetidAllQueues = true;
alertOnDebug = false;
doCommentFakeForm = true;
doSmartHighlight = true;
doLDAPall = true;
if (firstRun) alert(INSTALLED_BETA);
} else if (v == 4) { // Set script to alpha / enable almost everything, used for development
myFailSafe = 123;
displayCommentBox = false;
DBG = true;
dbgp = true;
doScriptStatus = false;
doLDAP = true;
doRegexp = true;
doRegexpTest = false;
doNetidAllQueues = true;
alertOnDebug = false;
doSmartHighlight = true;
doCommentFakeForm = true;
doLDAPall = true;
if (firstRun) alert(INSTALLED_ALPHA);
}
} // end set version
// Initialization stuff
allTables = getAllTables(); // Start out by getting all the tables for easy manipulation
netid = getPersonLoggedInToHDRT();
if (doRegexpTest) addRegexpPane();
if (doScriptStatus) addScriptStatus(); // Add some text to the top of the page to verify that the script is on and what options are enabled
// TODO - Create @exclude rules instead for user profile page (will this effect XMLHttpRequest?)
// TODO - FIX - Why does the script not run after submitting comment with the script??
if ( location.pathname.indexOf("REDACTED") != -1 && getHDRTMenu() != "User" ) { // HDRT Ticket Page (not HDRT User Profile though)
//if not on comment page and not on basics page (where you change the subject and queue), do stuff
var m = getHDRTMenu();
//alertd('here');
if (m != "Comment" && m != "Basics" && m != "Special_Fields" && !(location.pathname.match("REDACTED")) ) {
modifyTicketPage();
//if (DBG) showTables();
} else
addDebugPaneToPage();
} else if (location.pathname == "/REDACTED" || location.pathname == "/") { // HDRT Home Page
modifyHomePage();
} else if (DBG) {// else add debug pane??
addDebugPaneToPage();
}
// Add a notification that the script is running and which features are enabled
// This breaks the countdown and the lookup ticket/netid/user forms
// TODO - move this to the debug pane
function addScriptStatus() {
var oldstr = "logged in as " + netid + "";
var newstr = " HDRT Script Live"
var scriptOptions = "";
if (DBG) scriptOptions = "; CommentBox = " + displayCommentBox + ", Failsafe = " + ((myFailSafe != FAILSAFE) ? "Enabled" : "Disabled");
document.body.innerHTML = document.body.innerHTML.replace( LOGGEDIN_REGEXP, oldstr + newstr + scriptOptions );
}
// Enhance HDRT Ticket page by adding RN Links and Comment Box
function modifyTicketPage() {
// See if the ticket was just modified (an extra green table created at the top)
// We will adjust tables to account for this.
// How? - See if a green table starts at character 1490 of the page. Normal pages have it at 1552
// Problems - Do NOT allow script to add stuff above this character
// Modified means:
// 1) "A resolution email was previously sent to the user. No additional email is being sent to the user."
// 2) Ticket resolved a first time
// 3) Special fields updated
var b = document.body.innerHTML;
var s = 'table bgcolor="#97CF97"';
if (b.indexOf(s) == 1490) {
tableOffsetNum += 2; // that message at the top adds 2 tables. account for this in offset var
dbgInfol('adjusted table offset to ' + tableOffsetNum);
}
var theQ = getQueue();
var qNum = queueToNum(theQ); // TODO - fix error here
commentTable = findCommentTable();
//doRegexp = false;
if (doRegexp) { // Do regex first to avoid messing up the modified HTML
linkifyRegexp('HDRT_TICKET');
if ( matchesQueue(qNum, RN_NUM_QUEUES) ) linkifyRegexp('RN_IP_ADDRESS');
//linkifyRegexp('IPV4_ADDRESS');
if ( matchesQueue(qNum, RN_NUM_QUEUES) ) linkifyRegexp('MAC_ADDRESS');
//linkifyRegexp('MAC_ADDRESS_2');
//linkifyRegexp('MAC_ADDRESS_3');
}
//fixHTML(); // fix html/js errors that are already in the page
allTables = getAllTables();
commentTableNum = 1;
netidTableNum = 21 + tableOffsetNum; // RUW CIRT, RN CIRT, help@RUW, help@RN, Virus, Outage, RUW ESC
// Add useful 'Search on RN' links to Special Fields
// Relevant Queues - Mac Update, Network Support, SWAT, any more?
// Working Queues - Mac Update, Network Support, RN CIRT, RUW CIRT, help@RN, help@RUW
// TODO - test queues
// TODO - change to use new qmethods
if ( matchesQueue(qNum, new Array(20, 22, 24, 41, 42, 60)) ) { //macupdate, netsupport, rncirt, ruwcirt, ruw
addRNLinksToSF(theQ);
if (qNum == 22 || qNum == 24) netidTableNum = 23 + tableOffsetNum;
} else if ( theQ == "RUWireless/RUWired - Escalation" ) { // Linkify MAC addresses to Coffer in RUW ESC queue
originalFieldCell = allTables.snapshotItem(15 + tableOffsetNum).rows[4].cells[1];
originalFieldCell.innerHTML = linkify(COFFER_URL, originalFieldCell.innerHTML);
}
// Add queue numbers next to queue name on page for debugging purposes
var qField = allTables.snapshotItem(11 + tableOffsetNum).rows[1].cells[4];
if (DBG && queueToNum(theQ) != null) qField.innerHTML += "(" + queueToNum(theQ) + ")";
var netidField;
if ((allTables.snapshotItem(netidTableNum-2).rows[0].textContent.indexOf('User') != -1))
dbgInfol('Correct netidField: ' + (allTables.snapshotItem(netidTableNum-2).rows[0].textContent.indexOf('User') != -1) );
else
dbgWarnl('incorrect netidField');
// Error checking - make sure putting netid in "user" box
// Case 1 - If it's not, try correcting it; otherwise abort on any further netidField errors
if ( allTables.snapshotItem(netidTableNum - 2).rows[0].textContent.indexOf('User') == -1 ) {
dbgWarnl("Netid table is wrong. Attempting correction.");
netidTableNum = 24 + tableOffsetNum; // For sups queue when appointment has been set
// Abort if netid tables are null
if (!allTables.snapshotItem(netidTableNum)) {
dbgFatall("[abort] Correction Failed: netidTable is null.");
return;
} else if (!allTables.snapshotItem(netidTableNum).rows[1]) { // double check row as well
dbgFatall("[abort] Correction Failed: Row of netid table null.");
} else { // correction worked. netidField good
//dbgInfol('correcting to 24. content - ' + allTables.snapshotItem(netidTableNum).textContent);
dbgInfol("Correction succeeded. Continuing.");
netidField = allTables.snapshotItem(netidTableNum).rows[1].cells[1];
}
} else { // everything works normally. no corrections needed. do some err checking and continue to netid retrieval
if (!allTables.snapshotItem(netidTableNum).rows[1]) {
dbgFatall("Row of netid table null. Aborting.");
netidField = null; // setNetid will abort in this case
} else
netidField = allTables.snapshotItem(netidTableNum).rows[1].cells[1];
}
// Add netid next to user's name
// Works - Mac Update, Network Support, Sups, RN CIRT, RUW CIRT, Virus, help@RN, help@RUW, RUW, RUW ESC
if (matchesQueue(qNum, RN_NUM_QUEUES) || qNum == -1) // -1 is RUW ESC
setNetID(netidField, RN_AUTH_URL);
else if ( theQ.toLowerCase().indexOf('eden') != -1 || theQ.toLowerCase().indexOf('rci') != -1 || theQ.toLowerCase().indexOf('scarletmail') != -1 || theQ.toLowerCase().indexOf('netid') != -1 )
setNetID(netidField, LDAP_URL);
else if (doNetidAllQueues) //retrieve netid for all queues; do NOT link to anything, TODO - more testing, then remove debug
setNetID(netidField, VARIABLE_TEXT);
// Run the comment box code last before adding elements to the page
if (displayCommentBox || doCommentFakeForm) runCommentCode();
// ldapDiv is added by setNetId
// Add all extra divs to the page
if (doRegexpTest && regexpDiv != null)
document.body.appendChild(regexpDiv);
else if (doRegexpTest && regexpDiv == null)
dbgErrl('regexpDiv is null');
if ( (displayCommentBox && commentTable != null) || (doCommentFakeForm && fakeCommentForm != null) ) {
//dbgInfol(commentTable.innerHTML);
var newCell = (commentTable.insertRow(-1)).insertCell(0);
newCell.appendChild(fakeCommentForm);
if (infoDiv)
newCell.appendChild(infoDiv);
else
dbgErrl('infodiv null');
newCell.style.border="3px solid blue";
newCell.style.backgroundColor="#dddddd";
newCell.style.width = "60%";
newCell.style.padding="20px";
} else if (commentTable == null || fakeCommentForm == null) {
if (commentTable == null)
dbgErrl('commentTable null');
if (fakeCommentForm == null)
dbgErrl('fake form null');
}
addDebugPaneToPage(); // actually add it to the document body
// End of main procedure
// ========== Queue-Based Adding RN Links to Special Fields ========
// Works for MacUpdate, Network Support, RN CIRT, RUW CIRT, RUW
function addRNLinksToSF(theQ) { // Put this in a broader function
var rowNum;
var myQNum = queueToNum(theQ);
switch(myQNum)
{
case RN_NUM_QUEUES[1]: { // Works for Network Support
if (doRegexp) return; // don't re-linkify fields
rowNum = 8;
numRows = 2;
// Linkify IP and MAC address in Networks Support Queue
for (var i = rowNum; i < rowNum + numRows; i++) {
var originalFieldCell = allTables.snapshotItem(15).rows[i].cells[1];
originalFieldCell.innerHTML = linkify(RN_AUTH_URL, originalFieldCell.innerHTML);
}
break;
}
case RN_NUM_QUEUES[0]: { // Works for Mac Update
if (doRegexp) return; // don't re-linkify fields
rowNum = 4;
numRows = 3;
// Linkify IP and MAC address in MAC Update/Dereg Queue
for (var i = rowNum; i < rowNum + numRows; i++) {
var originalFieldCell = allTables.snapshotItem(15).rows[i].cells[1];
originalFieldCell.innerHTML = linkify(RN_AUTH_URL, originalFieldCell.innerHTML);
}
break;
}
case RN_NUM_QUEUES[4]: {
// Linkify RTIR Incident Ticket
originalFieldCell = allTables.snapshotItem(15).rows[1].cells[1];
originalFieldCell.innerHTML = linkify(IPS_URL, originalFieldCell.innerHTML);
if (doRegexp) return; // don't re-linkify fields
// Linkify MAC address in RN CIRT Queue
var originalFieldCell = allTables.snapshotItem(15).rows[3].cells[1];
originalFieldCell.innerHTML = linkify(RN_AUTH_URL, originalFieldCell.innerHTML);
break;
}
case RN_NUM_QUEUES[5]: {
// Linkify RTIR Incident Ticket
originalFieldCell = allTables.snapshotItem(15).rows[1].cells[1];
originalFieldCell.innerHTML = linkify(IPS_URL, originalFieldCell.innerHTML);
if (doRegexp) return; // don't re-linkify fields
// Linkify MAC address in RUW CIRT Queue
var originalFieldCell = allTables.snapshotItem(15).rows[3].cells[1];
originalFieldCell.innerHTML = linkify(COFFER_URL, originalFieldCell.innerHTML);
break;
}
//TODO - finish
case RN_NUM_QUEUES[9]: {
var originalFieldCell = allTables.snapshotItem(15).rows[4].cells[1];
originalFieldCell.innerHTML = linkify(COFFER_URL, originalFieldCell.innerHTML);
break;
}
default: {
break;
}
}
}
// Linkify text - pass URL with place where you want data/text inserted marked as VARIABLE_TEXT
function linkify(theURL, data) {
if (theURL == IPS_URL && isRNSup == false)
return null;
if (theURL == VARIABLE_TEXT || theURL == LDAP_URL) //return just the netid if NO URL or LDAP_URL specified
// for LDAP, we add an extra box so no tag is necessary
return data;
return "" + data + "";
}
// Return true if qNum matches an element of the qArray
// Return false otherwise
// TODO - test
function matchesQueue(qNum, qArray) {
for(var i = 0; i < qArray.length; i++) {
if (qNum == qArray[i]) return true;
}
return false;
}
// Fix the broken javscript by cleaning the HTML
// TODO - Fix the netid/name/ticket lookup code
function fixHTML() {
replaceBody('', '');
dbgWarnl('Debug fixHTML!!');
function replaceBody(find, replace) {
theBody = document.body.innerHTML;
theBody = theBody.replace(find, replace);
document.body.innerHTML = theBody;
}
// From http://www.javascriptkit.com/javatutors/loadjavascriptcss.shtml
function loadjscssfile(filename, filetype){
if (filetype=="js"){ //if filename is a external JavaScript file
var fileref=document.createElement('script')
fileref.setAttribute("type","text/javascript")
fileref.setAttribute("src", filename)
}
else if (filetype=="css"){ //if filename is an external CSS file
var fileref=document.createElement("link")
fileref.setAttribute("rel", "stylesheet")
fileref.setAttribute("type", "text/css")
fileref.setAttribute("href", filename)
}
if (typeof fileref!="undefined")
document.getElementsByTagName("head")[0].appendChild(fileref)
}
}
// ========== Comment box SECTION =========
// find comment table and create comment box
function runCommentCode() {
commentTable = findCommentTable();
//alertd(commentTable.innerHTML);
//alertd(tableOffsetNum);
if (!doCommentFakeForm) { // create manual ajax request and submit
createCommentBox(commentTable);
} else if (doCommentFakeForm) { // create fake HTML form and submit
createFakeForm(commentTable);
//dbgInfol('fakeform done');
//alertd(getFullName(netidTableNum)); //REDACTED
//dbgInfol('for → [ ' + getFullName(netidTableNum) + ' ]'); // to confirm which person the ticket is under
}
}
// Find the table that contains all the HDRT comments
// It is the second table cell with [valign=middle align=left bgcolor="#003399"]
// Basically this means that it is the second table with the blue heading. The first one is "dates"
// After it gets this cell which says: "History", it goes up the DOM tree to get the comment table
// TODO - add a check to verify that it says "History"
// DEPRECATED - It is the 8th table with "width=100% and cellpadding=2"
// DEPRECATED - It is the THIRD table with "width="100%" border=0 cellpadding=3"
function findCommentTable() {
// '//table[@border='0' and @width='100%' and @cellpadding='3']'
// TODO - redo this thing using allTables
var el;
el = document.evaluate('//td[@valign="middle" and @align="left" and @bgcolor="#003399"]', document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
//alertd(el.snapshotItem(commentTableNum).innerHTML);
// TODO - test if tableOffsetNum is working and supposed to be here - probably not, it's already modified above
return el.snapshotItem(commentTableNum).parentNode.parentNode.parentNode.parentNode.parentNode.parentNode;
}
// Create comment box
// Insert comment box into table and make it look prominent
function createCommentBox(table) {
// Create and initialize the comment box
box = document.createElement('textarea');
box.defaultValue = DEFAULT_HDRT_TEXT;
box.name = "body";
box.id = "theCommentBox"; // Add unique id just in case
box.setAttribute('cols', 72); // SUPER IMPORTANT for multiline comments - possibly not true
box.setAttribute('rows', 15);
box.setAttribute('wrap', 'hard'); // SUPER IMPORTANT for multiline comments - possibly not true
statusText = document.createElement('p');
statusText.innerHTML = COMMENT_NOT_SAVED;
failSafeText = document.createElement('p');
failSafeText.innerHTML = (myFailSafe == FAILSAFE) ? "Application Live" : "Application NOT Live";
// Create the owner box - not really necessary yet
ownerField = document.createElement('input');
ownerField.name = "owner";
ownerField.value = getOwner();
ownerField.size = 12;
//optionField = document.createElement('option');
//optionField.value = netid;
//optionField.innerHTML = netid;
//ownerField.appendChild(optionField);
// Create Status box - TODO - fix - does NOT work
/*var statusBox = "" */
var statusBox = document.createElement('select');
var statusNew = document.createElement('option');
statusNew.value = "N";
statusNew.text = "New";
//statusNew.name = "NewName";
statusNew.value = "New";
statusNew.innerHTML = "New";
statusBox.add(statusNew, null);
//statusBox.appendChild(statusNew);
//statusBox.name = "status"
//statusBox.multiple = "false";
//statusBox.size = 4;
//statusBox.type = "select-one";
statusBox.id = "ticketStatus";
//statusBox.selectedIndex = 0;*/
// TODO - Insert other elements for ticket properties HERE
// Create the comment submit button
var submitCommentBtn = document.createElement('input');
submitCommentBtn.type = "submit";
submitCommentBtn.name = "Submit button";
submitCommentBtn.value = "Submit Comment";
// Create button to preview comment
var previewBtn = document.createElement('input');
previewBtn.type = "submit";
previewBtn.name = "Preview button";
previewBtn.value = "Preview Comment";
//box.style.height = "50%";
//box.style.width = "50%";
// Insert row and cell in comment table
//alert('inserting');
var newRow = table.insertRow(-1);
var newCell = newRow.insertCell(0);
// TESTING statusBox - remove below
// var newCell2 = table.inserRow(1).insertCell(1);
// Add elements to the page
owner = newCell.appendChild(ownerField); // Owner input box
//newcell.appendChild(statusBox); // HDRT Ticket Status Chooser - TODO - fix, doesn't work
//newcell2.innerHTML += statusBox;
newCell.appendChild(failSafeText); // Display whether application is live
newCell.appendChild(box);
newCell.appendChild(statusText) // Saved Status
newCell.appendChild(submitCommentBtn);
newCell.appendChild(previewBtn);
// Change CSS of Row and Cell
newCell.style.border="3px solid blue";
newCell.style.backgroundColor="#dddddd";
//theEl.style.width = newRow.style.width = "100%";
//theEl.style.height = newRow.style.height = "50%";
newCell.style.padding="20px";
// Change CSS of the comment box
//box.style.height = "300px";
//box.style.width = "80%";
// === EVENT LISTENERS SECTION ===
// Clear textarea text when first clicked
box.addEventListener('click',
function(e){
if (box.value.indexOf(DEFAULT_HDRT_TEXT) != -1) { // If default text is present
box.value = "";
}
}, false);
// Change window title to "&[TICKET]" when box edited and focus is lost
// Save data to Greasemonkey browser data upon same event
box.addEventListener('change',
function(e){
if (box.value.indexOf(DEFAULT_HDRT_TEXT) == -1) {
GM_setValue("HDRT_Text1", box.value);
// TODO - show saved value if DBG is on
statusText.innerHTML = COMMENT_SAVED + " [at " + (new Date()).toLocaleTimeString() + " on " + (new Date()).toLocaleDateString() + "] Data ends with: [" + box.value.substring(box.value.length - 20, box.value.length) + "]";
document.title = "&[" + getTicket() + "]";
}
}, false);
// Go to custom address when clicked - aka send comment to HDRT
submitCommentBtn.addEventListener('click', function(e){ submitComment(box.value, myFailSafe);}, false);
// Append comment to table to see how it would look
previewBtn.addEventListener('click', function(e) { previewComment(box.value); }, false);
} // END createCommentBox()
// Create fake comment form
// Intercept submit
// Add more failsafes
// Validate owner
// Save comment in HDRT var
function createFakeForm(table) {
fakeCommentForm = document.createElement('form');
fakeCommentForm.id = 'fakeCommentForm';
fakeCommentForm.setAttribute('method', 'post');
fakeCommentForm.setAttribute('action','/REDACTED' + getTicket());
//dbgInfol('tkt '+getTicket());
//alertd((getStatus()=="Resolved")?'selected':' ');
if (myFailSafe != FAILSAFE) // abort if failsafes don't match
return;
fakeCommentForm.innerHTML = '
Update Type
Status
Owner
' /*
Worked
*/ + '' + /*minutes
*/ '
Subject
Additional Comments
If Resolving Ticket, Send Preset Email Message To User
';
dbgInfol('comments: ' + document.getElementsByName('body')[0]);
// create a div for ticket info (useful for help@s)
infoDiv = document.createElement('div');
infoDiv.style.border = "2px solid black";
infoDiv.style.backgroundColor = "#ccf";
infoDiv.style.padding = "5px";
infoDiv.style.maxWidth = "80%";
infoDiv.style.fontFamily = "Courier New";
infoDiv.style.fontSize = "110%";
infoDiv.innerHTML += 'Email: ' + getEmailAddress() + ' | Name: ' + getFullName(netidTableNum) + ' Subject: ' + getSubject() + ' | Ticket: ' + getTicket();
// selected - (getStatus()=="New")?'selected':''
//alertd(fakeCommentForm.innerHTML);
//fakeCommentForm.addEventListener('
}
// Submit specified comment on HDRT Ticket.
// Pass failSafe parameter as 123 to actually submit
function submitComment(commentText, failSafe) {
if (!commentText) {
alert('Error: commentText is null');
return;
}
//alert('submitting comment: ' + commentText + failSafe );
//alert('final result = ' + decodeURIComponent(newText));
var status = getStatus();
var owner = getOwner();
var ticket = getTicket();
commentText = encodeURIComponent(commentText); // URL Encode text - Super Important
// TODO - verify owner is valid
if (ownerField.value != owner) {
if ( confirm("Would you like to change the owner from \"" + owner + "\" => \"" + ownerField.value + "\"?") ) {
owner = ownerField.value;
} else { ownerField.value = owner; }
}
//alert(status + " " + owner + " " + ticket);
// What does 'provision' arg mean? - Looks like it can be blank or 'OnComment'
// Where does HDRT get values for 'email_user'? - HDRT config probably, put a line in the netid AJAX request to also get the value for 'email_user'; set global var; default should be 'no'? or should we alert the user and ask them?
var argNames = new Array("id", "provision", "status", "owner", "time_worked", "subject", "form_submitted", "body", "email_user");
var argValues = new Array(ticket, "OnComment", status, owner, "", "", "comment", commentText, 0);
if (argNames.length != argValues.length) {
alert('Error: arg names and values do not have the same length');
return;
}
// Build URL with all the parameters
var thePath = "https://REDACTED";
var theParams = "";
for (var i = 0; i < argNames.length; i++) {
theParams += argNames[i] + "=" + argValues[i] + "&";
}
theParams = theParams.substring(0, theParams.length - 1); // Remove last & char
//alert(theParams);
// Submits comment - checks failsafe code, displays URL, checks if test ticket, warns before submitting
if (failSafe == FAILSAFE) {
alert("The POST params will be: " + theParams);
// TODO - Remove this check once more testing is done
if (ticket != 523811) {
if ( !confirm("WARNING: You are NOT commenting on Test Ticket 523811.\n\nYou are commenting on ticket: " + ticket + ".\n\nAre you sure you want to proceed?") ) {
alert('Comment aborted');
return;
}
}
if ( confirm("WARNING: Are you sure you want to submit this comment? This is the FINAL WARNING.\n\n Press CANCEL to NOT submit\n\nThe POST params will be: \n" + decodeURIComponent(theParams)) ) {
// Submit AJAX POST request and then reloads page
// Should we use display comment with JS similar to previewComment to avoid reload? - can wait till later
GM_xmlhttpRequest({
method: "POST",
url: thePath,
data: theParams,
headers: {
"Content-Type": "application/x-www-form-urlencoded" //necessary for this to work
},
onload: function(response) {
window.location = window.location; //reload page
},
onerror: function(response) {
alert("Error submitting comment:\n\n" + response.statusText);
}
});
} else {
alert('Comment Aborted');
}
}
// Does NOT actually submit comment
else if (failSafe != FAILSAFE) {
alert('Not submitting comment.\n\nURL is:\n' + decodeURIComponent(theParams));
}
}
// PREVIEW COMMENT - Append comment to comment table to see how it would look
function previewComment(text) {
var otext = text; //original text
var prevRow = commentTable.insertRow( commentTable.rows.length - 1 );
var previewCell = prevRow.insertCell(0);
const LINEBREAK = " "; //should this be or \n ????
// Cell style
previewCell.style.backgroundColor = "#aaedaa";
previewCell.style.colspan = 4;
previewCell.style.vAlign = "top";
previewCell.innerHTML = "--- COMMENT PREVIEW --- ";
function add(aName, aVal) { previewCell.innerHTML += aName + " = " + aVal + " "; }
function addl(t) { previewCell.innerHTML += t + " "; }
var lastColNum = 72;
// Comment Pre-processing
// Find closest space or linebreak to 72nd column, but skip if not found
// Enables wrapping of multiline comments
// Some stupid javascript quirk requires me to test for '\n' matches to make sure they exist
var numLineBreaks = (/\n/.test(text)) ? text.match(/(\n)/).length : 0;
var numLines = Math.floor( (text.length - numLineBreaks) / lastColNum ) + numLineBreaks;
// TODO - figure out how to deal with newlines in blocks of text
/* danglingCharsNum - necessary for proper formatting especially for longer comments
* Was extremely annoying to figure out this bug and implement a solution
* Since our line lengths can actually be shorter than lastColNum
causing chars to 'overflow' to the next line, numLines undercalculate
the number of lines, so we need to keep track of the characters on the
last line of text and if this goes over lastColNum, we need to increment
numLines by 1, subtract lastColNum from danglingCharsNum, and keep doing this
for the length of the comment
*/
var danglingCharsNum = text.length - (numLines - 1) * lastColNum;
add("total text length", text.length);
add("starting lines", numLines);
addl("");
var startIndex = 0, currLine = 0;
dbgAddl(startIndex);
var endIndex = lastColNum - 1;
while ( currLine < numLines ) {
//add("currLine", currLine);
if (dbgp) addl("DOING line(" + currLine + ") --> unadj EOL char [" + text.charAt(endIndex) + "], Danglers = " + danglingCharsNum);
if ( text.charAt(endIndex) == LINEBREAK ) {
if (dbgp) addl("*last char is NEWLINE");
startIndex += lastColNum;
endIndex = startIndex + lastColNum;
currLine++;
continue;
}
// backtrack to space (or line break?) and we didn't get back to the start of the line
while ( text.charAt(endIndex) != " " && endIndex >= startIndex ) {
endIndex--;
}
danglingCharsNum += startIndex + lastColNum - endIndex; // Track danglingCharsNum
// After loop - if space char found
if (text.charAt(endIndex) == " ") {
if (dbgp) addl("from " + startIndex + " to " + endIndex + ", charat = " + text.charAt(endIndex));
text = text.substring(0, endIndex) + LINEBREAK + text.substring(endIndex+1, text.length);
addl("added linebreak");
// Shift string depending on where space char was located
startIndex = endIndex + 1;
endIndex = startIndex + lastColNum;
} else { // If we couldn't find a space in this line, skip it
if (dbgp) addl("SKIPPING line; from " + startIndex + " to " + endIndex);
startIndex += lastColNum;
endIndex = startIndex + lastColNum;
}
// Keep danglingCharsNum under lastColNum
/*if ( danglingCharsNum >= lastColNum ) {
if (dbgp) addl("*adding new line due to DANGLERS");
numLines++;
danglingCharsNum -= lastColNum;
}*/
currLine++; // Move on to the next line if < numLines
}
addl("");
//previewCell.innerHTML += '
' + otext + '
'; // Insertion of comment preview - cheat
previewCell.innerHTML += text + "
"; // Insertion of comment preview - my code
if (dbgp) add("numLineBreaks", numLineBreaks);
if (dbgp) add("numLines", numLines);
if (dbgp) addl("Cheating with extra <pre> tag DISABLED");
}
// Set NetID - need to access it from HDRT Profile page
// Appends the netid linked to RN Auth to the argument which should be an HTML element
// Uses GM XMLHttpRequest to retrieve HDRT Profile Page
// Retrieving NetID does not work well due to the asynchronous properties of AJAX
function setNetID(netidField, link) {
if (!netidField) {
dbgFatall('netidField is null. Aborting.');
return;
}
// TODO - only take location.href before first ampersand
if (getHDRTMenu()) { // if the menu parameter is specified
profileURL = location.href.substring(0, location.href.indexOf('&')) + "&REDACTED";
} else
profileURL = location.href + "&REDACTED";
//dbgInfol('start netid ajax URL');
GM_xmlhttpRequest({
method: "GET",
url: profileURL,
onload: function(response) {
//dbgInfol('In NetID AJAX');
var theNetid = NETID_FROM_USER_PAGE_REGEXP.exec(response.responseText);
if ( theNetid == null) { //if no netid e.g. 527468
netidField.innerHTML += " (" + NO_NETID_FOR_USER +")";
dbgInfol('[abort setNetid] none');
return;
} else
theNetid = theNetid[1];
netidField.innerHTML += " (" + linkify(link, theNetid) + ")"; //linkify if applicable
// Decide whether to do LDAP or not
//dbgInfol('doing LDAP - ' + (link==LDAP_URL));
if (doLDAPall) {
linkifyLDAPURL(netidField, theNetid, link);
} else if (link == LDAP_URL) {
if (doLDAP) {
linkifyLDAPURL(netidField, theNetid, link);
} else {
dbgWarnl("LDAP Search is off. Aborting.");
return;
}
}
},
onerror: function(response) {
alert("Error connecting to webpage to retrieve User Profile:\n\n" + response.statusText +
"\nThis is most likely a problem with the HDRT Server");
}
});
}
// Creates link that when clicked, sends POST Data to services/ldap
// Use AJAX POST and insert responseText in frame
function linkifyLDAPURL(netidField, theNetid, link) {
//netidField.appendChild(theForm);
ldapDiv = document.createElement('div');
ldapDiv.style.padding = "10px";
ldapDiv.style.border = "2px solid green";
ldapDiv.innerHTML = LDAP_INITIAL_MESSAGE.replace('[NETID]', theNetid);
//alertd(findUserTable().innerHTML);
var userTable = findUserTable().parentNode;
userTable.appendChild(ldapDiv);
ldapDiv.addEventListener('click', retrieveLDAP, false);
// Use cross site AJAX to retrieve LDAP info
function retrieveLDAP() {
ldapDiv.innerHTML = "Loading info....";
GM_xmlhttpRequest({
method: "POST",
url: LDAP_URL,
data: "user="+theNetid,
headers: {
"Content-Type": "application/x-www-form-urlencoded" //necessary for this to work
},
onload: function(r) {
var ldapContent = r.responseText.substring( r.responseText.indexOf('body')+6, r.responseText.lastIndexOf('/body')-245);
//if (DBG) alert(ldapContent);
// Make clicking on results load with the correct domain name
ldapContent = ldapContent.replace(/REDACTED/g, LDAP_URL.replace('REDACTED', 'query2'));
// Make clicking on results open in a new tab
ldapContent = ldapContent.replace(/REDACTED/g, 'target="_blank" REDACTED');
ldapDiv.innerHTML = ldapContent;
ldapDiv.removeEventListener('click', retrieveLDAP, false); //so that clicking again doesn't reload stuff
},
onerror: function(response) {
dbgErrl("Comment submit w/ AJAX failed:\n\n" + response.statusText);
}
});
}
}
// Linkify using RegExp
function linkifyRegexp(data) {
var doHdrtApprox = true; // should we use the approximate hdrt ticket regexp or do the specific ones
// for reference
// HDRT_TICKET_REGEXP_1 = /(?:[\s]{1,5})(\d{6})(?:\b)/gi;
// HDRT_TICKET_REGEXP_2 = /(?:\s[#])(\d{6})/gi;
// After some testing, it looks like the HDRT regexp breaks the name/netid/ticket search
// TODO - fix this! fixHTML breaks it as well
const HDRT_TICKET_REGEXP_3 = /ticket(?:[\s]{1,5})(\d{6})(?:\b)/gi;
const HDRT_TICKET_REGEXP_4 = /(?:[\s]{1,5})(\d{6})(?:\b)/gi;
switch (data) {
case 'HDRT_TICKET': {
if (doHdrtApprox) {
processLink(HDRT_TICKET_REGEXP_1, HDRT_TICKET_URL, false);
processLink(HDRT_TICKET_REGEXP_2, HDRT_TICKET_URL, false); //this one works poorly
} else {
processLink(HDRT_TICKET_REGEXP_3, HDRT_TICKET_URL, false);
//processLink(HDRT_TICKET_REGEXP_4, HDRT_TICKET_URL, false)
}
break;
}
case 'RN_IP_ADDRESS': { processLink(RN_IP_ADDRESS_REGEXP_1, RN_AUTH_URL, false); break; }
case 'IPV4_ADDRESS': { processLink(IPV4_ADDRESS_REGEXP_1, RN_AUTH_URL, false); break; }
case 'MAC_ADDRESS': { processLink(MAC_ADDRESS_REGEXP_1, RN_AUTH_URL, false); break; }
case 'MAC_ADDRESS_2': { processLink(MAC_ADDRESS_REGEXP_2, RN_AUTH_URL, true); break; }
case 'MAC_ADDRESS_3': { processLink(MAC_ADDRESS_REGEXP_3, RN_AUTH_URL, true); break; }
default: { dbgErrl('Could not linkify Regexp: [' + data + '] correctly to URL: [' + theURL + ']'); }
}
// Do regexp replace in document body
// replaceData asks whether we want to replace the matched data with 're-formatted data' for the tool we're using e.g. a MAC of xxxx.xxxx.xxxx -> xx:xx:xx:xx:xx:xx. This is only done for the linked text and not for the displayed text
function processLink(regexp, theURL, replaceData) {
var comments = findCommentTable().parentNode.parentNode.childNodes[3].innerHTML;
var specialFields = findSpecialFieldsTable().innerHTML;
//dbgInfol('matches for ' + data + ' - ' + theBody.match(regexp));
if (!replaceData) { // if we do a simple regexp replace
comments = comments.replace(regexp, ' $1');
specialFields = specialFields.replace(regexp, ' $1');
}
else { // debug this - may not work
var newdataArr = {c: regexp.exec(comments), s: regexp.exec(specialFields)};
//var newdata = regexp.exec(comments);
var i;
for (newdata in newdataArr) {
if (newdata == null) return; // do nothing when no matches exist
dbgAddl('original - ' + newdata);
//process data - change mac2 to proper format for RN_AUTH
if (theURL == RN_AUTH_URL && regexp == MAC_ADDRESS_REGEXP_2 ) { //change - to :
for (i=0; i normal)
else if (theURL == RN_AUTH_URL && regexp == MAC_ADDRESS_REGEXP_3 ) { //change . to : and insert two extra ones
for (i=0; i$1');
dbgAddl('Warning: replaceData set to true but not used.\n\n\nregexp = ' + regexp.toString() + '\n\nURL = ' + theURL.replace(VARIABLE_TEXT, '') + '\n\nnewdata = ' + newdata);
}
// do final replace for each instance
for (i=0; i < newdata.length; i++) {
dbgAddl('newdata - ', newdata[i]);
theBody = theBody.replace(regexp, '$1');
}
// do regexp replace
theBody = theBody.replace(regexp.replace('/g', '/'), '$1');
}
}
/* DELETE THIS STUFF BELOW
else if (numVars == 2)
theBody = theBody.replace(regexp, '$1$2');
*/
findCommentTable().parentNode.parentNode.childNodes[3].innerHTML = comments;
findSpecialFieldsTable().innerHTML = specialFields;
}
}
} // End modifyTicketPage()
// ========== HDRT PARSE INFO SECTION =========
// Gets the HDRT Ticket Number
function getTicket() {
return allTables.snapshotItem(11 + tableOffsetNum).rows[1].cells[0].firstChild.innerHTML;
}
// Gets the person's name under who the ticket is created
// Pass in tnum with table offset included - same as normal netidTableNum for NetID Linkify
// Use regexp to not get the netid with the fullname
function getFullName(tnum) {
return allTables.snapshotItem(tnum).rows[1].cells[1].firstChild.firstChild.innerHTML;//REDACTED
//allTables.snapshotItem(tnum).rows[1].cells[1].innerHTML
// REDACTED
}
// Get user's email address
function getEmailAddress() {
return (findUserTable()).rows[1].cells[0].childNodes[1].firstChild.firstChild.firstChild.childNodes[1].rows[1].cells[2].firstChild.firstChild.innerHTML;
}
// Get HDRT Ticket Status
function getStatus() {
return allTables.snapshotItem(11 + tableOffsetNum).rows[1].cells[1].firstChild.innerHTML;
}
// Gets current HDRT Ticket Owner
function getOwner() {
return allTables.snapshotItem(13 + tableOffsetNum).rows[1].cells[1].childNodes[1].innerHTML;
}
// Get Main HDRT Ticket Subject
function getSubject() {
return commentTable.firstChild.firstChild.firstChild.rows[1].firstChild.childNodes[1].firstChild.firstChild.firstChild.childNodes[1].rows[0].cells[1].firstChild.innerHTML.replace(/\w+ - /, ''); //remove netid and dash
}
// Get Main HDRT Queue - Works
function getQueue() {
if ( !allTables.snapshotItem(11 + tableOffsetNum) ) {
dbgFatall('Could not get queue - table tbody off');
return ERR;
} else if ( !allTables.snapshotItem(11 + tableOffsetNum).rows[1] ) {
alertd('Could not get queue - table rows off');
return ERR;
} else if ( !allTables.snapshotItem(11 + tableOffsetNum).rows[1].cells[4] ) {
dbgFatall('Could not get queue - table cells off');
return ERR;
} else
return allTables.snapshotItem(11 + tableOffsetNum).rows[1].cells[4].firstChild.firstChild.innerHTML;
}
// Gets the HDRT Requester
function getRequester() {
return allTables.snapshotItem(13 + tableOffsetNum).rows[2].cells[1].childNodes[0].nodeValue;
}
// Get the person logged in to HDRT
function getPersonLoggedInToHDRT() {
return document.body.innerHTML.match( LOGGEDIN_REGEXP )[1];
}
// ========== DEBUGGING SECTION =========
// Adds a fixed div at the top right with debug info
function addDebugPane() {
// Add elements to HTML
debugDiv = document.createElement('div');
//Some CSS stuff
debugDiv.style.position = "fixed";
debugDiv.style.top = "10%";
debugDiv.style.right = "10px";
debugDiv.style.padding = "10px";
debugDiv.style.border = "2px solid red";
debugDiv.style.backgroundColor = "white";
debugDiv.style.minWidth = "20%";
debugDiv.style.maxHeight = "40%";
debugDiv.style.maxWidth = "40%";
debugDiv.style.overflow = "auto"; // why does
debugDiv.style.zIndex = 100; // always on top
debugDiv.innerHTML = "Debug Info ";
var radioTables = new Array();
for (i=0; i<2; i++) {
radioTables[i] = document.createElement('input');
radioTables[i].setAttribute('name', 'showTablesRadio');
radioTables[i].setAttribute('type', 'radio');
radioTables[i].setAttribute('id', 'showTables'+i);
radioTables[i].setAttribute('value', 'onoff'+i);
}
radioTables[1].setAttribute('checked', 'true');
dbgAdd("showTables – on");
debugDiv.appendChild(radioTables[0]);
dbgAdd("off");
debugDiv.appendChild(radioTables[1]);
dbgAdd('');
//showTables(true);
// Add events - DOESN'T WORK - FIX
/* radioTables[0].addEventListener('click', turnOnTables, false);
radioTables[1].addEventListener('click', turnOffTables, false);*/
//document.getElementsByName('showTablesRadio')[0].addEventListener('click', turnOnTables, false);
//document.getElementById('showTables0').addEventListener('click', showTables, false);
//document.getElementById('showTables1').addEventListener('click', showTables, false);
function turnOnTables() { showTables(true); dbgInfol('turn on tables'); }
function turnOffTables() { showTables(false); dbgInfol('turn on tables'); }
}
// Add info to debug div
function dbgAdd(htmlText) {
if (DBG && debugDiv != null)
debugDiv.innerHTML += htmlText;
else if (DBG) {
var tmpDiv = document.createElement('div');
tmpDiv.innerHTML = htmlText;
alert('DBG info:\n\t' + tmpDiv.textContent + ' \n\n\n(Note: debugDiv is null)');
}
}
function dbgAddl(htmlText) { dbgAdd(htmlText + " "); }
function dbgFatal(htmlText) { dbgAdd('Fatal Err: ' + htmlText);}
function dbgFatall(htmlText) { dbgAddl('Fatal Err: ' + htmlText);}
function dbgErr(htmlText) { dbgAdd('Err: ' + htmlText); }
function dbgErrl(htmlText) { dbgAddl('Err: ' + htmlText); }
function dbgWarn(htmlText) { dbgAdd('Warning: ' + htmlText); }
function dbgWarnl(htmlText) { dbgAddl('Warning: ' + htmlText); }
function dbgInfo(htmlText) { dbgAdd('Info: ' + htmlText); }
function dbgInfol(htmlText) { dbgAddl('Info: ' + htmlText); }
function alertd(text) { if (DBG) alert(text); } // alert if DBG for when debugDiv doesn't work
// Actually adds the debug div to the document body - do this after running all the modification code
function addDebugPaneToPage() {
if (DBG && debugDiv != null) // if everything's good, add DEBUG div
document.body.appendChild(debugDiv);
else if (DBG && debugDiv != null)
dbgFatall('debugDiv is null');
}
function addRegexpPane() {
// Add elements to HTML
regexpDiv = document.createElement('div');
//Some CSS stuff
regexpDiv.style.position = "fixed";
regexpDiv.style.top = "2%";
regexpDiv.style.right = "30%";
regexpDiv.style.padding = "3px";
regexpDiv.style.border = "2px solid red";
regexpDiv.style.backgroundColor = "white";
regexpDiv.style.minWidth = "40%";
regexpDiv.style.textAlign = 'center';
regexpDiv.innerHTML = "Regexp Tester (broken) ";
var regexpInput = document.createElement('input');
regexpInput.setAttribute('type', 'text');
regexpInput.setAttribute('size', 60);
regexpInput.setAttribute('value', HDRT_TICKET_REGEXP_1);
var regexpSubmit = document.createElement('input');
regexpSubmit.setAttribute('type', 'button');
regexpSubmit.setAttribute('value', 'Search');
regexpDiv.appendChild(regexpInput);
regexpDiv.appendChild(regexpSubmit);
regexpDiv.appendChild(document.createElement('br'));
//regexpDiv.innerHTML += ' ';
regexpSubmit.addEventListener('click', doRegexp, false);
function doRegexp() {
//document.body.innerHTML.match(regexpInput.value)
if (!regexpDiv) dbgErrl('regexpDiv is null');
var r = regexpInput.value.substring(1, regexpInput.value.length - 3);
var re = new RegExp(r, "gi");
dbgInfol(r);
var b = document.body.innerHTML;
var x = b.match(re);
dbgAddl(x);
//(x) ? regexpDiv.appendChild(x) : regexpDiv.appendChild('null');
regexpDiv.appendChild(x);
//regexpDiv.appendChild(document.createElement('br'));
}
}
// TODO - create a dbg span that you can update
// pass in spanID and then your content
// TODO - Have wrapper set/get functions for variables so that debug gets autoupdated?
// Enhance HDRT Home Page - just highlights RN Queues for now
function modifyHomePage() {
if (location.search.indexOf('allqueues=show') != -1 && !doSmartHighlight) {
dbgFatall('[Abort] All queue highlighting not supported'); //don't do anything if all queues are showing
return null;
}
var RNColor = "#ffa500"; // light orange
var HDEOSColor = "#fff01f"; // yellow
var HDAcctColor = "#5aaac0"; // light blue
if (doSmartHighlight) qTable = findQueueTable().childNodes[1].childNodes[2];;
highlightQueues(RN_NUM_QUEUES, RNColor);
//isHDSup = true;
if (!isHDSup && workHDshifts) { // works HD shifts, not HD Sup
highlightQueues(HD_ACCT_NUM_QUEUES, HDAcctColor);
highlightQueues(HD_ADDTL_NUM_QUEUES, HDAcctColor); // should we move this somewhere
} else if (isHDSup) { // is HD Sup
highlightQueues(HD_EOS_NUM_QUEUES, HDEOSColor);
// Some queues don't show up for me so I will regexp highlight them separetely
// Maybe I will add fake numbers in HD_EOS_NUM_QUEUES later
regexpQueueReplace('0 - After Hours - general', HDEOSColor);
regexpQueueReplace('NB -HR Rep Password Changes', HDEOSColor);
}
addDebugPaneToPage();
}
// Find queue table - first dark blue table
function findQueueTable() {
return document.evaluate('//table[@bgcolor="#003399"]', document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null).snapshotItem(1);
}
// Find user table on ticket page with user info like name, email, phone, etc.
function findUserTable() {
return document.evaluate('//table[@width="100%" and @cellspacing="0" and @cellpadding="0" and @border="0" and @bgcolor="#97CF97"]', document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null).snapshotItem(1);
}
// Get the table with all the info and comments for regexp without breaking the "tickets" table or messing up regexp in other places
function findSpecialFieldsTable() {
return document.evaluate('//table[@bgcolor="#9900CC"]', document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null).snapshotItem(0);
}
// Change background color of RN Queue to specified color
// Use regex for this
function highlightQueues(queueArray, color) {
if (doSmartHighlight) {
for (var i = 0; i < queueArray.length; i++) {
regexpQueueReplace(numToQueue(queueArray[i]), color);
}
} else { // dumb highlight
allTables = getAllTables(); // Get all tables again (not sure why this is necessary), but it doesn't work otherwise
var queueTableNum = 16;
// Adjust queue table index if appointment box is on HDRT home page (Temporary Fix)
if (allTables.snapshotItem(8).rows[0].cells[1].innerHTML.indexOf("Appointments") != -1)
queueTableNum = 19;
qTable = allTables.snapshotItem(queueTableNum);
for (var i = 0; i < queueArray.length; i++) {
//dbgInfol(qTable.rows[queueArray[i]].cells[0].innerHTML);
//dbgInfol(numToQueue(queueArray[i]))
if (qTable.rows[queueArray[i]].cells[0].innerHTML.indexOf(numToQueue(queueArray[i])) != -1)
qTable.rows[queueArray[i]].cells[0].style.backgroundColor = color;
}
}
}
// Replace an individual queue's HTML using regexp
// Links in HTML to queues are NOT URI encoded - they only replace spaces s far as I can tell
// @ and / are not replaced
function regexpQueueReplace(qName, color) {
var encQName = qName.replace(/\s/g, '%20');
qTable.innerHTML = qTable.innerHTML.replace('