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 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */2316 if (arguments.length < 2) {2317 return console.warn("tools.shrinkToFit requires inner and outer jQuery elements!");2318 }2319 $inner = forceJQuery($inner);2320 $outer = forceJQuery($outer);2321 const upperLimit = options.tryCeiling || 20;2322 const shrinkIncrement = options.shrinkIncrement || 2;2323 const outerHeight = () => parseInt($outer.height());2324 const innerHeight = () => parseInt($inner.height());2325 const outerWidth = () => parseInt($outer.width());2326 const innerWidth = () => parseInt($inner.width());2327 // actually shrinking the font2328 let counter = 0;2329 while ((innerHeight() > outerHeight() || innerWidth() > outerWidth()) && counter < upperLimit) {2330 counter++;2331 const currentFontSize = parseInt($inner.css("font-size"));2332 const newFontSize = currentFontSize - shrinkIncrement;2333 $inner.css({ fontSize: newFontSize });2334 }2335 return $outer;2336 }2337 tools.shrinkToFit = shrinkToFit;2338 function fadeAndReload(opacity = 0.3) {2339 $("body").css({ opacity });2340 window.location.reload();2341 }2342 tools.fadeAndReload = fadeAndReload;2343 function doubleConfirm(text) {2344 if (!window.confirm(text) || !window.confirm("** " + text + " **")) return false;2345 return true;2346 }2347 tools.doubleConfirm = doubleConfirm;2348 tools.page = {2349 rememberScroll: function () {2350 $(window).scroll(() => sessionStorage.scrollPosition = $("body").scrollTop());2351 },2352 restoreScroll: function () {2353 $("body").scrollTop(sessionStorage.scrollPosition);2354 }2355 };2356 function doAfterNoUserInteraction(object) {2357 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *2358 *2359 *2360 * object.callback = some function to call when user hasn't interacted for however long2361 *2362 * object.interval (optional) = how many seconds to wait before calling the callback2363 *2364 *2365 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */2366 // param scrubbing2367 if (!object || typeof object !== "object" || !object.callback || typeof object.callback !== "function") {2368 return log("tools.beCheckingForUserInput requires an object passed in with a callback property, which must be a function!");2369 }2370 // defaults to 15 seconds2371 object.interval = object.interval || 15;2372 let checkInterval; // will hold a setTimeout2373 let hasFinished = false;2374 // on any user interaction, clearing any old intervals and starting a new one2375 restartCheckInterval(); // starting once without user interaction2376 function restartCheckInterval() {2377 clearTimeout(checkInterval);2378 checkInterval = setTimeout(function () {2379 if (hasFinished) return;2380 object.callback();2381 hasFinished = true;2382 }, object.interval * 1000);2383 }2384 // adding all sorts of listeners for any sort of user input2385 $("body, html").on("scroll mousedown mousemove DOMMouseScroll mousewheel keydown keyup touchstart touchmove touchend", restartCheckInterval);2386 function cancel() {2387 hasFinished = true;2388 }2389 // returning a way to manually cancel the thing2390 return { cancel, };2391 }2392 tools.doAfterNoUserInteraction = doAfterNoUserInteraction;2393 function getTime() {2394 return (new Date()).getTime();2395 }2396 tools.getTime = getTime;2397 function secondsFromNow(time) {2398 return getTime() + time;2399 }2400 tools.secondsFromNow = secondsFromNow;2401 function showMistakenVocab(words) {2402 /*2403 *2404 * returns a string in the format "cat-猫<br>dog-犬<br>horse-馬"2405 *2406 */2407 words = words || {};2408 let returnString = "";2409 for (var key in words) {2410 const value = words[key];2411 returnString += `${key} - <i>${value}</i><br>`;2412 }2413 return returnString;2414 }2415 tools.showMistakenVocab = showMistakenVocab;2416 function getFontSize($object) {2417 if (!$object) {2418 log("tools.getFontSize requires a jQuery object passed in!");2419 return false;2420 }2421 return parseInt($object.css("font-size"));2422 }2423 tools.getFontSize = getFontSize;2424 function refreshAfterWakingFromSleep(object = {}) {2425 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *2426 *2427 * Reloads the page if the computer has been asleep2428 * for more than 2 minutes2429 *2430 * This relies on the fact that javascript (and therefor this function)2431 * stops when the computer's asleep2432 *2433 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */2434 // making the object an object, if none is passed in2435 const updateInterval = object.updateInterval || 2000; // update every 2 seconds2436 const maxAllowed = object.allowedSleepInterval || 120 * 1000; // allowing 120 seconds between2437 let lastTime = (new Date()).getTime();2438 setInterval(function () {2439 const currentTime = (new Date()).getTime();2440 const elapsedTime = currentTime - lastTime;2441 if (elapsedTime < maxAllowed) {2442 lastTime = currentTime;2443 } else {2444 location.reload();2445 }2446 }, updateInterval);2447 }2448 tools.refreshAfterWakingFromSleep = refreshAfterWakingFromSleep;2449 // triggering the change event on any focussed object on Enter key down2450 function enterKeyTriggersChangeEvent() {2451 /*2452 *2453 * NOTE this is necessary only when not using a <form> tag!2454 *2455 */2456 keyevent.keydown(13, function () {2457 $(":focus").trigger("change");2458 });2459 }2460 tools.enterKeyTriggersChangeEvent = enterKeyTriggersChangeEvent;2461 // converts 全角 and 半角 alphanumeric stuff, as well as ? and ! marks2462 // NOTE this does not work with 漢字2463 function zenHanConvert(string) {2464 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *2465 *2466 *2467 * Two-part function! So, for example...2468 *2469 * zenHanConvert("1234").to("hankaku");2470 *2471 *2472 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */2473 // error checking2474 if (!string || typeof string !== "string" || string.length < 1) {2475 log("tools.convertZenkaku needs a string as the first paramter!");2476 return;2477 }2478 return {2479 to: function (convertTo) {2480 if (!convertTo || !(convertTo === "zenkaku" || convertTo === "hankaku")) {2481 log("tools.convertZenkaku takes a string, either 'zenkaku' or 'hankaku', as the second paramter!");2482 return;2483 }2484 // 全角に2485 if (convertTo === "zenkaku") {2486 return string.replace(/[A-Za-z0-9?!]/g, function (s) {2487 return String.fromCharCode(s.charCodeAt(0) + 0xFEE0);2488 });2489 }2490 // 半角に2491 if (convertTo === "hankaku") {2492 return string.replace(/[A-Za-z0-9?!]/g, function (s) {2493 return String.fromCharCode(s.charCodeAt(0) - 0xFEE0);2494 });2495 }2496 }2497 };2498 }2499 tools.zenHanConvert = zenHanConvert;2500 function fitOnOneLine($div) {2501 if (!$div) {2502 log("tools.fitOnOneLine requires a jquery id of the container holding the text!");2503 return;2504 }2505 if ($div.text() === "") {2506 log("tools.fitOnOneLine received no text that needs shrinking!");2507 return;2508 }2509 // adding an invisible for-testing div at the bottom to measure the text in2510 if ($("#fit-on-one-line-thing").length === 0) {2511 $("html").append("<div style='clear: both; opacity: 0; visibility: 0;'><span id='fit-on-one-line-thing'></span></div>");2512 }2513 const $fitOnOneLineThing = $("#fit-on-one-line-thing");2514 let fontSize = parseInt($div.css("font-size"));2515 let safetyCounter = 0;2516 $fitOnOneLineThing.text($div.text()).css({ fontSize: fontSize });2517 while (($fitOnOneLineThing.width() > $div.parent().width() || $fitOnOneLineThing.height() > $div.parent().height()) && safetyCounter < 20) {2518 safetyCounter++;2519 fontSize -= 1;2520 $fitOnOneLineThing.css({ fontSize: fontSize });2521 }2522 // finally, setting the font size of the original object2523 $div.css({ fontSize: fontSize - 2 });2524 return true;2525 }2526 tools.fitOnOneLine = fitOnOneLine;2527 function setMobileScreenWidth(width, callback) {2528 // exiting if there is no meta-tag with an id of "viewport"2529 if ($("#viewport").length < 1) {2530 log("tools.setMobileScreenWidth requires a meta tag with id='viewport'");2531 return;2532 }2533 width = width || 320; // default width2534 // using the default width if the screen is smaller than 400px (so this won't apply to desktop)2535 if (screen.width <= 400) {2536 $("#viewport").prop("content", "width = " + width + ", initial-scale=1.0, maximum-scale=1.0, user-scalable=no");2537 if (callback) { callback(); }2538 }2539 }2540 tools.setMobileScreenWidth = setMobileScreenWidth;2541 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *2542 *2543 *2544 * Returns "Japanese" if there are ANY Japanese characters2545 *2546 * in the string; otherwise, returns "English"2547 *2548 *2549 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */2550 const languageOf = (function () {2551 // regex testing for Japanese hiragana, katakana, and kanji2552 const japaneseLetters = /[\u3040-\u309F]|[\u30A0-\u30FF]|[\u4E00-\u9FAF]/;2553 return function (string) {2554 if (!string || typeof string !== "string" || string.length === 0) {2555 return "tools.languageOf requires a string!";2556 }2557 return japaneseLetters.test(string) ? "Japanese" : "English";2558 };2559 }());2560 tools.languageOf = languageOf;2561 const numbToTouch = (function () {2562 return function ($elementsArray, string) {2563 tools.forceArray($elementsArray).forEach(function ($element) {2564 if (!$element && $element.length < 1) return; // is the && right here? Should be ||?2565 $element.off("touchstart", disableTouch);2566 if (string !== "off") $element.on("touchstart", disableTouch);2567 function disableTouch(e) {2568 if (e.touches) e = e.touches[0];2569 return false;2570 }2571 });2572 };2573 }());2574 tools.numbToTouch = numbToTouch;2575 function shrinkFont($container, percent) {2576 if (!$container || !($container instanceof $)) return log("tools.shrinkFont requires a jQuery DOM element as the first parameter!");2577 // how much of the element to fill (default 90%)2578 percent = percent || 0.9;2579 // used to break out of infinite loops2580 let counter = 0;2581 let finalFontSize = 16; // nice, round default?2582 function getContainerHeight() {2583 return parseInt($container.height());2584 }2585 function getFontSize() {2586 return parseInt($container.css("font-size"));2587 }2588 // exiting here if it's already one line, or if the font is already ridiculously small2589 if (getContainerHeight() < getFontSize * 1.5 || getFontSize < 4) return true;2590 // shrinking the font size2591 while (getContainerHeight() > (getFontSize * 1.5) && counter < 40) {2592 counter++;2593 finalFontSize = getFontSize - 1;2594 // log("finalFontSize is: " + finalFontSize);2595 $container.css({ fontSize: finalFontSize });2596 }2597 // calculating the final font size2598 finalFontSize *= percent;2599 $container.css({ fontSize: finalFontSize });2600 }2601 tools.shrinkFont = shrinkFont;2602 // returns 'click' if it's desktop, or 'touchend' if it's mobile2603 tools.clickOrTouch = tools.isMobile() ? "touchend" : "click"; // NEW TEST changed from "touchstart" to "touchend"2604 function score(obj) {2605 const settings = $.extend({2606 timerAutoStart: false2607 }, obj || {});2608 let time1; // time at the FIRST answer, constant2609 let time2; // time of the LAST answer, updated with each problem2610 let myInterval;2611 let timerHasStarted = false;2612 function markTimeOfAnswer() {2613 score.number_correct++;2614 time2 = (new Date()).getTime();2615 return this;2616 }2617 function getAverageTimeBetweenAnswers() {2618 const avgTime = (time2 - time1) / score.number_correct; // miliseconds2619 return {2620 miliseconds: avgTime, // miliseconds2621 seconds: Math.round(avgTime / 1000),2622 twoDecimal: Math.round(avgTime / 10) / 100 // e.g. 1789 => 1.792623 };2624 }2625 function startTimer() {2626 if (timerHasStarted) return;2627 timerHasStarted = true;2628 time1 = (new Date()).getTime();2629 myInterval = setInterval(incrementTimer, 1000);2630 return this;2631 }2632 function incrementTimer() {2633 const currentTime = (new Date()).getTime();2634 const timeElapsed = Math.floor((currentTime - time1) / 1000);2635 score.time_taken = timeElapsed;2636 return this;2637 }2638 function stopTimer() {2639 clearInterval(myInterval);2640 return this;2641 }2642 function getNumberAnswered() {2643 return this.number_correct + this.number_mistakes;2644 }2645 if (settings.timerAutoStart) startTimer();2646 return {2647 time_taken: function () {2648 return score.time_taken;2649 },2650 number_correct: 0,2651 number_mistakes: 0,2652 total_number_problems: null,2653 stopTimer,2654 startTimer,2655 markTimeOfAnswer,2656 getAverageTimeBetweenAnswers,2657 getNumberAnswered,2658 };2659 }2660 tools.score = score;2661 // returning the tools object so it works with Require.js2662 return tools;2663 }...

