Project

General

Profile

1
/**
2
  *
3
  *  Copyright 2005 Sabre Airline Solutions
4
  *
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
7
  *
8
  *         http://www.apache.org/licenses/LICENSE-2.0
9
  *
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.
14
  **/
15

    
16

    
17
//-------------------- rico.js
18
var Rico = {
19
  Version: '1.1.0',
20
  prototypeVersion: parseFloat(Prototype.Version.split(".")[0] + "." + Prototype.Version.split(".")[1])
21
}
22

    
23
if((typeof Prototype=='undefined') || Rico.prototypeVersion < 1.3)
24
      throw("Rico requires the Prototype JavaScript framework >= 1.3");
25

    
26
Rico.ArrayExtensions = new Array();
27

    
28
if (Object.prototype.extend) {
29
   Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Object.prototype.extend;
30
}else{
31
  Object.prototype.extend = function(object) {
32
    return Object.extend.apply(this, [this, object]);
33
  }
34
  Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Object.prototype.extend;
35
}
36

    
37
if (Array.prototype.push) {
38
   Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Array.prototype.push;
39
}
40

    
41
if (!Array.prototype.remove) {
42
   Array.prototype.remove = function(dx) {
43
      if( isNaN(dx) || dx > this.length )
44
         return false;
45
      for( var i=0,n=0; i<this.length; i++ )
46
         if( i != dx )
47
            this[n++]=this[i];
48
      this.length-=1;
49
   };
50
  Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Array.prototype.remove;
51
}
52

    
53
if (!Array.prototype.removeItem) {
54
   Array.prototype.removeItem = function(item) {
55
      for ( var i = 0 ; i < this.length ; i++ )
56
         if ( this[i] == item ) {
57
            this.remove(i);
58
            break;
59
         }
60
   };
61
  Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Array.prototype.removeItem;
62
}
63

    
64
if (!Array.prototype.indices) {
65
   Array.prototype.indices = function() {
66
      var indexArray = new Array();
67
      for ( index in this ) {
68
         var ignoreThis = false;
69
         for ( var i = 0 ; i < Rico.ArrayExtensions.length ; i++ ) {
70
            if ( this[index] == Rico.ArrayExtensions[i] ) {
71
               ignoreThis = true;
72
               break;
73
            }
74
         }
75
         if ( !ignoreThis )
76
            indexArray[ indexArray.length ] = index;
77
      }
78
      return indexArray;
79
   }
80
  Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Array.prototype.indices;
81
}
82

    
83
// Create the loadXML method and xml getter for Mozilla
84
if ( window.DOMParser &&
85
	  window.XMLSerializer &&
86
	  window.Node && Node.prototype && Node.prototype.__defineGetter__ ) {
87

    
88
   if (!Document.prototype.loadXML) {
89
      Document.prototype.loadXML = function (s) {
90
         var doc2 = (new DOMParser()).parseFromString(s, "text/xml");
91
         while (this.hasChildNodes())
92
            this.removeChild(this.lastChild);
93

    
94
         for (var i = 0; i < doc2.childNodes.length; i++) {
95
            this.appendChild(this.importNode(doc2.childNodes[i], true));
96
         }
97
      };
98
	}
99

    
100
	Document.prototype.__defineGetter__( "xml",
101
	   function () {
102
		   return (new XMLSerializer()).serializeToString(this);
103
	   }
104
	 );
105
}
106

    
107
document.getElementsByTagAndClassName = function(tagName, className) {
108
  if ( tagName == null )
109
     tagName = '*';
110

    
111
  var children = document.getElementsByTagName(tagName) || document.all;
112
  var elements = new Array();
113

    
114
  if ( className == null )
115
    return children;
116

    
117
  for (var i = 0; i < children.length; i++) {
118
    var child = children[i];
119
    var classNames = child.className.split(' ');
120
    for (var j = 0; j < classNames.length; j++) {
121
      if (classNames[j] == className) {
122
        elements.push(child);
123
        break;
124
      }
125
    }
126
  }
127

    
128
  return elements;
129
}
130

    
131

    
132
//-------------------- ricoAccordion.js
133
Rico.Accordion = Class.create();
134

    
135
Rico.Accordion.prototype = {
136

    
137
   initialize: function(container, options) {
138
      this.container            = $(container);
139
      this.lastExpandedTab      = null;
140
      this.accordionTabs        = new Array();
141
	  this.clickBeforeActions	= new Array();
142
	  this.clickAfterActions	= new Array();
143
      this.setOptions(options);
144
      this._attachBehaviors();
145
      if(!container) return;
146

    
147
	  //PMA
148
      ///////this.container.style.borderBottom = '1px solid ' + this.options.borderColor;
149
      // validate onloadShowTab
150
       if (this.options.onLoadShowTab >= this.accordionTabs.length)
151
        this.options.onLoadShowTab = 0;
152

    
153
      // set the initial visual state...
154
	  //if (!onLoadHideTabs) {
155
		  for ( var i=0 ; i < this.accordionTabs.length ; i++ )
156
		  {
157
			if (i != this.options.onLoadShowTab){
158
			 this.accordionTabs[i].collapse();
159
			 this.accordionTabs[i].content.style.display = 'none';
160
			}
161
		  }
162
	  //}
163
      this.lastExpandedTab = this.accordionTabs[this.options.onLoadShowTab];
164
      if (this.options.panelHeight == 'auto'){
165
          var tabToCheck = (this.options.onloadShowTab === 0)? 1 : 0;
166
          var titleBarSize = parseInt(RicoUtil.getElementsComputedStyle(this.accordionTabs[tabToCheck].titleBar, 'height'));
167
          if (isNaN(titleBarSize))
168
            titleBarSize = this.accordionTabs[tabToCheck].titleBar.offsetHeight;
169
          
170
          var totalTitleBarSize = this.accordionTabs.length * titleBarSize;
171
          var parentHeight = parseInt(RicoUtil.getElementsComputedStyle(this.container.parentNode, 'height'));
172
          if (isNaN(parentHeight))
173
            parentHeight = this.container.parentNode.offsetHeight;
174
          
175
          this.options.panelHeight = parentHeight - totalTitleBarSize-2;
176
      }
177
      
178
      this.lastExpandedTab.content.style.height = this.options.panelHeight + "px";
179
      this.lastExpandedTab.showExpanded();
180
      this.lastExpandedTab.titleBar.style.fontWeight = this.options.expandedFontWeight;
181

    
182
   },
183

    
184
   setOptions: function(options) {
185
      this.options = {
186
         expandedBg          : '#63699c',
187
         hoverBg             : '#63699c',
188
         collapsedBg         : '#6b79a5',
189
         expandedTextColor   : '#ffffff',
190
         expandedFontWeight  : 'bold',
191
         hoverTextColor      : '#ffffff',
192
         collapsedTextColor  : '#ced7ef',
193
         collapsedFontWeight : 'normal',
194
         borderColor         : '#1f669b',
195
         panelHeight         : 200,
196
         onHideTab           : null,
197
         onShowTab           : null,
198
         onLoadShowTab       : 0
199
      }
200
      Object.extend(this.options, options || {});
201
   },
202

    
203
   showTabByIndex: function( anIndex, animate ) {
204
      var doAnimate = arguments.length == 1 ? true : animate;
205
      this.showTab( this.accordionTabs[anIndex], doAnimate );
206
   },
207

    
208
   showTab: function( accordionTab, animate ) {
209

    
210
      var doAnimate = arguments.length == 1 ? true : animate;
211

    
212
      if ( this.options.onHideTab )
213
         this.options.onHideTab(this.lastExpandedTab);
214

    
215
      this.lastExpandedTab.showCollapsed(); 
216
      var accordion = this;
217
      var lastExpandedTab = this.lastExpandedTab;
218

    
219
      this.lastExpandedTab.content.style.height = (this.options.panelHeight - 1) + 'px';
220
      accordionTab.content.style.display = '';
221

    
222
      accordionTab.titleBar.style.fontWeight = this.options.expandedFontWeight;
223

    
224
      if ( doAnimate ) {
225
         new Rico.Effect.AccordionSize( this.lastExpandedTab.content,
226
                                   accordionTab.content,
227
                                   1,
228
                                   this.options.panelHeight,
229
                                   100, 10,
230
                                   { complete: function() {accordion.showTabDone(lastExpandedTab)} } );
231
         this.lastExpandedTab = accordionTab;
232
      }
233
      else {
234
         this.lastExpandedTab.content.style.height = "1px";
235
         accordionTab.content.style.height = this.options.panelHeight + "px";
236
         this.lastExpandedTab = accordionTab;
237
         this.showTabDone(lastExpandedTab);
238
      }
239
   },
240

    
241
   showTabDone: function(collapsedTab) {
242
      collapsedTab.content.style.display = 'none';
243
      this.lastExpandedTab.showExpanded();
244
      if ( this.options.onShowTab )
245
         this.options.onShowTab(this.lastExpandedTab);
246
   },
247

    
248
   _attachBehaviors: function() {
249
      var panels = this._getDirectChildrenByTag(this.container, 'DIV');
250
      for ( var i = 0 ; i < panels.length ; i++ ) {
251

    
252
         var tabChildren = this._getDirectChildrenByTag(panels[i],'DIV');
253
         if ( tabChildren.length != 2 )
254
            continue; // unexpected
255

    
256
         var tabTitleBar   = tabChildren[0];
257
         var tabContentBox = tabChildren[1];
258
         this.accordionTabs.push( new Rico.Accordion.Tab(this,tabTitleBar,tabContentBox) );
259
      }
260
   },
261

    
262
   _getDirectChildrenByTag: function(e, tagName) {
263
      var kids = new Array();
264
      var allKids = e.childNodes;
265
      for( var i = 0 ; i < allKids.length ; i++ )
266
         if ( allKids[i] && allKids[i].tagName && allKids[i].tagName == tagName )
267
            kids.push(allKids[i]);
268
      return kids;
269
   }
270

    
271
};
272

    
273
Rico.Accordion.Tab = Class.create();
274

    
275
Rico.Accordion.Tab.prototype = {
276

    
277
   initialize: function(accordion, titleBar, content) {
278
      this.accordion = accordion;
279
      this.titleBar  = titleBar;
280
      this.content   = content;
281
      this._attachBehaviors();
282
   },
283

    
284
   collapse: function() {
285
      this.showCollapsed();
286
      this.content.style.height = "1px";
287
   },
288

    
289
   showCollapsed: function() {
290
      this.expanded = false;
291
      this.titleBar.style.backgroundColor = this.accordion.options.collapsedBg;
292
      this.titleBar.style.color           = this.accordion.options.collapsedTextColor;
293
      this.titleBar.style.fontWeight      = this.accordion.options.collapsedFontWeight;
294
      this.content.style.overflow = "hidden";
295
   },
296

    
297
   showExpanded: function() {
298
      this.expanded = true;
299
      this.titleBar.style.backgroundColor = this.accordion.options.expandedBg;
300
      this.titleBar.style.color           = this.accordion.options.expandedTextColor;
301
      this.content.style.overflow         = "visible";
302
   },
303

    
304
   titleBarClicked: function(e) {
305
      if ( this.accordion.lastExpandedTab == this )
306
         return;
307

    
308

    
309
	  for (var i=0 ; i < this.accordion.clickBeforeActions.length; i++) {
310
		  this.accordion.clickBeforeActions[i](this);
311
	  }
312

    
313
	  // show the selected tab
314
      this.accordion.showTab(this);
315

    
316
	  for (i=0 ; i < this.accordion.clickAfterActions.length; i++) {
317
		  this.accordion.clickAfterActions[i](this);
318
	  }
319
   },
320

    
321
   hover: function(e) {
322
		this.titleBar.style.backgroundColor = this.accordion.options.hoverBg;
323
		this.titleBar.style.color           = this.accordion.options.hoverTextColor;
324
   },
325

    
326
   unhover: function(e) {
327
      if ( this.expanded ) {
328
         this.titleBar.style.backgroundColor = this.accordion.options.expandedBg;
329
         this.titleBar.style.color           = this.accordion.options.expandedTextColor;
330
      }
331
      else {
332
         this.titleBar.style.backgroundColor = this.accordion.options.collapsedBg;
333
         this.titleBar.style.color           = this.accordion.options.collapsedTextColor;
334
      }
335
   },
336

    
337
   _attachBehaviors: function() {
338
      this.content.style.border = "1px solid " + this.accordion.options.borderColor;
339
      this.content.style.borderTopWidth    = "0px";
340
      this.content.style.borderBottomWidth = "0px";
341
      this.content.style.margin            = "0px";
342

    
343
      this.titleBar.onclick     = this.titleBarClicked.bindAsEventListener(this);
344
      this.titleBar.onmouseover = this.hover.bindAsEventListener(this);
345
      this.titleBar.onmouseout  = this.unhover.bindAsEventListener(this);
346
   }
347

    
348
};
349

    
350

    
351
//-------------------- ricoEffects.js
352

    
353
/**
354
  *  Use the Effect namespace for effects.  If using scriptaculous effects
355
  *  this will already be defined, otherwise we'll just create an empty
356
  *  object for it...
357
 **/
