/** * * Copyright 2005 Sabre Airline Solutions * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this * file except in compliance with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under the * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * either express or implied. See the License for the specific language governing permissions * and limitations under the License. **/ //-------------------- rico.js var Rico = { Version: '1.1.0', prototypeVersion: parseFloat(Prototype.Version.split(".")[0] + "." + Prototype.Version.split(".")[1]) } if((typeof Prototype=='undefined') || Rico.prototypeVersion < 1.3) throw("Rico requires the Prototype JavaScript framework >= 1.3"); Rico.ArrayExtensions = new Array(); if (Object.prototype.extend) { Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Object.prototype.extend; }else{ Object.prototype.extend = function(object) { return Object.extend.apply(this, [this, object]); } Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Object.prototype.extend; } if (Array.prototype.push) { Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Array.prototype.push; } if (!Array.prototype.remove) { Array.prototype.remove = function(dx) { if( isNaN(dx) || dx > this.length ) return false; for( var i=0,n=0; i<this.length; i++ ) if( i != dx ) this[n++]=this[i]; this.length-=1; }; Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Array.prototype.remove; } if (!Array.prototype.removeItem) { Array.prototype.removeItem = function(item) { for ( var i = 0 ; i < this.length ; i++ ) if ( this[i] == item ) { this.remove(i); break; } }; Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Array.prototype.removeItem; } if (!Array.prototype.indices) { Array.prototype.indices = function() { var indexArray = new Array(); for ( index in this ) { var ignoreThis = false; for ( var i = 0 ; i < Rico.ArrayExtensions.length ; i++ ) { if ( this[index] == Rico.ArrayExtensions[i] ) { ignoreThis = true; break; } } if ( !ignoreThis ) indexArray[ indexArray.length ] = index; } return indexArray; } Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Array.prototype.indices; } // Create the loadXML method and xml getter for Mozilla if ( window.DOMParser && window.XMLSerializer && window.Node && Node.prototype && Node.prototype.__defineGetter__ ) { if (!Document.prototype.loadXML) { Document.prototype.loadXML = function (s) { var doc2 = (new DOMParser()).parseFromString(s, "text/xml"); while (this.hasChildNodes()) this.removeChild(this.lastChild); for (var i = 0; i < doc2.childNodes.length; i++) { this.appendChild(this.importNode(doc2.childNodes[i], true)); } }; } Document.prototype.__defineGetter__( "xml", function () { return (new XMLSerializer()).serializeToString(this); } ); } document.getElementsByTagAndClassName = function(tagName, className) { if ( tagName == null ) tagName = '*'; var children = document.getElementsByTagName(tagName) || document.all; var elements = new Array(); if ( className == null ) return children; for (var i = 0; i < children.length; i++) { var child = children[i]; var classNames = child.className.split(' '); for (var j = 0; j < classNames.length; j++) { if (classNames[j] == className) { elements.push(child); break; } } } return elements; } //-------------------- ricoAccordion.js Rico.Accordion = Class.create(); Rico.Accordion.prototype = { initialize: function(container, options) { this.container = $(container); this.lastExpandedTab = null; this.accordionTabs = new Array(); this.clickBeforeActions = new Array(); this.clickAfterActions = new Array(); this.setOptions(options); this._attachBehaviors(); if(!container) return; //PMA ///////this.container.style.borderBottom = '1px solid ' + this.options.borderColor; // validate onloadShowTab if (this.options.onLoadShowTab >= this.accordionTabs.length) this.options.onLoadShowTab = 0; // set the initial visual state... //if (!onLoadHideTabs) { for ( var i=0 ; i < this.accordionTabs.length ; i++ ) { if (i != this.options.onLoadShowTab){ this.accordionTabs[i].collapse(); this.accordionTabs[i].content.style.display = 'none'; } } //} this.lastExpandedTab = this.accordionTabs[this.options.onLoadShowTab]; if (this.options.panelHeight == 'auto'){ var tabToCheck = (this.options.onloadShowTab === 0)? 1 : 0; var titleBarSize = parseInt(RicoUtil.getElementsComputedStyle(this.accordionTabs[tabToCheck].titleBar, 'height')); if (isNaN(titleBarSize)) titleBarSize = this.accordionTabs[tabToCheck].titleBar.offsetHeight; var totalTitleBarSize = this.accordionTabs.length * titleBarSize; var parentHeight = parseInt(RicoUtil.getElementsComputedStyle(this.container.parentNode, 'height')); if (isNaN(parentHeight)) parentHeight = this.container.parentNode.offsetHeight; this.options.panelHeight = parentHeight - totalTitleBarSize-2; } this.lastExpandedTab.content.style.height = this.options.panelHeight + "px"; this.lastExpandedTab.showExpanded(); this.lastExpandedTab.titleBar.style.fontWeight = this.options.expandedFontWeight; }, setOptions: function(options) { this.options = { expandedBg : '#63699c', hoverBg : '#63699c', collapsedBg : '#6b79a5', expandedTextColor : '#ffffff', expandedFontWeight : 'bold', hoverTextColor : '#ffffff', collapsedTextColor : '#ced7ef', collapsedFontWeight : 'normal', borderColor : '#1f669b', panelHeight : 200, onHideTab : null, onShowTab : null, onLoadShowTab : 0 } Object.extend(this.options, options || {}); }, showTabByIndex: function( anIndex, animate ) { var doAnimate = arguments.length == 1 ? true : animate; this.showTab( this.accordionTabs[anIndex], doAnimate ); }, showTab: function( accordionTab, animate ) { var doAnimate = arguments.length == 1 ? true : animate; if ( this.options.onHideTab ) this.options.onHideTab(this.lastExpandedTab); this.lastExpandedTab.showCollapsed(); var accordion = this; var lastExpandedTab = this.lastExpandedTab; this.lastExpandedTab.content.style.height = (this.options.panelHeight - 1) + 'px'; accordionTab.content.style.display = ''; accordionTab.titleBar.style.fontWeight = this.options.expandedFontWeight; if ( doAnimate ) { new Rico.Effect.AccordionSize( this.lastExpandedTab.content, accordionTab.content, 1, this.options.panelHeight, 100, 10, { complete: function() {accordion.showTabDone(lastExpandedTab)} } ); this.lastExpandedTab = accordionTab; } else { this.lastExpandedTab.content.style.height = "1px"; accordionTab.content.style.height = this.options.panelHeight + "px"; this.lastExpandedTab = accordionTab; this.showTabDone(lastExpandedTab); } }, showTabDone: function(collapsedTab) { collapsedTab.content.style.display = 'none'; this.lastExpandedTab.showExpanded(); if ( this.options.onShowTab ) this.options.onShowTab(this.lastExpandedTab); }, _attachBehaviors: function() { var panels = this._getDirectChildrenByTag(this.container, 'DIV'); for ( var i = 0 ; i < panels.length ; i++ ) { var tabChildren = this._getDirectChildrenByTag(panels[i],'DIV'); if ( tabChildren.length != 2 ) continue; // unexpected var tabTitleBar = tabChildren[0]; var tabContentBox = tabChildren[1]; this.accordionTabs.push( new Rico.Accordion.Tab(this,tabTitleBar,tabContentBox) ); } }, _getDirectChildrenByTag: function(e, tagName) { var kids = new Array(); var allKids = e.childNodes; for( var i = 0 ; i < allKids.length ; i++ ) if ( allKids[i] && allKids[i].tagName && allKids[i].tagName == tagName ) kids.push(allKids[i]); return kids; } }; Rico.Accordion.Tab = Class.create(); Rico.Accordion.Tab.prototype = { initialize: function(accordion, titleBar, content) { this.accordion = accordion; this.titleBar = titleBar; this.content = content; this._attachBehaviors(); }, collapse: function() { this.showCollapsed(); this.content.style.height = "1px"; }, showCollapsed: function() { this.expanded = false; this.titleBar.style.backgroundColor = this.accordion.options.collapsedBg; this.titleBar.style.color = this.accordion.options.collapsedTextColor; this.titleBar.style.fontWeight = this.accordion.options.collapsedFontWeight; this.content.style.overflow = "hidden"; }, showExpanded: function() { this.expanded = true; this.titleBar.style.backgroundColor = this.accordion.options.expandedBg; this.titleBar.style.color = this.accordion.options.expandedTextColor; this.content.style.overflow = "visible"; }, titleBarClicked: function(e) { if ( this.accordion.lastExpandedTab == this ) return; for (var i=0 ; i < this.accordion.clickBeforeActions.length; i++) { this.accordion.clickBeforeActions[i](this); } // show the selected tab this.accordion.showTab(this); for (i=0 ; i < this.accordion.clickAfterActions.length; i++) { this.accordion.clickAfterActions[i](this); } }, hover: function(e) { this.titleBar.style.backgroundColor = this.accordion.options.hoverBg; this.titleBar.style.color = this.accordion.options.hoverTextColor; }, unhover: function(e) { if ( this.expanded ) { this.titleBar.style.backgroundColor = this.accordion.options.expandedBg; this.titleBar.style.color = this.accordion.options.expandedTextColor; } else { this.titleBar.style.backgroundColor = this.accordion.options.collapsedBg; this.titleBar.style.color = this.accordion.options.collapsedTextColor; } }, _attachBehaviors: function() { this.content.style.border = "1px solid " + this.accordion.options.borderColor; this.content.style.borderTopWidth = "0px"; this.content.style.borderBottomWidth = "0px"; this.content.style.margin = "0px"; this.titleBar.onclick = this.titleBarClicked.bindAsEventListener(this); this.titleBar.onmouseover = this.hover.bindAsEventListener(this); this.titleBar.onmouseout = this.unhover.bindAsEventListener(this); } }; //-------------------- ricoEffects.js /** * Use the Effect namespace for effects. If using scriptaculous effects * this will already be defined, otherwise we'll just create an empty * object for it... **/ if ( window.Effect == undefined ) Rico.Effect = {}; Rico.Effect.SizeAndPosition = Class.create(); Rico.Effect.SizeAndPosition.prototype = { initialize: function(element, x, y, w, h, duration, steps, options) { this.element = $(element); this.x = x; this.y = y; this.w = w; this.h = h; this.duration = duration; this.steps = steps; this.options = arguments[7] || {}; this.sizeAndPosition(); }, sizeAndPosition: function() { if (this.isFinished()) { if(this.options.complete) this.options.complete(this); return; } if (this.timer) clearTimeout(this.timer); var stepDuration = Math.round(this.duration/this.steps) ; // Get original values: x,y = top left corner; w,h = width height var currentX = this.element.offsetLeft; var currentY = this.element.offsetTop; var currentW = this.element.offsetWidth; var currentH = this.element.offsetHeight; // If values not set, or zero, we do not modify them, and take original as final as well this.x = (this.x) ? this.x : currentX; this.y = (this.y) ? this.y : currentY; this.w = (this.w) ? this.w : currentW; this.h = (this.h) ? this.h : currentH; // how much do we need to modify our values for each step? var difX = this.steps > 0 ? (this.x - currentX)/this.steps : 0; var difY = this.steps > 0 ? (this.y - currentY)/this.steps : 0; var difW = this.steps > 0 ? (this.w - currentW)/this.steps : 0; var difH = this.steps > 0 ? (this.h - currentH)/this.steps : 0; this.moveBy(difX, difY); this.resizeBy(difW, difH); this.duration -= stepDuration; this.steps--; this.timer = setTimeout(this.sizeAndPosition.bind(this), stepDuration); }, isFinished: function() { return this.steps <= 0; }, moveBy: function( difX, difY ) { var currentLeft = this.element.offsetLeft; var currentTop = this.element.offsetTop; var intDifX = parseInt(difX); var intDifY = parseInt(difY); var style = this.element.style; if ( intDifX != 0 ) style.left = (currentLeft + intDifX) + "px"; if ( intDifY != 0 ) style.top = (currentTop + intDifY) + "px"; }, resizeBy: function( difW, difH ) { var currentWidth = this.element.offsetWidth; var currentHeight = this.element.offsetHeight; var intDifW = parseInt(difW); var intDifH = parseInt(difH); var style = this.element.style; if ( intDifW != 0 ) style.width = (currentWidth + intDifW) + "px"; if ( intDifH != 0 ) style.height = (currentHeight + intDifH) + "px"; } } Rico.Effect.Size = Class.create(); Rico.Effect.Size.prototype = { initialize: function(element, w, h, duration, steps, options) { new Rico.Effect.SizeAndPosition(element, null, null, w, h, duration, steps, options); } } Rico.Effect.Position = Class.create(); Rico.Effect.Position.prototype = { initialize: function(element, x, y, duration, steps, options) { new Rico.Effect.SizeAndPosition(element, x, y, null, null, duration, steps, options); } } Rico.Effect.Round = Class.create(); Rico.Effect.Round.prototype = { initialize: function(tagName, className, options) { var elements = document.getElementsByTagAndClassName(tagName,className); for ( var i = 0 ; i < elements.length ; i++ ) Rico.Corner.round( elements[i], options ); } }; Rico.Effect.FadeTo = Class.create(); Rico.Effect.FadeTo.prototype = { initialize: function( element, opacity, duration, steps, options) { this.element = $(element); this.opacity = opacity; this.duration = duration; this.steps = steps; this.options = arguments[4] || {}; this.fadeTo(); }, fadeTo: function() { if (this.isFinished()) { if(this.options.complete) this.options.complete(this); return; } if (this.timer) clearTimeout(this.timer); var stepDuration = Math.round(this.duration/this.steps) ; var currentOpacity = this.getElementOpacity(); var delta = this.steps > 0 ? (this.opacity - currentOpacity)/this.steps : 0; this.changeOpacityBy(delta); this.duration -= stepDuration; this.steps--; this.timer = setTimeout(this.fadeTo.bind(this), stepDuration); }, changeOpacityBy: function(v) { var currentOpacity = this.getElementOpacity(); var newOpacity = Math.max(0, Math.min(currentOpacity+v, 1)); this.element.ricoOpacity = newOpacity; this.element.style.filter = "alpha(opacity:"+Math.round(newOpacity*100)+")"; this.element.style.opacity = newOpacity; /*//*/; }, isFinished: function() { return this.steps <= 0; }, getElementOpacity: function() { if ( this.element.ricoOpacity == undefined ) { var opacity = RicoUtil.getElementsComputedStyle(this.element, 'opacity'); this.element.ricoOpacity = opacity != undefined ? opacity : 1.0; } return parseFloat(this.element.ricoOpacity); } } Rico.Effect.AccordionSize = Class.create(); Rico.Effect.AccordionSize.prototype = { initialize: function(e1, e2, start, end, duration, steps, options) { this.e1 = $(e1); this.e2 = $(e2); this.start = start; this.end = end; this.duration = duration; this.steps = steps; this.options = arguments[6] || {}; this.accordionSize(); }, accordionSize: function() { if (this.isFinished()) { // just in case there are round errors or such... this.e1.style.height = this.start + "px"; this.e2.style.height = this.end + "px"; if(this.options.complete) this.options.complete(this); return; } if (this.timer) clearTimeout(this.timer); var stepDuration = Math.round(this.duration/this.steps) ; var diff = this.steps > 0 ? (parseInt(this.e1.offsetHeight) - this.start)/this.steps : 0; this.resizeBy(diff); this.duration -= stepDuration; this.steps--; this.timer = setTimeout(this.accordionSize.bind(this), stepDuration); }, isFinished: function() { return this.steps <= 0; }, resizeBy: function(diff) { var h1Height = this.e1.offsetHeight; var h2Height = this.e2.offsetHeight; var intDiff = parseInt(diff); if ( diff != 0 ) { this.e1.style.height = (h1Height - intDiff) + "px"; this.e2.style.height = (h2Height + intDiff) + "px"; } } }; //-------------------- ricoUtil.js Rico.ArrayExtensions = new Array(); if (Object.prototype.extend) { // in prototype.js... Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Object.prototype.extend; }else{ Object.prototype.extend = function(object) { return Object.extend.apply(this, [this, object]); } Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Object.prototype.extend; } if (Array.prototype.push) { // in prototype.js... Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Array.prototype.push; } if (!Array.prototype.remove) { Array.prototype.remove = function(dx) { if( isNaN(dx) || dx > this.length ) return false; for( var i=0,n=0; i<this.length; i++ ) if( i != dx ) this[n++]=this[i]; this.length-=1; }; Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Array.prototype.remove; } if (!Array.prototype.removeItem) { Array.prototype.removeItem = function(item) { for ( var i = 0 ; i < this.length ; i++ ) if ( this[i] == item ) { this.remove(i); break; } }; Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Array.prototype.removeItem; } if (!Array.prototype.indices) { Array.prototype.indices = function() { var indexArray = new Array(); for ( index in this ) { var ignoreThis = false; for ( var i = 0 ; i < Rico.ArrayExtensions.length ; i++ ) { if ( this[index] == Rico.ArrayExtensions[i] ) { ignoreThis = true; break; } } if ( !ignoreThis ) indexArray[ indexArray.length ] = index; } return indexArray; } Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Array.prototype.indices; } Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Array.prototype.unique; Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Array.prototype.inArray; // Create the loadXML method and xml getter for Mozilla if ( window.DOMParser && window.XMLSerializer && window.Node && Node.prototype && Node.prototype.__defineGetter__ ) { if (!Document.prototype.loadXML) { Document.prototype.loadXML = function (s) { var doc2 = (new DOMParser()).parseFromString(s, "text/xml"); while (this.hasChildNodes()) this.removeChild(this.lastChild); for (var i = 0; i < doc2.childNodes.length; i++) { this.appendChild(this.importNode(doc2.childNodes[i], true)); } }; } Document.prototype.__defineGetter__( "xml", function () { return (new XMLSerializer()).serializeToString(this); } ); } document.getElementsByTagAndClassName = function(tagName, className) { if ( tagName == null ) tagName = '*'; var children = document.getElementsByTagName(tagName) || document.all; var elements = new Array(); if ( className == null ) return children; for (var i = 0; i < children.length; i++) { var child = children[i]; var classNames = child.className.split(' '); for (var j = 0; j < classNames.length; j++) { if (classNames[j] == className) { elements.push(child); break; } } } return elements; } var RicoUtil = { getElementsComputedStyle: function ( htmlElement, cssProperty, mozillaEquivalentCSS) { if ( arguments.length == 2 ) mozillaEquivalentCSS = cssProperty; var el = $(htmlElement); if ( el.currentStyle ) return el.currentStyle[cssProperty]; else return document.defaultView.getComputedStyle(el, null).getPropertyValue(mozillaEquivalentCSS); }, createXmlDocument : function() { if (document.implementation && document.implementation.createDocument) { var doc = document.implementation.createDocument("", "", null); if (doc.readyState == null) { doc.readyState = 1; doc.addEventListener("load", function () { doc.readyState = 4; if (typeof doc.onreadystatechange == "function") doc.onreadystatechange(); }, false); } return doc; } if (window.ActiveXObject) return Try.these( function() { return new ActiveXObject('MSXML2.DomDocument') }, function() { return new ActiveXObject('Microsoft.DomDocument')}, function() { return new ActiveXObject('MSXML.DomDocument') }, function() { return new ActiveXObject('MSXML3.DomDocument') } ) || false; return null; }, getContentAsString: function( parentNode ) { return parentNode.xml != undefined ? this._getContentAsStringIE(parentNode) : this._getContentAsStringMozilla(parentNode); }, _getContentAsStringIE: function(parentNode) { var contentStr = ""; for ( var i = 0 ; i < parentNode.childNodes.length ; i++ ) { var n = parentNode.childNodes[i]; if (n.nodeType == 4) { contentStr += n.nodeValue; } else { contentStr += n.xml; } } return contentStr; }, _getContentAsStringMozilla: function(parentNode) { var xmlSerializer = new XMLSerializer(); var contentStr = ""; for ( var i = 0 ; i < parentNode.childNodes.length ; i++ ) { var n = parentNode.childNodes[i]; if (n.nodeType == 4) { // CDATA node contentStr += n.nodeValue; } else { contentStr += xmlSerializer.serializeToString(n); } } return contentStr; }, toViewportPosition: function(element) { return this._toAbsolute(element,true); }, toDocumentPosition: function(element) { return this._toAbsolute(element,false); }, /** * Compute the elements position in terms of the window viewport * so that it can be compared to the position of the mouse (dnd) * This is additions of all the offsetTop,offsetLeft values up the * offsetParent hierarchy, ...taking into account any scrollTop, * scrollLeft values along the way... * * IE has a bug reporting a correct offsetLeft of elements within a * a relatively positioned parent!!! **/ _toAbsolute: function(element,accountForDocScroll) { if ( navigator.userAgent.toLowerCase().indexOf("msie") == -1 ) return this._toAbsoluteMozilla(element,accountForDocScroll); var x = 0; var y = 0; var parent = element; while ( parent ) { var borderXOffset = 0; var borderYOffset = 0; if ( parent != element ) { var borderXOffset = parseInt(this.getElementsComputedStyle(parent, "borderLeftWidth" )); var borderYOffset = parseInt(this.getElementsComputedStyle(parent, "borderTopWidth" )); borderXOffset = isNaN(borderXOffset) ? 0 : borderXOffset; borderYOffset = isNaN(borderYOffset) ? 0 : borderYOffset; } x += parent.offsetLeft - parent.scrollLeft + borderXOffset; y += parent.offsetTop - parent.scrollTop + borderYOffset; parent = parent.offsetParent; } if ( accountForDocScroll ) { x -= this.docScrollLeft(); y -= this.docScrollTop(); } return { x:x, y:y }; }, /** * Mozilla did not report all of the parents up the hierarchy via the * offsetParent property that IE did. So for the calculation of the * offsets we use the offsetParent property, but for the calculation of * the scrollTop/scrollLeft adjustments we navigate up via the parentNode * property instead so as to get the scroll offsets... * **/ _toAbsoluteMozilla: function(element,accountForDocScroll) { var x = 0; var y = 0; var parent = element; while ( parent ) { x += parent.offsetLeft; y += parent.offsetTop; parent = parent.offsetParent; } parent = element; while ( parent && parent != document.body && parent != document.documentElement ) { if ( parent.scrollLeft ) x -= parent.scrollLeft; if ( parent.scrollTop ) y -= parent.scrollTop; parent = parent.parentNode; } if ( accountForDocScroll ) { x -= this.docScrollLeft(); y -= this.docScrollTop(); } return { x:x, y:y }; }, docScrollLeft: function() { if ( window.pageXOffset ) return window.pageXOffset; else if ( document.documentElement && document.documentElement.scrollLeft ) return document.documentElement.scrollLeft; else if ( document.body ) return document.body.scrollLeft; else return 0; }, docScrollTop: function() { if ( window.pageYOffset ) return window.pageYOffset; else if ( document.documentElement && document.documentElement.scrollTop ) return document.documentElement.scrollTop; else if ( document.body ) return document.body.scrollTop; else return 0; } };