How to use clearKeyEvents method in Appium Android Driver

Best JavaScript code snippet using appium-android-driver

Generic.js

Source:Generic.js Github

copy

Full Screen

1var _formName = "form1";2var _currentBusyDiv = "";3var _keyEvents = new Array();4var isdrag=false;5var x = 0,y = 0;6var dobj;7var cobj;8var bobj;9var bx = 0, by = 0;10var cx = 0, cy = 0;11var _popEvents = new Array();12var popupControls = new Array();13var _pagePath;14//XML FIX15var BrowserIE = (window.navigator.userAgent.indexOf("MSIE") > 0); //Must be declared here;16if (document.implementation.hasFeature("XPath", "3.0") && !BrowserIE)17{18 if (typeof XMLDocument == "undefined") { XMLDocument = Document; }19 XMLDocument.prototype.selectNodes = function(cXPathString, xNode)20 {21 if (!xNode) { xNode = this; }22 var oNSResolver = this.createNSResolver(this.documentElement)23 var aItems = this.evaluate(cXPathString, xNode, oNSResolver, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null)24 var aResult = [];25 for (var i = 0; i < aItems.snapshotLength; i++) { aResult[i] = aItems.snapshotItem(i); }26 return aResult;27 }28 XMLDocument.prototype.selectSingleNode = function(cXPathString, xNode)29 {30 if (!xNode) { xNode = this; }31 var xItems = this.selectNodes(cXPathString, xNode);32 if (xItems.length > 0) { return xItems[0]; }33 else { return null; }34 }35 Element.prototype.selectNodes = function(cXPathString)36 {37 if (this.ownerDocument.selectNodes) { return this.ownerDocument.selectNodes(cXPathString, this); }38 else { throw "For XML Elements Only"; }39 }40 Element.prototype.selectSingleNode = function(cXPathString)41 {42 if (this.ownerDocument.selectSingleNode) { return this.ownerDocument.selectSingleNode(cXPathString, this); }43 else { throw "For XML Elements Only"; }44 }45 Element.prototype.__defineGetter__("text",46 function() { return (this.textContent); });47 Element.prototype.__defineSetter__("text",48 function(txt) { this.textContent = txt; });49}50//multi Nodes for xpath 51//old name executeXpathSelectNodes;52function $mn(xmlDocument, xp)53{54 var ResultNodes = xmlDocument.selectNodes(xp);55 return ResultNodes;56}57//Single Node for xpath58//old name executeXpathSingleNode59function $sn(xmlDocument, xp)60{61 var ResultNode = xmlDocument.selectSingleNode(xp);62 return ResultNode;63}64//END XML FIX 65function ActivateGlobalKeys(DivId)66{67 if (DivId != "document")68 {69 $addEvent($id(DivId),"keydown",ExecuteKeyPressEvent);70 }71 else72 {73 $addEvent(document,"keydown",ExecuteKeyPressEvent);74 }75 ClearKeyEvents(); 76}77function AddKeyEvents(Key,Event,Cntrl,DivId)78{79 var cntrl = false;80 81 if (Cntrl != null)82 {83 cntrl = Cntrl;84 }85 86 if (DivId != null)87 {88 ActivateGlobalKeys(DivId)89 }90 _keyEvents[Key] = Event + "|" + cntrl;91}92function ClearKeyEvents()93{94 _keyEvents = new Array();95}96function Key_size(Keys){97 var size = 0;98 for (var i in Keys) {99 if (_keyEvents[i] != null) 100 size ++;101 }102 return size;103}104function GetKeyPressed(e)105{106 if (!e) 107 {108 if (window.event) 109 {110 //Internet Explorer111 e = window.event;112 } 113 else 114 {115 return;116 }117 }118 119 if (typeof( e.keyCode ) == 'number') 120 {121 //DOM122 e = e.keyCode;123 } 124 else if( typeof( e.which ) == 'number' ) 125 {126 //NS 4 compatible127 e = e.which;128 } 129 else if( typeof( e.charCode ) == 'number' ) 130 {131 //also NS 6+, Mozilla 0.9+132 e = e.charCode;133 } 134 else 135 {136 //total failure, we have no way of obtaining the key code137 return;138 }139 return e;140}141function CheckCtrlKey(e)142{143 var ctrlKeyPressed = false;144 if (!e) 145 {146 if (window.event) 147 {148 //Internet Explorer149 e = window.event;150 } 151 else 152 {153 return;154 }155 }156 157 try158 {159 ctrlKeyPressed = e.ctrlKey;160 }161 catch(ex)162 {}163 return ctrlKeyPressed;164}165function ExecuteKeyPressEvent(e) 166{167 var validKey = false;168 if (parseInt(Key_size(_keyEvents)) != 0)169 {170 var keypressed = GetKeyPressed(e);171 var ctrlpressed = CheckCtrlKey(e);172 if (_keyEvents[keypressed]) 173 {174 try175 {176 if (_keyEvents[keypressed].split("|")[1] == "true")177 {178 if (ctrlpressed)179 {180 validKey = true; 181 }182 }183 else184 {185 validKey = true;186 }187 if (validKey)188 {189 eval(_keyEvents[keypressed].split("|")[0]);190 return false;191 }192 }193 catch(ex)194 {}195 }196 }197}198function ExecuteKeyPressEventPopUp(e)199{200 if (parseInt(Key_size(_popEvents)) != 0)201 {202 var keypressed = GetKeyPressed(e) 203 if (_popEvents[keypressed]) 204 {205 try206 {207 eval(_popEvents[keypressed]);208 }209 catch(ex)210 {}211 return false;212 }213 }214}215//document.getElementByID216function $id(id) 217{218 return document.getElementById(id);219}220function $tn(id)221{222 return document.getElementsByName(id);223}224 225// evaluateXPath226// $xpath227function $xpath(aNode, aExpr) 228{229 var xpe = new XPathEvaluator();230 var nsResolver = xpe.createNSResolver(aNode.ownerDocument == null ? aNode.documentElement : aNode.ownerDocument.documentElement);231 var result = aNode.evaluate(aExpr, aNode, null, 0, null);232 var found = [];233 var res;234 while (res = result.iterateNext())235 {236 found.push(res);237 }238 return found;239}240function $SingleNodeMoz(aNode,sXPath)241{242 var xpe = new XPathEvaluator();243 var oResult = xpe.evaluate(sXPath, aNode, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);244 //weird.. oResult is always object..245 if(oResult !=null)246 {247 if(oResult.singleNodeValue != null)248 {249 return oResult;250 }251 else252 {253 return null;254 }255 }256 else257 {258 return null;259 }260 /*if (oResult != null) 261 {262 return oResult;263 } 264 else 265 {266 return null;267 } */ 268}269//create Xml document270//createXMLObject is the old name271function $xml(xmlToLoad)272{273 var xmldoc;274 if (document.implementation && document.implementation.createDocument) 275 {276 var oXML = xmlToLoad;277 var parser = new DOMParser();278 var xmldoc = parser.parseFromString(oXML, "text/xml");279 } 280 else if (window.ActiveXObject) 281 {282 xmldoc = new ActiveXObject("Microsoft.XMLDOM");283 if(xmlToLoad != "")284 {285 xmldoc.loadXML(xmlToLoad);286 } 287 }288 return xmldoc;289}290//get Attribute for xml node 291//pass the xml node <node surname="">292//AttrToGet to get , ex surname293function $xa(xmlNode,AttrToGet)294{295 if(BrowserIE)296 {297 if(xmlNode !=null)298 {299 return xmlNode.getAttribute(AttrToGet);300 }301 else302 {303 return null;304 }305 }306 else307 {308 //return xmlNode.singleNodeValue.attributes[AttrToGet].nodeValue309 if(xmlNode == null)310 {311 return null;312 }313 if(xmlNode.toString() == "[object XPathResult]")314 {315 316 if(xmlNode.singleNodeValue.nodeValue == null)317 {318 return null;319 }320 else321 {322 return xmlNode.singleNodeValue.attributes[AttrToGet].nodeValue;323 }324 }325 else326 {327 if(xmlNode.attributes[AttrToGet] == null)328 {329 return null;330 }331 else332 {333 return xmlNode.attributes[AttrToGet].nodeValue;334 }335 }336 }337}338//get Attribute for xml node 339//pass the xml node <node surname="">340//AttrToGet to get , ex surname341function $xaparent(xmlNode,AttrToGet)342{343 if(BrowserIE)344 {345 if(xmlNode !=null)346 {347 return xmlNode.parentNode.getAttribute(AttrToGet);348 }349 else350 {351 return null;352 }353 }354 else355 {356 return xmlNode.singleNodeValue.parentNode.attributes[AttrToGet].nodeValue357 }358}359// old name getTextFromXmlNodeSingle360//returns text from single node 361function $xt(XmlNode)362{363 var ret = "";364 if(BrowserIE)365 {366 ret = XmlNode.childNodes[0].nodeValue;367 }368 else369 {370 ret = XmlNode.singleNodeValue.textContent ; //XmlNode[0].childNodes[0].nodeValue;371 }372 return ret;373} 374// old name replace375// replaces text in a string376function $rep(string, text, by) 377{378 // Replaces text with by in string379 var strLength = string.length;380 var txtLength = text.length;381 382 if ((strLength == 0) || (txtLength == 0)) 383 return string;384 var i = string.indexOf(text);385 386 if ((!i) && (text != string.substring(0, txtLength))) 387 return string;388 389 if (i == -1) 390 return string;391 var newstr = string.substring(0, i) + by;392 if (i + txtLength < strLength)393 newstr += $rep(string.substring(i + txtLength, strLength), text, by);394 return newstr;395}396function $togglePopUp(div, frame, viewState, widthType)397{398 var state = false;399 var IfrRef = $id(frame);400 401 if (IfrRef == null) 402 {403 return;404 }405 IfrRef.style.display = "none"; 406 407 div.style.zIndex = 1001;408 409 if (viewState == "") 410 {411 if (div.style.display == "none") 412 {413 state = true;414 } 415 else 416 {417 state = false;418 } 419 }420 else421 {422 if (viewState == "none")423 {424 state = false; 425 }426 else427 {428 if (div.style.display == "none") 429 {430 state = true;431 } 432 else 433 {434 state = false;435 } 436 }437 }438 if(state)439 {440 div.style.display = "block";441 if (widthType)442 {443 IfrRef.style.width = div.style.width;444 IfrRef.style.height = div.style.height;445 }446 else447 {448 IfrRef.style.width = div.clientWidth;449 IfrRef.style.height = div.clientHeight;450 }451 IfrRef.style.top = div.offsetTop;452 IfrRef.style.left = div.offsetLeft;453 IfrRef.style.zIndex = div.style.zIndex - 1;454 IfrRef.style.display = "block";455 }456 else457 {458 div.style.display = "none";459 IfrRef.style.display = "none";460 IfrRef.style.width = "0px";461 IfrRef.style.height = "0px";462 IfrRef.style.top = 0;463 IfrRef.style.left = 0;464 }465}466//popupdiv for view467function doViewPopup(headingText, contentText, viewID)468{469// busyDivTag();470// var HeadingText = headingText;471// var ContentText = contentText;472 var viewText = $id(viewID);473 var viewHeight = viewText.childNodes[0].childNodes[0].offsetHeight;474 var viewWidth = viewText.childNodes[0].childNodes[0].offsetWidth;475 476 if ((viewHeight == 0) && (viewWidth == 0))477 {478 viewText.style.display = "";479 viewHeight = viewText.childNodes[0].childNodes[0].offsetHeight;480 viewWidth = viewText.childNodes[0].childNodes[0].offsetWidth;481 viewText.style.display = "none";482 }483 484 if (viewWidth < 500)485 {486 var maintbl = ReplaceID(viewID, "part_","maintbl_");487 ($id(maintbl)).width = "500px"; 488 viewText.style.display = "";489 viewWidth = viewText.childNodes[0].childNodes[0].offsetWidth;490 viewText.style.width = "500px";491 viewText.style.display = "none";492 } 493// 494// var screenL = window.screen.availWidth - viewWidth;495// var screenH = window.screen.availHeight - viewHeight;496// var top = (screenH/3) + parseInt(returnScrollDimensions(0)); 497// var left = (screenL/2) + parseInt(returnScrollDimensions(1));498// var newDiv = false;499// var st = "top:" + (parseInt(top) - 40) + "px;z-index:9018;position:absolute;left:" + (parseInt(left) - 50) + "px;width:" + (viewWidth) + "px;height:" + (viewHeight) + "px";500// 501// viewText.style.cssText = st;502// 503// var divAlert = "";504// var divExists = $id("containerView");505// if(divExists == null)506// {507// divAlert = document.createElement("DIV");508// divAlert.id = "containerView";509// divAlert.className="dragme";510// divAlert.attachEvent("onmousedown",selectmouse);511// divAlert.attachEvent("onmouseup",new Function("isdrag=false"));512// newDiv= true;513// }514// else515// {516// newDiv = false;517// divAlert = test;518// }519// 520// var stDiv = "top:" + (parseInt(top) - 80) + "px;z-index:9018;position:absolute;left:" + (parseInt(left) - 60) + "px;width:" + (viewWidth+20) + "px;height:" + (viewHeight+20) + "px";521// var stIframe = "top:" + (parseInt(top) - 70) + "px;z-index:9017;position:absolute;left:" + (parseInt(left) - 50) + "px;width:" + (viewWidth+5) + "px;height:" + (viewHeight+30) + "px;frameborder=0;";522// 523// divAlert.style.cssText = "position:absolute;display:none;z-index:9019;" + stDiv;524// divAlert.innerHTML += '<table id="tblContainerView" cellpadding="0" cellspacing="0" border="0"><tr><td><div id="poptl" class="poptl"></div></td><td><div id="poptc" class="poptc"><div style="font-family:Arial;padding-top:5px;color:White;font-weight:bold;">' + HeadingText + '</div></div></td><td><div id="poptr" class="poptr"></div></td></tr><tr><td><div id="popcl" class="popcl"></div></td><td align="center"><div id="popcc" class="popcc">' + ContentText + '</div></td><td><div id="popcr" class="popcr"></div></td></tr><tr><td><div id="popbl" class="popbl"></div></td><td><div id="popbc" class="popbc"></div></td><td><div id="popbr" class="popbr"></div></td></tr></table>';525// 526// if(newDiv == true)527// { 528// document.body.appendChild(divAlert);529// }530// 531// //add iframe532// var ifr = $id("iframepopup");533// var table = $id("tblContainerView");534// var stIf = "top:" + (parseInt(top) - 80) + "px;z-index:9017;position:absolute;left:" + (parseInt(left) - 90) + "px;width:" + (viewWidth+20) + "px;height:" + (viewHeight+20) + "px";535// 536// $DivSetVisible(true,table,ifr,stIframe);537// ifr.frameBorder="no";538// ifr.style.backgroundColor = "green";539// ifr.className="dragmeIfr"540// var thediv = "";541// thediv = document.getElementById("containerView");542// thediv.style.display = "block";543// 544// document.getElementById("poptc").style.width=viewWidth+'px';545// document.getElementById("popcc").style.width=viewWidth+'px';546// document.getElementById("popbc").style.width=viewWidth+'px';547// document.getElementById("popcl").style.height=viewHeight+'px';548// document.getElementById("popcc").style.height=viewHeight+'px';549// document.getElementById("popcr").style.height=viewHeight+'px';550 551 $showPopup(headingText, contentText, viewID, viewHeight, viewWidth, "", "closeSubForm()", "", "", "", "", "", "", "", "", "");552 showSelectSpecific(viewID);553}554function doViewHidePopup()555{556 HideDisableDiv();557 var thediv = document.getElementById("containerView");558 559 if (thediv != null && thediv != "")560 {561 thediv.style.display = "none";562 thediv.parentNode.removeChild(thediv);563 }564 565}566// Removes leading whitespaces567function $LTrim( value ) 568{569 var re = /\s*((\S+\s*)*)/;570 return value.replace(re, "$1");571}572// Removes ending whitespaces573function $RTrim( value ) 574{575 var re = /((\s*\S+)*)\s*/;576 return value.replace(re, "$1");577}578// Removes leading and ending whitespaces579function $Trim( value ) 580{581 return $LTrim($RTrim(value));582}583//popup for alert in Iframe584function doPopupIframe(headingText, contentText, twidth , theight, btnValue1, fn1, btnValue2, fn2, btnValue3, fn3,zIndexSpec,zID, extraPath, helpID, popupImage)585{586// if (!extraPath)587// {588// extraPath = "";589// } 590// //jvz : zIndexSpec is overloaded for popups on each other591// if(zIndexSpec=="undefined")592// {593// busyDivTag();594// }595// else596// {597// busyDivTag(zIndexSpec,zID);598// }599// var HeadingText = headingText;600// var ContentText = contentText;601// var divAlert = document.createElement("DIV");602// var inpValue = "";603// var strValue = "";604// var screenL = document.documentElement.offsetWidth - twidth ;605// var screenH = document.documentElement.offsetHeight - theight;606//// if (infoText.length > 0)607//// {608//// screenH = screenH - 110;609//// }610//// else611//// {612// screenH = screenH - 150;613//// } 614// var top = (screenH/3) + parseInt(returnScrollDimensions(0)); 615// var left = (screenL/2) + parseInt(returnScrollDimensions(1));616// 617// 618//// if (btnValue1 != "")619//// {620//// inpValue += '<input type="button" class="button" id="' + btnValue1 + '" value="' + btnValue1 + '" onclick=' + fn1 + '>&nbsp;';621//// }622//// 623//// if (btnValue2 != "")624//// {625//// inpValue += '<input type="button" class="button" id="' + btnValue2 + '" value="' + btnValue2 + '" onclick=' + fn2 + '>&nbsp;';626//// }627//// 628//// if (btnValue3 != "")629//// {630//// inpValue += '<input type="button" class="button" id="' + btnValue3 + '" value="' + btnValue3 + '" onclick=' + fn3 + '>';631//// }632//// 633//// strValue = inpValue;634// 635 var buttonvalues = btnValue1 + "☺" + fn1 ;636 if (btnValue2.length > 0)637 { 638 buttonvalues += "☺" + btnValue2 + "☺" + fn2 ;639 } 640 if (btnValue3.length > 0)641 {642 buttonvalues += "☺" + btnValue3 + "☺" + fn3 ;643 }644 645// var stDiv = "top:" + parseInt(top - 5) + "px;left:" + parseInt(left -5) + "px;width:" + parseInt(twidth + 10) + "px;height:" + parseInt(theight + 10) + "px;"646// 647// divAlert.style.cssText = "position:absolute;display:none;z-index:10020;" + stDiv;648// //divAlert.innerHTML += '<table id="tblContainer" cellpadding="0" cellspacing="0"><tr><td><div id="poptlA" class="poptl"></div></td><td><div id="poptcA" class="poptc"><div valign="middle" align="left" class="smllabelboldwhite" style="font-family:Arial;padding-top:15px;color:White;font-weight:bold;">' + HeadingText + '</div></div></td><td><div id="poptrA" class="poptr"></div></td></tr><tr><td><div id="popclA" class="popcl"></div></td><td align="center"><div id="popccA" class="popcc"><table cellspacing="0" cellpadding="0" style="font-family:Arial;padding-top:15px;font-size:12px;"><tr><td>' + ContentText + '</td></tr><tr><td align="right">' + strValue + '</td></tr></table></div></td><td><div id="popcrA" class="popcr"></div></td></tr><tr><td><div id="popblA" class="popbl"></div></td><td><div id="popbcA" class="popbc"></div></td><td><div id="popbrA" class="popbr"></div></td></tr></table>';649// divAlert.innerHTML += generatePopupHTML('tblContainer', HeadingText, '', ContentText, buttonvalues, theight, twidth, '', '', "","", extraPath);650// divAlert.className="dragme";651// divAlert.onmousedown=selectmouse;652// divAlert.onmouseup=new Function("isdrag=false"); 653// divAlert.id = "container";654// 655// document.body.appendChild(divAlert);656// 657// //add iframe658// //var ifr = $id("iframepopup");659// var ifr = document.createElement("IFRAME");660// ifr.id = "iframepopups"661// ifr.frameBorder = "0";662// ifr.className="dragmeIfr";663// var table = $id("tblContainer");664// //var st = "width:" + twidth + "px; height:" + theight + "px;";665// var st = "top:" + parseInt(top) + "px;z-index:10019;position:absolute;left:" + parseInt(left) + "px;width:" + (twidth) + "px;height:" + (theight) + "px";666// 667// divAlert.parentElement.appendChild(ifr);668// 669// $DivSetVisible(true,table,ifr,st);670// 671// var thediv = document.getElementById("container");672// thediv.style.display = "block";673// 674//// document.getElementById("poptcA").style.width=twidth+'px';675//// document.getElementById("popccA").style.width=twidth+'px';676//// document.getElementById("popbcA").style.width=twidth+'px';677//// document.getElementById("popclA").style.height=theight+'px';678//// document.getElementById("popccA").style.height=theight+'px';679//// document.getElementById("popcrA").style.height=theight+'px';680if (!popupImage)681{682 popupImage = "";683}684if (!helpID)685{686 helpID = "";687}688 $showPopup(headingText, contentText, "", theight, twidth, "", "doHidePopup()", buttonvalues, zIndexSpec, zID, extraPath, "", helpID, "", "",popupImage)689}690//folowing two functions are used to make the popups dragable691function movemouse(e)692{693 var obj = null;694 var i = true;695 var eventclientX = event.clientX;696 var eventclientY = event.clientY; 697 if (isdrag)698 {699 //checks if the window has content ie. which type of popup?700 if(dobj != null)701 {702 dobj.style.left = parseInt(tx) + parseInt(eventclientX) - parseInt(x);703 dobj.style.top = parseInt(ty) + parseInt(eventclientY) - parseInt(y);704 obj = dobj;705 }706 else if(bobj != null)707 {708 bobj.style.left = parseInt(tx) + parseInt(eventclientX) - parseInt(x);709 bobj.style.top = parseInt(ty) + parseInt(eventclientY) - parseInt(y);710 obj = bobj;711 }712 713 if (obj != null)714 { 715 while(i==true)716 {717 if(obj.className!="dragmeIfr")718 {719 if (obj.nextSibling != null)720 {721 obj = obj.nextSibling;722 }723 else724 {725 return false;726 }727 }728 else729 {730 i = false;731 }732 }733 if (obj != null)734 {735 obj.style.left = parseInt(tx) + parseInt(eventclientX) - parseInt(x) +12;736 obj.style.top = parseInt(ty) + parseInt(eventclientY) - parseInt(y) +22;737 }738 if (cobj != null)739 { 740 if (isNaN(cx)) cx = 0;741 if (isNaN(cy)) cy = 0;742 743 cobj.style.left = parseInt(cx) + parseInt(eventclientX) - parseInt(x);744 cobj.style.top = parseInt(cy) + parseInt(eventclientY) - parseInt(y);745 746 }747 return false;748 }749 }750 751}752function selectmouse(e) 753{754 cobj = popupControls[popupControls.length-1];755 var fobj = event.srcElement; 756 var topelement = "BODY";757 var aobj = event.srcElement;758 759 if ((fobj != null) && (aobj != null))760 {761 while (fobj.tagName != topelement && fobj.className!="dragme")762 {763 fobj = fobj.parentElement;764 }765 while(aobj.tagName != topelement && aobj.className!="dragmain")766 {767 aobj=aobj.parentElement;768 } 769 if (fobj.className=="dragme")770 {771 aobj=null;772 bobj=null;773 isdrag = true;774 dobj = fobj;775 tx = parseInt(dobj.style.left+0);776 ty = parseInt(dobj.style.top+0);777 x = event.clientX;778 y = event.clientY;779 if (cobj)780 {781 cx = parseInt(cobj.style.left);782 cy = parseInt(cobj.style.top);783 }784 document.onmousemove=movemouse;785 return false;786 }787 if (aobj.className == "dragmain")788 {789 fobj = null;790 dobj = null;791 bobj = aobj;792 isdrag = true;793 tx = parseInt(bobj.style.left+0);794 ty = parseInt(bobj.style.top+0);795 x = event.clientX;796 y = event.clientY;797 if (cobj)798 {799 cx = parseInt(cobj.style.left);800 cy = parseInt(cobj.style.top);801 }802 document.onmousemove=movemouse;803 return false; 804 }805 }806}807//popup for alert808function doPopup(headingText, contentText, twidth , theight, btnValue1, fn1, btnValue2, fn2, btnValue3, fn3,zIndexSpec,zID, extraPath, helpID, popupImage)809{810// //jvz : zIndexSpec is overloaded for popups on each other811// if(zIndexSpec=="undefined")812// {813// busyDivTag();814// }815// else816// {817// busyDivTag(zIndexSpec,zID);818// }819// var HeadingText = headingText;820// var ContentText = contentText;821// var divAlert ;//= document.createElement("DIV");822// var inpValue = "";823// var strValue = "";824// var screenL = window.screen.availWidth - twidth ;825// var screenH = window.screen.availHeight - theight;826// // if (infoText.length > 0)827//// {828//// screenH = screenH - 110;829//// }830//// else831//// {832// screenH = screenH - 150;833//// } 834// var top = (screenH/3) + parseInt(returnScrollDimensions(0)); 835// var left = (screenL/2) + parseInt(returnScrollDimensions(1));836// 837// 838//// if (btnValue1 != "")839//// {840//// if (fn1.split("|")[1] != null)841//// {842//// _popEvents[fn1.split("|")[1]] = fn1.split("|")[0];843//// fn1 = fn1.split("|")[0]; 844//// }845//// inpValue += '<input type="button" class="button" id="' + btnValue1 + '" value="' + btnValue1 + '" onclick=' + fn1 + '>&nbsp;';846//// }847//// 848//// if (btnValue2 != "")849//// {850//// if (fn2.split("|")[1] != null)851//// {852//// _popEvents[fn2.split("|")[1]] = fn2.split("|")[0];853//// fn2 = fn2.split("|")[0]; 854//// } 855//// inpValue += '<input type="button" class="button" id="' + btnValue2 + '" value="' + btnValue2 + '" onclick=' + fn2 + '>&nbsp;';856//// }857//// 858//// if (btnValue3 != "")859//// {860//// if (fn3.split("|")[1] != null)861//// {862//// _popEvents[fn3.split("|")[1]] = fn3.split("|")[0];863//// fn3 = fn3.split("|")[0]; 864//// } 865//// inpValue += '<input type="button" class="button" id="' + btnValue3 + '" value="' + btnValue3 + '" onclick=' + fn3 + '>';866//// }867//// 868//// strValue = inpValue;869// 870// var stDiv = "top:" + parseInt(top-5) + "px;left:" + parseInt(left-5) + "px;width:" + parseInt(twidth+10) + "px;height:" + parseInt(theight+10) + "px;"871// 872// if ($id("container"))873// {874// divAlert = ($id("container"));875// }876// else877// {878// divAlert = document.createElement("DIV"); 879// divAlert.id = "container";880// divAlert.className = "dragmain";881// divAlert.attachEvent("onmousedown",selectmouse);882// divAlert.attachEvent("onmouseup",new Function("isdrag=false"));883// divAlert.attachEvent("onkeydown",ExecuteKeyPressEventPopUp);884// document.body.appendChild(divAlert);885// } 886// 887// 888 var buttonvalues = btnValue1 + "☺" + fn1 ;889 if (btnValue2.length > 0)890 { 891 buttonvalues += "☺" + btnValue2 + "☺" + fn2 ;892 } 893 if (btnValue3.length > 0)894 {895 buttonvalues += "☺" + btnValue3 + "☺" + fn3 ;896 }897// //divAlert.innerHTML = '<table id="tblContainer" cellpadding="0" cellspacing="0"><tr><td><div id="poptlA" class="poptl" /></td><td><div id="poptcA" class="poptc"><div valign="middle" align="left" class="smllabelboldwhite" style="font-family:Arial;padding-top:15px;color:White;font-weight:bold;">' + HeadingText + '</div></div></td><td><div id="poptrA" class="poptr" /></td></tr><tr><td><div id="popclA" class="popcl" /></td><td align="center"><div id="popccA" class="popcc"><table cellspacing="0" cellpadding="0" style="font-family:Arial;padding-top:2px;font-size:12px;"><tr><td><div style="overflow:auto;"><table cellspacing="0" cellpadding="0"><tr><td>' + ContentText + '</td></tr></table></div></td></tr><tr><td align="right">' + strValue + '</td></tr></table></div></td><td><div id="popcrA" class="popcr" /></td></tr><tr><td><div id="popblA" class="popbl" /></td><td><div id="popbcA" class="popbc" /></td><td><div id="popbrA" class="popbr" /></td></tr></table>';898// divAlert.innerHTML = generatePopupHTML('tblContainer',HeadingText, '', ContentText, buttonvalues, theight, twidth, '', '');899// divAlert.style.cssText = "position:absolute;display:none;z-index:10020;" + stDiv;900// 901// //add iframe902// //var ifr = $id("iframepopup");903// var ifr;904// if ($id("iframepopups"))905// {906// ifr = ($id("iframepopups"));907// } 908// else909// {910// ifr = document.createElement("IFRAME");911// ifr.id = "iframepopups"912// ifr.className="dragmeIfr";913// divAlert.parentElement.appendChild(ifr);914// }915// ifr.frameBorder = "0";916// var table = $id("tblContainer");917// //var st = "width:" + twidth + "px; height:" + theight + "px;";918// //var st = "top:" + parseInt(top + 10) + "px;z-index:10019;position:absolute;left:" + parseInt(left + 8) + "px;width:" + parseInt(twidth) + "px;height:" + parseInt(theight) + "px";919// var st = "top:" + parseInt(top) + "px;z-index:10019;position:absolute;left:" + parseInt(left) + "px;width:" + parseInt(twidth-5) + "px;height:" + parseInt(theight-5) + "px"; 920// 921// $DivSetVisible(true,table,ifr,st);922// 923// var thediv = document.getElementById("container");924// thediv.style.display = "block";925// //divAlert.style.display = "block";926// 927//// document.getElementById("poptcA").style.width=twidth+'px';928//// document.getElementById("popccA").style.width=twidth+'px';929//// document.getElementById("popbcA").style.width=twidth+'px';930//// document.getElementById("popclA").style.height=theight+'px';931//// document.getElementById("popccA").style.height=theight+'px';932//// document.getElementById("popcrA").style.height=theight+'px';933// divAlert.focus();934 if (!popupImage)935 {936 popupImage = "";937 } 938 if (!helpID)939 {940 helpID = "";941 }942 943 //if zIndex is specified, and the closefunction is not changed, the relevant busydiv is never hidden944 var closeFunction = "doHidePopup()";945 try946 {947 if (zID.length > 0)948 {949 closeFunction = "doHidePopup('" + zID + "');"950 }951 }952 catch(error)953 {954 }955 956 $showPopup(headingText, contentText, "", theight, twidth, "", closeFunction, buttonvalues, zIndexSpec, zID , extraPath,"", helpID, "", "", popupImage) 957}958function doHidePopup(ControlID, doHideSpecify)959{960 if (!ControlID)961 {962 ControlID = "";963 } 964 965 if (ControlID.length > 0)966 { 967 HideDisableDiv("busy_" + ControlID); 968 HideDisableDiv( ControlID); 969 }970 else971 { 972 HideDisableDiv();973 }974 var thediv = document.getElementById("container" + ControlID);975 if (!thediv)976 {977 ControlID = "";978 thediv = document.getElementById("container" + ControlID);979 } 980// $removeEvent(thediv, "mousedown", selectmouse);981// $removeEvent(thediv, "mouseup", new Function("isdrag=false"));982// $removeEvent(thediv, "keydown", ExecuteKeyPressEventPopUp) ; 983 popupControls.pop(); 984 985// var oldControl = popupControls[popupControls.length-1];986// if (oldControl)987// {988// $addEvent(oldControl, "mousedown", selectmouse);989// $addEvent(oldControl, "mouseup", new Function("isdrag=false"));990// $addEvent(oldControl, "keydown", ExecuteKeyPressEventPopUp) ; 991// 992// if ($id("container"+ oldControl.id))993// {994// oldControl = ($id("container"+ oldControl.id));995// $addEvent(oldControl, "mousedown", selectmouse);996// $addEvent(oldControl, "mouseup", new Function("isdrag=false"));997// $addEvent(oldControl, "keydown", ExecuteKeyPressEventPopUp) ; 998// } 999// } 1000 1001 var ifr = window.parent.document.getElementById("iframepopups" + ControlID) != null ? window.parent.document.getElementById("iframepopups" + ControlID) : document.getElementById("iframepopups" + ControlID);1002 1003 if (thediv != null && thediv != "")1004 {1005// var ifr = $id("iframepopup");1006// ifr.style.display = "none";1007 var ifr = window.document.getElementById("iframepopups" + ControlID);1008 if (ifr)1009 {1010 ifr.style.display = "none";1011 ifr.parentNode.removeChild(ifr);1012 }1013 thediv.style.display = "none";1014 thediv.parentNode.removeChild(thediv);1015 }1016 1017 if (ControlID.length > 0)1018 {1019 if ($id(ControlID))1020 {1021 ($id(ControlID)).style.display = "none";1022 }1023 } 1024// if ((doHideSpecify != "false") || (doHideSpecify == null))1025 if ((doHideSpecify != "false"))1026 {1027 hidePWait(); 1028 }1029}1030//get Scrolling values for all browsers1031function returnScrollDimensions(which) 1032{1033 //if which = 1 return x, if which = 0 return y1034 var scrOfX = 0, scrOfY = 0;1035 var d = document;1036 if( typeof( window.pageYOffset ) == 'number' ) 1037 {1038 //Netscape compliant1039 scrOfY = window.pageYOffset;1040 scrOfX = window.pageXOffset;1041 } 1042 else if ( document.body && ( document.body.scrollLeft || document.body.scrollTop ) ) 1043 {1044 //DOM compliant1045 scrOfY = document.body.scrollTop;1046 scrOfX = document.body.scrollLeft;1047 } 1048 else if( document.documentElement && ( document.documentElement.scrollLeft || document.documentElement.scrollTop ) ) 1049 {1050 //IE6 standards compliant mode1051 scrOfY = document.documentElement.scrollTop;1052 scrOfX = document.documentElement.scrollLeft;1053 }1054 if(which) 1055 {1056 return scrOfX;1057 } 1058 else 1059 {1060 return scrOfY;1061 }1062} 1063//do popup control1064function $doControlPopup(headingText, contentText, controlID, closeBtn, closeBtnFn, pathExtra)1065{1066// if (!pathExtra)1067// {1068// pathExtra = "";1069// } 1070// _controlID = controlID1071// var HeadingText = headingText;1072// var ContentText = contentText;1073// var newDiv = false;1074// var headerClose = "";1075// var headerMain = "";1076// var controlText = $id(controlID);1077// controlText.style.display = "block";1078// 1079// var controlValue = "";1080// var controlHeight = (parseInt(controlText.style.height.replace("px","")));1081// var controlWidth = (parseInt(controlText.style.width.replace("px","")));1082// 1083// if ((controlHeight == "") || isNaN(controlHeight))1084// controlHeight = controlText.offsetHeight;1085// 1086// if ((controlWidth == "") || isNaN(controlWidth))1087// controlWidth = controlText.offsetWidth; 1088// 1089// var screenL = window.screen.availWidth - controlWidth ;1090// var screenH = window.screen.availHeight - controlHeight;1091//// if (infoText.length > 0)1092//// {1093//// screenH = screenH - 110;1094//// }1095//// else1096//// {1097// screenH = screenH - 150;1098//// } 1099// var top = (screenH/3) + parseInt(returnScrollDimensions(0)); 1100// var left = (screenL/2) + parseInt(returnScrollDimensions(1));1101// var divAlert = "";1102// var divExists = $id("containerControl" + controlID); 1103// //control style 1104// //var st = "top:" + (parseInt(top) - parseInt(35)) + "px;" + "position:absolute;left:" + (parseInt(left)+ parseInt(25)) + "px;width:"+(parseInt(controlWidth)) + "px;height:"+(parseInt(controlHeight))+"px;";1105// //70 as dit infotext bevat1106// //var st = "top:" + (parseInt(top) + parseInt(70)) + "px;" + "position:absolute;left:" + (parseInt(left)+ parseInt(5)) + "px;width:"+(parseInt(controlWidth)) + "px;height:"+(parseInt(controlHeight+10))+"px;"; 1107// //40 as daar nie info is nie1108// var st = "top:" + (parseInt(top) + parseInt(40)) + "px;" + "position:absolute;left:" + (parseInt(left) + parseInt(2)) + "px;width:"+(parseInt(controlWidth)) + "px;height:"+(parseInt(controlHeight ))+"px;"; 1109// 1110// if (controlText.style.zIndex == "")1111// {1112// st += "z-index:9020;";1113// }1114// else1115// {1116// st += "z-index:" + controlText.style.zIndex + ";";1117// }1118// 1119// if(divExists == null)1120// {1121// divAlert = document.createElement("DIV");1122// divAlert.id = "containerControl" + controlID;1123// divAlert.className = "dragme";1124// divAlert.attachEvent("onmousedown",selectmouse);1125// divAlert.attachEvent("onmouseup",new Function("isdrag=false"));1126// newDiv= true;1127// }1128// else1129// {1130// return;1131// }1132// 1133// controlText.style.cssText = "";1134// controlText.style.cssText = st;1135// 1136// //div se style 1137// var stDiv = "top:" + (parseInt(top) +parseInt(2)) + "px;" + "position:absolute;left:" + (parseInt(left) + parseInt(2)) + "px;width:"+(parseInt(controlWidth )) + "px;height:"+(parseInt(controlHeight) )+"px;";1138// //iframe se style 1139// //var stMain = "top:" + (parseInt(top) - parseInt(60)) + "px;" + "position:absolute;left:" + (parseInt(left)+ parseInt(25)) + "px;width:"+(parseInt(controlWidth)) + "px;height:"+(parseInt(controlHeight)+20)+"px;";1140// var stMain = "top:" + (parseInt(top) + parseInt(2)) + "px;" + "position:absolute;left:" + (parseInt(left) + parseInt(2)) + "px;width:"+(parseInt(controlWidth - 12)) + "px;height:"+(parseInt(controlHeight) - 4)+"px;"; 1141// 1142// var currentIndex = controlText.style.zIndex; 1143// stDiv += "z-index:" + (parseInt(currentIndex)-1) + ";"; 1144// stMain += "z-index:" + (parseInt(currentIndex)-2) + ";";1145// busyDivTag((parseInt(currentIndex)-3), "busy_" + controlID);1146// 1147// if (closeBtn != false)1148// {1149// headerClose = '<img id="btnClose' + controlID + '" src="../images/clear.GIF" style="width:15px;height:15px;cursor:hand;">'1150// }1151// 1152// //headerMain = '<table cellspacing="0" cellpadding="0" style="table-layout:fixed;"><tr><td valign="middle" align="left" class="smllabelboldwhite"><nobr>' + headingText + '</td><td align="right" style="width:15px;">' + headerClose + '</td></tr></table>';1153// 1154// divAlert.style.cssText = "";1155// divAlert.style.cssText = "position:absolute;display:none;" + stDiv;1156// //divAlert.innerHTML += '<table id="tblContainerControl' + controlID + '" cellpadding="0" cellspacing="0" border="0"><tr><td><div id="poptl' + controlID + '" class="poptl"></div></td><td><div id="poptc' + controlID + '" class="poptc"><div style="font-family:Arial;padding-top:15px;color:White;font-weight:bold; width:100%;">' + headerMain + '</div></div></td><td><div id="poptr' + controlID + '" class="poptr"></div></td></tr><tr><td><div id="popcl' + controlID + '" class="popcl"></div></td><td align="center"><div align="center" id="popcc' + controlID + '" class="popcc">' + controlValue + '</div></td><td><div id="popcr' + controlID + '" class="popcr"></div></td></tr><tr><td><div id="popbl' + controlID + '" class="popbl"></div></td><td><div id="popbc' + controlID + '" class="popbc"></div></td><td><div id="popbr' + controlID + '" class="popbr"></div></td></tr></table>';1157// var closeName = "btnClose" + controlID ;1158// divAlert.innerHTML += generatePopupHTML('tblContainerControl' + controlID, headingText, '', controlValue, '', controlHeight + 'px', controlWidth + 'px', closeName, closeBtnFn,'','',pathExtra) 1159// 1160// if(newDiv == true)1161// { 1162// //mozilla 1163// //controlText.parentElement.appendChild(divAlert);1164// controlText.parentNode.appendChild(divAlert);1165// }1166// 1167// //add iframe1168// var ifr = document.createElement("IFRAME");1169// ifr.id = "containerframe" + controlID;1170// ifr.className = "dragmeIfr";1171// ifr.style.cssText = "";1172// ifr.style.cssText = "display: none;position:absolute";1173// 1174// //Jaco Lubbe - Verander vir die property grid se popup1175// //document.body.appendChild(ifr);1176// //mozilla 1177// //controlText.parentElement.appendChild(ifr);1178// controlText.parentNode.appendChild(ifr); 1179// 1180// 1181// var table = $id("tblContainerControl" + controlID);1182// 1183// $DivSetVisible(true,table,ifr,stMain);1184// 1185// var thediv = "";1186// var divID = $id("containerControl" + controlID);1187// thediv = divID;1188// thediv.style.display = "block";1189// 1190//// $id("poptc" + controlID).style.width=controlWidth+'px';1191//// $id("popcc" + controlID).style.width=controlWidth+'px';1192//// $id("popbc" + controlID).style.width=controlWidth+'px';1193//// $id("popcl" + controlID).style.height=controlHeight+'px';1194//// $id("popcc" + controlID).style.height=controlHeight+'px';1195//// $id("popcr" + controlID).style.height=controlHeight+'px';1196// 1197// if (closeBtnFn != "") 1198// document.getElementById("btnClose" + controlID).attachEvent("onclick", closeBtnFn);1199 //$showPopup(headingText, contentText, controlID, "", "", "", "doHidePopup()", "", "", "", pathExtra, "", "", "", "")1200 $showPopup(headingText, contentText, controlID, "", "", "", "doHidePopup()", "", "", "", pathExtra, "", "", "", "");1201 showSelectSpecific(controlID); 1202}1203function $doControlPopupDetail(headingText, contentText, infoText, controlID, buttons, closeBtn, closeBtnFn, pathExtra, helpID, popupImage)1204{1205// if (!pathExtra)1206// {1207// pathExtra = "";1208// } 1209// _controlID = controlID1210// var HeadingText = headingText;1211// var ContentText = contentText;1212// var newDiv = false;1213// var headerClose = "";1214// var headerMain = "";1215// var controlText = $id(controlID);1216// controlText.style.display = "block";1217// 1218// var controlValue = "";1219// var controlHeight = (parseInt(controlText.style.height.replace("px","")));1220// var controlWidth = (parseInt(controlText.style.width.replace("px","")));1221// 1222// if ((controlHeight == "") || isNaN(controlHeight))1223// controlHeight = controlText.offsetHeight;1224// 1225// if ((controlWidth == "") || isNaN(controlWidth))1226// controlWidth = controlText.offsetWidth; 1227// 1228// var screenL = window.screen.availWidth - controlWidth ;1229// var screenH = window.screen.availHeight - controlHeight;1230// if (infoText.length > 0)1231// {1232// screenH = screenH - 110;1233// }1234// else1235// {1236// screenH = screenH - 150;1237// }1238// var top = (screenH/3) + parseInt(returnScrollDimensions(0)); 1239// var left = (screenL/2) + parseInt(returnScrollDimensions(1));1240// var divAlert = "";1241// var divExists = $id("containerControl" + controlID); 1242// //control style 1243// //var st = "top:" + (parseInt(top) - parseInt(35)) + "px;" + "position:absolute;left:" + (parseInt(left)+ parseInt(25)) + "px;width:"+(parseInt(controlWidth)) + "px;height:"+(parseInt(controlHeight))+"px;";1244// //70 as dit infotext bevat1245// var st = "";1246// if (infoText.length > 0)1247// {1248// st = "top:" + (parseInt(top) + parseInt(70)) + "px;" + "position:absolute;left:" + (parseInt(left)+ parseInt(5)) + "px;width:"+(parseInt(controlWidth)) + "px;height:"+(parseInt(controlHeight+10))+"px;"; 1249// }1250// else1251// {1252// //40 as daar nie info is nie1253// st = "top:" + (parseInt(top) + parseInt(40)) + "px;" + "position:absolute;left:" + (parseInt(left) + parseInt(2)) + "px;width:"+(parseInt(controlWidth)) + "px;height:"+(parseInt(controlHeight ))+"px;"; 1254// }1255// 1256// if (controlText.style.zIndex == "")1257// {1258// st += "z-index:9020;";1259// }1260// else1261// {1262// st += "z-index:" + controlText.style.zIndex + ";";1263// }1264// 1265// if(divExists == null)1266// {1267// divAlert = document.createElement("DIV");1268// divAlert.id = "containerControl" + controlID;1269// divAlert.className = "dragme";1270// divAlert.attachEvent("onmousedown",selectmouse);1271// divAlert.attachEvent("onmouseup",new Function("isdrag=false"));1272// newDiv= true;1273// }1274// else1275// {1276// return;1277// }1278// 1279// controlText.style.cssText = "";1280// controlText.style.cssText = st;1281// 1282// //div se style 1283// var stDiv = "top:" + (parseInt(top) +parseInt(2)) + "px;" + "position:absolute;left:" + (parseInt(left) + parseInt(2)) + "px;width:"+(parseInt(controlWidth )) + "px;height:"+(parseInt(controlHeight) )+"px;";1284// //iframe se style 1285// //var stMain = "top:" + (parseInt(top) - parseInt(60)) + "px;" + "position:absolute;left:" + (parseInt(left)+ parseInt(25)) + "px;width:"+(parseInt(controlWidth)) + "px;height:"+(parseInt(controlHeight)+20)+"px;";1286// var stMain = "top:" + (parseInt(top) + parseInt(2)) + "px;" + "position:absolute;left:" + (parseInt(left) + parseInt(2)) + "px;width:"+(parseInt(controlWidth - 12)) + "px;height:"+(parseInt(controlHeight) - 4)+"px;"; 1287// 1288// var currentIndex = controlText.style.zIndex; 1289// stDiv += "z-index:" + (parseInt(currentIndex)-1) + ";"; 1290// stMain += "z-index:" + (parseInt(currentIndex)-2) + ";";1291// busyDivTag((parseInt(currentIndex)-3), "busy_" + controlID);1292// 1293// if (closeBtn != false)1294// {1295// headerClose = '<img id="btnClose' + controlID + '" src="../images/clear.GIF" style="width:15px;height:15px;cursor:hand;">'1296// }1297// 1298// //headerMain = '<table cellspacing="0" cellpadding="0" style="table-layout:fixed;"><tr><td valign="middle" align="left" class="smllabelboldwhite"><nobr>' + headingText + '</td><td align="right" style="width:15px;">' + headerClose + '</td></tr></table>';1299// 1300// divAlert.style.cssText = "";1301// divAlert.style.cssText = "position:absolute;display:none;" + stDiv;1302// //divAlert.innerHTML += '<table id="tblContainerControl' + controlID + '" cellpadding="0" cellspacing="0" border="0"><tr><td><div id="poptl' + controlID + '" class="poptl"></div></td><td><div id="poptc' + controlID + '" class="poptc"><div style="font-family:Arial;padding-top:15px;color:White;font-weight:bold; width:100%;">' + headerMain + '</div></div></td><td><div id="poptr' + controlID + '" class="poptr"></div></td></tr><tr><td><div id="popcl' + controlID + '" class="popcl"></div></td><td align="center"><div align="center" id="popcc' + controlID + '" class="popcc">' + controlValue + '</div></td><td><div id="popcr' + controlID + '" class="popcr"></div></td></tr><tr><td><div id="popbl' + controlID + '" class="popbl"></div></td><td><div id="popbc' + controlID + '" class="popbc"></div></td><td><div id="popbr' + controlID + '" class="popbr"></div></td></tr></table>';1303// var closeName = "btnClose" + controlID ;1304// divAlert.innerHTML += generatePopupHTML('tblContainerControl' + controlID, headingText, infoText, controlValue, buttons, controlHeight + 'px', controlWidth + 'px', closeName, closeBtnFn, "","", pathExtra) 1305// 1306// if(newDiv == true)1307// { 1308// //mozilla 1309// //controlText.parentElement.appendChild(divAlert);1310// controlText.parentNode.appendChild(divAlert);1311// }1312// 1313// //add iframe1314// var ifr = document.createElement("IFRAME");1315// ifr.id = "containerframe" + controlID;1316// ifr.className = "dragmeIfr";1317// ifr.style.cssText = "";1318// ifr.style.cssText = "display: none;position:absolute";1319// 1320// //Jaco Lubbe - Verander vir die property grid se popup1321// //document.body.appendChild(ifr);1322// //mozilla 1323// //controlText.parentElement.appendChild(ifr);1324// controlText.parentNode.appendChild(ifr); 1325// 1326// 1327// var table = $id("tblContainerControl" + controlID);1328// 1329// $DivSetVisible(true,table,ifr,stMain);1330// 1331// var thediv = "";1332// var divID = $id("containerControl" + controlID);1333// thediv = divID;1334// thediv.style.display = "block";1335// 1336//// $id("poptc" + controlID).style.width=controlWidth+'px';1337//// $id("popcc" + controlID).style.width=controlWidth+'px';1338//// $id("popbc" + controlID).style.width=controlWidth+'px';1339//// $id("popcl" + controlID).style.height=controlHeight+'px';1340//// $id("popcc" + controlID).style.height=controlHeight+'px';1341//// $id("popcr" + controlID).style.height=controlHeight+'px';1342// 1343// //if (closeBtnFn != "") 1344// // document.getElementById("btnClose" + controlID).attachEvent("onclick", closeBtnFn);1345 if (!helpID)1346 {1347 helpID = "";1348 } 1349 if (!popupImage)1350 {1351 popupImage = "";1352 }1353 if (!infoText)1354 {1355 infoText = "";1356 }1357 $showPopup(headingText, contentText, controlID, "", "", "", closeBtnFn, buttons, "", "", pathExtra, infoText, helpID, "", "", popupImage);1358 showSelectSpecific(controlID); 1359}1360function $doHideControlPopup(controlID)1361{1362 doHidePopup(controlID);1363// var thediv = $id("containerControl" + controlID);1364// var theControlID = $id(controlID);1365 var thediv = window.parent.document.getElementById("containerControl" + controlID) != null ? window.parent.document.getElementById("containerControl" + controlID) : document.getElementById("containerControl" + controlID);1366 var theControlID = window.parent.document.getElementById(controlID) != null ? window.parent.document.getElementById(controlID) : document.getElementById(controlID);1367 1368 if (thediv != null && thediv != "")1369 {1370 theControlID.style.display = "none";1371// var ifr = $id("containerframe" + controlID);1372 var ifr = window.parent.document.getElementById("containerframe" + controlID) != null ? window.parent.document.getElementById("containerframe" + controlID) : document.getElementById("containerframe" + controlID);1373 ifr.style.display = "none";1374 ifr.parentNode.removeChild(ifr);1375 thediv.style.display = "none";1376 thediv.parentNode.removeChild(thediv);1377 }1378 HideDisableDiv("busy_" + controlID);1379 hidePWait();1380 1381}1382//subforms;1383function $DivSetVisible(state,DivRef,IfrRef,st)1384{1385 if(state)1386 {1387 DivRef.style.display = "block";1388 IfrRef.style.cssText=st;1389 //Jaco Lubbe - Uitgecomment vir Property grid se popup1390 //IfrRef.style.zIndex = DivRef.style.zIndex - 1;1391 IfrRef.border=0;1392 IfrRef.style.display = "block";1393 }1394 else1395 {1396 DivRef.style.display = "none";1397 IfrRef.style.display = "none";1398 }1399}1400 /* replace function */1401function ReplaceID( str, currentvalue, newvalue) 1402{ 1403 str += '';1404 var idx = str.indexOf( currentvalue );1405 while ( idx > -1 ) {1406 str = str.replace( currentvalue, newvalue ); 1407 idx = str.indexOf( currentvalue );1408 }1409 return str;1410}1411/* return http://hostname/solutionname and passes in the rest of the path to a page */1412function buildURL(path)1413{1414 1415 path = location.pathname.substring(0,location.pathname.indexOf('/',1,0)) + "/" + path1416 //changed the buildURL function so the current solution (IIS) name of the project is not hardcoded1417 if (path.substring(0,1) == "/")1418 {1419 return "//" + location.host + path;1420 //return "http://" + location.host + path;1421 }1422 else1423 { 1424 return "//" + location.host + "/" + path;1425 //return "http://" + location.host + "/" + path;1426 }1427}1428 1429//Validation for a valid e-mail address1430function validateEmail(emailAddress)1431{1432 var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[(2([0-4]\d|5[0-5])|1?\d{1,2})(\.(2([0-4]\d|5[0-5])|1?\d{1,2})){3} \])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/1433 return re.test(emailAddress);1434}1435//Validation on special chars1436function validateSpecialChars(id, friendlyName, specialChar, allowBlank, extraPath)1437{1438 var validateResult = ""1439 var objValue = "$id('" + id + "').value";1440 var _path = "";1441 1442 if (_pagePath != null)1443 {1444 _path = _pagePath.replace("../","");1445 }1446 1447 if (extraPath != null)1448 {1449 _path = extraPath;1450 } 1451 1452 1453 if ($Trim(eval(objValue)).length == "")1454 {1455 if((allowBlank == null) || (allowBlank == false))1456 {1457 doPopup(Generic_js_ValidateHeading, Generic_js_ValidateDescription + " '" + friendlyName + "'.", 400 , 75, Generic_js_ButtonOk, "doHidePopup('valID')|13", "", "", "", "", 11500, "valID", _path,"","error");1458 validateResult = false;1459 return validateResult;1460 }1461 else1462 validateResult = true;1463 }1464 1465 var iChars = "&!@#$%^&*()+=-[]\\\';,./{}|\":<>?_~";1466 iChars = iChars.replace(specialChar,"");1467 for (var i = 0; i < eval(objValue).length; i++) 1468 {1469 if (iChars.indexOf(eval(objValue).charAt(i)) != -1) {1470 doPopup(Generic_js_ValidateSpecialCharHeading, Generic_js_ValidateSpecialCharDescription + " '" + friendlyName + "' " + Generic_js_ValidateSpecialCharDescription1 + " '" + eval(objValue).charAt(i) + "'.<br>" + Generic_js_ValidateSpecialCharDescription2, 400 , 70, Generic_js_ButtonOk, "doHidePopup('valIDSpec')|13", "", "", "", "", 11500, "valIDSpec", _path, "", "warning");1471 validateResult = false;1472 return validateResult;1473 }1474 else1475 {1476 validateResult = true;1477 }1478 }1479 return validateResult;1480}1481//check a string for special chars and return a 'true' or 'false'1482//set a space delimited exclude list if you need to1483function containsSpecialChars(inputString, excludeChars)1484{1485 var validateResult = false;1486 var specialChars = "&@#$%?!^*()+=-[]\\';,./{}|:<>_~";1487 var chinSpecialChars1 = "≈≠=≤≥≤<>≮≯∷±+-×÷∫∮∝∧∨∑∏∪∩∈∵∴⊥∥∠⌒⊙≌∽√";1488 var chinSpecialChars2 = "┼┽┾┿╀╁╂╃┬┭┮┯┰┰┱┱┲┳├┝┞┟┠┡┢┣┍┎┏┐┑┒┓┒─┄";1489 var chinSpecialChars3 = "§№☆★○●◎◇◆□℃‰€■△▲※→←↑↓〓¤°#&@\︿_ ̄―♂♀";1490 var chinSpecialChars4 = "〖〗【】[]{}《》「」『』々‖…—•ˉ〃";1491 var chinSpecialChars5 = "ㄅㄉˇˋㄓˊˊ˙˙ㄚㄞㄢㄆㄊㄍㄐㄔㄗㄧㄛㄟㄣㄇㄋㄎㄑㄕㄘㄨㄜㄠㄈㄌㄏㄒㄖㄙㄩㄝㄡㄥ";1492 1493 var ExcludeList = excludeChars.split(" ");1494 //remove excluded chars form list 1495 for (var k = 0; k < ExcludeList.length; k++)1496 {1497 specialChars = specialChars.replace(ExcludeList[k],"");1498 chinSpecialChars1 = chinSpecialChars1.replace(ExcludeList[k],"");1499 chinSpecialChars2 = chinSpecialChars2.replace(ExcludeList[k],"");1500 chinSpecialChars3 = chinSpecialChars3.replace(ExcludeList[k],"");1501 chinSpecialChars4 = chinSpecialChars4.replace(ExcludeList[k],"");1502 chinSpecialChars5 = chinSpecialChars5.replace(ExcludeList[k],"");1503 }1504 1505 for (var i = 0; i < inputString.length; i++) 1506 {1507 if (specialChars.indexOf(inputString.charAt(i)) != -1) 1508 {1509 validateResult = true;1510 }1511 if (chinSpecialChars1.indexOf(inputString.charAt(i)) != -1) 1512 {1513 validateResult = true;1514 }1515 if (chinSpecialChars2.indexOf(inputString.charAt(i)) != -1) 1516 {1517 validateResult = true;1518 }1519 if (chinSpecialChars3.indexOf(inputString.charAt(i)) != -1) 1520 {1521 validateResult = true;1522 }1523 if (chinSpecialChars4.indexOf(inputString.charAt(i)) != -1) 1524 {1525 validateResult = true;1526 }1527 if (chinSpecialChars5.indexOf(inputString.charAt(i)) != -1) 1528 {1529 validateResult = true;1530 }1531 }1532 return validateResult;1533}1534 function addbookmark()1535{1536 if (document.all)1537 window.external.AddFavorite(location,'WorkSpace')1538}1539//Fix texttoplace in for 1st time its created; 1540function createPWait(texttoplace, zIndexValue)1541{1542 var divt = $id("div_SAVING");1543 if(divt == null)1544 {1545 divt = document.createElement("DIV");1546 var left = (document.documentElement.clientWidth - 64) / 2;1547 if (left <= 0)1548 {1549 left = (document.body.clientWidth - 64) / 2;1550 }1551 var top = (document.documentElement.clientHeight - 64) / 2; 1552 if (top <= 0)1553 {1554 top = (document.body.clientHeight - 64) / 2;1555 }1556 // divt.style.cssText = "background:whitesmoke;border:1px solid gray;text-align: center;vertical-align: middle; line-height: normal; letter-spacing: normal;width: 381px; height: 51px; z-index: 1010; left: 390px; position: absolute; top: 209px;";1557 divt.style.cssText = "border:none;width: 32px; height: 32px; z-index: 1010; left:" + left + "px; position: absolute; top: " + top +"px;"; 1558 divt.innerHTML = textDiv(texttoplace); 1559 //divt.style.zIndex=12500;1560 divt.style.zIndex = zIndexValue;1561 divt.id = "div_SAVING";1562 1563 document.body.appendChild(divt); 1564 }1565 1566}1567function textDiv(eventtodisplay)1568{1569 eventtodisplay = (typeof(eventtodisplay) == 'undefined') ? "" : " : " + eventtodisplay1570 1571 //var d= "<img src='../images/please_wait.gif'>" + "<br />"+ "Please wait " + eventtodisplay + "<br />";1572 var d= "<img id='imgBigGreenRot' src='../images/Green_Big_Rotate.gif'>";1573 return d;1574}1575//duplicate1576function showPWait(texttoplace, zIndex)1577{1578 var divt = $id("div_SAVING");1579 var ifr = $id("iframepopup");1580 1581 if(divt != null)1582 {1583 1584// //divt.style.zIndex=9080;1585// //Port_togglePopUpMenuDisplay(divt,"hiddenframe",true);1586// $togglePopUp(divt, "hiddenframe", true);1587// divt.innerHTML = textDiv(texttoplace);1588// 1589// divt.style.display = "inline";1590 divt.parentNode.removeChild(divt);1591 }1592 1593 1594 1595 1596 var divtest = $id("div_SAVING");1597 if (zIndex != null)1598 {1599 createPWait(texttoplace, (parseInt(zIndex) + 100));1600 busyDivTag(zIndex);1601 } 1602 else1603 {1604 createPWait(texttoplace, 11500);1605 busyDivTag(11400);1606 }1607 _canload_Portal = false; 1608}1609function showPWaitIframe(texttoplace)1610{1611 var divt = $id("div_SAVING");1612 if(divt != null)1613 {1614 divt.parentNode.removeChild(divt); 1615 }1616 divt = document.createElement("DIV");1617// var left = (document.documentElement.offsetWidth) /2;1618// var top = (document.documentElement.offsetHeight) / 3; 1619 var left = (document.documentElement.clientWidth - 64) / 2;1620 if (left <= 0)1621 {1622 left = (document.body.clientWidth - 64) / 2;1623 }1624 var top = (document.documentElement.clientHeight - 64) / 2; 1625 if (top <= 0)1626 {1627 top = (document.body.clientHeight - 64) / 2;1628 }1629 // divt.style.cssText = "background:whitesmoke;border:1px solid gray;text-align: center;vertical-align: middle; line-height: normal; letter-spacing: normal;width: 381px; height: 51px; z-index: 1010; left: 390px; position: absolute; top: 209px;";1630 divt.style.cssText = "border:none;width: 32px; height: 32px; z-index: 1010; left:" + left + "px; position: absolute; top: " + top +"px;"; 1631 divt.innerHTML = textDiv(texttoplace); 1632 divt.style.zIndex=9031;1633 divt.id = "div_SAVING";1634 1635 document.body.appendChild(divt); 1636 busyDivTag();1637 _canload_Portal = false; 1638 1639}1640//duplicate1641function hidePWait()1642{1643 var divt = $id("div_SAVING");1644 if(divt != null)1645 {1646 // Port_togglePopUpMenuDisplay(divt,"hiddenframe","none");1647 $togglePopUp(divt, "hiddenframe","none");1648 divt.style.display = "none";1649 }1650 HideDisableDiv();1651 _canload_Portal = true; 1652}1653function setFormName(customFormName)1654{1655 _formName = customFormName;1656}1657//Jvz : File and image upload div1658function busyDivTagTester(zIndex, ID,Con)1659{1660 var d;1661 var newDiv = false;1662 1663 if((ID != null) && (ID.length > 0))1664 {1665 d = $id(ID); 1666 if(d==null)1667 {1668 d= document.createElement("div");1669 d.id = ID;1670 _currentBusyDiv = ID;1671 newDiv=true;1672 }1673 }1674 else1675 {1676 d = $id("divbusywithtop"); 1677 if(d==null)1678 {1679 d= document.createElement("div");1680 d.id = "divbusywithtop";1681 newDiv=true;1682 }1683 }1684 1685 d.style.backgroundColor = "black";1686 d.style.filter = "Alpha(opacity=50)";1687 d.style.top = "1px";1688 d.style.left="1px";1689 d.style.position="absolute";1690 d.style.width = document.forms[0].offsetWidth;// screen.availWidth;//document.documentElement.clientWidth;//document.body.offsetWidth + "px";//document.documentElement.offsetWidth + "px";1691// d.style.height = screen.availHeight;//document.documentElement.clientHeight;1692 if (document.forms[0].offsetHeight >100)1693 {1694 d.style.height = document.forms[0].offsetHeight;//screen.availHeight;//document.documentElement.clientHeight;//document.body.offsetHeight + "px"; //document.documentElement.offsetHeight + "px";1695 }1696 else1697 {1698 d.style.height = document.documentElement.clientHeight;1699 }1700 if ((zIndex != null) && (zIndex.toString().length > 0 )) //jvz : zIndex.length1701 {1702 d.style.zIndex = zIndex;1703 }1704 else1705 {1706 d.style.zIndex="9010";1707 }1708 d.className="alphadiv";1709 d.style.display="inline";1710 1711 //Jvz het dit ingesit. Dis vir die FREAKING SUBFORMS!!!!!!!!!1712 if(typeof(_SubFormChildID) != "undefined")1713 {1714 hideSelectsButKeepID(_SubFormChildID);1715 }1716 else1717 {1718 hideSelects();1719 }1720 if(newDiv==true)1721 {1722 try1723 {1724 try1725 {1726 var form = $id(Con);1727 if (form != null)1728 {1729 $id(Con).appendChild(d);1730 }1731 else1732 {1733 $id(_formName).appendChild(d);1734 }1735 }1736 catch(e)1737 {1738 $id(_formName).appendChild(d);1739 } 1740 }1741 catch(e)1742 {1743 document.forms[0].appendChild(d);1744 }1745 }1746}1747function busyDivTag(zIndex, ID)1748{1749 var d;1750 var newDiv = false;1751 1752 if((ID != null) && (ID.length > 0))1753 {1754 d = $id(ID); 1755 if(d==null)1756 {1757 d= document.createElement("div");1758 d.id = ID;1759 _currentBusyDiv = ID;1760 newDiv=true;1761 }1762 }1763 else1764 {1765 d = $id("divbusywithtop"); 1766 if(d==null)1767 {1768 d= document.createElement("div");1769 d.id = "divbusywithtop";1770 newDiv=true;1771 }1772 }1773 1774 d.style.backgroundColor = "black";1775 d.style.filter = "Alpha(opacity=50)";1776 d.style.top = "1px";1777 d.style.left="1px";1778 d.style.position="absolute";1779 d.style.width = document.forms[0].offsetWidth;// screen.availWidth;//document.documentElement.clientWidth;//document.body.offsetWidth + "px";//document.documentElement.offsetWidth + "px";1780// d.style.height = screen.availHeight;//document.documentElement.clientHeight;1781// if (document.forms[0].offsetHeight >100)1782// {1783// d.style.height = document.forms[0].offsetHeight;//screen.availHeight;//document.documentElement.clientHeight;//document.body.offsetHeight + "px"; //document.documentElement.offsetHeight + "px";1784// }1785// else1786// {1787// d.style.height = document.documentElement.clientHeight;1788// }1789 d.style.height = document.documentElement.offsetHeight; //changed for Q4_2007 (bug 10309)1790 if ((zIndex != null) && (zIndex.toString().length > 0 )) //jvz : zIndex.length1791 {1792 d.style.zIndex = zIndex;1793 }1794 else1795 {1796 d.style.zIndex="9010";1797 }1798 d.className="alphadiv";1799 d.style.display="inline";1800 1801 //Jvz het dit ingesit. Dis vir die FREAKING SUBFORMS!!!!!!!!!1802 if(typeof(_SubFormChildID) != "undefined")1803 {1804 hideSelectsButKeepID(_SubFormChildID);1805 }1806 else1807 {1808 hideSelects();1809 }1810 if(newDiv==true)1811 {1812 try1813 {1814 try1815 {1816 var form = $id("form1");1817 if (form != null)1818 {1819 $id("form1").appendChild(d);1820 }1821 else1822 {1823 $id(_formName).appendChild(d);1824 }1825 }1826 catch(e)1827 {1828 $id(_formName).appendChild(d);1829 } 1830 }1831 catch(e)1832 {1833 document.forms[0].appendChild(d);1834 }1835 }1836}1837function hideSelects()1838{1839 //mozilla1840 //var selCount = document.all.tags("select");1841 var selCount = document.getElementsByTagName("select"); 1842 for (var i=0; i<selCount.length; i++)1843 {1844 selCount[i].style.visibility = "hidden";1845 }1846}1847 1848function showSelects()1849{1850 //mozilla1851 //var selCount = document.all.tags("select");1852 var selCount = document.getElementsByTagName("select");1853 for (var i=0; i<selCount.length; i++)1854 {1855 selCount[i].style.visibility = "visible";1856 }1857 if ($id("textStyle"))1858 {1859 //mozilla1860 //selCount = ($id("textStyle")).all.tags("select");1861 selCount = ($id("textStyle")).getElementsByTagName("select");1862 for (var i=0; i<selCount.length; i++)1863 {1864 selCount[i].style.visibility = "hidden";1865 } 1866 } 1867}1868function showSelectSpecific(controlID)1869{1870 if ($id(controlID))1871 {1872 //This is a fix for Mozilla browser.1873 //selCount = ($id(controlID)).all.tags("select");1874 selCount = ($id(controlID)).getElementsByTagName("select");1875 for (var i=0; i<selCount.length; i++)1876 {1877 selCount[i].style.visibility = "visible";1878 } 1879 } 1880} 1881function hideSelectSpecific(controlID)1882{1883 if ($id(controlID))1884 {1885 //This is a fix for Mozilla browser.1886 //selCount = ($id(controlID)).all.tags("select");1887 selCount = ($id(controlID)).getElementsByTagName("select");1888 for (var i=0; i<selCount.length; i++)1889 {1890 selCount[i].style.visibility = "hidden";1891 } 1892 } 1893} 1894 1895function HideDisableDiv(ID)1896{1897 var df;// = $id("divbusywithtop");1898 if ((ID != null) && (ID.length > 0))1899 {1900 df = $id(ID);1901 }1902 else1903 {1904 df = $id("divbusywithtop");1905 }1906 1907 if(df!=null)1908 {1909 df.style.display="none";1910 _currentBusyDiv = "";1911 }1912 showSelects();1913}1914function hideSelectsButKeepID(idtoKeep)1915{1916 //var selCount = _portaldocument.all.tags("select");1917 var selCount = document.getElementsByTagName("select"); 1918 1919 for (var i=0; i<selCount.length; i++)1920 {1921 var id = selCount[i].getAttribute("id");1922 1923 if(idtoKeep !=null)1924 {1925 if(getParamsNumber(id) != getParamsNumber(idtoKeep))1926 {1927 selCount[i].style.visibility = "hidden";1928 }1929 else1930 {1931 selCount[i].style.visibility = "visible";1932 }1933 }1934 else1935 {1936 selCount[i].style.visibility = "hidden";1937 }1938 1939 //selCount[i].style.visibility = "hidden";1940 }1941}1942//Shows certain selects but keep the id passed visible;1943function showSelectsButKeepID(idtoKeep)1944{1945 var selCount = document.getElementsByTagName("select");1946 for (var i=0; i<selCount.length; i++)1947 {1948 var id = selCount[i].getAttribute("id");1949 1950 if(idtoKeep !=null)1951 {1952 if(getParamsNumber(id) != getParamsNumber(idtoKeep))1953 {1954 selCount[i].style.visibility = "hidden";1955 }1956 else1957 {1958 selCount[i].style.visibility = "visible";1959 }1960 }1961 else1962 {1963 selCount[i].style.visibility = "visible";1964 }1965 }1966 1967 //selCount = ($id("textStyle")).all.tags("select");1968 selCount = ($id("textStyle")).getElementsByTagName("select"); 1969 1970 for (var i=0; i<selCount.length; i++)1971 {1972 selCount[i].style.visibility = "hidden";1973 } 1974 1975}1976function checkoutsideBottomPopUp(inputObj,height, scrollDivID)1977{1978 //var i = clienty + parseInt(divImageUpload.style.height);1979 if (!scrollDivID)1980 {1981 scrollDivID = "PageContentScrollDiv";1982 }1983 var i = getTopPos(inputObj) + parseInt(height.replace("px",""));1984 if ($id(scrollDivID))1985 {1986 var scrolltop = ($id(scrollDivID)).scrollTop;1987 var contentheight = ($id(scrollDivID)).offsetHeight;1988 if ((i - scrolltop) > (contentheight))1989 {1990 i = getTopPos(inputObj) ;1991 }1992 }1993 else1994 {1995 if( i > document.body.offsetHeight-10)1996 {1997 i = getTopPos(inputObj); //works1998 }1999 var scrolltop = 0;2000 }2001 2002 return i = i - scrolltop - parseInt(height.replace("px",""));2003}2004function checkoutsideWidth(inputObj,width, scrollDivID)2005{2006 if (!scrollDivID)2007 {2008 scrollDivID = "PageContentScrollDiv";2009 }2010 2011 var i = getleftPos(inputObj)+ parseInt(width.replace("px",""));2012 2013 var scrolleft = 0;2014 if ($id(scrollDivID))2015 {2016 scrolleft = ($id(scrollDivID)).scrollLeft;2017 }2018 2019 i = i - scrolleft;2020 if( i > document.body.offsetWidth-10)2021 {2022 i =getleftPos(inputObj) - scrolleft - parseInt(width.replace("px","")); //out2023 }2024 else2025 {2026 i = i - scrolleft - parseInt(width.replace("px",""));2027 }2028 2029 return i;2030}2031//jvz: function for Multivalue popup control;2032function $ShowSelectPopUpControl(headingText, contentText, controlID, closeBtn, closeBtnFn)2033{2034 if(($id(controlID)).style.width == "" || ($id(controlID)).style.width.indexOf("%") >0)2035 {2036 ($id(controlID)).style.width = "100px";2037 }2038 2039 $showPopup(headingText, contentText, controlID, "", "110", "", closeBtnFn, "", "", "", "", "", "", "", "", "");2040// var containerControl = "containerControlPOP";2041// var tblContainerControl = "tblContainerControlPOP";2042// var obj= event.srcElement;2043// var HeadingText = headingText;2044// var ContentText = contentText;2045// var newDiv = false;2046// var headerClose = "";2047// var headerMain = "";2048// var controlText = $id(controlID);2049// var controlValue = "";//controlText.innerHTML;2050// //Added 20px 24/nov due to bug in des?2051// if(controlText.style.height == "" || controlText.style.height == "20px")2052// {2053// controlText.style.height = "100px";2054// }2055// 2056// if(controlText.style.width == "" || controlText.style.width.indexOf("%") >0)2057// {2058// 2059// controlText.style.width = "100px";2060// }2061// 2062// var iPos = checkoutsideWidth(obj,controlText.style.width);2063// var xPosRec = checkoutsideBottomPopUp(obj,controlText.style.height);2064// if (_SubFormChildID == null)2065// {2066// controlText.style.left = iPos;2067// controlText.style.top = xPosRec;2068// } 2069// 2070// var controlHeight = controlText.style.height.replace("px","");2071// var controlWidth = controlText.style.width.replace("px","");2072// var screenL = window.screen.availWidth - controlWidth ;2073// var screenH = window.screen.availHeight - controlHeight;2074// var top =controlText.style.top.replace("px",""); //(screenH/3) + parseInt(returnScrollDimensions(0)); 2075// var left = controlText.style.left.replace("px",""); //(screenL/2) + parseInt(returnScrollDimensions(1));2076// 2077// var divAlert = ""; 2078// var divExists = $id(containerControl); 2079// var ViewID = "part_" + getParamsNumber(controlID);2080// var View = $id(ViewID);2081// var vtop = View.offsetTop;2082// var vleft = View.offsetLeft;2083// 2084// var dtop = (parseInt(top) + parseInt(vtop)) - parseInt(10);2085// var dleft = (parseInt(left) + parseInt(vleft)) + parseInt(20);2086// var st = "top:" + dtop + "px;" + "z-index:9025;position:absolute;left:" + dleft + "px;width:"+(parseInt(controlWidth)+10) + "px;height:"+(parseInt(controlHeight)+ 5)+"px";2087// 2088// if(divExists == null)2089// {2090// divAlert = document.createElement("DIV");2091// divAlert.id = containerControl; //"containerControl";2092// newDiv= true;2093// }2094// else2095// {2096// //return;2097// }2098// 2099// var stTop = (parseInt(top) + parseInt(vtop)) - parseInt(35);2100// var stLeft = parseInt(left)+ parseInt(vleft) - parseInt(7);2101// 2102// var stDiv = "top:" + stTop + "px;" + "z-index:9021;position:absolute;left:" + stLeft + "px;width:"+(parseInt(controlWidth)+30) + "px;height:"+(parseInt(controlHeight)+10)+"px";2103// 2104// if (closeBtn != false)2105// {2106// headerClose = '<img id="btnClose" src="../images/clear.GIF" style="width:15px;height:15px;cursor:hand;">'2107// }2108// 2109// headerMain = '<table cellspacing="0" cellpadding="0" style="table-layout:fixed;width:100%;"><tr><td style="padding-top:10px" align="left" nowrap>' + headingText + '</td><td align="right">' + headerClose + '</td></tr></table>';2110// 2111// //divAlert.style.cssText = "position:absolute;display:none;" + stDiv;2112// divAlert.style.cssText = controlText.style.cssText;2113// divAlert.style.top = parseInt(divAlert.style.top) - 36;2114// divAlert.style.left = parseInt(divAlert.style.left) - 10; 2115// divAlert.style.zIndex = "9995";2116// divAlert.innerHTML += '<table id="tblContainerControlPOP" cellpadding="0" cellspacing="0" border="0"><tr><td><div id="poptl" class="poptl"></div></td><td><div id="poptcPop" class="poptc"><div style="font-family:Arial;padding-top:5px;color:White;font-weight:bold;">' + headerMain + '</div></div></td><td><div id="poptrPOP" class="poptr"></div></td></tr><tr><td><div id="popclPOP" class="popcl"></div></td><td align="center"><div id="popccPOP" class="popcc">' + ""+ '</div></td><td><div id="popcrPOP" class="popcr"></div></td></tr><tr><td><div id="popblPOP" class="popbl"></div></td><td><div id="popbcPOP" class="popbc"></div></td><td><div id="popbrPOP" class="popbr"></div></td></tr></table>';2117// 2118// if(newDiv == true)2119// { 2120// var cid = getParamsNumber(controlID);2121// $id("part_" + cid).appendChild(divAlert);2122// 2123// }2124// 2125// //add iframe2126// 2127// var table = $id(tblContainerControl);2128// 2129// var testi = $id("ifr")2130// var i = null;2131// if(testi == null)2132// {2133// i = document.createElement("Iframe");2134// }2135// else2136// {2137// i = $id("ifr");2138// }2139// i.id = "ifr";2140// 2141// if(_SubViewIsOnTop ==true)2142// {2143// i.style.cssText = controlText.style.cssText;2144// i.style.zIndex = "9994"2145// //i.style.top = stTop - 35;2146// //i.style.left = stLeft - 7; 2147// //i.style.cssText = divAlert.style.cssText;2148// 2149// if(testi == null)2150// {2151// $id("part_" + cid).appendChild(i);2152// }2153// else2154// {2155// i.style.display = "block";2156// }2157// 2158// }2159// 2160// 2161// 2162// 2163// var thediv =null;2164// thediv = document.getElementById(containerControl);2165// thediv.style.display = "block";2166// 2167// 2168// document.getElementById("poptcPop").style.width=controlWidth+'px';2169// document.getElementById("popccPOP").style.width=controlWidth+'px';2170// document.getElementById("popbcPOP").style.width=controlWidth+'px';2171// document.getElementById("popclPOP").style.height=controlHeight+'px';2172// document.getElementById("popccPOP").style.height=controlHeight+'px';2173// document.getElementById("popcrPOP").style.height=controlHeight+'px';2174// 2175// document.getElementById("btnClose").attachEvent("onclick", closeBtnFn);2176 2177}2178//jvz multivalue popup;2179function $doHideControlPopupControl(controlID)2180{2181 var thediv = window.parent.document.getElementById("containerControlPOP") != null ? window.parent.document.getElementById("containerControlPOP") : document.getElementById("containerControlPOP");2182 var theControlID = window.parent.document.getElementById(controlID) != null ? window.parent.document.getElementById(controlID) : document.getElementById(controlID);2183 2184 if (thediv != null && thediv != "")2185 {2186 theControlID.style.display = "none";2187 ///var ifr = window.parent.document.getElementById("containerframePOP") != null ? window.parent.document.getElementById("containerframe") : document.getElementById("containerframe");2188 //ifr.style.display = "none";2189 var testi = $id("ifr")2190 if(testi !=null)2191 {2192 testi.style.display = "none";2193 }2194 thediv.style.display = "none";2195 thediv.parentNode.removeChild(thediv);2196 }2197}2198function RemoveAllTableRows(TableName)2199{2200 var thisTable = $id(TableName);2201 2202 if (thisTable != null)2203 {2204 var rows = thisTable.rows.length;2205 2206 for (var i = 0; i < rows; i++)2207 {2208 thisTable.deleteRow(0);2209 }2210 }2211}2212// Use for IFrame , in green div2213// setups everything but doesn't show until being called;2214function $doViewPopupIframe(headingText, contentText, src, viewHeight, viewWidth)2215{2216 showPWait()2217 var HeadingText = headingText;2218 var ContentText = contentText;2219 2220 if (viewHeight == null)2221 {2222 viewHeight = 350; 2223 }2224 2225 if (viewWidth == null)2226 {2227 viewWidth = 318;2228 }2229 2230 var screenL = (window.screen.availWidth/2) - (viewWidth/2);2231 var screenH = window.screen.availHeight - viewHeight;2232 2233 var top = (screenH/3) + parseInt(returnScrollDimensions(0)); 2234 var left = (screenL) + parseInt(returnScrollDimensions(1));2235 2236 var newDiv = false;2237 var divAlert = "";2238 var divExists = $id("containerView");2239 2240 var IframeEx = false;2241 2242 if(divExists == null)2243 {2244 divAlert = document.createElement("DIV");2245 divAlert.id = "containerView";2246 newDiv= true;2247 }2248 else2249 {2250 newDiv = false;2251 divAlert = divExists;2252 }2253 2254 var IFrameSrc = $id("IFrameSrc");2255 2256 if(IFrameSrc == null)2257 {2258 IFrameSrc = document.createElement("IFRAME");2259 IFrameSrc.id = "IFrameSrc";2260 IFrameSrc.src = src;2261 IframeEx = false;2262 IFrameSrc.frameBorder =0;2263 }2264 else2265 {2266 IframeEx = true;2267 }2268 2269 var stDiv = "top:" + (parseInt(top) - 100) + "px;z-index:9018;position:absolute;left:" + (parseInt(left) - 25) + "px;width:" + (viewWidth+20) + "px;height:" + (viewHeight+10) + "px";2270 var IframeStyle = "top:" + (parseInt(top) - 59) + "px;z-index:9017;position:absolute;left:" + (parseInt(left)-15) + "px;width:" + (viewWidth+10) + "px;height:" + (viewHeight+30) + "px;frameborder=0;";2271 2272 IFrameSrc.style.cssText = IframeStyle;2273 IFrameSrc.style.zIndex = IFrameSrc.style.zIndex +1;2274 IFrameSrc.style.height = IFrameSrc.style.height.replace("px","") -40;2275 IFrameSrc.style.width = IFrameSrc.style.width.replace("px","") -15;2276 IFrameSrc.style.left = parseInt(IFrameSrc.style.left.replace("px","")) + (parseInt(5));2277 IFrameSrc.style.display = "none";2278 2279 divAlert.style.cssText = "position:absolute;display:none;z-index:9019;" + stDiv;2280 //divAlert.innerHTML += '<table id="tblContainerView" cellpadding="0" cellspacing="0" border="0"><tr><td><div id="poptl" class="poptl"></div></td><td><div id="poptc" class="poptc"><div style="font-family:Arial;padding-top:15px;color:White;font-weight:bold;">' + HeadingText + '</div></div></td><td><div id="poptr" class="poptr"></div></td></tr><tr><td><div id="popcl" class="popcl"></div></td><td align="center"><div id="popcc" class="popcc">' + ContentText + '</div></td><td><div id="popcr" class="popcr"></div></td></tr><tr><td><div id="popbl" class="popbl"></div></td><td><div id="popbc" class="popbc"></div></td><td><div id="popbr" class="popbr"></div></td></tr></table>';2281 divAlert.innerHTML = generatePopupHTML("tblContainerView",headingText, "", ContentText, "", viewHeight, viewWidth, "","", "","");2282 2283 if(newDiv == true)2284 { 2285 document.body.appendChild(divAlert);2286 }2287 if(IframeEx==false)2288 {2289 document.body.appendChild(IFrameSrc);2290 }2291 2292 /* var thediv = "";2293 thediv = document.getElementById("containerView");2294 thediv.style.display = "block";2295 */2296// document.getElementById("poptc").style.width=viewWidth+'px';2297// document.getElementById("popcc").style.width=viewWidth+'px';2298// document.getElementById("popbc").style.width=viewWidth+'px';2299// document.getElementById("popcl").style.height=viewHeight+'px';2300// document.getElementById("popcc").style.height=viewHeight+'px';2301// document.getElementById("popcr").style.height=viewHeight+'px';2302}2303//Helper2304//this is to build the packet removing NAME_203 will return NAME2305function $getParamWithOutNumber(idcomingin)2306{2307 var arrS = idcomingin.split('_');2308 2309 //return arrS[0];2310 if (arrS != null)2311 { 2312 if(arrS.length == 1)2313 {2314 return arrS[0];2315 }2316 2317 if(arrS.length == 2) //LOAD_155 Course_Code (2)2318 { 2319 return arrS[0]; 2320 }2321 else2322 {2323 //bug met _ op die einde. bv 2324 //Send_for_Approval__7232325 var Id = arrS[arrS.length-1];2326 var sub = idcomingin.substring(0,idcomingin.indexOf('_'+Id));2327 return sub; 2328 }2329 } 2330}2331function $doViewPopupShowIframe()2332{2333 var thediv = "";2334 2335 thediv = window.parent.document.getElementById("containerView")2336 thediv.style.display = "block";2337 var theIFrame = window.parent.document.getElementById("IFrameSrc")2338 theIFrame.style.display = "block";2339 window.parent.hidePWait();2340 window.parent.busyDivTag();2341}2342function $doViewPopupCloseIframe()2343{2344 window.parent.HideDisableDiv();2345 var IfClose = window.parent.document.getElementById("tblContainerView");2346 if(IfClose !=null)2347 {2348 IfClose.parentNode.removeChild(IfClose);2349 }2350 2351 var containerView = window.parent.document.getElementById("containerView");2352 if(containerView !=null)2353 {2354 containerView.parentNode.removeChild(containerView);2355 }2356 2357 var Iframe = window.parent.document.getElementById("IFrameSrc");2358 if(Iframe !=null)2359 {2360 Iframe.parentNode.removeChild(Iframe);2361 }2362}2363//Hover Context Menus2364function showSelectedContext(obj)2365{2366 if (obj.className != "divSelected"){2367 obj.className = "selectedItemCat";2368 }2369}2370function hideSelectedContext(obj)2371{2372 obj.className = "divNormal";2373}2374//Hover Tree Items2375function showSelected()2376{2377 var hoverID = event.srcElement;2378 2379 hoverID.className = "selectedItem";2380 //selectedItem2381}2382function hideSelected()2383{2384 var hoverID = event.srcElement;2385 2386 hoverID.className = "smllabel";2387}2388//Resize of Window2389function ResizeEvent()2390{2391 var busyD = $id("divbusywithtop"); 2392 var CheckGlobalDiv = false;2393 if (busyD == null)2394 {2395 CheckGlobalDiv = true;2396 }2397 else2398 {2399 if (busyD.style.display == "none")2400 {2401 CheckGlobalDiv = true;2402 } 2403 }2404 2405 if (CheckGlobalDiv)2406 {2407 if (_currentBusyDiv != null)2408 { 2409 if (_currentBusyDiv != "")2410 {2411 busyD = $id(_currentBusyDiv); 2412 }2413 } 2414 }2415 2416 if (busyD != null)2417 {2418 busyD.style.width = document.forms[0].offsetWidth;2419 if (document.forms[0].offsetHeight >100)2420 {2421 busyD.style.height = document.forms[0].offsetHeight;2422 }2423 else2424 {2425 busyD.style.height = document.documentElement.clientHeight;2426 }2427 }2428 //the line below added by sean to recalculate all expressions on the page2429 document.recalc(true);2430}2431 /* mozlla insertAdjacentHTML replacement function - not quite working */2432 function mozilla_insertAdjacentHTML(control, sWhere, sHTML) 2433 {2434 var df; // : DocumentFragment2435 var r =control.ownerDocument.createRange();2436 2437 switch (String(sWhere).toLowerCase()) 2438 { // convert to string and unify case2439 case "beforebegin":2440 r.setStartBefore(control);2441 df = r.createContextualFragment(sHTML);2442 control.parentNode.insertBefore(df, control);2443 break;2444 2445 case "afterbegin":2446 r.selectNodeContents(control);2447 r.collapse(control);2448 df = r.createContextualFragment(sHTML);2449 control.insertBefore(df, control.firstChild);2450 break;2451 2452 case "beforeend":2453 r.selectNodeContents(control);2454 r.collapse(false);2455 df = r.createContextualFragment(sHTML);2456 control.appendChild(df);2457 break;2458 2459 case "afterend":2460 r.setStartAfter(control);2461 df = r.createContextualFragment(sHTML);2462 control.parentNode.insertBefore(df, control.nextSibling);2463 break;2464 } 2465 }2466 2467 var mozilla_emptyTags = {2468 "IMG": true,2469 "BR": true,2470 "INPUT": true,2471 "META": true,2472 "LINK": true,2473 "PARAM": true,2474 "HR": true2475 }2476 /*mozilla outerHTML replacement function */2477 function mozilla_outerHTML(control)2478 {2479 var attrs = control.attributes;2480 var str = "<" + control.tagName;2481 for (var i = 0; i < attrs.length; i++)2482 str += " " + attrs[i].name + "=\"" + attrs[i].value + "\"";2483 if (mozilla_emptyTags[this.tagName])2484 return str + ">";2485 return str + ">" + control.innerHTML + "</" + control.tagName + ">";2486 } 2487 2488//var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";2489//function encode64(input) 2490//{2491// if (input == "") return input;2492// var output = "";2493// var chr1, chr2, chr3;2494// var enc1, enc2, enc3, enc4;2495// var i = 0;2496// do 2497// {2498// chr1 = input.charCodeAt(i++);2499// chr2 = input.charCodeAt(i++);2500// chr3 = input.charCodeAt(i++);2501// enc1 = chr1 >> 2;2502// enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);2503// enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);2504// enc4 = chr3 & 63;2505// if (isNaN(chr2)) 2506// {2507// enc3 = enc4 = 64;2508// } 2509// else if (isNaN(chr3)) 2510// {2511// enc4 = 64;2512// }2513// output = output + keyStr.charAt(enc1) + keyStr.charAt(enc2) + keyStr.charAt(enc3) + keyStr.charAt(enc4);2514// } while (i < input.length);2515// 2516// return output;2517//}2518//function decode64(input) 2519//{2520// if (input == "") return input;2521// var output = "";2522// var chr1, chr2, chr3;2523// var enc1, enc2, enc3, enc4;2524// var i = 0;2525// // remove all characters that are not A-Z, a-z, 0-9, +, /, or =2526// input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");2527// do 2528// {2529// enc1 = keyStr.indexOf(input.charAt(i++));2530// enc2 = keyStr.indexOf(input.charAt(i++));2531// enc3 = keyStr.indexOf(input.charAt(i++));2532// enc4 = keyStr.indexOf(input.charAt(i++));2533// chr1 = (enc1 << 2) | (enc2 >> 4);2534// chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);2535// chr3 = ((enc3 & 3) << 6) | enc4;2536// output = output + String.fromCharCode(chr1);2537// if (enc3 != 64) 2538// {2539// output = output + String.fromCharCode(chr2);2540// }2541// if (enc4 != 64) 2542// {2543// output = output + String.fromCharCode(chr3);2544// }2545// } while (i < input.length);2546// return output;2547//}2548function $createCookie(name,value,days) {2549 if (days) {2550 var date = new Date();2551 date.setTime(date.getTime()+(days*24*60*60*1000));2552 var expires = "; expires="+date.toGMTString();2553 }2554 else var expires = "";2555 document.cookie = name+"="+value+expires+"; path=/";2556}2557function $readCookie(name) {2558 var nameEQ = name + "=";2559 var ca = document.cookie.split(';');2560 for(var i=0;i < ca.length;i++) {2561 var c = ca[i];2562 while (c.charAt(0)==' ') c = c.substring(1,c.length);2563 if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);2564 }2565 return null;2566}2567function $eraseCookie(name) {2568 createCookie(name,"",-1);2569}2570function $containsSpecialChars(inputString, excludeChars)2571{2572 var validateResult = -1;2573 var specialChars = "&!@#$%^&*()+=-[]\\\';,./{}|\":<>?_~";2574 var chinSpecialChars1 = "≈≠=≤≥≤<>≮≯∷±+-×÷∫∮∝∧∨∑∏∪∩∈∵∴⊥∥∠⌒⊙≌∽√";2575 var chinSpecialChars2 = "┼┽┾┿╀╁╂╃┬┭┮┯┰┰┱┱┲┳├┝┞┟┠┡┢┣┍┎┏┐┑┒┓┒─┄";2576 var chinSpecialChars3 = "§№☆★○●◎◇◆□℃‰€■△▲※→←↑↓〓¤°#&@\︿_ ̄―♂♀";2577 var chinSpecialChars4 = "〖〗【】[]{}《》「」『』々‖…—•ˉ〃";2578 var chinSpecialChars5 = "ㄅㄉˇˋㄓˊˊ˙˙ㄚㄞㄢㄆㄊㄍㄐㄔㄗㄧㄛㄟㄣㄇㄋㄎㄑㄕㄘㄨㄜㄠㄈㄌㄏㄒㄖㄙㄩㄝㄡㄥ";2579 var ExcludeList = excludeChars.split(" ");2580 //remove excluded chars form list 2581 for (var k = 0; k < ExcludeList.length; k++)2582 {2583 specialChars = specialChars.replace(ExcludeList[k],"");2584 chinSpecialChars1 = chinSpecialChars1.replace(ExcludeList[k],"");2585 chinSpecialChars2 = chinSpecialChars2.replace(ExcludeList[k],"");2586 chinSpecialChars3 = chinSpecialChars3.replace(ExcludeList[k],"");2587 chinSpecialChars4 = chinSpecialChars4.replace(ExcludeList[k],"");2588 chinSpecialChars5 = chinSpecialChars5.replace(ExcludeList[k],"");2589 2590 }2591 2592 for (var i = 0; i < inputString.length; i++) 2593 {2594 if (specialChars.indexOf(inputString.charAt(i)) != -1) 2595 {2596 validateResult = i;2597 }2598 if (chinSpecialChars1.indexOf(inputString.charAt(i)) != -1) 2599 {2600 validateResult = true;2601 }2602 if (chinSpecialChars2.indexOf(inputString.charAt(i)) != -1) 2603 {2604 validateResult = true;2605 }2606 if (chinSpecialChars3.indexOf(inputString.charAt(i)) != -1) 2607 {2608 validateResult = true;2609 }2610 if (chinSpecialChars4.indexOf(inputString.charAt(i)) != -1) 2611 {2612 validateResult = true;2613 }2614 if (chinSpecialChars5.indexOf(inputString.charAt(i)) != -1) 2615 {2616 validateResult = true;2617 }2618 }2619 return validateResult;2620}2621function convertToGuidString(normalstring)2622{2623 if (normalstring == "0")2624 {2625 normalstring = "00000000-0000-0000-0000-000000000000";2626 } 2627 var newstring = normalstring;2628 var part1 = "";2629 var part2 = "";2630 var part3 = "";2631 var part4 = "";2632 var part5 = ""; 2633 if (normalstring.indexOf('-') == -1)2634 {2635 normalstring = ReplaceID(normalstring, 'part_', '');2636 part1 = normalstring.substring(0, 8);2637 part2 = normalstring.substring(8, 12);2638 part3 = normalstring.substring(12, 16);2639 part4 = normalstring.substring(16, 20);2640 part5 = normalstring.substring(20);2641 newstring = part1 + "-" + part2 + "-" + part3 + "-" + part4 + "-" + part5;2642 } 2643 return newstring;2644}2645function convertFromGuidString(guidstring)2646{2647 var newstring = ReplaceID(guidstring, "-", "");2648 newstring = newstring.toUpperCase();2649 return newstring; 2650}2651// Allows the developer to find HTML elements of a specific classname2652function getElementsByClassName(node, classname)2653{2654 var a = [];2655 var re = new RegExp('(^| )'+classname+'( |$)');2656 var els = node.getElementsByTagName("*");2657 for(var i=0,j=els.length; i<j; i++)2658 if(re.test(els[i].className))a.push(els[i]);2659 return a;2660}2661function hasClassName(el, name) {2662 // Return true if the given element currently has the given class2663 // name. 2664 var re = new RegExp('(?:^|\\s)'+name+'(?:\\s|$)');2665 2666 if (el.className.match(re) != -1 && el.className.match(re) != null)2667 {2668 return true;2669 }2670 else2671 {2672 return false;2673 }2674 2675}2676function addClassName(el, name)2677{2678 if (!hasClassName(el, name)) el.className = (el.className+' '+name);2679}2680function removeClassName(el, name) {2681 // Remove the given class name from the element's className property.2682 2683 /*var re = new RegExp('(^|\\s)'+name+'(?:\\s|$)');2684 el.className = el.className.replace(re, '$1');*/2685 2686 var curClasses = el.className.split(" ");2687 var newClasses = [];2688 2689 for (var i = 0; i < curClasses.length; i++)2690 {2691 if (curClasses[i] != "" && curClasses[i] != name) newClasses.push(curClasses[i]);2692 }2693 2694 el.className = newClasses.join(" ");2695 2696}2697function toggleClassName(el, name)2698{2699 if (hasClassName(el, name))2700 {2701 removeClassName(el, name);2702 }2703 else2704 {2705 addClassName(el, name);2706 }2707}2708function getPageOffsetLeft(el) {2709 var x;2710 // Return the x coordinate of an element relative to the page.2711 x = el.offsetLeft;2712 if (el.offsetParent != null)2713 x += getPageOffsetLeft(el.offsetParent);2714 return x;2715}2716function getPageOffsetTop(el) {2717 var y;2718 // Return the x coordinate of an element relative to the page.2719 y = el.offsetTop;2720 if (el.offsetParent != null)2721 y += getPageOffsetTop(el.offsetParent);2722 return y;2723}2724function $showException(objErr,CloseMethod, extraPath)2725{2726 var finalErr = "";2727 var closeMethod = "doHidePopup()";2728 2729 if ((CloseMethod != null) && (typeof(CloseMethod) != "undefined"))2730 {2731 closeMethod = CloseMethod;2732 }2733 2734 2735 finalErr += "<Table cellspacing=2 cellpadding=0 border=0><tr><td colspan=2 align=left class='smllabelbold'>An unexpected error occurred, please review the following information:</td></tr><tr><td colspan=2>&nbsp;</td></tr>";2736 2737 if (objErr.Title != null)2738 {2739 finalErr += "<tr><td valign=top align=left class='smllabelbold'>Title:</td><td align=left class='smllabel'>" + objErr.Title + "</td></tr>";2740 }2741 2742 if (objErr.Type != null)2743 { 2744 finalErr += "<tr><td valign=top align=left class='smllabelbold'>Type:</td><td align=left class='smllabel'>" + objErr.Type + "</td></tr>";2745 }2746 2747 if (objErr.Description != null)2748 {2749 finalErr += "<tr><td valign=top align=left class='smllabelbold'>Description:</td><td align=left class='smllabel'>" + objErr.Description + "</td></tr>"2750 }2751 2752 if (objErr.StackTrace != null)2753 {2754 finalErr += "<tr><td valign=top align=left class='smllabelbold'>StackTrace:</td><td align=left class='smllabel'>" + objErr.StackTrace + "</td></tr>"2755 } 2756 2757 finalErr += "</table>";2758 if (!extraPath)2759 {2760 extraPath = "";2761 } 2762 doPopupIframe("Error",finalErr,450,200,"OK",closeMethod,"","","","","20000","",extraPath, "", "error");2763}2764function $CustomError()2765{2766 this.Title;2767 this.Type;2768 this.Description;2769 this.StackTrace;2770}2771function $addEvent(obj, evType, fn)2772{2773 //if(evType.indexOf("on"))2774 //{2775 // evType = ReplaceID(evType,"on","");2776 //}2777 var evTypeRef = '__' + evType;2778 if (obj[evTypeRef])2779 {2780 if (array_search(fn, obj[evTypeRef]) > -1) return;2781 }2782 else2783 {2784 obj[evTypeRef] = [];2785 if (obj['on'+evType]) obj[evTypeRef][0] = obj['on'+evType];2786 obj['on'+evType] = handleEvent;2787 }2788 obj[evTypeRef][obj[evTypeRef].length] = fn;2789}2790/* Adds multiple events to an object that fires the same function */2791function $addEvents(obj, evs, fn)2792{2793 for (var i = evs.length; --i >= 0;)2794 {2795 $addEvent(el, evs[i], func);2796 }2797}2798function $removeEvent(obj, evType, fn)2799{2800 var evTypeRef = '__' + evType;2801 if (obj != null)2802 {2803 if (obj[evTypeRef])2804 {2805 var i = array_search(fn, obj[evTypeRef]);2806 if (i > -1) delete obj[evTypeRef][i];2807 }2808 }2809}2810/* Remove multiple events from an object that fires the same function */2811function $removeEvents(obj, evs, fn)2812{2813 for (var i = evs.length; --i >= 0;)2814 {2815 $removeEvent(el, evs[i], func);2816 }2817}2818function handleEvent(e)2819{2820 e = e || window.event;2821 var evTypeRef = '__' + e.type;2822 var retValue = true;2823 for (var i = 0, j = this[evTypeRef].length; i < j; i++)2824 {2825 if (this[evTypeRef][i])2826 {2827 this.__fn = this[evTypeRef][i];2828 retValue = this.__fn(e) && retValue;2829 }2830 }2831 if (this.__fn) try { delete this.__fn; } catch(e) { this.__fn = null; }2832 return retValue;2833}2834function array_search(val, arr)2835{2836 var i = arr.length;2837 while (i--)2838 if (arr[i] && arr[i] === val) break;2839 return i;2840}2841/* SVE: 15/02/2007: shows a mini version of the busydivtag, when only a certain div should be disabled */2842function miniBusyDiv(divTagID)2843{2844// if (_MustShowPop)2845// {2846// return;2847// } 2848 if ($id('miniBusy_' + divTagID)) 2849 {2850 var controlMiniState = ($id('miniBusy_' + divTagID));2851 controlMiniState.parentNode.removeChild(controlMiniState); 2852 } 2853 2854 var controlwidth = ($id(divTagID)).offsetWidth;2855 var controlheight = ($id(divTagID)).offsetHeight;2856 var controlzindex = 10000;2857 var controltop = getElementTrueTop($id(divTagID));2858 var controlleft = getElementTrueLeft($id(divTagID));2859 2860 var controlBusyDiv = document.createElement("div");2861 controlBusyDiv.id = 'miniBusy_' + divTagID; 2862 controlBusyDiv.style.width = controlwidth;2863 controlBusyDiv.style.height = controlheight;2864 controlBusyDiv.style.zIndex = controlzindex;2865 controlBusyDiv.style.left = controlleft;2866 controlBusyDiv.style.top = controltop; 2867 controlBusyDiv.style.position = "absolute";2868 controlBusyDiv.style.background = "white";2869 controlBusyDiv.style.border = "2px solid whitesmoke"; 2870 controlBusyDiv.style.filter = "Alpha(opacity=85)"; 2871 controlBusyDiv.innerHTML = "<table height='100%' width='100%'><tr valign='middle'><td align='center'><img src='../images/Blue_Big_Rotate.gif' /></td></tr></table>"; 2872 ($id(divTagID)).disabled = "disabled"; 2873 document.body.appendChild(controlBusyDiv); 2874}2875function miniBusyDone(divTagID)2876{2877 if ($id(divTagID))2878 { 2879 if ($id('miniBusy_' + divTagID)) 2880 {2881 var controlBusyDiv = ($id('miniBusy_' + divTagID));2882 controlBusyDiv.parentNode.removeChild(controlBusyDiv); 2883 } 2884 ($id(divTagID)).disabled = "";2885 }2886}2887/* end mini busy div */2888function generatePopupHTML(id, heading, info, content, buttons, height, width, closeButtonName, closeFunction, infoHeader, infoContent, pathExtra, popupImage)2889{2890 if (!pathExtra)2891 {2892 pathExtra = "";2893 } 2894 2895 if (!popupImage)2896 {2897 popupImage = "";2898 }2899 var htmlValue = "";2900 2901 htmlValue += '<table width="100%" height="100%" cellpadding="0" border="0" cellspacing="0" id="' + id + '">'; 2902 htmlValue += ' <tr>';2903 htmlValue += ' <td valign=top align=left >';2904 htmlValue += ' <table id="body" width="100%" height="100%" border="0" cellpadding="0" cellspacing="0" >'; 2905 htmlValue += ' <tr >';2906 htmlValue += ' <td valign=top><IMG SRC="' + pathExtra + '../images/popup_top_left.gif"></td>';2907 htmlValue += ' <td class="toptab_repeat " width="100%" >';2908 htmlValue += ' <table cellpadding="0" cellspacing="0" width="100%" >';2909 htmlValue += ' <tr>';2910 htmlValue += ' <td colspan="2"><IMG height="3px" SRC="' + pathExtra + '../images/spacer.gif"></td>';2911 htmlValue += ' </tr>';2912 htmlValue += ' <tr>';2913 htmlValue += ' <td >';2914 htmlValue += ' <table width=100%>';2915 htmlValue += ' <tr>';2916 htmlValue += ' <td class="white_heading" >&nbsp;' + heading + '</td>';2917 if ((closeFunction != null) && (closeFunction.length > 0))2918 { 2919 htmlValue += ' <td align=right>';2920 htmlValue += ' <img src="' + pathExtra + '../images/close.gif" onclick="' + closeFunction + '" style="cursor:hand;" /></td>';2921 } 2922 htmlValue += ' </tr>'; 2923 htmlValue += ' </table>';2924 htmlValue += ' </td>';2925 htmlValue += ' </tr>';2926 htmlValue += ' </table>';2927 htmlValue += ' </td>';2928 htmlValue += ' <td align="right" valign=top><IMG SRC="' + pathExtra + '../images/popup_top_right.gif"></td>';2929 htmlValue += ' </tr>';2930 htmlValue += ' <tr>';2931 htmlValue += ' <td colspan="3" height="100%" bgcolor="white">';2932 htmlValue += ' <table width="100%" height="100%" cellpadding="0" cellspacing="0" border="0" bgcolor="white">';2933 htmlValue += ' <tr>';2934 htmlValue += ' <td class="tabs_left_plain_repeat" width="3px"><img width="3px" src="' + pathExtra + '../images/spacer.gif"></td>';2935 htmlValue += ' <td width="100%" height="100%">';2936 htmlValue += ' <table width="100%" height="100%" cellpadding="1" cellspacing="1" border="0">';2937 htmlValue += ' <tr>';2938 htmlValue += ' <td style="width: 1px;"></td>';2939 htmlValue += ' </tr>';2940 if (info.length > 0)2941 { 2942 htmlValue += ' <tr>';2943 if (popupImage.length > 0)2944 {2945 htmlValue += '<td colspan="2" valign="top" width="100%"><div id="info" style="height:30px; overflow:auto;width:100%;" class="info"> ' + info + '</div>';2946 }2947 else2948 {2949 htmlValue += '<td valign="top" width="100%"><div id="info" style="height:30px; overflow:auto;width:100%;" class="info"> ' + info + '</div>';2950 }2951 htmlValue += ' </td>';2952 htmlValue += ' </tr>';2953 } 2954 htmlValue += ' <tr valign=top>';2955 if (popupImage.length > 0)2956 {2957 htmlValue += '<td style=\"width:48px;\"><img src="' + pathExtra + '../images/' + popupImage + '48x48.gif" /></td>'; 2958 htmlValue += ' <td height=' + (parseInt(height) + 10) ;2959 }2960 else2961 {2962 htmlValue += ' <td colspan="2" style="padding-left:10px;" height="' + (parseInt(height) + 10) + 'px"';2963 }2964 if (content.length > 0)2965 { 2966 htmlValue += ' class=black_bdtxt >' + content;2967 } 2968 else2969 {2970 htmlValue += '>';2971 } 2972 htmlValue += ' </td>';2973 htmlValue += ' </tr>';2974 htmlValue += ' </table>';2975 htmlValue += ' </td>';2976 htmlValue += ' <td class="tabs_right_plain_repeat" style="border-right: solid 1px #E0E0E0" width=4px><img width=4px src="' + pathExtra + '../images/spacer.gif"></td>';2977 htmlValue += ' </tr>';2978 htmlValue += ' </table>';2979 htmlValue += ' </td>';2980 htmlValue += ' </tr>';2981 //if buttons should be added into the popup 2982 if (buttons.length > 0)2983 { 2984 2985 //left edge of buttons2986 htmlValue += ' <tr>';2987 htmlValue += ' <td colspan=3>';2988 htmlValue += ' <table cellpadding=0 cellspacing=0 border=0 width="100%">';2989 htmlValue += ' <tr>';2990 2991 if (infoHeader.length > 0)2992 {2993 htmlValue += ' <td rowspan=2><img src="' + pathExtra + '../images/help_button.gif" onclick="ShowK2Help(' + infoHeader + ')" /></td>';2994 //onclick=showHelpPopup("help' + id + '")2995 }2996 else2997 {2998 htmlValue += ' <td rowspan=2><img src="' + pathExtra + '../images/button_left_two_edges.gif" /></td>';2999 }3000 htmlValue += ' <td class="button_bar_repeat" width=100%></td>';3001 htmlValue += ' <td class="button_bar_repeat" valign=top width=4px><img src="' + pathExtra + '../images/button_left.gif" /></td>';3002 3003 var btnValues = buttons.split("☺");3004 var btnValue = '';3005 var fn = '';3006 var looper = 0;3007 for (var i=0; i<btnValues.length; i++)3008 {3009 if (i % 2 == 0)3010 {3011 //new button & values3012 btnValue = btnValues[i];3013 if (btnValue.length > 0)3014 { 3015 fn = btnValues[i + 1];3016 if (fn.split("|")[1] != null)3017 {3018 _popEvents[fn.split("|")[1]] = fn.split("|")[0];3019 fn = fn.split("|")[0]; 3020 } 3021 3022 htmlValue += ' <td style="cursor:hand;" class="button_repeat" id="' + btnValue +'" onclick="' + fn +'" onmouseover=\'popupButtonMouseOver(event, "' + pathExtra +'")\' onmouseout=\'popupButtonMouseOut(event, "' + pathExtra +'")\' nowrap>' + btnValue+ '</td>';3023 looper += 1; 3024 }3025 3026 if ((i + 2) < btnValues.length)3027 {3028 htmlValue += ' <td ><img src="' + pathExtra + '../images/toolbar_repeat-.gif" /></td>';3029 looper +=1;3030 }3031 else3032 {3033 htmlValue += ' <td rowspan=2 ><img src="' + pathExtra + '../images/buttonbar_right2.gif" /></td>';3034 looper +=2;3035 }3036 }3037 }3038 3039 //repeater for looper 3040 htmlValue += ' </tr>';3041 htmlValue += ' <tr>';3042 htmlValue += ' <td class=button_bar_bottom_repeat colspan=' + looper + ' width=100% height=4px ><img src="' + pathExtra + '../images/spacer.gif" /></td>';3043 htmlValue += ' </tr>';3044 htmlValue += ' </table>';3045 htmlValue += ' </td>';3046 htmlValue += ' </tr>';3047 htmlValue += ' </table>';3048 htmlValue += ' </td>';3049 htmlValue += ' </tr>';3050 }3051 else // just the "normal" closing tags - without place for buttons3052 {3053 htmlValue += ' <tr>';3054 htmlValue += ' <td colspan=3>';3055 htmlValue += ' <table cellpadding=0 cellspacing=0 border=0 width="100%">';3056 htmlValue += ' <tr>';3057 htmlValue += ' <td rowspan=2><img src="' + pathExtra + '../images/bottom_left_clear.gif" /></td>';3058 htmlValue += ' <td width=100% style="background:white;"></td>';3059 htmlValue += ' <td rowspan=2 ><img src="' + pathExtra + '../images/buttonbar_right_clear.gif" /></td>';3060 htmlValue += ' </tr>';3061 htmlValue += ' <tr>';3062 htmlValue += ' <td class=button_bar_bottom_repeat width=100% ><img src="' + pathExtra + '../images/spacer.gif" /></td>';3063 htmlValue += ' </tr>';3064 htmlValue += ' </table>';3065 htmlValue += ' </td>';3066 htmlValue += ' </tr>';3067 htmlValue += ' </table>';3068 htmlValue += ' </td>';3069 htmlValue += ' </tr>';3070 } 3071 htmlValue += ' </table>';3072 3073// htmlValue += '<tr><td>';3074// htmlValue += generateInfoPopupHTML('blablabla','morebla die bla <br>again and again', width, 0);3075// htmlValue += '</td></tr>'; 3076 3077 return htmlValue; 3078}3079function setPopupButtonStatus(id, status)3080{3081 //id = id of control3082 //status = new status (disabled, enabled)3083 //todo: remove the click events from the buttons (or do the check from the functions?)3084 ($id(id)).setAttribute("status", status); 3085 if (status == "disabled")3086 {3087 ($id(id)).className = "button_repeat_disabled";3088 }3089 else3090 {3091 ($id(id)).className = "button_repeat";3092 }3093}3094function generateInfoPopupHTML(InfoHeader, InfoText, width, height, pathExtra)3095{3096 var htmlValue = '';3097 if ((!width)||(width < 100))3098 {3099 width = 100;3100 } 3101 htmlValue += '<table cellpadding=0 cellspacing=0 border=0 width="' + width +'">';3102 htmlValue += ' <tr>';3103 htmlValue += ' <td width=6px><img src="' + pathExtra + '../images/help_left_top.gif" /></td>';3104 htmlValue += ' <td class=help_top_repeat></td>';3105 htmlValue += ' <td ><img src="' + pathExtra + '../images/help_top_right.gif" /></td>';3106 htmlValue += ' </tr>';3107 htmlValue += ' <tr>';3108 htmlValue += ' <td class=help_left_repeat height=100% width=6px></td>';3109 htmlValue += ' <td width=100% class=help_body><b><i>' + InfoHeader + '</i></b><br>';3110 htmlValue += InfoText;3111 htmlValue += ' </td>';3112 htmlValue += ' <td class=help_right_repeat></td>';3113 htmlValue += ' </tr>';3114 htmlValue += ' <tr>';3115 htmlValue += ' <td colspan=3>';3116 htmlValue += ' <table cellpadding=0 cellspacing=0>';3117 htmlValue += ' <tr>';3118 htmlValue += ' <td colspan=2 align=left width=52px><img src="' + pathExtra + '../images/help_left_bottom.gif" /></td>';3119 htmlValue += ' <td class=help_bottom_repeat width=100%></td>';3120 htmlValue += ' <td valign=top><img src="' + pathExtra + '../images/help_right_bottom.gif" /></td>';3121 htmlValue += ' </tr>';3122 htmlValue += ' </table>';3123 htmlValue += ' </td>';3124 htmlValue += ' </tr>';3125 htmlValue += '</table>';3126 3127 return htmlValue; 3128}3129function createHelpPopup(ID, InfoHeader, InfoText, width, height, pathExtra)3130{3131 var helpDiv;3132 if ($id(ID))3133 {3134 helpDiv = ($id(ID));3135 }3136 else3137 {3138 helpDiv = document.createElement("DIV");3139 helpDiv.id = ID;3140 document.appendChild(helpDiv);3141 } 3142 helpDiv.innerHTML = generateInfoPopupHTML(InfoHeader, InfoText, width, height, pathExtra);3143 helpDiv.style.display = "none";3144 helpDiv.style.position = "absolute";3145}3146function showHelpPopup(ID, top, left)3147{3148 var helpDiv;3149 if ($id(ID))3150 {3151 helpDiv = ($id(ID));3152 helpDiv.style.display = "";3153 if (!top)3154 {3155 top = event.clientY;3156 }3157 if (!left)3158 {3159 left = event.clientX;3160 }3161 helpDiv.style.top = top;3162 helpDiv.style.left = left;3163 }3164}3165function hideHelpPopup(ID)3166{3167 var helpDiv;3168 if ($id(ID))3169 {3170 helpDiv = ($id(ID));3171 helpDiv.style.display = "none";3172 }3173}3174function $showPopup(HeadingText, ContentText, ControlID, Height, Width, IframeSrc, CloseFunction, ButtonValues, ZIndex, BusyDivID, ExtraPath, InfoText, HelpHeader, HelpContents, Drag, popupImage)3175{3176 //Text in the header of the popup3177 if (!HeadingText)3178 {3179 HeadingText = "";3180 } 3181 //Text to be displayed in the popup, if no control is popped up3182 if (!ContentText)3183 {3184 ContentText = "";3185 } 3186 //control to display in the popup3187 if (!ControlID)3188 {3189 ControlID = "";3190 }3191 //height of the popup3192 if (!Height)3193 {3194 Height = "";3195 } 3196 //width of the popup3197 if (!Width)3198 {3199 Width = "";3200 }3201 //src of the iframe that will be popped up3202 if (!IframeSrc)3203 {3204 IframeSrc = "";3205 }3206 //function to execute on the close button3207 if (!CloseFunction)3208 {3209 CloseFunction = "";3210 }3211 //list of buttons with relevant functions3212 if (!ButtonValues)3213 {3214 ButtonValues = "";3215 }3216 //zindex of popup3217 if (!ZIndex)3218 {3219 ZIndex = "";3220 }3221 //name of busy div to be displayed3222 if (!BusyDivID)3223 {3224 BusyDivID = "";3225 }3226 //extra path which will be appended to src of images of popup3227 if (!ExtraPath)3228 {3229 ExtraPath = "";3230 }3231 //information text of popup (green section)3232 if (!InfoText)3233 {3234 InfoText = "";3235 }3236 //Help ID to be passed to the help file3237 if (!HelpHeader)3238 {3239 HelpHeader = "";3240 }3241 //contents of help (redundant)3242 if (!HelpContents)3243 {3244 HelpContents = "";3245 }3246 //whether the popup should be draggable - not implemented3247 if (!Drag)3248 {3249 Drag = "";3250 }3251 //image to be displayed next to the message in the popup3252 //options: warning, info, error, help3253 if (!popupImage)3254 {3255 popupImage = "";3256 }3257 3258 //declaration of variables3259 var IframeZIndex = 10019;3260 var DivZIndex = 10020; 3261 var currentIndex = 9020; 3262 var divAlert ; 3263 var ControlDiv;3264 var ifr; 3265 3266 //calculation of relevant zIndeces3267 if (ControlID.length > 0)3268 { 3269 if (($id(ControlID)).style.zIndex)3270 {3271 currentIndex = ($id(ControlID)).style.zIndex; 3272 } 3273 else3274 {3275 ($id(ControlID)).style.zIndex = currentIndex;3276 }3277 DivZIndex = parseInt(parseInt(currentIndex) - parseInt(1));3278 IframeZIndex = parseInt(parseInt(currentIndex) - parseInt(2));3279 } 3280 3281 //generate/reference foreground iframe 3282 if ((ControlID.length == 0) && (IframeSrc.length > 0))3283 {3284 var IframeControl = ($id("IFrameSrc"));3285 if(!(IframeControl))3286 {3287 IframeControl = document.createElement("IFRAME");3288 IframeControl.id = "IFrameSrc";3289 IframeControl.frameBorder =0; 3290 document.body.appendChild(IframeControl);3291 }3292 IframeControl.style.width = Width;3293 IframeControl.style.height = (parseInt(Height) + 15);3294 IframeControl.src = IframeSrc;3295 3296 IframeControl.style.zIndex = (parseInt(DivZIndex) + parseInt(2));3297 ControlID = IframeControl.id;3298 }3299 //Busy Div tag & zIndex3300 if (ZIndex == undefined)3301 {3302 ZIndex= "";3303 } 3304 if ((ZIndex=="undefined")||(ZIndex.length == 0))3305 {3306 3307 if (ControlID.length > 0)3308 {3309 busyDivTag((parseInt(DivZIndex)-parseInt(2)), "busy_" + ControlID);3310 } 3311 else3312 {3313 if ((BusyDivID=="undefined")||(BusyDivID.length == 0))3314 {3315 busyDivTag();3316 }3317 else3318 {3319 busyDivTag((parseInt(DivZIndex)-parseInt(2)), "busy_" + BusyDivID);3320 } 3321 }3322 }3323 else3324 {3325 IframeZIndex = (parseInt(ZIndex) + parseInt(1));3326 DivZIndex = (parseInt(ZIndex) + parseInt(2));3327 busyDivTag(ZIndex,BusyDivID);3328 }3329 3330 //display of control3331 if (!ControlID)3332 {3333 ControlID = "";3334 }3335 else if ($id(ControlID))3336 { 3337 ControlDiv = $id(ControlID);3338 ControlDiv.style.display = "block"; 3339 if (!Height)3340 {3341 Height =(parseInt(ControlDiv.style.height.replace("px","")));3342 } 3343 3344 if (!Width)3345 {3346 Width = (parseInt(ControlDiv.style.width.replace("px","")));3347 }3348 3349 if ((Height == "") || isNaN(Height))3350 Height = ControlDiv.offsetHeight;3351 3352 if ((Width == "") || isNaN(Width))3353 Width = ControlDiv.offsetWidth; 3354 }3355 3356 if ((CloseFunction.length == 0)||(CloseFunction == "doHidePopup()"))3357 {3358 //close function of the popup3359 CloseFunction = "doHidePopup('" + ControlID + "')";3360 }3361 var screenL = document.documentElement.offsetWidth - Width ;3362 var screenH = document.documentElement.offsetHeight - Height; 3363 if (InfoText.length > 0)3364 {3365 screenH = screenH - 110;3366 }3367 var xtraPopupHeight=70;3368 var top = ((screenH-xtraPopupHeight)/2) + parseInt(returnScrollDimensions(0));3369 if (top<0)3370 {3371 top=0;3372 } 3373 var left = (screenL/2) + parseInt(returnScrollDimensions(1));3374 //poisitioning of div 3375 var stDiv = "top:" + parseInt(top-5) + "px;left:" + parseInt(left-5) + "px;width:" + (parseInt(Width)+10) + "px;height:" + (parseInt(Height)+10) + "px;"3376 3377 if ($id("container" + ControlID))3378 {3379 divAlert = ($id("container" + ControlID));3380 }3381 else3382 {3383 divAlert = document.createElement("DIV"); 3384 divAlert.id = "container" + ControlID;3385 divAlert.className = "dragmain";3386 3387 //add control/parentdiv to array of controls which can be moved3388 if ($id(ControlID))3389 {3390 popupControls.push(($id(ControlID)));3391 }3392 else3393 {3394 popupControls.push(divAlert);3395 }3396 3397 if ((ControlID.length == 0)||(IframeSrc.length > 0))3398 {3399 document.body.appendChild(divAlert);3400 }3401 else3402 {3403 ($id(ControlID)).parentNode.appendChild(divAlert);3404 }3405 } 3406 //set the innerhtml of the div3407 divAlert.innerHTML = generatePopupHTML('tblContainer' + ControlID, HeadingText, InfoText, ContentText, ButtonValues, Height, Width, "X", CloseFunction, HelpHeader, HelpContents, ExtraPath, popupImage)3408 divAlert.style.cssText = "position:absolute;display:none;z-index:"+ DivZIndex +";" + stDiv;3409 3410 //add background iframe3411 if ($id("iframepopups" + ControlID))3412 {3413 ifr = ($id("iframepopups" + ControlID));3414 } 3415 else3416 {3417 ifr = document.createElement("IFRAME");3418 ifr.id = "iframepopups" + ControlID;3419 divAlert.parentElement.appendChild(ifr);3420 }3421 ifr.className="dragmeIfr"; 3422 ifr.frameBorder = "0";3423 var table = $id("tblContainer" + ControlID);3424 var st = "top:" + parseInt(top) + "px;z-index:" + IframeZIndex+";position:absolute;left:" + parseInt(left) + "px;width:" + (parseInt(Width)-5) + "px;height:" + (parseInt(Height)-5) + "px"; 3425 3426 //toggle the relevant visibility of the div and iframe 3427 $DivSetVisible(true,table,ifr,st);3428 3429 if (ControlDiv)3430 {3431 //Control style 3432 var stcontrol = "";3433 if (InfoText.length > 0)3434 {3435 stcontrol = ";top:" + (parseInt(top) + parseInt(75)) + "px;z-index:" + parseInt(parseInt(DivZIndex) + parseInt(1)) + ";position:absolute;left:" + (parseInt(left)) + "px;";3436 }3437 else3438 { 3439 stcontrol = ";top:" + (parseInt(top) + parseInt(33)) + "px;z-index:" + parseInt(parseInt(DivZIndex) + parseInt(1)) + ";position:absolute;left:" + (parseInt(left)) + "px;";3440 } 3441 ControlDiv.style.cssText += stcontrol;3442 }3443 divAlert.style.display = "block";3444 divAlert.focus(); 3445 3446// if (HelpHeader.length > 0)3447// {3448// createHelpPopup("help" + 'tblContainer' + ControlID, HelpHeader, HelpContents, 0, 200, ExtraPath);3449// } 3450}3451function getElementTrueLeft(inputObj)3452{3453 var returnValue = inputObj.offsetLeft;3454 3455 while((inputObj = inputObj.offsetParent) != null)3456 {3457 if(inputObj.tagName!='HTML')returnValue += inputObj.offsetLeft;3458 }3459 3460 return returnValue;3461}3462function getElementTrueTop(inputObj)3463{ 3464 var returnValue = inputObj.offsetTop;3465 3466 while((inputObj = inputObj.offsetParent) != null)3467 {3468 if(inputObj.tagName!='HTML')returnValue += inputObj.offsetTop;3469 }3470 return returnValue;3471}3472function popupButtonMouseOver(e, pathExtra)3473{3474 var openevent = (e) ? e : window.event;3475 var tg = (e.target) ? e.target : e.srcElement3476 if (tg.getAttribute("status") == "disabled")3477 {3478 return false;3479 } 3480 tg.className = "green_button_repeat3"; 3481 if (tg.previousSibling)3482 {3483 if (tg.previousSibling.childNodes.length > 0)3484 {3485 if ((tg.previousSibling.childNodes[0].tagName.toLowerCase() == "img") && (tg.previousSibling.childNodes[0].src.toLowerCase().indexOf("left") > 0))3486 {3487 tg.previousSibling.childNodes[0].src = pathExtra + "../images/green_button_left.gif";3488 }3489 } 3490 }3491 if (tg.nextSibling)3492 {3493 if (tg.nextSibling.childNodes.length > 0)3494 {3495 if ((tg.nextSibling.childNodes[0].tagName.toLowerCase() == "img") && (tg.nextSibling.childNodes[0].src.toLowerCase().indexOf("right") > 0))3496 {3497 tg.nextSibling.childNodes[0].src = pathExtra + "../images/buttonbar_green_right.gif";3498 }3499 } 3500 } 3501 3502}3503function popupButtonMouseOut(e, pathExtra)3504{3505 var openevent = (e) ? e : window.event;3506 var tg = (e.target) ? e.target : e.srcElement3507 if (tg.getAttribute("status") == "disabled")3508 {3509 return false;3510 } 3511 tg.className = "button_repeat";3512 if (tg.previousSibling)3513 {3514 if (tg.previousSibling.childNodes.length > 0)3515 {3516 if ((tg.previousSibling.childNodes[0].tagName.toLowerCase() == "img") && (tg.previousSibling.childNodes[0].src.toLowerCase().indexOf("left") > 0))3517 {3518 tg.previousSibling.childNodes[0].src = pathExtra + "../images/button_left.gif";3519 }3520 } 3521 }3522 if (tg.nextSibling)3523 {3524 if (tg.nextSibling.childNodes.length > 0)3525 {3526 if ((tg.nextSibling.childNodes[0].tagName.toLowerCase() == "img") && (tg.nextSibling.childNodes[0].src.toLowerCase().indexOf("right") > 0))3527 {3528 tg.nextSibling.childNodes[0].src = pathExtra + "../images/buttonbar_right2.gif";3529 }3530 } 3531 }3532}3533//Pass the URL , it will return the filename3534function $getFileName(URL)3535{3536 var tr = URL;3537 var strBack = "";3538 len = tr.length 3539 rs = 0 3540 for (i = len; i > 0; i--) 3541 { 3542 vb = tr.substring(i,i+1) 3543 if (vb == "/" && rs == 0) 3544 { 3545 strBack = tr.substring(i+1,len);3546 rs = 1 3547 } 3548 }3549 3550 return strBack;3551}3552function $swopImage(URL,to,from)3553{3554 //http://bp1/images/area1.gif3555 //area1.gif3556 var filename = $getFileName(URL);3557 var fileTemp = filename;3558 if(filename == "")3559 {3560 alert('Error in swop Image');3561 } 3562 else3563 {3564 fileTemp = $rep(fileTemp,to,from);3565 fileTemp = $rep(URL,filename,fileTemp);3566 }3567 3568 return fileTemp;3569}3570//////////3571function showSimplePopupDiv(popuptablename, nohide, top, left)3572{3573 //shows the context menu type, showing the popuptable name's innerHTML3574 // need to add your own getTopPos & getLeftPos function in your own JS for checkoutsideWidth & checkoutsideBottomPopUp to work - specifically done like this to reuse code, but work with calendar3575 var htmlValue = '';3576 htmlValue +=' <table class="context_menu_main"> ';3577 htmlValue +=' <tr> ';3578 htmlValue +=' <td class="context_menu_second"> ';3579 if (!nohide)3580 {3581 htmlValue +=' <table cellpadding="1" cellspacing="0" onmouseleave="closeSimplePopupDiv()">';3582 }3583 else3584 {3585 htmlValue +=' <table cellpadding="1" cellspacing="0">';3586 }3587 htmlValue += ($id(popuptablename)).innerHTML;3588 htmlValue +=' </table>' 3589 htmlValue +=' </td> ';3590 htmlValue +=' </tr> ';3591 htmlValue +=' </table> ';3592 3593 var popupDiv =($id("simplePopupDiv"));3594 if (popupDiv) 3595 {3596 popupDiv.innerHTML = htmlValue;3597 }3598 else3599 {3600 popupDiv = document.createElement("div");3601 popupDiv.style.position = "absolute";3602 popupDiv.style.display = "none";3603 popupDiv.style.backgroundColor = "white";3604 popupDiv.id= "simplePopupDiv";3605 popupDiv.innerHTML = htmlValue;3606 document.body.appendChild(popupDiv);3607 }3608 3609 //do the physical popup section3610 var IfrRef = $id("backgroundframe");3611 if (!IfrRef)3612 {3613 IfrRef = document.createElement("iframe");3614 IfrRef.id = "backgroundframe";3615 document.body.appendChild(IfrRef);3616 }3617 3618 popupDiv.style.zIndex=9031;3619 popupDiv.style.display = "block";3620 IfrRef.style.position = 'absolute';3621 IfrRef.style.width = popupDiv.offsetWidth ;3622 IfrRef.style.height = popupDiv.offsetHeight ;3623 IfrRef.style.zIndex = popupDiv.style.zIndex - 1;3624 IfrRef.style.display = "block";3625 IfrRef.style.backgroundColor = "black";3626 3627 var iPos = 0;3628 var xPosRec = 0;3629 3630 if (event)3631 {3632 var obj= event.srcElement;3633 3634 iPos = checkoutsideWidth(obj,IfrRef.style.width, "MenuStructureScrollDiv");3635 xPosRec = checkoutsideBottomPopUp(obj,IfrRef.style.height, "MenuStructureScrollDiv");3636 }3637 else3638 {3639 iPos = left;3640 xPosRec = top;3641 }3642 3643 IfrRef.style.left = parseInt(iPos);3644 IfrRef.style.top = parseInt(xPosRec);3645 3646 popupDiv.style.left = parseInt(iPos);3647 popupDiv.style.top = parseInt(xPosRec);3648}3649function closeSimplePopupDiv()3650{3651 var IfrRef = $id("backgroundframe");3652 var div = ($id("simplePopupDiv"));3653 3654 if (div)3655 {3656 div.style.display = "none";3657 }3658 if (IfrRef)3659 {3660 IfrRef.style.display = "none";3661 }3662 3663 var tg = ($id("imageActionSelected"));3664 if (tg)3665 {3666 tg.src = "../images/black_context_arrow.gif";3667 tg.id = "";3668 tg.className = "normalItem";3669 }3670}3671function ShowK2Help(helpID)3672{3673 if (helpID == 0)3674 helpID = "";3675 3676 if (helpID != "")3677 window.open(buildURL("WorkspaceHelp/WorkspaceHelp.aspx?HelpID=" + helpID, null,"directories=0, location=0, menubar=0, titlebar=0, toolbar=0"));3678 else3679 window.open(buildURL("WorkspaceHelp/WorkspaceHelp.aspx", null,"directories=0, location=0, menubar=0, titlebar=0, toolbar=0"));3680}3681function ValidateDate(FromDate, ToDate, pagePath)3682{3683 if (FromDate > ToDate)3684 {3685 doPopup(Generic_js_DateValidationHeading, Generic_js_StartDateEndDate, 400 , 75, Generic_js_ButtonOk, "doHidePopup('dateCompare')|13", "", "", "", "", 11500, "dateCompare", pagePath,"","error");3686 return true;3687 }3688 else3689 {3690 return false;3691 }3692}3693function generateGuid()3694{3695 var result, i, j;3696 result = '';3697 for(j = 0; j < 32; j++)3698 {3699 if( j == 8 || j == 12|| j == 16|| j == 20)3700 {3701 result = result + '-';3702 }3703 i = Math.floor(Math.random()*16).toString(16).toUpperCase();3704 result = result + i;3705 }3706 return result;...

Full Screen

Full Screen

tools.js

Source:tools.js Github

copy

Full Screen

1/* jshint expr: true */2(function () {3 "use strict";4}());5define = define || function () {6 //7};8define(9 [10 "jquery",11 "jqueryui",12 "howler",13 ],14 function ($) {15 window.log = console.log;16 /*17 *18 * Extending jQuery! How cool is this?19 *20 * A few functions to deal with various input types, their21 * various change events, and methods for retrieving values22 *23 *24 *25 */26 // gets input type, like "button" or "radio"27 // usage: let type = $("#thisElement").getInputType();28 // NOTE can't use fat-arrow function here, because it screws with "this"29 $.fn.getInputType = function () {30 if (!$(this)) return log("No $(this) for getInputType!"); // NEW TEST sometimes it seems there's no "this"!31 const type = $(this).attr("type");32 const tagName = $(this)[0].tagName;33 return (type || tagName).toLowerCase();34 };35 // gets the input value for various types of input36 // like this: let value = $("#someElement").getInputValue();37 $.fn.getInputValue = function () {38 const type = this.getInputType();39 if (["text", "number", "textarea", "range", "select"].indexOf(type) !== -1) return this.val();40 if (type === "checkbox") return this.is(":checked") ? 1 : 0;41 if (type === "radio") {42 const name = $(this[0]).prop("name");43 return $(`input[name='${name}'']:checked`).val();44 }45 return null;46 };47 // gets the appropriate change event to listen for for various48 // kinds of inputs, e.g., "change", "click", or "input"49 $.fn.getInputChangeEvent = function () {50 const type = this.getInputType();51 const inputTypes = ["checkbox", "text", "textarea", "number", "radio", "select"];52 if (inputTypes.indexOf(type) !== -1) return "change";53 if (type === "button" || type === "submit") return "click";54 if (type === "range") return "input"; // 'input' responds while sliding; 'change' responds only when finished sliding55 return null;56 };57 let tools = {};58 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *59 *60 *61 *62 * Simple timer - starts, stops, clears, does something every second, etc.63 *64 *65 *66 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */67 function timer(obj = {}) {68 obj = $.extend({69 onEachFrame: function () {70 // log("Frame!");71 },72 onEachSecond: function () {73 // log(lastSecond + " seconds");74 },75 onStart: function () {76 log("Started");77 },78 onStop: function () {79 // log("Stopped");80 },81 onPause: function () {82 log("Paused");83 },84 onClear: function () {85 // log("Cleared!");86 },87 }, obj);88 let t1 = Date.now();89 let timeElapsed = 0;90 let secondsCounter = 0;91 let timerIsRunning = false;92 function eachFrame() {93 t2 = Date.now()94 if (timerIsRunning) timeElapsed += (t2 - t1);95 if (timerIsRunning) secondsCounter += (t2 - t1);96 t1 = t2;97 checkForSecond();98 obj.onEachFrame();99 window.requestAnimationFrame(eachFrame);100 }101 function checkForSecond() {102 if (secondsCounter < 1000) return;103 secondsCounter -= 1000;104 obj.onEachSecond();105 }106 function start() {107 if (timerIsRunning) return;108 timerIsRunning = true;109 t1 = Date.now();110 eachFrame();111 obj.onStart();112 }113 function stop() {114 if (!timerIsRunning) return this;115 timerIsRunning = false;116 t1 = null;117 obj.onStop();118 return this;119 }120 function getTimeElapsed() {121 return timeElapsed;122 }123 function getSecondsElapsed() {124 return Math.floor(getTimeElapsed() / 1000);125 }126 function isRunning() {127 return timerIsRunning;128 }129 function pause() {130 timerIsRunning = false;131 t1 = null;132 obj.onPause();133 return this;134 }135 function reset() {136 stop();137 t1 = null;138 t2 = null;139 lastSecond = null;140 timeElapsed = 0;141 obj.onClear();142 return this;143 }144 return {145 isRunning,146 pause,147 reset,148 start,149 stop,150 getTimeElapsed,151 getSecondsElapsed,152 };153 }154 function Timer(obj = {}) {155 const controller = new TimerController(Ticker, Display, Interval);156 const public = this;157 function TimerController(Ticker, Display, Interval) {158 const ticker = new Ticker();159 const display = new Display();160 display.getMs = () => ticker.getElapsedMs();161 };162 function Ticker() {163 let elapsedMs = 0;164 let isRunning = false;165 let t1 = Date.now();166 let elapsedSeconds = 0;167 setInterval(() => {168 const t2 = Date.now();169 if (isRunning) elapsedMs += t2 - t1;170 if (isRunning) checkForSecond(t2 - t1);171 t1 = t2;172 }, 20);173 function checkForSecond(ms) {174 elapsedMs += ms;175 if (elapsedSeconds < 1000) return;176 elapsedSeconds -= 1000;177 this.onElapsedSecond();178 }179 this.getElapsedMs = () => elapsedMs;180 this.onElapsedSecond = () => undefined;181 this.changeRunningState = val => isRunning = val ?? !isRunning;182 }183 function Display() {184 const pad = t => t < 10 ? "0" + t : t;185 this.getMs = () => undefined;186 this.getFormattedTime = () => {187 const ms = this.getMs();188 const totalSeconds = Math.floor(ms / 1000);189 const displaySeconds = totalSeconds % 60;190 const minutes = Math.floor(totalSeconds / 60);191 const hundredths = Math.floor(ms / 10) % 100;192 return {193 raw: {194 totalSeconds,195 displaySeconds,196 minutes,197 hundredths198 },199 padded: {200 totalSeconds: pad(totalSeconds),201 displaySeconds: pad(displaySeconds),202 minutes: pad(minutes),203 hundredths: pad(hundredths),204 },205 };206 }207 }208 // return {209 // isRunning,210 // pause,211 // reset,212 // start,213 // stop,214 // getTimeElapsed,215 // getSecondsElapsed,216 // };217 }218 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *219 *220 *221 *222 * Analyzing arrays to see if they intersect partially, completely, etc.223 *224 *225 *226 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */227 function arrayIntersectHandler(a1, a2) {228 if (arguments.length !== 2 || !Array.isArray(a1) || !Array.isArray(a2)) {229 return log("Didn't the right number of arrays!");230 }231 if (!a1.length || !a2.length) return false;232 const intersection = a1.filter(item => a2.indexOf(item) !== -1);233 const numOverlap = intersection.length;234 const arraysDoIntersect = !!numOverlap;235 const arraysDontOverlap = !arraysDoIntersect;236 const arraysOverlapCompletely = a1.every(item => a2.indexOf(item) !== -1) || a2.every(item => a1.indexOf(item) !== -1);237 return {238 numOverlap,239 arraysDoIntersect,240 arraysDontOverlap,241 arraysOverlapCompletely,242 };243 }244 function arraysDoIntersect(a1, a2) {245 return arrayIntersectHandler(a1, a2).arraysDoIntersect;246 }247 tools.arraysDoIntersect = arraysDoIntersect;248 function arraysOverlapCompletely(a1, a2) {249 return arrayIntersectHandler(a1, a2).arraysOverlapCompletely;250 }251 tools.arraysOverlapCompletely = arraysOverlapCompletely;252 function stringsIntersect(s1, s2, obj = {}) {253 const a1 = s1.split(" " ?? obj.breakOn);254 const a2 = s2.split(" " ?? obj.breakOn);255 return arraysDoIntersect(a1, a2);256 }257 tools.stringsIntersect = stringsIntersect;258 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *259 *260 *261 *262 * Just a shortcut for the audio voices263 *264 *265 *266 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */267 const getAudioVoices = (function () {268 const baseArray = ["Emma", "Joanna", "Justin", "Matthew"];269 return function (doShuffle = false) {270 return doShuffle ? shuffleArray(baseArray) : baseArray;271 };272 }());273 tools.getAudioVoices = getAudioVoices;274 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *275 *276 *277 *278 * Picking a random voice for the audio279 *280 *281 *282 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */283 const audioVoice = (function () {284 const voicesArray = getAudioVoices();285 const shuffledArray = getAudioVoices(true);286 let voicePointer = 0;287 return {288 rotateVoice: () => voicePointer++,289 getCurrentVoice: () => shuffledArray[voicePointer % voicesArray.length],290 getAllVoices: (obj = {}) => obj.shuffle ? shuffledArray : voicesArray,291 };292 }());293 tools.rotateVoice = audioVoice.rotateVoice;294 tools.getCurrentVoice = audioVoice.getCurrentVoice;295 tools.getAllVoices = audioVoice.getAllVoices;296 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *297 *298 *299 * Simply plays a sound. Stops on any keypress.300 *301 *302 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */303 const simplePlayer = (function () {304 let isPlaying = false;305 let playerSettings = {};306 let howl = null;307 function set(obj = {}) {308 $.extend(playerSettings, obj);309 return true;310 }311 function play(file, obj = {}) {312 if (!file) return;313 howl && howl.stop();314 if (isPlaying) return;315 isPlaying = false;316 if (file.toString().indexOf(".mp3") === -1) file += ".mp3";317 const voice = obj.voice || audioVoice.pickRandom();318 howl = new Howl({319 src: playerSettings.useCustomPath ? [file] : [`/audio/${voice}/${file}`],320 autoplay: playerSettings.autoplay || true,321 onplay: function () {322 $(window).on("keydown", stop);323 playerSettings.onplay && playerSettings.onplay();324 obj.onplay && obj.onplay();325 },326 onend: function () {327 $(window).off("keydown", stop);328 isPlaying = false;329 playerSettings.onstop && playerSettings.onstop();330 obj.onstop && obj.onstop();331 },332 onstop: function () {333 $(window).off("keydown", stop);334 isPlaying = false;335 playerSettings.onstop && playerSettings.onstop();336 obj.onstop && obj.onstop();337 },338 onloaderror: function (e) {339 log("Couldn't load " + file);340 }341 });342 }343 function stop(e) {344 e.preventDefault();345 howl && howl.stop();346 }347 return {348 play,349 stop,350 set,351 };352 }());353 tools.simplePlayer = simplePlayer;354 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *355 *356 *357 *358 * Loads a JavaScript file dynamically359 *360 *361 *362 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */363 function loadScript(scriptSrc, callback) {364 let scriptTag = document.createElement("script");365 scriptTag.src = scriptSrc;366 document.head.appendChild(scriptTag);367 scriptTag.onload = function () {368 callback && callback();369 };370 }371 tools.loadScript = loadScript;372 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *373 *374 *375 *376 * Returns the average width of an array of jQuery elements377 *378 *379 *380 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */381 function getAverageWidth(elements = []) {382 let totalWidth = 0;383 elements.forEach($span => {384 $span = forceJQuery($span);385 totalWidth += $span.outerWidth();386 });387 return totalWidth / elements.length;388 }389 tools.getAverageWidth = getAverageWidth;390 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *391 *392 *393 *394 * Forcing an element to be jQuery395 *396 *397 *398 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */399 function forceJQuery(element) {400 return element instanceof $ ? element : $(element);401 }402 tools.forceJQuery = forceJQuery;403 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *404 *405 *406 *407 * Couldn't be simpler408 *409 *410 *411 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */412 function isMobile() {413 return typeof window.orientation !== "undefined";414 }415 tools.isMobile = isMobile;416 tools.isNotMobile = () => !isMobile();417 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *418 *419 *420 *421 * Scrolls an element to the middle of the page (actually, the top of the element)422 *423 *424 *425 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */426 function scrollToMiddle(elem) {427 elem = (elem instanceof $) ? elem[0] : elem; // extracting HTML element from jQuery428 const absoluteElementTop = elem.getBoundingClientRect().top + window.pageYOffset;429 const middle = absoluteElementTop - (window.innerHeight / 2);430 window.scrollTo(0, middle);431 }432 tools.scrollToMiddle = scrollToMiddle;433 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *434 *435 *436 *437 * Handles the saving an object or array in localStorage (or sessionStorage) as JSON438 *439 *440 *441 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */442 function objectStorage(masterKey, sessionOrLocalStorage = "sessionStorage") {443 if (!masterKey) return log("objectStorage requires a key for the local (or session) storage!");444 const storage = window[sessionOrLocalStorage]; // either "localStorage" or "sessionStorage"445 let json = safeParseJSON(storage[masterKey]);446 return function (p) {447 /*448 Usage:449 tools.userInfo() --> GETS the WHOLE string, parsed as JSON450 tools.userInfo("clear") --> DELETES the object entirely from storage451 tools.userInfo("username") --> GETS the "username" value from the object452 tools.userInfo("username", "James") --> SETS the "username" to "James"453 tools.userInfo({ one: 1, two: 2 }) --> SETS multiple values to the object454 tools.userInfo([1, 2, 3,]) --> SETS the whole ARRAY into storage455 */456 const numArgs = arguments.length;457 if (!numArgs) return Object.keys(json).length ? json : null; // returning null if it's an empty object458 const arg1 = arguments[0];459 const arg2 = arguments[1];460 // saving key + value, like "storeObject('numStudent', 3)"461 if (numArgs === 2) { // key + value, presumably462 json[arg1] = arg2;463 storage[masterKey] = JSON.stringify(json);464 return json;465 }466 if (numArgs === 1) {467 if (arg1 === "clear") return storage.removeItem(masterKey);468 if (typeof arg1 === "string") return json[arg1];469 // overwriting the whole value with array new array470 if (Array.isArray(p)) {471 storage[masterKey] = JSON.stringify(p);472 return p;473 }474 // extending the values475 if (typeof p === "object") {476 $.extend(json, p);477 storage[masterKey] = JSON.stringify(json);478 return json;479 }480 }481 return false;482 };483 }484 tools.objectStorage = objectStorage;485 // shortcut methods for objectStorage486 tools.objectLocalStorage = function (masterKey) {487 return objectStorage(masterKey, "localStorage");488 };489 tools.objectSessionStorage = function (masterKey) {490 return objectStorage(masterKey, "sessionStorage");491 };492 /*493 Testing whether localStorage works or not, and alerting a warning if not494 */495 function warnPrivateBrowsing() {496 try {497 localStorage.setItem("testItem", "test_value");498 localStorage.removeItem("testItem");499 } catch (e) {500 alert("このサイトはプライベート・ブラウズに対応していません!\n\nプライベート・ブラウズを解除してください!\n\n - by Wood!");501 }502 }503 tools.warnPrivateBrowsing = warnPrivateBrowsing;504 function getArrayIndex(obj) {505 if (!obj || typeof obj !== "object" || !obj.array || !obj.find) return false;506 if (obj.searchFrom && obj.searchFrom !== "start" && obj.searchFrom !== "end") {507 return log("searchFrom property must be 'start' or 'end'");508 }509 if (!obj.find || typeof obj.find !== "function") {510 return log("getArrayIndex requires a 'find' property that is a function!");511 }512 const array = obj.array;513 const searchFrom = obj.searchFrom || "start";514 const meetsSearchCondition = obj.find;515 const onNull = obj.onNull;516 // loops through an array, either forwards or backwards, and517 // returns the index of the searched-for value, else -1518 function searchArrayByDirection(startValue, testCondition, direction) {519 for (let i = startValue; testCondition(i); i += direction) {520 if (meetsSearchCondition(array[i])) return i;521 }522 onNull && onNull();523 return -1;524 }525 if (searchFrom === "start") {526 return searchArrayByDirection(0, function (i) {527 return i < array.length;528 }, 1);529 } else {530 return searchArrayByDirection(array.length - 1, function (i) {531 return i >= 0;532 }, -1);533 }534 }535 tools.getArrayIndex = getArrayIndex;536 const pickColor = (function () {537 const baseColors = {538 light: shuffleArray([539 "yellow",540 "orange",541 "springgreen",542 "powderblue",543 "lightcyan",544 "greenyellow",545 "aqua",546 ]),547 dark: shuffleArray([548 "navy",549 "blue",550 "purple",551 "darkred",552 "darkslateblue",553 "indigo",554 "darkcyan",555 "green",556 "darkgreen",557 ]),558 };559 baseColors.allColors = [...baseColors.light, ...baseColors.dark];560 let index = 0;561 return function (colorType) {562 if (!(colorType in baseColors)) return log("Requires either 'light', 'dark', or 'allColors'!");563 const numColors = baseColors[colorType].length;564 return () => baseColors[colorType][++index % numColors];565 };566 }());567 tools.pickColor = pickColor("allColors");568 tools.pickDarkColor = pickColor("dark");569 tools.pickLightColor = pickColor("light");570 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *571 *572 *573 * Takes an array and removes random elements574 * until it's a specified length575 *576 *577 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */578 function whittleDownArray(array, desiredLength) {579 if (arguments.length === 0 || !Array.isArray(array)) return log("whittleDownArray got some bad parameteres!");580 if (!desiredLength) return array;581 while (array.length > desiredLength) pickOneFrom(array, true); // true means "delete this index"582 return array;583 }584 tools.whittleDownArray = whittleDownArray;585 /*586 *587 * Removes elements from an object whose keys are not in a given array588 *589 * Example: whittleDownObject(obj).toKeysIn(array);590 *591 * NOTE this "returns" nothing, since objects are passed by reference592 *593 *594 */595 function whittleDownObject(object) {596 if (!object || typeof object !== "object" || Object.keys(object).length < 1) {597 return log("whittleDownObject requires an object as the first parameter!");598 }599 return {600 toKeysIn: function toKeysIn(array) {601 if (!array || !Array.isArray(array) || !array.length) {602 return log("whittleDownObject requires an array as the second parameter!");603 }604 // looping through the object, removing any elements where605 // the key isn't in the array606 for (let key in object) if (array.indexOf(key) === -1) delete object[key];607 }608 };609 }610 tools.whittleDownObject = whittleDownObject;611 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *612 *613 *614 *615 * Links a checkbox with a localStorage key, toggling between "true" and "false"616 *617 *618 *619 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */620 function checkboxStateHandler(obj = {}) {621 obj = $.extend({622 checkbox: null, // REQUIRED623 localStorageKey: null, // REQUIRED624 checkedValue: "true",625 uncheckedValue: "false",626 defaultToChecked: false, // whether to check by default on first use627 onChange: function () {628 //629 },630 onCheck: function () {631 //632 },633 onUncheck: function () {634 //635 },636 }, obj);637 if (!obj.checkbox || !obj.localStorageKey) {638 return log("checkBoxStateHandler requires 'checkbox' and 'localStorageKey' properties!");639 }640 const $checkbox = tools.forceJQuery(obj.checkbox);641 const key = obj.localStorageKey;642 const checkedValue = obj.checkedValue;643 const uncheckedValue = obj.uncheckedValue;644 // checking by default IF it has never been set before AND 'defaultToChecked' is true645 if (!localStorage.hasOwnProperty(key) && obj.defaultToChecked) {646 localStorage.setItem(key, checkedValue);647 setCheckedStateTo(true);648 obj.onChange && obj.onChange();649 }650 $checkbox.on("change", function () {651 localStorage[key] = isChecked() ? checkedValue : uncheckedValue;652 obj.onChange();653 $checkbox.is(":checked") ? obj.onCheck() : obj.onUncheck();654 });655 function setCheckedStateTo(thisValue = false) {656 $checkbox.prop("checked", thisValue);657 return this;658 }659 function isChecked() {660 return $checkbox.is(":checked");661 }662 function disable() {663 $checkbox.prop("disabled", true);664 return this;665 }666 function enable() {667 $checkbox.prop("disabled", false);668 return this;669 }670 $checkbox.prop("checked", localStorage[key] === checkedValue);671 return {672 isChecked,673 disable,674 enable,675 };676 }677 tools.checkboxStateHandler = checkboxStateHandler;678 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *679 *680 *681 *682 * Links a radio input with a localStorage key, toggling between "true" and "false"683 *684 *685 *686 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */687 function radioStateHandler(obj = {}) {688 obj = $.extend({689 radioName: null, // REQUIRED690 localStorageKey: null, // REQUIRED691 onChange: function () {692 //693 },694 }, obj);695 const radioName = obj.radioName;696 const $radios = $(`input[type='radio'][name='${radioName}']`);697 const localStorageKey = obj.localStorageKey;698 $radios.on("change", function () {699 localStorage[localStorageKey] = getValue();700 obj.onChange();701 });702 function getValue() {703 return $(`input[type='radio'][name='${radioName}']:checked`).val();704 }705 function setValue(value) {706 $(`input[type='radio'][name='${radioName}'][value='${value}']`).prop("checked", true);707 return this;708 }709 function disable() {710 $radios.prop("disabled", true);711 }712 function enable() {713 $radios.prop("disabled", false);714 }715 setValue(localStorage[localStorageKey]);716 return {717 getValue,718 setValue,719 disable,720 enable,721 };722 }723 tools.radioStateHandler = radioStateHandler;724 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *725 *726 *727 *728 * Links a select input with a localStorage key, toggling between "true" and "false"729 *730 *731 *732 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */733 function selectStateHandler(obj = {}) {734 obj = $.extend({735 select: null, // REQUIRED, jQuery or not736 localStorageKey: null, // REQUIRED737 options: [],738 onChange: function () {739 //740 },741 }, obj);742 const $select = forceJQuery(obj.select);743 const localStorageKey = obj.localStorageKey;744 setOptions(obj.options);745 $select.on("change", function () {746 localStorage[localStorageKey] = getValue();747 obj.onChange();748 });749 function setOptions(array) {750 forceArray(array).forEach(function (item) {751 const value = (typeof item === "object" && item.value) ? item.value : item;752 const label = (typeof item === "object" && item.label) ? item.label : item;753 $select.append(`<option value="${value}">${label}</option>`);754 });755 return true;756 }757 function getValue() {758 return $select.val();759 }760 function setValue(value) {761 $select.val(value);762 return this;763 }764 function disable() {765 $select.prop("disabled", true);766 }767 function enable() {768 $select.prop("disabled", false);769 }770 setValue(localStorage[localStorageKey]);771 return {772 getValue,773 setValue,774 disable,775 enable,776 setOptions,777 };778 }779 tools.selectStateHandler = selectStateHandler;780 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *781 *782 *783 * naturally sorts an array of items, or an array of objects by some key in the objects784 *785 *786 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */787 function naturallySort(array, key) {788 array.sort(function (a, b) {789 let k1 = a,790 k2 = b;791 if (key) {792 k1 = k1[key];793 k2 = k2[key];794 }795 return k1.toString().localeCompare(k2.toString(), undefined, { // WHOOOA I don't understand this796 numeric: true,797 sensitivity: "base"798 });799 });800 return true;801 }802 tools.naturallySort = naturallySort;803 /*804 *805 *806 * Converts an image to a dataURI, via a canvas element (which is not added to the DOM)807 *808 *809 */810 function imageToDataURL(image, obj = {}) {811 const ratio = (function () {812 if (obj.maxWidth && obj.maxHeight) {813 return Math.min(obj.maxWidth / image.width, obj.maxHeight / image.height);814 } else if (obj.maxWidth) {815 return obj.maxWidth / image.width;816 } else if (obj.maxHeight) {817 return obj.maxHeight / image.height;818 }819 return 1;820 }());821 // creating a canvas element, but never adding it to the DOM822 const canvas = document.createElement("canvas");823 canvas.width = image.width * ratio;824 canvas.height = image.height * ratio;825 canvas.getContext("2d").drawImage(image, 0, 0, canvas.width, canvas.height);826 return canvas.toDataURL();827 }828 tools.imageToDataURL = imageToDataURL;829 /*830 *831 *832 * Converts an image to a dataURI, via a canvas element833 *834 *835 */836 function dataURLToBlob(obj = {}) {837 if (!obj.url) return log("dataURLToBlob got some bad parameters");838 const callback = obj.onFinish;839 let parts,840 contentType,841 raw,842 blob,843 dataURL = obj.url;844 if (dataURL.indexOf(";base64,") === -1) {845 parts = dataURL.split(',');846 contentType = parts[0].split(':')[1];847 raw = parts[1];848 blob = new Blob([raw], { type: contentType });849 obj.onFinish && obj.onFinish(blob);850 return;851 }852 parts = dataURL.split(";base64,");853 contentType = parts[0].split(':')[1];854 raw = window.atob(parts[1]);855 const uInt8Array = new Uint8Array(raw.length);856 for (let i = 0; i < raw.length; ++i) uInt8Array[i] = raw.charCodeAt(i);857 blob = new Blob([uInt8Array], { type: contentType });858 obj.onFinish && obj.onFinish(blob);859 }860 tools.dataURLToBlob = dataURLToBlob;861 /*862 *863 *864 * Converts a Konva layer (canvas) to a PNG image, so it can be printed865 *866 *867 *868 */869 function konvaLayerToImage(layer) {870 const imageData = layer.getCanvas().toDataURL();871 const canvas = layer.getCanvas()._canvas; // funky872 const $image = $(`<img src='${imageData}'>`).css({873 width: layer.width() + "px", // NOTE have to force width & height, for cases where874 height: layer.height() + "px", // the pixel ration may be weird875 });876 $(canvas).replaceWith($image);877 return true;878 }879 tools.konvaLayerToImage = konvaLayerToImage;880 function objectToArray(thing) {881 /* * * * * * * * * * * * * * * * * * * * * * * *882 *883 *884 * changes an object to an array, like this:885 *886 * {dog: 犬} --> ["dog", "犬"]887 *888 *889 * * * * * * * * * * * * * * * * * * * * * * * * */890 if (Array.isArray(thing)) return thing;891 let array = [];892 for (let word in thing) array.push([word, thing[word]]);893 return array;894 }895 tools.objectToArray = objectToArray;896 // adjusting quotes (slanted to straight) and removing any 2+ consecutive spaces897 function removeExtraWhiteSpace(string, obj = {}) {898 string = string.replace(/’|‘/g, "'"); // slanted single quotes (open and close) to straight899 string = string.replace(/“|”/g, '"'); // slanted double quotes (open and close) to straight900 string = string.replace(/\s{2,}/g, " ").trim();901 return string;902 }903 tools.removeExtraWhiteSpace = removeExtraWhiteSpace;904 function straightQuotesToSlanted(string) {905 // string = string.replace(/(\w)'(\w)/g, "$1’$2"); // apostrophe906 // string = string.replace(/ "/g, " ”"); // opening double quote907 // string = string.replace(/(\w)"/g, "$1”"); // closing double quote908 return string;909 }910 tools.straightQuotesToSlanted = straightQuotesToSlanted;911 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *912 *913 *914 * 1. Splits a string into an array of words,915 * 2. Trims white space from all elements (words), and916 * 3. Optionally removes underscores917 * 4. Optionally shuffles918 *919 *920 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */921 function trimAllElements(array, options = {}) {922 if (typeof array === "string") {923 array = removeExtraWhiteSpace(array);924 array = array.split(" ");925 }926 if (!Array.isArray(array)) return log("trimAll requires an array or a string!");927 // trimming each item (string) and replacing underscores with spaces, optionally928 array = array.map(item => {929 item = item.trim();930 item = removeExtraWhiteSpace(item);931 if (options.removeUnderscores) item = item.replace(/_/gi, " ");932 item = item.replace(/‘|’/g, "'"); // slanted single quotes to straight933 item = item.replace(/“|”/g, "\""); // slanted double quotes to straight934 return item;935 });936 if (options.shuffle) array = shuffleArray(array, options.alwaysMoveFirst);937 return array;938 }939 tools.trimAllElements = trimAllElements;940 // adds an item to an array IF it isn't there already941 function pushUnique(item, array) {942 if (arguments.length !== 2 || !Array.isArray(array)) return log("Bad arguments!");943 array.indexOf(item) === -1 && array.push(item);944 return true;945 }946 tools.pushUnique = pushUnique;947 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * *948 *949 *950 *951 * "turn (to the) left" --> ["turn left, turn to the left"]952 * "(an) apple" --> ["apple", "an apple"]953 * "[one's, your] left" --> ["one's left", "your left"] NOTE separated by comma, not slash!954 *955 *956 *957 * * * * * * * * * * * * * * * * * * * * * * * * * * * * */958 function getCandidateAnswers(string, divider = "/") {959 string = removeExtraWhiteSpace(string);960 let candidatesArray = string.split(divider).map(answer => removeExtraWhiteSpace(answer));961 // adding scrubbed versions to the array962 candidatesArray.forEach(answer => {963 answer = scrubString(answer);964 pushUnique(answer, candidatesArray);965 // adding versions WITH optional bits, and without966 const withoutOptional = answer.replace(/\(.*?[^\)]\)/g, "");967 const withOptional = answer.replace(/\(|\)/g, "");968 const withoutDashes = answer.replace(/-/g, " "); // replacing dashes with SPACES969 pushUnique(withoutOptional, candidatesArray);970 pushUnique(withOptional, candidatesArray);971 pushUnique(withoutDashes, candidatesArray);972 // "lose [one's, your, my] way" --> ["lose one's way", "lose your way", "lose my way"]973 if (answer.indexOf("[") !== -1 && answer.indexOf("]") !== -1) {974 const alternates = answer.split("[")[1].split("]")[0].split(",").map(word => word.trim());975 alternates.forEach(alternate => {976 const newString = answer.replace(/\[.[^\]]{0,}\]/, alternate); // any text between square brackets977 pushUnique(newString, candidatesArray);978 });979 }980 });981 candidatesArray = candidatesArray.map(item => removeExtraWhiteSpace(item));982 return candidatesArray;983 }984 tools.getCandidateAnswers = getCandidateAnswers;985 function getIdealAnswer(string) {986 return removeParenthetical(getCandidateAnswers(string)[0]).trim();987 }988 tools.getIdealAnswer = getIdealAnswer;989 // limiting to alphanumeric, spaces, (), [], and select punctuation990 function scrubString(text) {991 return text.replace(/[^\w\s\(\)\[\]\/',_-]/gi, "");992 }993 tools.scrubString = scrubString;994 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * *995 *996 *997 * Stripping any text between (parentheses) or [brackets] from a string,998 * and returning the first letter999 *1000 *1001 * * * * * * * * * * * * * * * * * * * * * * * * * * * * */1002 function getFirstRealLetter(string) {1003 string = string.replace(/\(.[^\)]*\)/g, ""); // removing anything in ( ) - same as "removeParenthetical" below1004 string = string.replace(/\[.[^\]]*\]/g, ""); // removing anything in [ ]1005 string = removeExtraWhiteSpace(string);1006 return string.charAt(0);1007 }1008 tools.getFirstRealLetter = getFirstRealLetter;1009 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * *1010 *1011 *1012 * Removes any text between parentheses, and any spaces after1013 *1014 * "(the) United States (of America)" --> "United States"1015 *1016 *1017 * * * * * * * * * * * * * * * * * * * * * * * * * * * * */1018 function removeParenthetical(string) {1019 string = string.replace(/\([^\(\)]*\)/gi, ""); // removing anything in parentheses1020 string = string.replace(/\[[^\[\]]*\]/gi, ""); // removing anything in square brackets1021 string = string.replace(/<[^<>]*>/gi, ""); // removing anything in angle brackets1022 return string;1023 }1024 tools.removeParenthetical = removeParenthetical;1025 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * *1026 *1027 *1028 * Takes an array and returns a shuffled version of it1029 *1030 * ALWAYS returns a differently ordered version1031 * UNLESS there are only two elements, in which case it1032 * MAY return an identical version1033 *1034 *1035 * * * * * * * * * * * * * * * * * * * * * * * * * * * * */1036 function shuffleArray(originalArray) {1037 if (!Array.isArray(originalArray)) return log("shuffleArray requires an array!");1038 let arrayCopy = originalArray.concat(); // cloning the array1039 let shuffledArray = [];1040 while (arrayCopy.length > 0) shuffledArray.push(pickOneFrom(arrayCopy, true)); // true => delete that element1041 // ensuring that arrays of length 3+ are changed1042 if (shuffledArray.length >= 3) {1043 while (arraysAreIdentical(shuffledArray, originalArray)) shuffledArray = shuffleArray(originalArray);1044 }1045 return shuffledArray;1046 }1047 tools.shuffle = shuffleArray;1048 // gets the x & y coordinates of mouse click or touch, relative to any offset parent1049 function pointerPosition(event, offsetParent) {1050 const offsetLeft = offsetParent ? offsetParent.offset().left : 0;1051 const offsetTop = offsetParent ? offsetParent.offset().top : 0;1052 let x, y;1053 // calculating position, for either touch or click1054 if (event.type === "touchstart" || event.type === "touchend") {1055 const touch = event.originalEvent.touches[0] || event.originalEvent.changedTouches[0];1056 x = touch.pageX - offsetLeft;1057 y = touch.pageY - offsetTop;1058 } else {1059 x = event.pageX - offsetLeft;1060 y = event.pageY - offsetTop;1061 }1062 return { x, y, };1063 }1064 tools.pointerPosition = pointerPosition;1065 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *1066 *1067 *1068 * Picks a random index (integer) from an array,1069 *1070 * or else a random int, 0 <= int < some given number1071 *1072 *1073 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */1074 function pickIntFrom(arrayOrNumber) {1075 if (!arrayOrNumber || !(Array.isArray(arrayOrNumber) || !isNaN(arrayOrNumber))) {1076 return log("pickIntFrom requires an array or a number as a parameter!");1077 }1078 if (Array.isArray(arrayOrNumber)) {1079 return Math.floor(Math.random() * arrayOrNumber.length);1080 }1081 return Math.floor(Math.random() * arrayOrNumber);1082 }1083 tools.pickIntFrom = pickIntFrom;1084 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *1085 *1086 *1087 *1088 * Returns a random ELEMENT from an array (not just the index integer),1089 *1090 * and deletes that element, optionally1091 *1092 *1093 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */1094 function pickOneFrom(array, deleteChosenItem) {1095 if (!array || !Array.isArray(array) || array.length < 1) {1096 return log("tools.pickOneFrom requires an array!");1097 }1098 const index = pickIntFrom(array);1099 const item = array[index];1100 if (deleteChosenItem) array.splice(index, 1);1101 return item;1102 }1103 tools.pickOneFrom = pickOneFrom;1104 function removeOneFrom(array) {1105 return pickOneFrom(array, true);1106 }1107 tools.removeOneFrom = removeOneFrom;1108 function elementOnScreen($element, callback, obj = null) {1109 if (!$element || !callback) return false;1110 $element = tools.forceJQuery($element);1111 // wiring up the scroll listener, and triggering once1112 $(window).off("scroll", scrollHandler).on("scroll", scrollHandler).trigger("scroll");1113 function scrollHandler() {1114 const elementTop = $element.offset().top;1115 const screenBottom = $(window).scrollTop() + $(window).height();1116 if (elementTop > screenBottom || $element.is(":hidden")) return;1117 $(window).off("scroll", scrollHandler);1118 callback();1119 }1120 function activate() {1121 $(window).off("scroll", scrollHandler).on("scroll", scrollHandler);1122 }1123 return {1124 activate1125 };1126 }1127 tools.elementOnScreen = elementOnScreen;1128 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * *1129 *1130 *1131 * Simply returns whether an element is on screen, vertically1132 * NOTE doesn't check left and right1133 *1134 *1135 * * * * * * * * * * * * * * * * * * * * * * * * * * * * */1136 function elementIsOnScreen($element) {1137 const elementTop = $element.offset().top;1138 const elementBottom = $element.offset().bottom;1139 const screenTop = $(window).scrollTop();1140 const screenBottom = $(window).scrollTop() + $(window).height();1141 return !(elementTop > screenBottom || elementBottom < screenTop);1142 }1143 tools.elementIsOnScreen = elementIsOnScreen;1144 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *1145 *1146 *1147 * Checks whether arrays contain the same elements, though not necessarily in the1148 *1149 * same order. NOTE that this is different than "arraysAreIdentical" below.1150 *1151 * Does NOT work on nested arrays!1152 *1153 *1154 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */1155 function arraysContainSameElements(a1, a2) {1156 if (!Array.isArray(a1) || !Array.isArray(a2) || a1.length !== a2.length) return false;1157 const intersection = a1.filter(element => a2.indexOf(element) !== -1);1158 return intersection.length === a1.length;1159 }1160 tools.arraysContainSameElements = arraysContainSameElements;1161 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *1162 *1163 *1164 * Checks whether arrays are identical - same elements in the same order1165 *1166 * Also checks for nested arrays (useful?) but DOES NOT WORK with nested objects!1167 *1168 *1169 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */1170 function arraysAreIdentical(a1, a2) {1171 if (!Array.isArray(a1) || !Array.isArray(a2) || a1.length !== a2.length) return false;1172 for (let i = 0; i < a1.length; i++) {1173 if (Array.isArray(a1[i])) {1174 if (!arraysAreIdentical(a1[i], a2[i])) return false;1175 } else if (a1[i] !== a2[i]) {1176 return false;1177 }1178 }1179 return true;1180 }1181 tools.arraysAreIdentical = arraysAreIdentical;1182 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * *1183 *1184 *1185 * Tries to parse a string into JSON, and1186 * returns an empty object if it fails1187 *1188 *1189 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */1190 function safeParseJSON(string) {1191 try {1192 return JSON.parse(string) || {};1193 } catch (err) {1194 return {};1195 }1196 }1197 tools.safeParseJSON = safeParseJSON;1198 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *1199 *1200 *1201 *1202 * Takes a string with words surrounded by * (astrixes) and replaces those * with1203 * other strings, such as span tags1204 *1205 * NOTE that the opening and closing replacement string may be different1206 *1207 * Usage:1208 * replaceStars("This is *bold*", "<b>", "</b>"); --> "This is <b>bold</b>"1209 *1210 *1211 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */1212 function replaceStars(string, before, after = null) {1213 if (arguments.length < 2 || arguments.length > 3) return;1214 after = after || before; // if after is null, setting it to same as the "before" element1215 // returning the string unchanged if there are no stars1216 if (string.indexOf("*") === -1) return string;1217 // exiting if stars are not of an even number1218 if (string.match(/\*/g).length % 2 !== 0) {1219 return log("Odd number of stars!");1220 }1221 return string.replace(/\*(.[^\*]{0,})\*/g, before + "$1" + after);1222 }1223 tools.replaceStars = replaceStars;1224 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *1225 *1226 *1227 *1228 * In a text input (or textarea), toggles square brackets around selected text1229 * (inserts them if not present, removes them if they are)1230 *1231 * Usage: "Shift + Ctrl + [" (opening square backet)1232 *1233 *1234 *1235 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */1236 function toggleBrackets($input, e, p = {}) {1237 const keyCode = p.which || 219; // opening square bracket1238 const openingCharacter = p.openingCharacter || "[";1239 const closingCharacter = p.closingCharacter || "]";1240 const oldVal = $input.val();1241 if (e.which !== keyCode || !e.ctrlKey || !e.shiftKey) return;1242 // auto-selecting the current word, if nothing is selected1243 selectWholeWord($input);1244 const start = $input.prop("selectionStart"); // COOL! getting the start and end of an input's selected area1245 const end = $input.prop("selectionEnd");1246 const alreadySurrounded = oldVal.substring(start - 1, start) === openingCharacter && oldVal.substring(end, end + 1 === closingCharacter);1247 let newVal;1248 if (!alreadySurrounded) {1249 newVal = oldVal.substring(0, start) + openingCharacter + oldVal.substring(start, end) + closingCharacter + oldVal.substring(end, oldVal.length);1250 } else {1251 newVal = oldVal.substring(0, start - 1) + oldVal.substring(start, end) + oldVal.substring(end + 1, oldVal.length);1252 }1253 $input.val(newVal);1254 // re-selecting the selected test, just for good measure1255 const adjustment = alreadySurrounded ? -1 : 1; // moving the selected area by 1, depending1256 $input.prop({ selectionStart: start + adjustment, selectionEnd: end + adjustment }).change();1257 }1258 tools.toggleBrackets = toggleBrackets;1259 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *1260 *1261 *1262 *1263 * In a text input, selects the whole word (if nothing is otherwise selected)1264 *1265 * or whole words, if words are partially selected1266 *1267 *1268 *1269 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */1270 function selectWholeWord($input) {1271 const string = $input.val();1272 let start = $input.prop("selectionStart");1273 let end = $input.prop("selectionEnd");1274 while (string.charAt(start - 1).match(/\w\b/) && start >= 0) start--;1275 while (string.charAt(end).match(/\w\b/) && end < string.length) end++;1276 $input.prop({ selectionStart: start, selectionEnd: end });1277 }1278 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *1279 *1280 *1281 *1282 * In a text input (or textarea), replaces the next space (based on the insertion point)1283 * with an underscore.1284 *1285 * Usage: Shift + Ctrl + "u" (NOTE: can't use "_" 'cause that doubles as "-" minus on Windows - fuck!)1286 *1287 *1288 *1289 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */1290 function toggleUnderscores($input, e, p = {}) {1291 const keyCode = p.which || 85; // 85 = "u" for "underscore"1292 if (e.which !== keyCode || !e.ctrlKey || !e.shiftKey) return;1293 e.preventDefault();1294 const string = $input.val();1295 const selectionStart = $input.prop("selectionStart");1296 const selectionEnd = $input.prop("selectionEnd");1297 const p1 = string.substring(0, selectionStart);1298 const p2 = string.substring(selectionEnd, string.length).replace(/\s/, "_"); // only the first space, 'cause no global "g" flag1299 $input.val(p1 + p2).prop({ selectionStart: selectionStart, selectionEnd: selectionStart }).change();1300 }1301 tools.toggleUnderscores = toggleUnderscores;1302 // keeps track of user info (name, grade, etc.) in sessionStorage1303 tools.userInfo = tools.objectLocalStorage("user_info");1304 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *1305 *1306 *1307 * Abstracting away the tediousness of making something fullscreen1308 *1309 * NOTE some browsers don't use promises, so we can't use: elem.requestFullscreen().then()1310 *1311 *1312 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */1313 function requestFullscreen($elem, obj = {}) {1314 const elem = ($elem instanceof $) ? $elem[0] : $elem; // extracting the raw HTML if it's jQuery1315 elem.requestFullscreen = elem.webkitRequestFullscreen || elem.msRequestFullscreen || elem.requestFullscreen;1316 try {1317 elem.requestFullscreen();1318 obj.onFullscreen && obj.onFullscreen();1319 return true;1320 } catch (err) {1321 obj.onError && obj.onError(err);1322 return false;1323 }1324 }1325 tools.requestFullscreen = requestFullscreen;1326 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * *1327 *1328 *1329 * Handles the ".my-template" stuff, detaching and returning1330 * an element that can be cloned many times1331 *1332 *1333 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */1334 function makeTemplate($element, obj = {}) {1335 $element = forceJQuery($element);1336 const classToRemove = obj.klass || "my-template";1337 $element.removeClass(classToRemove);1338 $element.detach();1339 return $element;1340 }1341 tools.makeTemplate = makeTemplate;1342 /*1343 * UNDER CONSTRUCTION!!1344 *1345 */1346 // function sentenceWithDummyWords(string) {1347 //1348 // if (!string || typeof string !== "string") {1349 // console.log("sentenceWithDummyWords needs a string");1350 // return false;1351 // }1352 //1353 // if (string.includes("¥") && string.includes("[")) {1354 // console.log("Either a ¥ *OR* square brackets, butthead!");1355 // return false;1356 // }1357 //1358 // let divider = string.includes("¥") ? "¥" : "[";1359 //1360 // let twoArrays = string.split(divider);1361 //1362 //1363 // return {1364 // //1365 // };1366 // }1367 // tools.sentenceWithDummyWords = sentenceWithDummyWords;1368 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *1369 *1370 *1371 * the dateTime of the pageLoad, so we only get chats1372 * that showed up AFTER the page was loaded1373 *1374 *1375 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */1376 const getPageLoadDateTime = (function () {1377 const pageLoadTime = (new Date()).getTime();1378 return function () {1379 return (new Date(pageLoadTime));1380 };1381 }());1382 tools.pageLoadDateTime = getPageLoadDateTime;1383 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *1384 *1385 *1386 * Shortcut for creating a range1387 * NOTE that the loop returns THROUGH the end value1388 *1389 *1390 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */1391 function range(startValue, throughValue) {1392 if (arguments.length !== 2) {1393 return console.log("tools.range takes two arguments, a startValue and a throughValue!");1394 }1395 let array = [];1396 for (let i = startValue; i <= throughValue; i++) array.push(i);1397 return array;1398 }1399 tools.range = range;1400 /*1401 *1402 * Gets the index of the first element in an array that meets1403 * some condition, as defined by a testIsTrueFor function1404 *1405 *1406 */1407 function getIndexOfElementInArray(array, testIsTrueFor) {1408 for (let i = 0; i < array.length; i++) {1409 if (testIsTrueFor(array[i])) return i;1410 }1411 return -1;1412 }1413 tools.getIndexOfElementInArray = getIndexOfElementInArray;1414 /*1415 *1416 * Removes the first element in an array that meets1417 * some condition, as defined by a testFunction1418 *1419 *1420 */1421 function removeElement(array, testFunction) {1422 const index = getIndexOfElementInArray(array, testFunction);1423 array.splice(index, 1);1424 }1425 tools.removeElement = removeElement;1426 /*1427 *1428 * Calculates the number of rows and columns for a grid of objects, e.g.1429 *1430 * 4 objects => 2x21431 * 5 objects => 3x21432 * 6 objects => 3x21433 * 7 objects => 3x31434 * 8 objects => 3x31435 * ...1436 * 15 objects => 5x51437 *1438 *1439 */1440 // function calculateGrid(numItems) {1441 //1442 // const squareRouteRoundedUp = Math.ceil(Math.sqrt(numItems));1443 // const numRows = squareRouteRoundedUp;1444 //1445 // let numColumns = squareRouteRoundedUp;1446 //1447 // if (numRows * (numColumns - 1) >= numItems) {1448 // numColumns--;1449 // }1450 //1451 // return { numRows, numColumns };1452 // }1453 // tools.calculateGrid = calculateGrid;1454 /*1455 *1456 * converts MySQL timestamp to a readable format, e.g.1457 *1458 * 2018-04-06 13.15.06 -> Mar 06, 20181459 *1460 */1461 const readableDate = (function () {1462 const months = ["Jan", "Feb", "March", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];1463 return function (timestamp) {1464 const yearMonthDate = timestamp.split(" ")[0].split("-");1465 const year = yearMonthDate[0];1466 const month = months[parseInt(yearMonthDate[1]) - 1];1467 const date = yearMonthDate[2];1468 return month + " " + date + ", " + year;1469 };1470 }());1471 tools.readableDate = readableDate;1472 function promptStringWithTrim(obj = {}) {1473 obj = $.extend({1474 label: "",1475 placeholder: "default",1476 minLength: 21477 }, obj);1478 let inputString = prompt(obj.label, obj.placeholder);1479 if (!inputString || inputString <= obj.minLength) return;1480 inputString = inputString.trim();1481 if (!inputString || inputString <= obj.minLength) return;1482 return inputString;1483 }1484 tools.promptStringWithTrim = promptStringWithTrim;1485 function getSelectOptionWidth($select) {1486 const fontSize = $select.css("font-size");1487 const fontFamily = $select.css("font-family");1488 const fontWeight = $select.css("font-weight");1489 const text = $select.find("option:selected").text();1490 const $span = $("<span></span>").text(text).css({1491 visibility: "hidden",1492 position: "fixed",1493 top: "100%",1494 fontSize: fontSize,1495 fontFamily: fontFamily,1496 fontWeight: fontWeight1497 }).appendTo("html");1498 const width = $span.outerWidth(true);1499 $span.remove();1500 return width;1501 }1502 tools.getSelectOptionWidth = getSelectOptionWidth;1503 /*1504 *1505 * Returns true if an element has class "this-input-is-momentarily-disabled";1506 * otherwise, adds that class and then removes it after some number of miliseconds1507 * (100 by default)1508 *1509 * Used to temporarily disable an input - e.g., when "blur" and "sumbit"1510 * events call each other on an input, leading to stack overflow1511 *1512 *1513 */1514 const momentarilyDisable = (function () {1515 const className = "this-input-is-momentarily-disabled";1516 return function ($input, callback, obj = {}) {1517 obj = $.extend({1518 delay: 100 //ms1519 }, obj);1520 if (!$input.hasClass(className)) {1521 $input.addClass(className);1522 setTimeout(function () {1523 $input.removeClass(className);1524 }, obj.delay);1525 callback();1526 }1527 };1528 }());1529 tools.momentarilyDisable = momentarilyDisable;1530 const brackets = (function () {1531 function areBalanced(str) {1532 if (!str) return;1533 let nextExpectedType = "["; // first must be opening bracket1534 return str.split("").every(function (char) {1535 if (char === "[" || char === "]") {1536 if (char !== nextExpectedType) return false;1537 nextExpectedType = (nextExpectedType === "[") ? "]" : "[";1538 }1539 return true;1540 });1541 }1542 function sameNumber(str) {1543 if (!str) return;1544 const num = numberOfBrackets(str);1545 if (num[0] === num[1]) return true;1546 return false;1547 }1548 function numberOfBrackets(string) {1549 const numOpeningBrackers = (string.match(/\[/gi) || []).length;1550 const numClosingBrackets = (string.match(/\]/gi) || []).length;1551 return [numOpeningBrackers, numClosingBrackets];1552 }1553 function noBrackets(string) {1554 const num = numberOfBrackets(string);1555 return (num[0] === 0) && (num[1] === 0);1556 }1557 function areBrackets(str) {1558 return !noBrackets(str);1559 }1560 function areBalancedAndSameNumber(str) {1561 return areBalanced(str) && sameNumber(str); // && areBrackets(str);1562 }1563 function notBalanced(s) {1564 return !areBalanced(s);1565 }1566 function notSameNumber(s) {1567 return !sameNumber(s);1568 }1569 function notBalancedAndSame(s) {1570 return !areBalancedAndSameNumber(s);1571 }1572 return {1573 areBalanced,1574 sameNumber,1575 areBalancedAndSameNumber,1576 notBalanced,1577 notSameNumber,1578 notBalancedAndSame,1579 numberOfBrackets,1580 noBrackets,1581 };1582 }());1583 tools.brackets = brackets;1584 /*1585 * Takes one argument and returns that "array version" of that item1586 *1587 * This is so we can use Array.forEach, even when1588 *1589 */1590 function forceArray(item = []) {1591 return Array.isArray(item) ? item : [item];1592 }1593 tools.forceArray = forceArray;1594 const currentlyPressedKeys = (function () {1595 /*1596 *1597 * Keeps track of which keys are currently pressed1598 *1599 *1600 */1601 let keysDown = {};1602 // adding or removing keyCodes from the keysDown object1603 // whenever a key is pressed or released1604 $(window).on("keyup keydown", function (e) {1605 e.type === "keydown" ? keysDown[e.which] = true : delete keysDown[e.which];1606 });1607 function getAll() {1608 return keysDown;1609 }1610 function getArray() {1611 return Object.keys(keysDown);1612 }1613 function isPressed(keyCode) {1614 return forceArray(keyCode).some(function (thisKeycode) {1615 return keysDown.hasOwnProperty(thisKeycode);1616 });1617 }1618 function allArePressed(keyCodes) {1619 return forceArray(keyCodes).every(function (thisKeycode) {1620 return keysDown.hasOwnProperty(thisKeycode);1621 });1622 }1623 function numPressed() {1624 return getArray().length;1625 }1626 return {1627 getAll,1628 getArray,1629 isPressed,1630 numPressed,1631 allArePressed,1632 };1633 }());1634 tools.currentlyPressedKeys = currentlyPressedKeys;1635 tools.numKeysPressed = currentlyPressedKeys.numPressed;1636 tools.keyIsPressed = currentlyPressedKeys.isPressed;1637 tools.keysAreAllPressed = currentlyPressedKeys.allArePressed;1638 // returns True if ANY arrow keys are pressed1639 function anyArrowKeysPressed() {1640 return currentlyPressedKeys.isPressed([37, 38, 39, 40]);1641 }1642 tools.anyArrowKeysPressed = anyArrowKeysPressed;1643 // returns True if NO arrow keys are pressed1644 function noArrowKeysPressed() {1645 return !anyArrowKeysPressed();1646 }1647 tools.noArrowKeysPressed = noArrowKeysPressed;1648 // returns an array of all the currently pressed arrow keys1649 function currentlyPressedArrowKeys() {1650 let array = [];1651 [37, 38, 39, 40].forEach(function (thisKey) {1652 currentlyPressedKeys.isPressed(thisKey) && array.push();1653 });1654 return array;1655 }1656 tools.currentlyPressedArrowKeys = currentlyPressedArrowKeys;1657 // matches keydown (and keyup) events with callback functions1658 const keyevent = (function () {1659 let anyKeyUpFunctions = [];1660 let bindings = {1661 keydown: {}, // e.g. {"37": someFunc}1662 keyup: {}1663 };1664 let anyKeyDownFunctions = [];1665 function anyKeyDown(func) {1666 anyKeyDownFunctions.push(func);1667 }1668 function anyKeyUp(func) {1669 anyKeyUpFunctions.push(func);1670 }1671 $(window).on("keydown keyup", function (e) {1672 // first, calling functions that are linked to ANY keydown or keyup1673 const funcs = (e.type === "keydown") ? anyKeyDownFunctions : anyKeyUpFunctions;1674 funcs.forEach(thisFunc => thisFunc(e));1675 e.which = e.which || e.keyCode;1676 if (!e.which) return;1677 const keyCode = e.which.toString(); // 'cause the numbers are object keys, which are string1678 const eventType = e.type; // keydown or keyup1679 // calling the associated function, if any1680 if (bindings[eventType][keyCode]) {1681 e.preventDefault();1682 bindings[eventType][keyCode].callback(e);1683 // deleting the binding after it's used, if the "callOnce" property is true1684 if (bindings[eventType][keyCode] && bindings[eventType][keyCode].callOnce) {1685 delete bindings[eventType][keyCode];1686 }1687 }1688 });1689 function bindKeyEvent(p) {1690 if (!p || typeof p !== "object" ||1691 !p.keys ||1692 !p.onOrOff ||1693 !(p.onOrOff === "on" || p.onOrOff === "off") ||1694 (isNaN(p.keys) && !Array.isArray(p.keys)) ||1695 (p.callback && typeof p.callback !== "function") ||1696 !p.event ||1697 !(p.event === "keydown" || p.event === "keyup")) {1698 log("bindKeyEvent got some bad arguments!");1699 return false;1700 }1701 const e = p.event;1702 const keys = p.keys;1703 forceArray(keys).forEach(function (thisKey) {1704 thisKey = thisKey.toString(); // 'cause it's a key in an object1705 if (p.onOrOff === "on") {1706 bindings[e][thisKey] = {1707 callback: p.callback,1708 callOnce: !!p.callOnce1709 };1710 } else {1711 delete bindings[e][thisKey];1712 }1713 });1714 return keyevent;1715 }1716 function keydown(keys, callback, callOnce) {1717 return bindKeyEvent({1718 keys: keys,1719 callback: callback,1720 callOnce: callOnce,1721 onOrOff: "on",1722 event: "keydown"1723 });1724 }1725 function keyup(keys, callback, callOnce) {1726 return bindKeyEvent({1727 keys: keys,1728 callback: callback,1729 callOnce: callOnce,1730 onOrOff: "on",1731 event: "keyup"1732 });1733 }1734 function keydownOnce(keys, callback) {1735 return bindKeyEvent({1736 keys: keys,1737 callback: callback,1738 onOrOff: "on",1739 callOnce: true,1740 event: "keydown"1741 });1742 }1743 function keyupOnce(keys, callback) {1744 return bindKeyEvent({1745 keys: keys,1746 callback: callback,1747 onOrOff: "on",1748 callOnce: true,1749 event: "keyup"1750 });1751 }1752 function keydownOff(keys) {1753 return bindKeyEvent({1754 keys: keys,1755 onOrOff: "off",1756 event: "keydown"1757 });1758 }1759 function keyupOff(keys) {1760 return bindKeyEvent({1761 keys: keys,1762 onOrOff: "off",1763 event: "keyup"1764 });1765 }1766 function hasKeydownEvent(key) {1767 return !!bindings.keydown[key];1768 }1769 function hasKeyupEvent(key) {1770 return !!bindings.keyup[key];1771 }1772 function hasSomeEvent(key) {1773 return !!(hasKeydownEvent(key) || hasKeyupEvent(key));1774 }1775 function clearAll(event) {1776 if (event) {1777 bindings[event] = {};1778 } else {1779 bindings.keydown = {};1780 bindings.keyup = {};1781 }1782 }1783 // returning "on" or "off" functionality1784 return {1785 keydown,1786 keyup,1787 keydownOnce,1788 keydownOff,1789 keyupOff,1790 hasKeydownEvent,1791 hasKeyupEvent,1792 clearAll,1793 hasSomeEvent,1794 anyKeyDown,1795 anyKeyUp,1796 };1797 }());1798 tools.keydown = keyevent.keydown;1799 tools.keydownOnce = keyevent.keydownOnce;1800 tools.keydownOff = keyevent.keydownOff;1801 tools.keyup = keyevent.keyup;1802 tools.keyupOnce = keyevent.keyupOnce;1803 tools.keyupOff = keyevent.keyupOff;1804 tools.hasKeydownEvent = keyevent.hasKeydownEvent;1805 tools.hasKeyupEvent = keyevent.hasKeyupEvent;1806 tools.clearKeyEvents = keyevent.clearAll;1807 tools.hasSomeEvent = keyevent.hasSomeEvent;1808 tools.anyKeyDown = keyevent.anyKeyDown;1809 tools.anyKeyUp = keyevent.anyKeyUp;1810 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *1811 *1812 *1813 *1814 * Listens for any user interaction with the device, and calls a callback1815 *1816 *1817 *1818 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */1819 const onUserInteraction = (function () {1820 // NOTE removed "keydown" from the events list, 'cause it's easily spoofed by simply1821 // holding down any key (thanks, Kyota!) and anyway "keyup" is sufficient.1822 // Also erased "mousedown" 'cause it can probably be spoofed too1823 let eventsToListenFor = "scroll mouseup mousemove DOMMouseScroll mousewheel touchmove touchend";1824 // adding keyup listeners ONLY for desktop; this is because other1825 // plugins (e.g. "tiltSimulatesArrowKeys") may simulate keypresses1826 // on mobile, even though there's no actual keyboard1827 if (!tools.isMobile()) { eventsToListenFor += " keyup"; }1828 return function (callback) {1829 if (!callback || typeof callback !== "function") {1830 log("onUserIntraction requires a callback function!");1831 return false;1832 }1833 // activating by default1834 activate();1835 function activate() {1836 $(window).on(eventsToListenFor, callback);1837 }1838 function deactivate() {1839 $(window).off(eventsToListenFor, callback);1840 }1841 return {1842 deactivate,1843 activate,1844 };1845 };1846 }());1847 tools.onUserInteraction = onUserInteraction;1848 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *1849 *1850 *1851 * Returns the first several items from an array, e.g.,1852 * items [0 ~ 4] of an array of ten items1853 *1854 *1855 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */1856 function getFirstFromArray(number, array) {1857 if (!array || !number ||1858 !Array.isArray(array) ||1859 isNaN(number) ||1860 number < 1 ||1861 number > array.length) {1862 log("Got some bad parameters!");1863 return false;1864 }1865 return array.slice(0, number);1866 }1867 tools.getFirstFromArray = getFirstFromArray;1868 /*1869 *1870 *1871 * returns TRUE if any element is repeated in the array, otherwise FALSE1872 *1873 *1874 */1875 function arrayContainsDuplicates(array) {1876 var previousItems = [];1877 return array.some(function (thisElement) {1878 if (previousItems.indexOf(thisElement) !== -1) return true;1879 previousItems.push(thisElement);1880 });1881 }1882 tools.arrayContainsDuplicates = arrayContainsDuplicates;1883 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *1884 *1885 *1886 * returns TRUE if an array contains no duplicates1887 *1888 *1889 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */1890 function arrayAllUnique(array) {1891 return !arrayContainsDuplicates(array);1892 }1893 tools.arrayAllUnique = arrayAllUnique;1894 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *1895 *1896 *1897 * Checks whether two objects (or arrays, which are objects) are identical1898 *1899 * Returns "identical", "different", or FALSE if they're not comparable1900 *1901 * NOTE this works for objects (or arrays) with values of primitive1902 * types, but not for functions with constructors, etc.1903 *1904 *1905 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */1906 function objectsAreIdentical(a1, a2) {1907 if (arguments.length !== 2) return;1908 // checking that they're both objects, or both arrays, and that1909 // their lengths are the same,1910 if (typeof a1 !== "object" ||1911 typeof a2 !== "object" ||1912 typeof a1 === "function" ||1913 typeof a2 === "function" ||1914 Array.isArray(a1) !== Array.isArray(a2) ||1915 Object.keys(a1).length !== Object.keys(a2).length) {1916 return false;1917 }1918 // returning false if ANY members are not identical1919 const areIdentical = Object.keys(a1).every(function (thisKey) {1920 if (!(thisKey in a2)) return;1921 // recursion!1922 if (typeof a1[thisKey] === "object" || typeof a2[thisKey] === "object") {1923 return objectsAreIdentical(a1[thisKey], a2[thisKey]);1924 }1925 // simply comparing elements1926 return a1[thisKey] === a2[thisKey];1927 });1928 return areIdentical ? "identical" : "different";1929 }1930 tools.objectsAreIdentical = objectsAreIdentical;1931 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *1932 *1933 *1934 * Removes angle brackets and anything between them1935 *1936 *1937 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */1938 function removeSSMLTags(string) {1939 return string.replace(/<.*?>/g, "");1940 }1941 tools.removeSSMLTags = removeSSMLTags;1942 function isJapanese(string) {1943 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *1944 *1945 *1946 * Returns TRUE if ANY characters in the string are Japanese1947 *1948 * Codes mean:1949 *1950 * 3000 - 303f: Japanese-style punctuation1951 * 3040 - 309f: Hiragana1952 * 30a0 - 30ff: Katakana1953 * ff00 - ff9f: Full-width Roman characters and half-width Katakana1954 * 4e00 - 9faf: CJK unified ideographs - Common and uncommon Kanji1955 * 3400 - 4dbf: CJK unified ideographs Extension A - Rare Kanji1956 *1957 *1958 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */1959 return !!string.match(/[\u3000-\u303f\u3040-\u309f\u30a0-\u30ff\uff00-\uff9f\u4e00-\u9faf\u3400-\u4dbf]/);1960 }1961 tools.isJapanese = isJapanese;1962 function isEnglish(string) {1963 return !isJapanese(string);1964 }1965 tools.isEnglish = isEnglish;1966 function countLanguageShifts(str) {1967 const letters = str.split("");1968 if (!letters) return log("Didn't get any text to process!");1969 return letters.filter((currentLetter, index) => {1970 const precedingLetter = letters[index - 1] ?? currentLetter;1971 return areDifferentLanguages(currentLetter, precedingLetter);1972 }).length;1973 }1974 tools.countLanguageShifts = countLanguageShifts;1975 const areDifferentLanguages = (t1, t2) => isJapanese(t1) !== isJapanese(t2);1976 tools.areDifferentLanguages = areDifferentLanguages;1977 function getIndexOfShift(t) {1978 const letters = t.split("");1979 for (let i = 0; i < letters.length; i++) {1980 const currentLetter = letters[i];1981 const precedingLetter = letters[i - 1] ?? currentLetter;1982 if (isJapanese(currentLetter) !== isJapanese(precedingLetter)) return i;1983 }1984 }1985 tools.getIndexOfShift = getIndexOfShift;1986 function splitAtLanguageShift(t) {1987 const index = getIndexOfShift(t);1988 const first = t.substr(0, index).trim();1989 const second = t.substr(index, t.length - index).trim();1990 return {1991 english: !isJapanese(first) ? first : second,1992 japanese: isJapanese(first) ? first : second,1993 };1994 }1995 tools.splitAtLanguageShift = splitAtLanguageShift;1996 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *1997 *1998 *1999 * Checks that a string has no forward slashes, while allowing "</", used in SSML tags2000 *2001 *2002 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */2003 function isSpeakable(text) {2004 return !text.match(/[^<]\/]/g);2005 }2006 tools.isSpeakable = isSpeakable;2007 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *2008 *2009 *2010 * Takes a string with underscores, brackets, etc., and returns a scrubbed version,2011 * with underscores removed, dummy words at end removed, and with the first word2012 * in bracketed text extracted. Like this...2013 *2014 *2015 * From: "There_is (only) [one, two] thing_to_do! [dummy words]"2016 * To: "There is one thing to do!"2017 *2018 *2019 *2020 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */2021 function scrubForVoiceSynthesis(string) {2022 if (!tools.isEnglish(string)) return;2023 string = string.replace(/_/g, " "); // removing underscores2024 string = string.replace(/\(.+?\)/g, ""); // removing anything in parentheses2025 string = string.replace(/\[.[^\[]*\]$/, ""); // removing any bracketed content at end of string2026 string = string.replace(/\[(.+?)(,.*?)*\]/g, "$1"); // extracting first word from words in brackets, separated by commas2027 string = string.replace(/\s{2,}/g, " ").trim(); // removing multiple spaces2028 return string;2029 }2030 tools.scrubForVoiceSynthesis = scrubForVoiceSynthesis;2031 function chances(fraction) {2032 if (!fraction || isNaN(fraction) || fraction >= 1 || fraction <= 0) {2033 return log("chances requires a fraction (or decimal number) between 0 and 1!");2034 }2035 return Math.random() < fraction;2036 }2037 tools.chances = chances;2038 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *2039 *2040 *2041 * Uses the "chances" function above to return true 50% of the time2042 *2043 *2044 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */2045 function coinToss() {2046 return chances(1 / 2);2047 }2048 tools.coinToss = coinToss;2049 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *2050 *2051 *2052 * Tests for deviceorientation, and executes a callback if it isn't supported.2053 *2054 * Mostly this is for iOS Safari, which is being stupid.2055 *2056 *2057 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */2058 // function ifNoTiltSupport(callback) {2059 // if (tools.isMobile()) {2060 // let timeout = setTimeout(callback, 1000);2061 // window.addEventListener("deviceorientation", (e) => clearTimeout(timeout));2062 // }2063 // }2064 // tools.ifNoTiltSupport = ifNoTiltSupport;2065 function jqueryuiModal(obj) {2066 if (!obj || typeof obj !== "object" || !obj.title || !obj.body) {2067 return console.log("jqueryuiModal requires an object with properties 'title' and 'body'!");2068 }2069 obj.buttons = forceArray(obj.buttons);2070 const modalID = "jquery-ui-modal";2071 $(`<div id='${modalID}' title='${obj.title}'></div>`).appendTo("body");2072 $(`<p>${obj.body}</p>`).appendTo($(`#${modalID}`));2073 $("#jquery-ui-modal").dialog({2074 buttons: obj.buttons ? obj.buttons : null2075 });2076 }2077 tools.jqueryuiModal = jqueryuiModal;2078 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *2079 *2080 *2081 *2082 * Wiring up any body touchend event to trigger permission for orentation change2083 *2084 * NOTE that this only activates the permission dialog; it does not wire up any listeners,2085 * though it does call a callback2086 *2087 *2088 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */2089 function activateTiltDetection(obj = {}) {2090 const onDesktop = obj.onDesktop || function () { };2091 const onSuccess = obj.onSuccess || function () { };2092 const onFail = obj.onFail || function () { };2093 if (!tools.isMobile()) return onDesktop();2094 $("body").on("touchend", getTiltPermission);2095 function getTiltPermission() {2096 $("body").off("touchend", getTiltPermission);2097 DeviceMotionEvent.requestPermission().then(function (response) {2098 if (response === "granted") onSuccess();2099 }).catch(function (e) {2100 onFail();2101 log("Failed!");2102 log.error(e);2103 });2104 }2105 }2106 tools.activateTiltDetection = activateTiltDetection;2107 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *2108 *2109 *2110 * Returns an object with properties x and y, that are constantly updated2111 *2112 *2113 *2114 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */2115 function DeviceTiltDetector(params) {2116 params = $.extend({2117 maxTilt: 10 // higher == less sensitive2118 }, params || {});2119 const maxTilt = params.maxTilt;2120 this.maxTilt = maxTilt;2121 // returning null properties if not mobile2122 if (!window.hasOwnProperty("orientation")) {2123 this.x = null;2124 this.y = null;2125 this.maxTilt = null;2126 return true;2127 }2128 // saving tilt info every time the device moves2129 registerNewTilt = event => {2130 const tilt = getTilt(event);2131 this.x = Math.max(Math.min(tilt.x, maxTilt), -maxTilt); // left-to-right2132 this.y = Math.max(Math.min(tilt.y, maxTilt), -maxTilt); // back-to-front2133 };2134 // saving tilt info every time the device moves2135 // NOTE adding this "requestPermission" bullshit2136 DeviceMotionEvent.requestPermission().then(function (response) {2137 response === "granted" && window.addEventListener("deviceorientation", registerNewTilt);2138 }).catch(function (e) {2139 console.error(e);2140 });2141 $(window).trigger("orientationchange");2142 }2143 tools.DeviceTiltDetector = DeviceTiltDetector;2144 // swapping x, y in portrait / landscape mode2145 function getTilt(event) {2146 const directions = {2147 "0": { x: event.gamma, y: event.beta },2148 "180": { x: -event.gamma, y: -event.beta }, // NEW 'cause some tables support this now!2149 "90": { x: event.beta, y: -event.gamma },2150 "-90": { x: -event.beta, y: event.gamma },2151 };2152 return directions[window.orientation];2153 }2154 tools.getTilt = getTilt;2155 function pauser(p) {2156 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * *2157 *2158 *2159 * Takes an array of keyCodes (e.g. [80] == p) and2160 * toggles a variable ("isPaused") on keyDown2161 *2162 * NEW:2163 * Also takes a button or checkbox2164 *2165 * NEW:2166 * Added methods "disable", "enable", and "destroy"2167 *2168 *2169 *2170 * * * * * * * * * * * * * * * * * * * * * * * * * * * * */2171 if (!p || typeof p !== "object") {2172 return log("tools.pauser got some bad parameters!");2173 }2174 const settings = $.extend({2175 keyCodes: [80], // the 'p' key ** NOTE this can be a single number, or an array of numbers2176 startValue: false, // false == not paused2177 element: null, // a jQuery element, such as button or checkbox2178 pausedClass: null, // class to add to the element when paused2179 resumedClass: null, // class to add to the element when not paused2180 onPause: function () {2181 // do something on pause2182 },2183 onResume: function () {2184 // do something on pause2185 }2186 }, p || {});2187 const $element = settings.element;2188 const kCodes = forceArray(settings.keyCodes);2189 let isPaused = settings.startValue; // false by default2190 let pauserDisabled = false; // USE THIS to comletely disable the pauser2191 keyevent.keydown(kCodes, togglePausedState);2192 // wiring up the element, if specified (e.g. button or checkbox)2193 // NOTE we're using the "click" event even on checkboxes, rather than the "change" method2194 if ($element && $element instanceof jQuery) $element.click(togglePausedState);2195 function togglePausedState() {2196 if (pauserDisabled) return;2197 isPaused = !isPaused;2198 isPaused ? settings.onPause() : settings.onResume();2199 $element && toggleElementState();2200 }2201 function toggleElementState() {2202 $element.toggleClass(settings.pausedClass, !!(isPaused));2203 $element.toggleClass(settings.resumedClass, !(isPaused));2204 $element.is(":checkbox") && $element.prop("checked", isPaused ? true : false); // only affects checkboxes2205 }2206 function getPausedState() {2207 return isPaused;2208 }2209 function disable() {2210 pauserDisabled = true;2211 }2212 function enable() {2213 pauserDisabled = false;2214 }2215 function destroy() {2216 $element && $element.off("click", togglePausedState);2217 keyevent.keydownOff(kCodes);2218 }2219 return {2220 isPaused: getPausedState,2221 togglePausedState: togglePausedState,2222 disable: disable,2223 enable: enable,2224 destroy: destroy2225 };2226 }2227 tools.pauser = pauser;2228 function secondsToOtherFormats(timeInSeconds) {2229 const seconds = timeInSeconds % 60;2230 const minutes = Math.floor(timeInSeconds / 60 % 60);2231 const hours = Math.floor(timeInSeconds / 3600);2232 const totalMinutes = Math.floor(timeInSeconds / 60);2233 return { seconds, minutes, hours, totalMinutes, timeInSeconds, };2234 }2235 tools.secondsToOtherFormats = secondsToOtherFormats;2236 // converts seconds (not miliseconds!) to h:m.s format2237 function secondsToHMS(time, obj = {}) {2238 const settings = $.extend({2239 hoursTag: "h ",2240 minutesTag: "m ",2241 secondsTag: "s",2242 useHours: true,2243 useMinutes: true,2244 useSeconds: true,2245 useLeadingZeroes: true,2246 prefix: "",2247 suffix: "",2248 }, obj);2249 time = secondsToOtherFormats(time);2250 function addLeadingZero(number) {2251 number = parseInt(number);2252 if (number >= 0 && number <= 9) return "0" + number;2253 return number.toString();2254 }2255 let hours = time.hours ?? "",2256 minutes = time.minutes ?? "",2257 seconds = time.seconds;2258 // only adding leading 0's IF there's something to the LEFT2259 if (settings.useLeadingZeroes) {2260 if (time.hours) minutes = addLeadingZero(minutes);2261 if (time.totalMinutes) seconds = addLeadingZero(seconds);2262 }2263 if (hours) hours += settings.hoursTag;2264 if (minutes) minutes += settings.minutesTag;2265 if (seconds) seconds += settings.secondsTag;2266 return hours + minutes + seconds;2267 }2268 tools.secondsToHMS = secondsToHMS;2269 const easer = (function () {2270 return function (power, duration, type) {2271 if (arguments.length !== 3 || isNaN(power) || isNaN(duration) || (type !== "easeIn" && type !== "easeOut")) {2272 return false;2273 }2274 const easingTypes = {2275 easeIn: function (t, d) {2276 d = d || duration;2277 return Math.pow((t / d), power);2278 },2279 easeOut: function (t, d) {2280 d = d || duration;2281 return 1 - Math.pow(1 - (t / d), power);2282 }2283 };2284 return easingTypes[type];2285 };2286 }());2287 tools.easer = easer;2288 function windowHasFocus() {2289 return !document.hidden && document.hasFocus();2290 }2291 tools.windowHasFocus = windowHasFocus;2292 function lightenElementsIncrementally(obj) {2293 if (!obj || typeof obj !== "object" || !obj.elements || isNaN(obj.minOpacity)) {2294 return log("lightenIncrementally received no params, or they're not right!");2295 }2296 let currentOpacity = obj.minOpacity;2297 const lightnessIncrement = (1 - obj.minOpacity) / obj.elements.length;2298 obj.elements.each(function () {2299 $(this).css({ opacity: currentOpacity });2300 currentOpacity += lightnessIncrement;2301 });2302 return true;2303 }2304 tools.lightenElementsIncrementally = lightenElementsIncrementally;2305 function shrinkToFit($inner, $outer, options = {}) {2306 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *2307 *2308 *2309 * Shrinks the font-size of an INNER div until it fits entirely inside an2310 * OUTER div.2311 *2312 * Ideal for text within cards.2313 *2314 *2315 * * * * * * * * * * * * * * * * * * * * * * * * * *