358
if ( window.Effect == undefined )
359
   Rico.Effect = {};
360

    
361
Rico.Effect.SizeAndPosition = Class.create();
362
Rico.Effect.SizeAndPosition.prototype = {
363

    
364
   initialize: function(element, x, y, w, h, duration, steps, options) {
365
      this.element = $(element);
366
      this.x = x;
367
      this.y = y;
368
      this.w = w;
369
      this.h = h;
370
      this.duration = duration;
371
      this.steps    = steps;
372
      this.options  = arguments[7] || {};
373

    
374
      this.sizeAndPosition();
375
   },
376

    
377
   sizeAndPosition: function() {
378
      if (this.isFinished()) {
379
         if(this.options.complete) this.options.complete(this);
380
         return;
381
      }
382

    
383
      if (this.timer)
384
         clearTimeout(this.timer);
385

    
386
      var stepDuration = Math.round(this.duration/this.steps) ;
387

    
388
      // Get original values: x,y = top left corner;  w,h = width height
389
      var currentX = this.element.offsetLeft;
390
      var currentY = this.element.offsetTop;
391
      var currentW = this.element.offsetWidth;
392
      var currentH = this.element.offsetHeight;
393

    
394
      // If values not set, or zero, we do not modify them, and take original as final as well
395
      this.x = (this.x) ? this.x : currentX;
396
      this.y = (this.y) ? this.y : currentY;
397
      this.w = (this.w) ? this.w : currentW;
398
      this.h = (this.h) ? this.h : currentH;
399

    
400
      // how much do we need to modify our values for each step?
401
      var difX = this.steps >  0 ? (this.x - currentX)/this.steps : 0;
402
      var difY = this.steps >  0 ? (this.y - currentY)/this.steps : 0;
403
      var difW = this.steps >  0 ? (this.w - currentW)/this.steps : 0;
404
      var difH = this.steps >  0 ? (this.h - currentH)/this.steps : 0;
405

    
406
      this.moveBy(difX, difY);
407
      this.resizeBy(difW, difH);
408

    
409
      this.duration -= stepDuration;
410
      this.steps--;
411

    
412
      this.timer = setTimeout(this.sizeAndPosition.bind(this), stepDuration);
413
   },
414

    
415
   isFinished: function() {
416
      return this.steps <= 0;
417
   },
418

    
419
   moveBy: function( difX, difY ) {
420
      var currentLeft = this.element.offsetLeft;
421
      var currentTop  = this.element.offsetTop;
422
      var intDifX     = parseInt(difX);
423
      var intDifY     = parseInt(difY);
424

    
425
      var style = this.element.style;
426
      if ( intDifX != 0 )
427
         style.left = (currentLeft + intDifX) + "px";
428
      if ( intDifY != 0 )
429
         style.top  = (currentTop + intDifY) + "px";
430
   },
431

    
432
   resizeBy: function( difW, difH ) {
433
      var currentWidth  = this.element.offsetWidth;
434
      var currentHeight = this.element.offsetHeight;
435
      var intDifW       = parseInt(difW);
436
      var intDifH       = parseInt(difH);
437

    
438
      var style = this.element.style;
439
      if ( intDifW != 0 )
440
         style.width   = (currentWidth  + intDifW) + "px";
441
      if ( intDifH != 0 )
442
         style.height  = (currentHeight + intDifH) + "px";
443
   }
444
}
445

    
446
Rico.Effect.Size = Class.create();
447
Rico.Effect.Size.prototype = {
448

    
449
   initialize: function(element, w, h, duration, steps, options) {
450
      new Rico.Effect.SizeAndPosition(element, null, null, w, h, duration, steps, options);
451
  }
452
}
453

    
454
Rico.Effect.Position = Class.create();
455
Rico.Effect.Position.prototype = {
456

    
457
   initialize: function(element, x, y, duration, steps, options) {
458
      new Rico.Effect.SizeAndPosition(element, x, y, null, null, duration, steps, options);
459
  }
460
}
461

    
462
Rico.Effect.Round = Class.create();
463
Rico.Effect.Round.prototype = {
464

    
465
   initialize: function(tagName, className, options) {
466
      var elements = document.getElementsByTagAndClassName(tagName,className);
467
      for ( var i = 0 ; i < elements.length ; i++ )
468
         Rico.Corner.round( elements[i], options );
469
   }
470
};
471

    
472
Rico.Effect.FadeTo = Class.create();
473
Rico.Effect.FadeTo.prototype = {
474

    
475
   initialize: function( element, opacity, duration, steps, options) {
476
      this.element  = $(element);
477
      this.opacity  = opacity;
478
      this.duration = duration;
479
      this.steps    = steps;
480
      this.options  = arguments[4] || {};
481
      this.fadeTo();
482
   },
483

    
484
   fadeTo: function() {
485
      if (this.isFinished()) {
486
         if(this.options.complete) this.options.complete(this);
487
         return;
488
      }
489

    
490
      if (this.timer)
491
         clearTimeout(this.timer);
492

    
493
      var stepDuration = Math.round(this.duration/this.steps) ;
494
      var currentOpacity = this.getElementOpacity();
495
      var delta = this.steps > 0 ? (this.opacity - currentOpacity)/this.steps : 0;
496

    
497
      this.changeOpacityBy(delta);
498
      this.duration -= stepDuration;
499
      this.steps--;
500

    
501
      this.timer = setTimeout(this.fadeTo.bind(this), stepDuration);
502
   },
503

    
504
   changeOpacityBy: function(v) {
505
      var currentOpacity = this.getElementOpacity();
506
      var newOpacity = Math.max(0, Math.min(currentOpacity+v, 1));
507
      this.element.ricoOpacity = newOpacity;
508

    
509
      this.element.style.filter = "alpha(opacity:"+Math.round(newOpacity*100)+")";
510
      this.element.style.opacity = newOpacity; /*//*/;
511
   },
512

    
513
   isFinished: function() {
514
      return this.steps <= 0;
515
   },
516

    
517
   getElementOpacity: function() {
518
      if ( this.element.ricoOpacity == undefined ) {
519
         var opacity = RicoUtil.getElementsComputedStyle(this.element, 'opacity');
520
         this.element.ricoOpacity = opacity != undefined ? opacity : 1.0;
521
      }
522
      return parseFloat(this.element.ricoOpacity);
523
   }
524
}
525

    
526
Rico.Effect.AccordionSize = Class.create();
527

    
528
Rico.Effect.AccordionSize.prototype = {
529

    
530
   initialize: function(e1, e2, start, end, duration, steps, options) {
531
      this.e1       = $(e1);
532
      this.e2       = $(e2);
533
      this.start    = start;
534
      this.end      = end;
535
      this.duration = duration;
536
      this.steps    = steps;
537
      this.options  = arguments[6] || {};
538

    
539
      this.accordionSize();
540
   },
541

    
542
   accordionSize: function() {
543

    
544
      if (this.isFinished()) {
545
         // just in case there are round errors or such...
546
         this.e1.style.height = this.start + "px";
547
         this.e2.style.height = this.end + "px";
548

    
549
         if(this.options.complete)
550
            this.options.complete(this);
551
         return;
552
      }
553

    
554
      if (this.timer)
555
         clearTimeout(this.timer);
556

    
557
      var stepDuration = Math.round(this.duration/this.steps) ;
558

    
559
      var diff = this.steps > 0 ? (parseInt(this.e1.offsetHeight) - this.start)/this.steps : 0;
560
      this.resizeBy(diff);
561

    
562
      this.duration -= stepDuration;
563
      this.steps--;
564

    
565
      this.timer = setTimeout(this.accordionSize.bind(this), stepDuration);
566
   },
567

    
568
   isFinished: function() {
569
      return this.steps <= 0;
570
   },
571

    
572
   resizeBy: function(diff) {
573
      var h1Height = this.e1.offsetHeight;
574
      var h2Height = this.e2.offsetHeight;
575
      var intDiff = parseInt(diff);
576
      if ( diff != 0 ) {
577
         this.e1.style.height = (h1Height - intDiff) + "px";
578
         this.e2.style.height = (h2Height + intDiff) + "px";
579
      }
580
   }
581

    
582
};
583

    
584

    
585
//-------------------- ricoUtil.js
586
Rico.ArrayExtensions = new Array();
587

    
588
if (Object.prototype.extend) {
589
   // in prototype.js...
590
   Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Object.prototype.extend;
591
}else{
592
  Object.prototype.extend = function(object) {
593
    return Object.extend.apply(this, [this, object]);
594
  }
595
  Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Object.prototype.extend;
596
}
597

    
598
if (Array.prototype.push) {
599
   // in prototype.js...
600
   Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Array.prototype.push;
601
}
602

    
603
if (!Array.prototype.remove) {
604
   Array.prototype.remove = function(dx) {
605
      if( isNaN(dx) || dx > this.length )
606
         return false;
607
      for( var i=0,n=0; i<this.length; i++ )
608
         if( i != dx )
609
            this[n++]=this[i];
610
      this.length-=1;
611
   };
612
  Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Array.prototype.remove;
613
}
614

    
615
if (!Array.prototype.removeItem) {
616
   Array.prototype.removeItem = function(item) {
617
      for ( var i = 0 ; i < this.length ; i++ )
618
         if ( this[i] == item ) {
619
            this.remove(i);
620
            break;
621
         }
622
   };
623
  Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Array.prototype.removeItem;
624
}
625

    
626
if (!Array.prototype.indices) {
627
   Array.prototype.indices = function() {
628
      var indexArray = new Array();
629
      for ( index in this ) {
630
         var ignoreThis = false;
631
         for ( var i = 0 ; i < Rico.ArrayExtensions.length ; i++ ) {
632
            if ( this[index] == Rico.ArrayExtensions[i] ) {
633
               ignoreThis = true;
634
               break;
635
            }
636
         }
637
         if ( !ignoreThis )
638
            indexArray[ indexArray.length ] = index;
639
      }
640
      return indexArray;
641
   }
642
  Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Array.prototype.indices;
643
}
644

    
645
  Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Array.prototype.unique;
646
  Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Array.prototype.inArray;
647

    
648

    
649
// Create the loadXML method and xml getter for Mozilla
650
if ( window.DOMParser &&
651
	  window.XMLSerializer &&
652
	  window.Node && Node.prototype && Node.prototype.__defineGetter__ ) {
653

    
654
   if (!Document.prototype.loadXML) {
655
      Document.prototype.loadXML = function (s) {
656
         var doc2 = (new DOMParser()).parseFromString(s, "text/xml");
657
         while (this.hasChildNodes())
658
            this.removeChild(this.lastChild);
659

    
660
         for (var i = 0; i < doc2.childNodes.length; i++) {
661
            this.appendChild(this.importNode(doc2.childNodes[i], true));
662
         }
663
      };
664
	}
665

    
666
	Document.prototype.__defineGetter__( "xml",
667
	   function () {
668
		   return (new XMLSerializer()).serializeToString(this);
669
	   }
670
	 );
671
}
672

    
673
document.getElementsByTagAndClassName = function(tagName, className) {
674
  if ( tagName == null )
675
     tagName = '*';
676

    
677
  var children = document.getElementsByTagName(tagName) || document.all;
678
  var elements = new Array();
679

    
680
  if ( className == null )
681
    return children;
682

    
683
  for (var i = 0; i < children.length; i++) {
684
    var child = children[i];
685
    var classNames = child.className.split(' ');
686
    for (var j = 0; j < classNames.length; j++) {
687
      if (classNames[j] == className) {
688
        elements.push(child);
689
        break;
690
      }
691
    }
692
  }
693

    
694
  return elements;
695
}
696

    
697
var RicoUtil = {
698

    
699
   getElementsComputedStyle: function ( htmlElement, cssProperty, mozillaEquivalentCSS) {
700
      if ( arguments.length == 2 )
701
         mozillaEquivalentCSS = cssProperty;
702

    
703
      var el = $(htmlElement);
704
      if ( el.currentStyle )
705
         return el.currentStyle[cssProperty];
706
      else
707
         return document.defaultView.getComputedStyle(el, null).getPropertyValue(mozillaEquivalentCSS);
708
   },
709

    
710
   createXmlDocument : function() {
711
      if (document.implementation && document.implementation.createDocument) {
712
         var doc = document.implementation.createDocument("", "", null);
713

    
714
         if (doc.readyState == null) {
715
            doc.readyState = 1;
716
            doc.addEventListener("load", function () {
717
               doc.readyState = 4;
718
               if (typeof doc.onreadystatechange == "function")
719
                  doc.onreadystatechange();
720
            }, false);
721
         }
722

    
723
         return doc;
724
      }
725

    
726
      if (window.ActiveXObject)
727
          return Try.these(
728
            function() { return new ActiveXObject('MSXML2.DomDocument')   },
729
            function() { return new ActiveXObject('Microsoft.DomDocument')},
730
            function() { return new ActiveXObject('MSXML.DomDocument')    },
731
            function() { return new ActiveXObject('MSXML3.DomDocument')   }
732
          ) || false;
733

    
734
      return null;
735
   },
736

    
737
   getContentAsString: function( parentNode ) {
738
      return parentNode.xml != undefined ? 
739
         this._getContentAsStringIE(parentNode) :
740
         this._getContentAsStringMozilla(parentNode);
741
   },
742

    
743
  _getContentAsStringIE: function(parentNode) {
744
     var contentStr = "";
745
     for ( var i = 0 ; i < parentNode.childNodes.length ; i++ ) {
746
         var n = parentNode.childNodes[i];
747
         if (n.nodeType == 4) {
748
             contentStr += n.nodeValue;
749
         }
750
         else {
751
           contentStr += n.xml;
752
       }
753
     }
754
     return contentStr;
755
  },
756

    
757
  _getContentAsStringMozilla: function(parentNode) {
758
     var xmlSerializer = new XMLSerializer();
759
     var contentStr = "";
760
     for ( var i = 0 ; i < parentNode.childNodes.length ; i++ ) {
761
          var n = parentNode.childNodes[i];
762
          if (n.nodeType == 4) { // CDATA node
763
              contentStr += n.nodeValue;
764
          }
765
          else {
766
            contentStr += xmlSerializer.serializeToString(n);
767
        }
768
     }
769
     return contentStr;
770
  },
771

    
772
   toViewportPosition: function(element) {
773
      return this._toAbsolute(element,true);
774
   },
775

    
776
   toDocumentPosition: function(element) {
777
      return this._toAbsolute(element,false);
778
   },
779

    
780
   /**
781
    *  Compute the elements position in terms of the window viewport
782
    *  so that it can be compared to the position of the mouse (dnd)
783
    *  This is additions of all the offsetTop,offsetLeft values up the
784
    *  offsetParent hierarchy, ...taking into account any scrollTop,
785
    *  scrollLeft values along the way...
786
    *
787
    * IE has a bug reporting a correct offsetLeft of elements within a
788
    * a relatively positioned parent!!!
789
    **/
790
   _toAbsolute: function(element,accountForDocScroll) {
791

    
792
      if ( navigator.userAgent.toLowerCase().indexOf("msie") == -1 )
793
         return this._toAbsoluteMozilla(element,accountForDocScroll);
794

    
795
      var x = 0;
796
      var y = 0;
797
      var parent = element;
798
      while ( parent ) {
799

    
800
         var borderXOffset = 0;
801
         var borderYOffset = 0;
802
         if ( parent != element ) {
803
            var borderXOffset = parseInt(this.getElementsComputedStyle(parent, "borderLeftWidth" ));
804
            var borderYOffset = parseInt(this.getElementsComputedStyle(parent, "borderTopWidth" ));
805
            borderXOffset = isNaN(borderXOffset) ? 0 : borderXOffset;
806
            borderYOffset = isNaN(borderYOffset) ? 0 : borderYOffset;
807
         }
808

    
809
         x += parent.offsetLeft - parent.scrollLeft + borderXOffset;
810
         y += parent.offsetTop - parent.scrollTop + borderYOffset;
811
         parent = parent.offsetParent;
812
      }
813

    
814
      if ( accountForDocScroll ) {
815
         x -= this.docScrollLeft();
816
         y -= this.docScrollTop();
817
      }
818

    
819
      return { x:x, y:y };
820
   },
821

    
822
   /**
823
    *  Mozilla did not report all of the parents up the hierarchy via the
824
    *  offsetParent property that IE did.  So for the calculation of the
825
    *  offsets we use the offsetParent property, but for the calculation of
826
    *  the scrollTop/scrollLeft adjustments we navigate up via the parentNode
827
    *  property instead so as to get the scroll offsets...
828
    *
829
    **/
830
   _toAbsoluteMozilla: function(element,accountForDocScroll) {
831
      var x = 0;
832
      var y = 0;
833
      var parent = element;
834
      while ( parent ) {
835
         x += parent.offsetLeft;
836
         y += parent.offsetTop;
837
         parent = parent.offsetParent;
838
      }
839

    
840
      parent = element;
841
      while ( parent &&
842
              parent != document.body &&
843
              parent != document.documentElement ) {
844
         if ( parent.scrollLeft  )
845
            x -= parent.scrollLeft;
846
         if ( parent.scrollTop )
847
            y -= parent.scrollTop;
848
         parent = parent.parentNode;
849
      }
850

    
851
      if ( accountForDocScroll ) {
852
         x -= this.docScrollLeft();
853
         y -= this.docScrollTop();
854
      }
855

    
856
      return { x:x, y:y };
857
   },
858

    
859
   docScrollLeft: function() {
860
      if ( window.pageXOffset )
861
         return window.pageXOffset;
862
      else if ( document.documentElement && document.documentElement.scrollLeft )
863
         return document.documentElement.scrollLeft;
864
      else if ( document.body )
865
         return document.body.scrollLeft;
866
      else
867
         return 0;
868
   },
869

    
870
   docScrollTop: function() {
871
      if ( window.pageYOffset )
872
         return window.pageYOffset;
873
      else if ( document.documentElement && document.documentElement.scrollTop )
874
         return document.documentElement.scrollTop;
875
      else if ( document.body )
876
         return document.body.scrollTop;
877
      else
878
         return 0;
879
   }
880

    
881
};
(2-2/33)