Full Screen

Full Screen

app.js

Source:app.js Github

copy

Full Screen

...695 alienPools.onCanvasCount[t] = 0;696 });697 waveData.curWave = (keyState.c) ? Math.floor(waveData.curWave/5) * 5 : 0;698 waveData.leftInCurWave = Object.assign({}, waveData.waves[waveData.curWave].aliens); 699 clearKeyEvents();700 powerupPool.active = -1;701 powerupPool.time = powerupPool.timeout;702 waveData.newWave = true;703 waveData.newWaveTime = waveData.newWaveTimeout;704 resetShip();705}706init = () => {707 canvas = document.getElementById('gameArea');708 display = {709 missiles: document.getElementById('missiles'),710 bombs: document.getElementById('bombs'),711 shield: document.getElementById('shield'),712 score: document.getElementById('score')713 };...

Full Screen

Full Screen

vocabulary.js

Source:vocabulary.js Github

copy

Full Screen

1/* jshint expr: true */2define(3 [4 "jquery",5 "assignment",6 "tools",7 "helpers/problemsAndChoicesList",8 "helpers/AudioLoader",9 "helpers/SoundEffects",10 "helpers/Timer",11 "helpers/scorebox",12 "helpers/shakeElement",13 "helpers/tangocho",14 "TweenMax",15 "TweenMax_CSSPlugin",16 "TweenMax_EasePack",17 ],18 function(19 $,20 assignment,21 tools,22 myVocabList,23 AudioLoader,24 SoundEffects,25 Timer,26 myScorebox,27 shakeElement,28 tangocho,29 TweenMax30 ) {31 let mistakesLine,32 timeLimit,33 recycle,34 audio,35 timer,36 myJSON,37 scorebox,38 problemNowActive = false,39 vocabList = {},40 sentencesMode = false,41 autoShowHint = false,42 autoAdvance = false,43 score = tools.score({44 number_guesses: 045 });46 const $startButton = $("#start-button"),47 $playButton = $("#play-button");48 const newChoice = (function() {49 const $choiceMaster = $(".choice-holder.my-template").detach().removeClass("my-template");50 const revertDuration = 100;51 const dragStartClass = "now-dragging mousedown";52 const dragStopClass = "now-dragging mousedown";53 return function(problem, japaneseWord, englishWord, index, isSentencesMode) {54 englishWord = tools.getIdealAnswer(englishWord);55 const $choiceHolder = $choiceMaster.clone().draggable({56 revert: true,57 revertDuration: revertDuration,58 stack: ".choice-holder",59 axis: "y",60 containment: "#choices-bounds",61 start: function() {62 $(this).addClass(dragStartClass);63 },64 stop: function() {65 $(this).removeClass(dragStopClass);66 }67 }).addClass(isSentencesMode ? "align-left" : "").css({68 height: (90 / problem.choices.length) + "%"69 }).data({70 japanese: japaneseWord,71 english: englishWord,72 isCorrect: index === problem.indexOfCorrectAnswer,73 });74 $choiceHolder.find(".text-holder").text(japaneseWord);75 return $choiceHolder;76 };77 }());78 const dropZone = (function() {79 const $textHolder = $("#drop-here-message");80 const $dropZone = $("#drop-zone");81 const textHolderFontSize = $textHolder.css("fontSize");82 const originalText = $textHolder.text();83 const height = parseInt($("#choices-bounds").height() / 4);84 let nextButtonIsActive = false;85 $dropZone.click(function() {86 $playButton.click();87 }).droppable({88 accept: ".active-choice",89 drop: function(event, ui) {90 checkAnswer($(ui.draggable));91 }92 }).css({ height: height * 0.9 });93 function showHint() {94 const hintText = tools.getIdealAnswer(vocabList.getTargetEnglish());95 $textHolder.text(hintText).addClass("hint-showing");96 tools.shrinkToFit($textHolder, $dropZone);97 }98 function restore() {99 nextButtonIsActive = false;100 $dropZone.removeClass("next-button-mode");101 $dropZone.off("click").on("click", function() {102 $playButton.click();103 });104 $textHolder.text(originalText).removeClass("hint-showing");105 $textHolder.css({106 fontSize: textHolderFontSize107 });108 }109 function setHeight() {110 restore();111 $dropZone.css({ height: $(".choice-holder").height() });112 }113 function nextButtonMode(d) {114 d = d || {};115 nextButtonIsActive = true;116 setTimeout(function() {117 $dropZone.addClass("next-button-mode");118 $dropZone.off("click").on("click", nextProblem);119 }, d.delay);120 }121 function isNextButtonMode() {122 return nextButtonIsActive;123 }124 return {125 showHint,126 restore,127 nextButtonMode,128 isNextButtonMode,129 setHeight130 };131 }());132 const sounds = new SoundEffects({133 sounds: {134 correct: "/sounds/vocabulary/tick.mp3",135 wrong: "/sounds/vocabulary/wrongSound.mp3",136 tick: "/sounds/vocabulary/tick.mp3"137 },138 playThisOnCheckboxCheck: "tick"139 });140 const hintButton = (function() {141 const $hintButton = $("#hint-button");142 const originalText = $hintButton.text();143 let isDisabled = false;144 let numTimesUsed = 0;145 autoShowHint && $hintButton.remove();146 $hintButton.click(hintButtonHandler);147 function hintButtonHandler() {148 if (problemNowActive && !isDisabled) {149 numTimesUsed++;150 dropZone.showHint();151 $hintButton.addClass("hint-showing");152 }153 }154 function enable() {155 if (autoShowHint) { return null; }156 $hintButton.text(originalText).removeClass("hint-showing");157 dropZone.restore();158 isDisabled = false;159 }160 function getNumTimesUsed() {161 return numTimesUsed;162 }163 return {164 enable,165 getNumTimesUsed,166 trigger: hintButtonHandler167 };168 }());169 function wireUpStartButton() {170 assignment.startButton({171 button: $startButton,172 buttonText: "スタート",173 buttonAlternate: $("#frame"),174 callback: function() {175 timer.start();176 score.startTimer();177 scorebox.clock.start();178 wireUpKeyboard(); // doing this here, so it doesn't collide with the startButton179 setTimeout(function() {180 nextProblem();181 }, 200);182 }183 });184 $("body").addClass("all-audio-loaded");185 }186 assignment.getProblemData(function(d) {187 myJSON = d;188 myJSON.number_sentakushi = myJSON.number_sentakushi || 3;189 timeLimit = myJSON.assignment.time_limit;190 recycle = myJSON.assignment.recycle;191 mistakesLine = myJSON.assignment.mistakes_limit;192 assignment.controlPanel.useVoices();193 wireUpStartButton();194 // myJSON.problem = myJSON.problem.map(pair => {195 // return pair.map(item => {196 // return tools.isEnglish(item) ? tools.getIdealAnswer(item) : item;197 // });198 // });199 assignment.removeProblemsWithoutAudio(myJSON);200 if (myJSON.number_problems) {201 myJSON.number_problems = parseInt(myJSON.number_problems);202 if (myJSON.number_problems < myJSON.problem.length) {203 tools.whittleDownArray(myJSON.problem, myJSON.number_problems);204 }205 }206 const numProblems = myJSON.problem.length;207 scorebox = myScorebox({208 correctCounter: {209 numberSegments: myJSON.problem.length,210 recycle: recycle ? true : false,211 fill: "blue"212 },213 wrongCounter: {214 numberSegments: mistakesLine,215 recycle: mistakesLine ? false : true,216 fill: "red"217 },218 clock: {219 duration: timeLimit ? (timeLimit * 1000) : 60 * 1000,220 labelText: timeLimit ? timeLimit : "0",221 repeat: true,222 dotMode: timeLimit ? false : true,223 labelFill: "darkorange",224 backgroundColor: "darkorange"225 }226 });227 timer = new Timer({228 pauseStart: true,229 countdownFrom: timeLimit,230 // onWarn: function() {231 // //232 // },233 eachSecond: function() {234 const time = tools.secondsToHMS(timer.time(), {235 useHours: false,236 minutesTag: "m ",237 secondsTag: "s",238 useLeadingZeroes: false239 });240 scorebox.clock.label(time);241 },242 onFinish: function() {243 endSequence(recycle ? "timeTrial" : "timeUp");244 }245 });246 assignment.directions.show("vocabulary", {247 directions: myJSON.assignment.directions,248 mistakes: mistakesLine,249 numProblems: recycle ? null : numProblems,250 time: timeLimit,251 timeTrial: recycle ? true : false252 });253 vocabList = myVocabList({254 problems: myJSON.problem,255 number_problems: numProblems,256 audioFiles: myJSON.audioFiles,257 numberSentakushi: myJSON.number_sentakushi || 3,258 recycleProblems: recycle ? true : false // optionally recycling words, so they never run out259 });260 sentencesMode = myJSON.misc.hasOwnProperty("sentencesMode") ?261 myJSON.misc.sentencesMode :262 vocabList.isSentences;263 // setting autoAdvance to "true" for vocabulary and "false" for sentencesMode,264 // or whatever is in myJSON.misc.autoAdvance265 if (myJSON.misc.hasOwnProperty("autoAdvance")) {266 autoAdvance = myJSON.misc.autoAdvance;267 } else {268 autoAdvance = sentencesMode ? false : true;269 }270 // setting autoAdvance to "true" for vocabulary and "false" for sentencesMode,271 // or whatever is in myJSON.misc.autoAdvance272 if (myJSON.misc.autoShowHint) {273 autoShowHint = myJSON.misc.autoShowHint;274 }275 audio = AudioLoader({276 audioFiles: myJSON.audioFiles, // NOTE not all of these words may be loaded; only the ones that are in getRemainingWords, below277 wordsList: vocabList.getRemainingWords(),278 playButton: "playIcon", // passing in the button on which to show "play" and "pause" symbols279 onReady: wireUpStartButton, // when all have loaded (if preloading) or immediately280 getWordToPlay: function() { // (optional) function to retrieve which word to play next, so we don't have to spoon-feed the word in281 return vocabList.getTargetEnglish();282 },283 onPlay: function() {284 $(".play-button-icon").addClass("now-playing");285 problemNowActive = true;286 },287 onEnded: function() {288 $(".play-button-icon").removeClass("now-playing");289 },290 });291 assignment.fixedProblemHolder({292 onSlideUp: function() {293 $("#directions").hide();294 },295 onSlideDown: function() {296 $("#directions").show();297 }298 });299 });300 function nextProblem() {301 $(".carriage.old").remove();302 const $carriageOld = $("<div class='carriage old'></div>").appendTo("#choices-holder");303 $(".choice-holder").removeClass("active-choice").appendTo($carriageOld);304 const problem = vocabList.pickRandomProblem();305 hintButton.enable();306 TweenMax.to($carriageOld, 0.75, {307 left: "110%",308 onComplete: function() {309 $carriageOld.remove();310 }311 });312 $(".carriage.new").remove();313 const $carriageNew = $("<div class='carriage new'/>").appendTo("#choices-holder");314 problem.choices.forEach(function(choice, index) {315 const japaneseWord = choice;316 const englishWord = vocabList.getEnglishFor(choice);317 const $choiceHolder = newChoice(problem, japaneseWord, englishWord, index, sentencesMode);318 $carriageNew.append($choiceHolder);319 TweenMax.to($carriageNew, 0.75, {320 left: "0%"321 });322 });323 dropZone.setHeight();324 autoShowHint && dropZone.showHint();325 setTimeout(function() {326 problemNowActive = true;327 audio.play();328 }, 500);329 }330 function checkAnswer($droppedObject) {331 if (!problemNowActive) return false;332 score.number_guesses++;333 const divider = sentencesMode ? "<br>" : " = ";334 const $textHolder = $droppedObject.find(".text-holder");335 $textHolder.html($droppedObject.data("japanese") + divider + $droppedObject.data("english"));336 tools.shrinkToFit($textHolder, $droppedObject);337 $droppedObject.data("isCorrect") ? rightAnswerHandler($droppedObject) : wrongAnswerHandler($droppedObject);338 }339 function rightAnswerHandler($droppedObject) {340 scorebox.correctCounter.increment();341 score.number_correct++;342 audio.stopAll();343 problemNowActive = false;344 sounds.play("correct");345 $droppedObject.addClass("answered-correct");346 vocabList.removeCurrentProblem();347 $(".choice-holder").draggable("disable");348 if (vocabList.getNumberRemaining() <= 0) {349 endSequence("allAnswered");350 return;351 }352 if (!autoAdvance) {353 dropZone.nextButtonMode({ delay: 0 });354 } else {355 setTimeout(nextProblem, 500);356 }357 }358 function wrongAnswerHandler($droppedObject) {359 sounds.play("wrong");360 shakeElement($("#choices-bounds"));361 score.number_mistakes += 1;362 scorebox.wrongCounter.increment();363 // sending mistaken vocabulary items to the user's tangocho364 const englishWord1 = tools.getIdealAnswer($droppedObject.data("english"));365 const japaneseWord1 = $droppedObject.data("japanese");366 const englishWord2 = tools.getIdealAnswer(vocabList.getTargetEnglish()); // can't use englishWord1, 'cause the real English may not be suitable for dsiplaying367 const japaneseWord2 = vocabList.getJapaneseFor(vocabList.getTargetEnglish());368 if (myJSON.assignment.use_user_vocab) {369 tangocho.add({ english: englishWord1, japanese: japaneseWord1 });370 tangocho.add({ english: englishWord2, japanese: japaneseWord2 });371 }372 $droppedObject.addClass("answered-wrong");373 if (mistakesLine && score.number_mistakes >= mistakesLine) {374 endSequence("tooManyMistakes");375 return;376 }377 }378 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */379 const endSequence = (function() {380 let hasBeenCalled = false;381 const passConditions = {382 tooManyMistakes: false,383 timeUp: false,384 allAnswered: true,385 timeTrial: true386 };387 return function(result) {388 if (hasBeenCalled) return;389 hasBeenCalled = true;390 timer && timer.stop();391 scorebox.clock && scorebox.clock.stop();392 score.stopTimer();393 assignment.gambariTimeStop();394 audio.disable().stopAll();395 tools.clearKeyEvents;396 const results = {397 time_taken: score.time_taken(),398 number_problems: vocabList.numberOfProblems,399 number_mistakes: score.number_mistakes,400 passed: passConditions[result]401 };402 assignment.send_results(results, function() {403 setTimeout(function() {404 // passing in the object to put the assignment_results stuff into, and the data to display405 const data = [406 { label: "時間", value: results.time_taken + " 秒" },407 { label: "問題数", value: results.number_problems ? results.number_problems + " 問" : "-" },408 { label: "正解", value: score.number_correct + " 問" },409 { label: "間違い", value: score.number_mistakes + " 問" }410 ];411 // adding mistaken vocabulary items to be displayed on the assignmentResults412 const wordsToReview = tools.showMistakenVocab(tangocho.getItems());413 if (wordsToReview && myJSON.assignment.use_user_vocab) {414 data.push({415 label: "復習しよう!",416 value: wordsToReview417 });418 }419 assignment.showAssignmentResults({420 container: $("#mainProblemsHolder"),421 result: result,422 data: data423 });424 let percentCorrect = results.number_problems / score.number_guesses;425 percentCorrect = Math.min(percentCorrect, 1);426 percentCorrect = Math.max(percentCorrect, 0);427 }, 1000);428 });429 return true;430 };431 }());432 $playButton.click(function() {433 problemNowActive && audio.play();434 });435 function wireUpKeyboard() {436 // keys 1 ~ 6 trigger "checkAnswer" on the appropriate .choice-holder437 tools.keydown([49, 50, 51, 52, 53, 54], (function() {438 // using this so the key can only be pressed once every 500ms,439 // to avoid accidental consecutive key presses440 const minTimeBetweenKeyPresses = 500;441 let lastTimePressed = (new Date()).getTime();442 return function(e) {443 const $choice = $(".active-choice").eq(e.keyCode - 49);444 if ($choice.length < 1) { return; }445 // calculating whether enough time has passed since the last key press446 const currentTime = (new Date()).getTime();447 const milisecondsPassed = currentTime - lastTimePressed;448 const enoughTimeHasPassed = (milisecondsPassed > minTimeBetweenKeyPresses);449 if (enoughTimeHasPassed) {450 lastTimePressed = currentTime;451 checkAnswer($choice);452 }453 };454 }()));455 tools.keydown(72, hintButton.trigger); // "H"456 tools.keydown(32, function() {457 $playButton.click();458 });459 tools.keydown(13, function() {460 if (dropZone.isNextButtonMode()) {461 $("#next-button").click();462 return;463 }464 });465 }466 }...

Full Screen

Full Screen

main.js

Source:main.js Github

copy

Full Screen

...424 self.shapes[i].reset(isOutside);425 }426427 self.mainWindow.context.stroke();428 self.clearKeyEvents();429 self.update();430 };431432433 self.getAngle = function(){434 var angleX, angleY, angleZ;435436437438439 return [angleX, angleY, angleZ];440 };441 442 ...

Full Screen

Full Screen

keyboard-e2e-specs.js

Source:keyboard-e2e-specs.js Github

copy

Full Screen

...59 await driver.pressKeyCode(29, 193);60 let el = await getElement(driver, TEXTVIEW_CLASS);61 return await driver.getText(el);62 };63 await clearKeyEvents(driver);64 let text = await runTest();65 if (text === '') {66 // the test is flakey... try again67 text = await runTest();68 }69 text.should.include('keyCode=KEYCODE_A');70 text.should.include('metaState=META_SHIFT_ON');71}72async function runKeyEventTest (driver) {73 let runTest = async function () {74 await driver.pressKeyCode(82);75 let el = await getElement(driver, TEXTVIEW_CLASS);76 return await driver.getText(el);77 };78 await clearKeyEvents(driver);79 let text = await runTest();80 if (text === '') {81 // the test is flakey... try again82 text = await runTest();83 }84 text.should.include('[keycode=82]');85 text.should.include('keyCode=KEYCODE_MENU');86}87const tests = [88 {label: 'editing a text field', text: 'Life, the Universe and Everything.'},89 {label: 'sending \'&-\'', text: '&-'},90 {label: 'sending \'&\' and \'-\' in other text', text: 'In the mid-1990s he ate fish & chips as mayor-elect.'},91 {label: 'sending \'-\' in text', text: 'Super-test.'},92 {label: 'sending numbers', text: '0123456789'},...

Full Screen

Full Screen

PopupMenu.js

Source:PopupMenu.js Github

copy

Full Screen

...120121 // Capture key events in the menu122 alib.events.listen(this, "onHide", function(evt) { 123 if (evt.data.popMenu.menu) {124 evt.data.popMenu.menu.clearKeyEvents();125 }126 }, {popMenu:this});127128}129130/**131 * Toggle menu132 *133 * @public134 */135alib.ui.PopupMenu.prototype.setVisible = function()136{137 if (!this.isRendered)138 this.render(); ...

Full Screen

Full Screen

Menu.js

Source:Menu.js Github

copy

Full Screen

1/**2 * @fileOverview Menu class used to build menus3 *4 * This class is a work in progress5 *6 * Example:7 * <code>8 * var menu = new alib.ui.Menu();9 * menu.addItem(new alib.ui.MenuItem("Item 1"), true, "opt_item_id");10 * menu.addItem(new alib.ui.MenuItem("Item 2"), true, "opt_item2_id");11 * menu.render(document.getElementById('divid'));12 * </code>13 *14 * @author: joe, sky.stebnicki@aereus.com; 15 * Copyright (c) 2012 Aereus Corporation. All rights reserved.16 */1718/**19 * Creates an instance ui menu20 *21 * @constructor22 */23alib.ui.Menu = function(options)24{25 /**26 * Main div contianer created when rendered27 *28 * @type {DOMElement}29 */30 this.mainCon = null;3132 /**33 * Options object34 *35 * @type {Object}36 */37 this.options = options || new Object();3839 /**40 * Array of entries41 *42 * @type {Array}43 */44 this.entries = new Array();4546 /**47 * Index of selected entry48 *49 * @type {int}50 */51 this.selectedEntry = -1;5253 /**54 * Flag to determine if we should show a filter search box55 *56 * @type {bool}57 */58 this.isFiltered = this.options.filtered || false;5960 /**61 * Flag to set this as a submenu of a parent menu62 *63 * @type {bool}64 */65 this.isSubmenu = this.options.submenu || false;6667 /**68 * Search input69 *70 * @type {DOMElement.input}71 */72 this.filteredInput = null;7374 /**75 * Filter container76 *77 * @type {DOMElement.div}78 */79 this.filterCon = null;8081 /**82 * Mobile mode flag83 *84 * @type {bool}85 */86 this.mobile = this.options.mobile || ((alib.dom.getClientWidth() < 800)?true:false);87}8889/**90 * Add a menu item to the menu91 *92 * @param {alib.ui.MenuItem} item93 */94alib.ui.Menu.prototype.addItem = function(item)95{96 this.entries.push(item);97 this.refresh(); // If alredy rendered then redraw with new item98 99 alib.events.triggerEvent(this, "onAddItem");100}101102/**103 * Clear all current items in the menu104 */105alib.ui.Menu.prototype.clear = function()106{107 this.mainCon.innerHTML = "";108 this.entries = new Array();109}110111/**112 * Refresh based on added items113 */114alib.ui.Menu.prototype.refresh = function()115{116 if (!this.mainCon)117 return;118119 // Clear rendered div because IE appears to leave it orphaned while clearing all child content120 for (var i in this.entries)121 {122 if (this.entries[i].con)123 this.entries[i].con.parentNode.removeChild(this.entries[i].con);124 }125126 if (this.filterCon != null)127 this.filterCon.innerHTML = "";128129 //this.mainCon.innerHTML = "";130131 this.render();132}133134/**135 * Render this item into the DOM tree136 *137 * @param {DOMElement} con The container to render this menu into138 */139alib.ui.Menu.prototype.render = function(con)140{141 if (!this.mainCon && con)142 {143 this.mainCon = alib.dom.createElement("div", con);144 alib.dom.styleSetClass(this.mainCon, "alibMenu");145 }146147 // If filtered then add search box148 if (this.isFiltered)149 {150 if (!this.filterCon)151 this.filterCon = alib.dom.createElement("div", this.mainCon);152153 this.renderFilterForm(this.filterCon);154 }155156 for (var i in this.entries)157 {158 this.entries[i].render(this.mainCon, this);159 }160}161162/**163 * Create filtered search box164 *165 * @param {DOMElement} con166 */167alib.ui.Menu.prototype.renderFilterForm = function(con)168{169 var filterCon = alib.dom.createElement("div", con);170 alib.dom.styleSet(filterCon, "margin", "0 5px 0 5px");171 alib.dom.styleSet(filterCon, "min-width", "100px");172173 var input = alib.dom.createElement("input", filterCon);174 input.type = "text";175 alib.dom.styleSet(input, "width", "98%");176 this.filteredInput = input;177178 alib.events.listen(input, "keyup", function(evt) {179 evt.data.menu.filterSearch(this.value);180 }, {menu:this});181}182183/**184 * Search through all the items in the array for a query string and hide anything that does not match185 *186 * @param {string} strQuery187 */188alib.ui.Menu.prototype.filterSearch = function(strQuery)189{190 for (var i in this.entries)191 {192 this.entries[i].applyVisibleFilter(strQuery);193 }194}195196/**197 * Search through all the items in the array for an id if set198 *199 * @param {string} strQuery200 * @return {alib.ui.MenuItem}201 */202alib.ui.Menu.prototype.getItemById = function(id)203{204 for (var i in this.entries)205 {206 if (this.entries[i].id == id)207 return this.entries[i];208 }209210 return null;211}212213/**214 * Put this menu in mobile mode215 *216 * @param {bool} on If in, then render this in one box217 * @return {alib.ui.MenuItem}218 */219alib.ui.Menu.prototype.setMobileMode = function(on) {220 this.mobile = on;221}222223/**224 * Move down an item from current position, or select first225 */226alib.ui.Menu.prototype.moveDown = function() {227 if (this.entries.length == 0)228 return;229230 // Make sure some items are visible231 var isVisible = false;232 for (var i in this.entries)233 {234 if (this.entries[i].visible)235 isVisible = true;236 }237 if (!isVisible)238 return;239240 this.selectedEntry++;241242 // If beyond range then wrap to 0243 if (this.selectedEntry > (this.entries.length - 1))244 this.selectedEntry = 0;245246 // If next item is not visible, then skip to next247 if (!this.entries[this.selectedEntry].visible)248 return this.moveDown();249250 // Hover active, remove over class from all others251 for (var i in this.entries)252 this.entries[i].setSelected((i==this.selectedEntry)?true:false);253}254255/**256 * Move down an item from current position, or select first257 */258alib.ui.Menu.prototype.moveUp = function() {259 if (this.entries.length == 0)260 return;261262 // Make sure some items are visible263 var isVisible = false;264 for (var i in this.entries)265 {266 if (this.entries[i].visible)267 isVisible = true;268 }269 if (!isVisible)270 return;271272 if (this.selectedEntry <= 0)273 this.selectedEntry = this.entries.length - 1;274 else275 this.selectedEntry--;276277 // If next item is not visible, then skip to next278 if (!this.entries[this.selectedEntry].visible)279 return this.moveUp();280281 // Hover active, remove over class from all others282 for (var i in this.entries)283 this.entries[i].setSelected((i==this.selectedEntry)?true:false);284}285286/**287 * Listen for arrow keys and return288 */289alib.ui.Menu.prototype.captureKeyEvents = function() {290291 var me = this;292 var onkeyDownHndler = function(evt) {293 if (!evt) evt = event;294 var a = evt.keyCode;295 296 switch (a)297 {298 // Up arrow299 case 38:300 me.moveUp();301 return false;302 break;303304 // Down arrow305 case 40:306 me.moveDown();307 return false;308 break;309310 // Return or tab gets hit311 case 13:312 if (me.selectedEntry)313 me.entries[me.selectedEntry].click();314 return true;315 /*316 if (actb_display)317 {318 actb_curr.m_inac = false;319 actb_caretmove = 1;320 actb_penter();321 return false;322 }323 else324 {325 return true;326 }327 */328 break;329330 default:331 return true;332 break;333 }334 };335336 alib.dom.addEvent(document, "keydown", onkeyDownHndler);337 //alib.dom.addEvent(document,"keypress", actb_keypress);338339 this.clearKeyEvents = function(){340 alib.dom.removeEvent(document,"keydown",onkeyDownHndler);341 //alib.dom.removeEvent(document,"keypress",actb_keypress);342 }343}344345/**346 * Clear key event listeners347 */348alib.ui.Menu.prototype.clearKeyEvents = function() {349 // Will be defined when captureKeyEvents is called350}351352/*353function actb_keypress(e)354 {355 if (actb_caretmove) alib.dom.stopEvent(e);356 return !actb_caretmove;357 }358 */ ...

Full Screen

Full Screen

Using AI Code Generation

copy

Full Screen

1var webdriver = require('selenium-webdriver');2 withCapabilities({3 build();4driver.executeScript("mobile: clearKeyEvents", []);5var webdriver = require('selenium-webdriver');6 withCapabilities({7 build();8driver.executeScript("mobile: clearKeyEvents", []);9var webdriver = require('selenium-webdriver');10 withCapabilities({11 build();12driver.executeScript("mobile: clearKeyEvents", []);13var webdriver = require('selenium-webdriver');14 withCapabilities({15 build();16driver.executeScript("mobile: clearKeyEvents", []);17var webdriver = require('selenium-webdriver');

Full Screen

Using AI Code Generation

copy

Full Screen

1var client = require('webdriverio').remote({2 desiredCapabilities: {3 }4});5 .init()6 .clearKeyEvents()7 .end();8var client = require('webdriverio').remote({9 desiredCapabilities: {10 }11});12 .init()13 .sendKeyEvent(3)14 .end();15var client = require('webdriverio').remote({16 desiredCapabilities: {17 }18});19 .init()20 .pressKeyCode(3)21 .end();22var client = require('webdriverio').remote({23 desiredCapabilities: {24 }25});26 .init()27 .longPressKeyCode(3)28 .end();29var client = require('webdriverio').remote({30 desiredCapabilities: {

Full Screen

Using AI Code Generation

copy

Full Screen

1var webdriver = require('selenium-webdriver');2var clearKeyEvents = require('appium-android-driver').AndroidDriver.clearKeyEvents;3var driver = new webdriver.Builder()4 .forBrowser('chrome')5 .build();6driver.findElement(webdriver.By.name('q')).sendKeys('webdriver');7driver.findElement(webdriver.By.name('btnG')).click();8driver.wait(function() {9 return driver.getTitle().then(function(title) {10 return title === 'webdriver - Google Search';11 });12}, 1000);13clearKeyEvents(driver);14driver.quit();

Full Screen

Using AI Code Generation

copy

Full Screen

1driver.clearKeyEvents();2driver.pushFile("path/to/file.txt");3driver.pullFile("path/to/file.txt");4driver.pullFolder("path/to/folder");5driver.toggleData();6driver.toggleWiFi();7driver.toggleAirplaneMode();8driver.toggleLocationServices();9driver.getSettings();10driver.updateSettings({});11driver.setGeoLocation({});12driver.getGeoLocation();13driver.sendSMS("555-555-5555", "Hello World!");14driver.gsmCall("555-555-5555", "GSM");15driver.gsmSignal();16driver.gsmVoice();17driver.shake();18driver.lock();19driver.unlock();20driver.isLocked();21driver.hideKeyboard();22driver.isKeyboardShown();23driver.installApp("path/to/app.apk");24driver.removeApp("com.example.app");25driver.launchApp();26driver.closeApp();

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run Appium Android Driver automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful