3 * Copyright 2005 Sabre Airline Solutions
5 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
6 * file except in compliance with the License. You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software distributed under the
11 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
12 * either express or implied. See the License for the specific language governing permissions
13 * and limitations under the License.
16 if (typeof Rico=='undefined')
17 throw("Cannot find the Rico object");
18 if (typeof Prototype=='undefined')
19 throw("Rico requires the Prototype JavaScript framework");
20 Rico.prototypeVersion = parseFloat(Prototype.Version.split(".")[0] + "." + Prototype.Version.split(".")[1]);
21 if (Rico.prototypeVersion < 1.3)
22 throw("Rico requires Prototype JavaScript framework version 1.3 or greater");
27 getDirectChildrenByTag: function(e, tagName) {
28 var kids = new Array();
29 var allKids = e.childNodes;
30 tagName=tagName.toLowerCase();
31 for( var i = 0 ; i < allKids.length ; i++ )
32 if ( allKids[i] && allKids[i].tagName && allKids[i].tagName.toLowerCase() == tagName )
33 kids.push(allKids[i]);
37 createXmlDocument : function() {
38 if (document.implementation && document.implementation.createDocument) {
39 var doc = document.implementation.createDocument("", "", null);
41 if (doc.readyState == null) {
43 doc.addEventListener("load", function () {
45 if (typeof doc.onreadystatechange == "function")
46 doc.onreadystatechange();
53 if (window.ActiveXObject)
55 function() { return new ActiveXObject('MSXML2.DomDocument') },
56 function() { return new ActiveXObject('Microsoft.DomDocument')},
57 function() { return new ActiveXObject('MSXML.DomDocument') },
58 function() { return new ActiveXObject('MSXML3.DomDocument') }
64 getInnerText: function(el) {
65 if (typeof el == "string") return el;
66 if (typeof el == "undefined") { return el };
67 var cs = el.childNodes;
70 for (var i = 0; i < l; i++) {
71 switch (cs[i].nodeType) {
72 case 1: //ELEMENT_NODE
73 if (Element.getStyle(cs[i],'display')=='none') continue;
74 switch (cs[i].tagName.toLowerCase()) {
75 case 'img': str += cs[i].alt || cs[i].title || cs[i].src; break;
76 case 'input': if (cs[i].type=='hidden') continue;
78 case 'textarea': str += $F(cs[i]) || ''; break;
79 default: str += this.getInnerText(cs[i]); break;
83 str += cs[i].nodeValue;
90 // For Konqueror 3.5, isEncoded must be true
91 getContentAsString: function( parentNode, isEncoded ) {
92 if (isEncoded) return this._getEncodedContent(parentNode);
93 if (typeof parentNode.xml != 'undefined') return this._getContentAsStringIE(parentNode);
94 return this._getContentAsStringMozilla(parentNode);
97 _getEncodedContent: function(parentNode) {
98 if (parentNode.innerHTML) return parentNode.innerHTML;
99 switch (parentNode.childNodes.length) {
101 case 1: return parentNode.firstChild.nodeValue;
102 default: return parentNode.childNodes[1].nodeValue;
106 _getContentAsStringIE: function(parentNode) {
108 for ( var i = 0 ; i < parentNode.childNodes.length ; i++ ) {
109 var n = parentNode.childNodes[i];
110 if (n.nodeType == 4) {
111 contentStr += n.nodeValue;
120 _getContentAsStringMozilla: function(parentNode) {
121 var xmlSerializer = new XMLSerializer();
123 for ( var i = 0 ; i < parentNode.childNodes.length ; i++ ) {
124 var n = parentNode.childNodes[i];
125 if (n.nodeType == 4) { // CDATA node
126 contentStr += n.nodeValue;
129 contentStr += xmlSerializer.serializeToString(n);
135 docElement: function() {
136 return (document.compatMode && document.compatMode.indexOf("CSS")!=-1) ? document.documentElement : document.getElementsByTagName("body")[0];
140 * return available height - excludes scrollbar & margin
142 windowHeight: function() {
143 return window.innerHeight? window.innerHeight : this.docElement().clientHeight;
144 //return this.docElement().clientHeight;
148 * return available width - excludes scrollbar & margin
150 windowWidth: function() {
151 return this.docElement().clientWidth;
154 docScrollLeft: function() {
155 if ( window.pageXOffset )
156 return window.pageXOffset;
157 else if ( document.documentElement && document.documentElement.scrollLeft )
158 return document.documentElement.scrollLeft;
159 else if ( document.body )
160 return document.body.scrollLeft;
165 docScrollTop: function() {
166 if ( window.pageYOffset )
167 return window.pageYOffset;
168 else if ( document.documentElement && document.documentElement.scrollTop )
169 return document.documentElement.scrollTop;
170 else if ( document.body )
171 return document.body.scrollTop;
176 nan2zero: function(n) {
177 if (typeof(n)=='string') n=parseInt(n);
178 return isNaN(n) || typeof(n)=='undefined' ? 0 : n;
181 eventKey: function(e) {
182 if( typeof( e.keyCode ) == 'number' ) {
183 return e.keyCode; //DOM
184 } else if( typeof( e.which ) == 'number' ) {
185 return e.which; //NS 4 compatible
186 } else if( typeof( e.charCode ) == 'number' ) {
187 return e.charCode; //also NS 6+, Mozilla 0.9+
189 return -1; //total failure, we have no way of obtaining the key code
193 * Return the previous sibling that has the specified tagName
195 getPreviosSiblingByTagName: function(el,tagName) {
196 var sib=el.previousSibling;
198 if ((sib.tagName==tagName) && (sib.style.display!='none')) return sib;
199 sib=sib.previousSibling;
205 * Return the parent HTML element that has the specified tagName.
206 * @param className optional
208 getParentByTagName: function(el,tagName,className) {
210 tagName=tagName.toLowerCase();
212 if (par.tagName && par.tagName.toLowerCase()==tagName)
213 if (!className || par.className.indexOf(className)>=0) return par;
220 * Wrap the children of a DOM element in a new element
221 * @param el the element whose children are to be wrapped
222 * @param cls class name of the wrapper (optional)
223 * @param id id of the wrapper (optional)
224 * @param wrapperTag type of wrapper element to be created (optional, defaults to DIV)
226 wrapChildren: function(el,cls,id,wrapperTag) {
227 var tag=wrapperTag || 'div';
228 var wrapper = document.createElement(tag);
229 if (id) wrapper.id=id;
230 if (cls) wrapper.className=cls;
231 while (el.firstChild)
232 wrapper.appendChild(el.firstChild);
233 el.appendChild(wrapper);
238 * Format a positive number
239 * @param decPlaces the number of digits to display after the decimal point
240 * @param thouSep the character to use as the thousands separator
241 * @param decPoint the character to use as the decimal point
243 formatPosNumber: function(posnum,decPlaces,thouSep,decPoint) {
244 var a=posnum.toFixed(decPlaces).split(/\./);
246 var rgx = /(\d+)(\d{3})/;
247 while (rgx.test(a[0]))
248 a[0]=a[0].replace(rgx, '$1'+thouSep+'$2');
250 return a.join(decPoint);
254 * Post condition - if childNodes[n] is refChild, than childNodes[n+1] is newChild.
256 DOMNode_insertAfter: function(newChild,refChild) {
257 var parentx=refChild.parentNode;
258 if(parentx.lastChild==refChild) { return parentx.appendChild(newChild);}
259 else {return parentx.insertBefore(newChild,refChild.nextSibling);}
262 positionCtlOverIcon: function(ctl,icon) {
263 if (ctl.style.display=='none') ctl.style.display='block';
264 var offsets=Position.page(icon);
265 var correction=Prototype.Browser.IE ? 1 : 2; // based on a 1px border
266 var lpad=this.nan2zero(Element.getStyle(icon,'padding-left'))
267 ctl.style.left = (offsets[0]+lpad+correction)+'px';
268 var scrTop=this.docScrollTop();
269 var newTop=offsets[1] + correction + scrTop;
270 var ctlht=ctl.offsetHeight;
271 var iconht=icon.offsetHeight;
272 if (newTop+iconht+ctlht < this.windowHeight()+scrTop)
273 newTop+=iconht; // display below icon
275 newTop=Math.max(newTop-ctlht,scrTop); // display above icon
276 ctl.style.top = newTop+'px';
279 createFormField: function(parent,elemTag,elemType,id,name) {
280 if (typeof name!='string') name=id;
281 if (Prototype.Browser.IE) {
282 // IE cannot set NAME attribute on dynamically created elements
283 var s=elemTag+' id="'+id+'"';
284 if (elemType) s+=' type="'+elemType+'"';
285 if (elemTag.match(/^(form|input|select|textarea|object|button|img)$/)) s+=' name="'+name+'"';
286 var field=document.createElement('<'+s+' />');
288 var field=document.createElement(elemTag);
289 if (elemType) field.type=elemType;
291 if (typeof field.name=='string') field.name=name;
293 parent.appendChild(field);
298 * Gets the value of the specified cookie
300 getCookie: function(itemName) {
301 var arg = itemName+'=';
302 var alen = arg.length;
303 var clen = document.cookie.length;
307 if (document.cookie.substring(i, j) == arg) {
308 var endstr = document.cookie.indexOf (';', j);
309 if (endstr == -1) endstr=document.cookie.length;
310 return unescape(document.cookie.substring(j, endstr));
312 i = document.cookie.indexOf(' ', i) + 1;
319 * Write information to cookie.
320 * For cookies to be retained for the current session only, set daysToKeep=null.
321 * To erase a cookie, pass a negative daysToKeep value.
323 setCookie: function(itemName,itemValue,daysToKeep,cookiePath,cookieDomain) {
324 var c = itemName+"="+escape(itemValue);
325 if (typeof(daysToKeep)=='number') {
326 var date = new Date();
327 date.setTime(date.getTime()+(daysToKeep*24*60*60*1000));
328 c+="; expires="+date.toGMTString();
330 if (typeof(cookiePath)=='string') c+="; path="+cookiePath;
331 if (typeof(cookieDomain)=='string') c+="; domain="+cookieDomain;
338 // Translation helper object
340 var RicoTranslate = {
345 re : /^(\W*)\b(.*)\b(\W*)$/,
346 dateFmt : "mm/dd/yyyy",
347 timeFmt : "hh:nn:ss a/pm",
348 monthNames: ['January','February','March','April','May','June',
349 'July','August','September','October','November','December'],
350 dayNames: ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'],
352 addPhrase: function(fromPhrase, toPhrase) {
353 this.phrases[fromPhrase]=toPhrase;
357 * fromPhrase may contain multiple words/phrases separated by tabs
358 * and each portion will be looked up separately.
359 * Punctuation & spaces at the beginning or
360 * ending of a phrase are ignored.
362 getPhrase: function(fromPhrase) {
363 var words=fromPhrase.split(/\t/);
364 var transWord,translated = '';
365 for (var i=0; i<words.length; i++) {
366 if (this.re.exec(words[i])) {
367 transWord=this.phrases[RegExp.$2];
368 translated += (typeof transWord=='string') ? RegExp.$1+transWord+RegExp.$3 : words[i];
370 translated += words[i];
378 if (!Date.prototype.formatDate) {
379 Date.prototype.formatDate = function(fmt) {
381 var datefmt=(typeof fmt=='string') ? datefmt=fmt : 'translateDate';
384 case 'localeDateTime':
385 return d.toLocaleString();
387 return d.toLocaleDateString();
389 case 'translateDateTime':
390 datefmt=RicoTranslate.dateFmt+' '+RicoTranslate.timeFmt;
392 case 'translateDate':
393 datefmt=RicoTranslate.dateFmt;
396 return datefmt.replace(/(yyyy|mmmm|mmm|mm|dddd|ddd|dd|hh|nn|ss|a\/p)/gi,
398 switch ($1.toLowerCase()) {
399 case 'yyyy': return d.getFullYear();
400 case 'mmmm': return RicoTranslate.monthNames[d.getMonth()];
401 case 'mmm': return RicoTranslate.monthNames[d.getMonth()].substr(0, 3);
402 case 'mm': return (d.getMonth() + 1).toPaddedString(2);
403 case 'm': return (d.getMonth() + 1);
404 case 'dddd': return RicoTranslate.dayNames[d.getDay()];
405 case 'ddd': return RicoTranslate.dayNames[d.getDay()].substr(0, 3);
406 case 'dd': return d.getDate().toPaddedString(2);
407 case 'd': return d.getDate();
408 case 'hh': return ((h = d.getHours() % 12) ? h : 12).toPaddedString(2);
409 case 'h': return ((h = d.getHours() % 12) ? h : 12);
410 case 'HH': return d.getHours().toPaddedString(2);
411 case 'H': return d.getHours();
412 case 'nn': return d.getMinutes().toPaddedString(2);
413 case 'ss': return d.getSeconds().toPaddedString(2);
414 case 'a/p': return d.getHours() < 12 ? 'a' : 'p';
421 if (!Date.prototype.setISO8601) {
423 * Converts a string in ISO 8601 format to a date object.
424 * Returns true if string is a valid date or date-time.
425 * Based on info at http://delete.me.uk/2005/03/iso8601.html
427 Date.prototype.setISO8601 = function (string) {
428 if (!string) return false;
429 var d = string.match(/(\d\d\d\d)(?:-?(\d\d)(?:-?(\d\d)(?:[T ](\d\d)(?::?(\d\d)(?::?(\d\d)(?:\.(\d+))?)?)?(Z|(?:([-+])(\d\d)(?::?(\d\d))?)?)?)?)?)?/);
430 if (!d) return false;
432 var date = new Date(d[1], 0, 1);
434 if (d[2]) { date.setMonth(d[2] - 1); }
435 if (d[3]) { date.setDate(d[3]); }
436 if (d[4]) { date.setHours(d[4]); }
437 if (d[5]) { date.setMinutes(d[5]); }
438 if (d[6]) { date.setSeconds(d[6]); }
439 if (d[7]) { date.setMilliseconds(Number("0." + d[7]) * 1000); }
441 if (d[10] && d[11]) offset = (Number(d[10]) * 60) + Number(d[11]);
442 offset *= ((d[9] == '-') ? 1 : -1);
443 offset -= date.getTimezoneOffset();
445 var time = (Number(date) + (offset * 60 * 1000));
446 this.setTime(Number(time));
451 if (!Date.prototype.toISO8601String) {
453 * Convert date to an ISO 8601 formatted string.
454 * <p>format is an integer in the range 1-6:<dl>
456 * <dd>YYYY (eg 1997)</dd>
457 * <dt>2 (year and month)</dt>
458 * <dd>YYYY-MM (eg 1997-07)</dd>
459 * <dt>3 (complete date)</dt>
460 * <dd>YYYY-MM-DD (eg 1997-07-16)</dd>
461 * <dt>4 (complete date plus hours and minutes)</dt>
462 * <dd>YYYY-MM-DDThh:mmTZD (eg 1997-07-16T19:20+01:00)</dd>
463 * <dt>5 (complete date plus hours, minutes and seconds)</dt>
464 * <dd>YYYY-MM-DDThh:mm:ssTZD (eg 1997-07-16T19:20:30+01:00)</dd>
465 * <dt>6 (complete date plus hours, minutes, seconds and a decimal
466 * fraction of a second)</dt>
467 * <dd>YYYY-MM-DDThh:mm:ss.sTZD (eg 1997-07-16T19:20:30.45+01:00)</dd>
469 * Based on: http://www.codeproject.com/jscript/dateformat.asp
471 Date.prototype.toISO8601String = function (format, offset) {
472 if (!format) { var format = 6; }
477 var d = offset.match(/([-+])([0-9]{2}):([0-9]{2})/);
478 var offsetnum = (Number(d[2]) * 60) + Number(d[3]);
479 offsetnum *= ((d[1] == '-') ? -1 : 1);
480 var date = new Date(Number(Number(this) + (offsetnum * 60000)));
483 var zeropad = function (num) { return ((num < 10) ? '0' : '') + num; }
486 str += date.getUTCFullYear();
487 if (format > 1) { str += "-" + zeropad(date.getUTCMonth() + 1); }
488 if (format > 2) { str += "-" + zeropad(date.getUTCDate()); }
490 str += "T" + zeropad(date.getUTCHours()) +
491 ":" + zeropad(date.getUTCMinutes());
494 var secs = Number(date.getUTCSeconds() + "." +
495 ((date.getUTCMilliseconds() < 100) ? '0' : '') +
496 zeropad(date.getUTCMilliseconds()));
497 str += ":" + zeropad(secs);
498 } else if (format > 4) { str += ":" + zeropad(date.getUTCSeconds()); }
500 if (format > 3) { str += offset; }
505 if (!String.prototype.formatDate) {
506 String.prototype.formatDate = function(fmt) {
507 var s=this.replace(/-/g,'/');
509 return isNaN(d) ? this : d.formatDate(fmt);
513 if (!Number.prototype.formatNumber) {
515 * Format a number according to the specs in assoc array 'fmt'.
516 * Result is a string, wrapped in a span element with a class of: negNumber, zeroNumber, posNumber
517 * These classes can be set in CSS to display negative numbers in red, for example.
519 * <p>fmt may contain:<dl>
520 * <dt>multiplier </dt><dd> the original number is multiplied by this amount before formatting</dd>
521 * <dt>decPlaces </dt><dd> number of digits to the right of the decimal point</dd>
522 * <dt>decPoint </dt><dd> character to be used as the decimal point</dd>
523 * <dt>thouSep </dt><dd> character to use as the thousands separator</dd>
524 * <dt>prefix </dt><dd> string added to the beginning of the result (e.g. a currency symbol)</dd>
525 * <dt>suffix </dt><dd> string added to the end of the result (e.g. % symbol)</dd>
526 * <dt>negSign </dt><dd> specifies format for negative numbers: L=leading minus, T=trailing minus, P=parens</dd>
529 Number.prototype.formatNumber = function(fmt) {
530 if (isNaN(this)) return 'NaN';
532 if (typeof fmt.multiplier=='number') n*=fmt.multiplier;
533 var decPlaces=typeof fmt.decPlaces=='number' ? fmt.decPlaces : 0;
534 var thouSep=typeof fmt.thouSep=='string' ? fmt.thouSep : RicoTranslate.thouSep;
535 var decPoint=typeof fmt.decPoint=='string' ? fmt.decPoint : RicoTranslate.decPoint;
536 var prefix=fmt.prefix || "";
537 var suffix=fmt.suffix || "";
538 var negSign=typeof fmt.negSign=='string' ? fmt.negSign : "L";
539 negSign=negSign.toUpperCase();
542 s=RicoUtil.formatPosNumber(-n,decPlaces,thouSep,decPoint);
543 if (negSign=="P") s="("+s+")";
545 if (negSign=="L") s="-"+s;
546 if (negSign=="T") s+="-";
549 cls=n==0.0 ? 'zeroNumber' : 'posNumber';
550 s=prefix+RicoUtil.formatPosNumber(n,decPlaces,thouSep,decPoint);
552 return "<span class='"+cls+"'>"+s+suffix+"</span>";
556 if (!String.prototype.formatNumber) {
558 * Take a string that can be converted via parseFloat
559 * and format it according to the specs in assoc array 'fmt'.
561 String.prototype.formatNumber = function(fmt) {
562 var n=parseFloat(this);
563 return isNaN(n) ? this : n.formatNumber(fmt);
568 * Fix select control bleed-thru on floating divs in IE.
569 * Based on technique published by Joe King at:
570 * http://dotnetjunkies.com/WebLog/jking/archive/2003/10/30/2975.aspx
572 Rico.Shim = Class.create();
574 if (Prototype.Browser.IE) {
575 Rico.Shim.prototype = {
577 initialize: function(DivRef) {
578 this.ifr = document.createElement('iframe');
579 this.ifr.style.position="absolute";
580 this.ifr.style.display = "none";
581 this.ifr.src="javascript:false;";
582 DivRef.parentNode.appendChild(this.ifr);
587 this.ifr.style.display = "none";
591 this.ifr.style.width = this.DivRef.offsetWidth;
592 this.ifr.style.height = this.DivRef.offsetHeight;
593 this.ifr.style.top = this.DivRef.style.top;
594 this.ifr.style.left = this.DivRef.style.left;
595 this.ifr.style.zIndex = this.DivRef.currentStyle.zIndex - 1;
596 this.ifr.style.display = "block";
600 Rico.Shim.prototype = {
601 initialize: function() {},
609 * Rico.Shadow is intended for positioned elements.
610 * Uses blur filter in IE, and alpha-transparent png images for all other browsers.
611 * Based on: http://www.positioniseverything.net/articles/dropshadows.html
613 Rico.Shadow = Class.create();
615 Rico.Shadow.prototype = {
617 initialize: function(DivRef) {
618 this.div = document.createElement('div');
619 this.div.style.position="absolute";
620 if (typeof this.div.style.filter=='undefined') {
621 new Image().src = Rico.imgDir+"shadow.png";
622 new Image().src = Rico.imgDir+"shadow_ur.png";
623 new Image().src = Rico.imgDir+"shadow_ll.png";
627 this.div.style.backgroundColor='#888';
628 this.div.style.filter='progid:DXImageTransform.Microsoft.Blur(makeShadow=1, shadowOpacity=0.3, pixelRadius=3)';
629 this.offset=0; // MS blur filter already does offset
631 this.div.style.display = "none";
632 DivRef.parentNode.appendChild(this.div);
636 createShadow: function() {
637 var tab = document.createElement('table');
638 tab.style.height='100%';
639 tab.style.width='100%';
643 var tr1=tab.insertRow(-1);
644 tr1.style.height='8px';
645 var td11=tr1.insertCell(-1);
646 td11.style.width='8px';
647 var td12=tr1.insertCell(-1);
648 td12.style.background="transparent url("+Rico.imgDir+"shadow_ur.png"+") no-repeat right bottom"
650 var tr2=tab.insertRow(-1);
651 var td21=tr2.insertCell(-1);
652 td21.style.background="transparent url("+Rico.imgDir+"shadow_ll.png"+") no-repeat right bottom"
653 var td22=tr2.insertCell(-1);
654 td22.style.background="transparent url("+Rico.imgDir+"shadow.png"+") no-repeat right bottom"
656 this.div.appendChild(tab);
660 this.div.style.display = "none";
664 this.div.style.width = this.DivRef.offsetWidth + 'px';
665 this.div.style.height= this.DivRef.offsetHeight + 'px';
666 this.div.style.top = (parseInt(this.DivRef.style.top)+this.offset)+'px';
667 this.div.style.left = (parseInt(this.DivRef.style.left)+this.offset)+'px';
668 this.div.style.zIndex= parseInt(Element.getStyle(this.DivRef,'z-index')) - 1;
669 this.div.style.display = "block";
674 Rico.Popup = Class.create();
676 Rico.Popup.prototype = {
678 initialize: function(options,DivRef) {
682 ignoreClicks : false,
683 position : 'absolute',
686 Object.extend(this.options, options || {});
687 if (DivRef) this.setDiv(DivRef);
690 setDiv: function(DivRef,closeFunc) {
691 this.divPopup=$(DivRef);
692 var position=this.options.position == 'auto' ? Element.getStyle(this.divPopup,'position').toLowerCase() : this.options.position;
693 if (!this.divPopup || position != 'absolute') return;
694 this.closeFunc=closeFunc || this.closePopup.bindAsEventListener(this);
695 this.shim=new Rico.Shim(this.divPopup);
696 if (this.options.shadow)
697 this.shadow=new Rico.Shadow(this.divPopup);
698 if (this.options.hideOnClick)
699 Event.observe(document,"click", this.closeFunc);
700 if (this.options.hideOnEscape)
701 Event.observe(document,"keyup", this._checkKey.bindAsEventListener(this));
702 if (this.options.ignoreClicks) this.ignoreClicks();
705 ignoreClicks: function() {
706 Event.observe(this.divPopup,"click", this._ignoreClick.bindAsEventListener(this));
709 _ignoreClick: function(e) {
710 if (e.stopPropagation)
713 e.cancelBubble = true;
717 // event handler to process keyup events (hide menu on escape key)
718 _checkKey: function(e) {
719 if (RicoUtil.eventKey(e)==27) this.closeFunc();
723 openPopup: function(left,top) {
724 if (typeof left=='number') this.divPopup.style.left=left+'px';
725 if (typeof top=='number') this.divPopup.style.top=top+'px';
726 this.divPopup.style.display="block";
727 if (this.shim) this.shim.show();
728 if (this.shadow) this.shadow.show();
731 closePopup: function() {
732 if (this.shim) this.shim.hide();
733 if (this.shadow) this.shadow.hide();
734 this.divPopup.style.display="none"
739 Rico.includeLoaded('ricoCommon.js');