JAVASCRIPT   2

balloon.js

Guest on 21st August 2021 09:16:47 AM

  1. /*jslint white:false,undef: false, rhino: true, onevar: true, evil: false */
  2. /*
  3.  * balloon.js -- a DHTML library for balloon tooltips
  4.  *
  5.  * $Id: balloon.js 22300 2009-12-01 09:40:39Z sheldon_mckay $
  6.  *
  7.  * See http://www.gmod.org/wiki/index.php/Popup_Balloons
  8.  * for documentation.
  9.  *
  10.  * Copyright (c) 2007-2009 Sheldon McKay, Cold Spring Harbor Laboratory
  11.  *
  12.  * This balloon tooltip package and associated files not otherwise copyrighted are
  13.  * distributed under the MIT-style license:
  14.  *
  15.  * http://opensource.org/licenses/mit-license.php
  16.  *
  17.  * Permission is hereby granted, free of charge, to any person obtaining a copy
  18.  * of this software and associated documentation files (the "Software"), to deal
  19.  * in the Software without restriction, including without limitation the rights
  20.  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  21.  * copies of the Software, and to permit persons to whom the Software is
  22.  * furnished to do so, subject to the following conditions:
  23.  *
  24.  * The above copyright notice and this permission notice shall be included in
  25.  * all copies or substantial portions of the Software.
  26.  *
  27.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  28.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  29.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  30.  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  31.  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  32.  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  33.  * THE SOFTWARE.
  34.  *
  35.  */
  36.  
  37. // These global variables are necessary to avoid losing scope when
  38. // setting the balloon timeout and for inter-object communication
  39. var currentBalloonClass;
  40. var balloonIsVisible;
  41. var balloonIsSticky;
  42. var balloonInvisibleSelects;
  43. var balloonIsSuppressed;
  44. var tooltipIsSuppressed;
  45.  
  46.  
  47. //////////////////////////////////////////////////////////////////////////
  48. // This is constructor that is called to initialize the Balloon object  //
  49. //////////////////////////////////////////////////////////////////////////
  50. var Balloon = function () {
  51.         // Cursor tracking enabled by default
  52.         this.trackCursor = true;
  53.        
  54.         // Track the cursor every time the mouse moves
  55.         //document.onmousemove = this.setActiveCoordinates;
  56.        
  57.         // scrolling aborts visible balloons
  58.         var myObject = this.isIE() ? window : document;
  59.         myObject.onscroll  = function(){Balloon.prototype.nukeTooltip();};
  60.        
  61.         // make balloons go away if the page is unloading or waiting
  62.         // to unload.
  63.         window.onbeforeunload = function(){
  64.                 Balloon.prototype.nukeTooltip();
  65.                 balloonIsSuppressed = true;
  66.         };
  67.        
  68.         // for IE, the balloons can't start until the page is finished loading
  69.         // set a flag that will get toggled when loading is finished
  70.         if (this.isIE()) {
  71.                 this.suppress = true;
  72.         }
  73.        
  74.         return this;
  75. };
  76.  
  77. //////////////////////////////////////////////////////////////////////////
  78. // This is the method that is called on mouseover.  It has a built-in   //
  79. // delay time to avoid balloons popping up on rapid mouseover events    //
  80. //////////////////////////////////////////////////////////////////////////
  81. Balloon.prototype.showTooltip = function(evt,caption,sticky,width,height,x,y) {
  82.         // If the objext is not configured by now, fall back to default
  83.         if (!this.configured) {
  84.                 BalloonConfig(this,'GBubble');
  85.         }
  86.        
  87.         // Cursor tracking halts after one of these vertical
  88.         // or horizontal thresholds are reached
  89.         this.stopTrackingX = this.trackCursor ? 100 : 10;
  90.         this.stopTrackingY = this.trackCursor ? 50  : 10;
  91.        
  92.         // Awful IE bug, page load aborts if the balloon is fired
  93.         // before the page is fully loaded.
  94.         if (this.isIE() && document.readyState.match(/complete/i)) {
  95.                 this.suppress = false;
  96.         }
  97.        
  98.         // All balloons have been suppressed, go no further
  99.         if (this.suppress || balloonIsSuppressed) {
  100.                 return false;
  101.         }
  102.        
  103.         // Non-sticky balloons suppressed
  104.         if (tooltipIsSuppressed && !sticky) {
  105.                 return false;
  106.         }
  107.        
  108.         // We use 1-100 scale for opacity internally
  109.         if (this.opacity && this.opacity < 1) {
  110.                 this.opacity = parseInt(parseFloat(this.opacity) * 100);
  111.         }
  112.         else if (this.opacity && this.opacity == 1) {
  113.                 this.opacity = 100;
  114.         }
  115.         else if (!this.opacity) {
  116.                 this.opacity == 100;
  117.         }
  118.        
  119.         // Sorry Konqueror, no fade-in or translucency for you!
  120.         if (this.isKonqueror()) {
  121.                 this.allowFade = false;
  122.                 this.opacity   = 100;
  123.         }
  124.        
  125.         // With IE, fading and translucency are not very compatible
  126.         // use opaque balloons if fadein is enabled
  127.         if (this.isIE() && this.allowFade) {
  128.                 this.opacity = 100;
  129.         }
  130.        
  131.         // Check for mouseover (vs. mousedown or click)
  132.         var mouseOver = true;
  133.         try{
  134.                 var mouseOver = evt.type.match('mouseover','i');
  135.         }catch(e){}  
  136.                
  137.                 // if the firing event is a click, fade-in and a non-sticky balloon make no sense
  138.                 if (!mouseOver) {
  139.                         sticky = true;
  140.                         this.fadeOK = false;
  141.                         // case where hover and click events both trigger balloons
  142.                         if (balloonIsVisible) {
  143.                                 this.hideTooltip();
  144.                         }
  145.                 }
  146.                 else {
  147.                         this.fadeOK = this.allowFade;
  148.                 }
  149.                
  150.                 // Don't fire on mouseover if a non-sticky balloon is visible
  151.                 if (balloonIsVisible && !balloonIsSticky && mouseOver) {
  152.                         return false;
  153.                 }
  154.                
  155.                 // Don't start a non-sticky balloon if a sticky one is visible
  156.                 if (balloonIsVisible && balloonIsSticky && !sticky) {
  157.                         return false;
  158.                 }
  159.                
  160.                 // Ignore repeated firing of mouseover->mouseout events on
  161.                 // the same element (Safari)
  162.                
  163.                 try{
  164.                         var el = this.getEventTarget(evt);
  165.                 }catch(e){var el = evt;}               
  166.                
  167.                 if (sticky && mouseOver && this.isSameElement(el,this.currentElement)) {
  168.                         return false;
  169.                 }  
  170.                 this.currentElement = el;
  171.                
  172.                 // remember the coordinates of the element
  173.                 this.elCoords = this.getLoc(el,'region');
  174.                
  175.                 // attach a mouseout event handler to the target element
  176.                 if (!sticky) {
  177.                         var mouseoutFunc = el.onmouseout;
  178.                         var closeBalloon = function() {
  179.                                 Balloon.prototype.hideTooltip();
  180.                                 // fall through to any onmouseout event specified elsewhere
  181.                                 if (mouseoutFunc) {
  182.                                         mouseoutFunc();
  183.                                 }
  184.                         };
  185.                         if (!mouseOver) {
  186.                                 el.onmouseup  = function() {return false;};
  187.                         }
  188.                         //el.onmouseout = closeBalloon;
  189.                 }  
  190.                
  191.                 balloonIsSticky = sticky;
  192.                
  193.                 this.hideTooltip();
  194.                
  195.                 // request the contents synchronously (ie wait for result)
  196.                 this.currentHelpText = this.getAndCheckContents(caption);
  197.                
  198.                 // no contents? abort.
  199.                 if (!this.currentHelpText) {
  200.                         return false;
  201.                 }
  202.                
  203.                 this.width  = width + "px";
  204.                 this.height = height + "px";
  205.                 this.actualWidth = null;
  206.                 //edmar
  207.                 this.x = x;
  208.                 this.y = y;
  209.                
  210.                 // make sure old balloons are removed
  211.                 this.hideTooltip();
  212.                
  213.                 // Put the balloon contents and images into a visible (but offscreen)
  214.                 // element so they will be preloaded and have a layout to
  215.                 // calculate the balloon dimensions
  216.                 this.container = document.createElement('div');
  217.                 this.container.id = 'balloonPreloadContainer';
  218.                 document.body.appendChild(this.container);
  219.                 this.setStyle(this.container,'position','absolute');
  220.                 this.setStyle(this.container,'top',-8888);
  221.                 this.setStyle(this.container,'font-family',this.fontFamily);
  222.                 this.setStyle(this.container,'font-size',this.fontSize);
  223.                
  224.                 // protect escaped '&'
  225.                 this.currentHelpText = this.currentHelpText.replace(/\&amp;/g, '&amp;amp');
  226.                 this.container.innerHTML = unescape(this.currentHelpText);
  227.                
  228.                 // make sure balloon image path is complete
  229.                 if (this.images) {
  230.                        
  231.                         // main background image
  232.                         this.balloonImage  = this.balloonImage  ? this.images +'/'+ this.balloonImage  : false;
  233.                         this.ieImage       = this.ieImage       ? this.images +'/'+ this.ieImage       : false;
  234.                        
  235.                         // optional stems
  236.                         this.upLeftStem    = this.upLeftStem    ? this.images +'/'+ this.upLeftStem    : false;
  237.                         this.upRightStem   = this.upRightStem   ? this.images +'/'+ this.upRightStem   : false;
  238.                         this.downLeftStem  = this.downLeftStem  ? this.images +'/'+ this.downLeftStem  : false;
  239.                         this.downRightStem = this.downRightStem ? this.images +'/'+ this.downRightStem : false;
  240.                        
  241.                         this.closeButton   = this.closeButton   ? this.images +'/'+ this.closeButton   : false;
  242.                        
  243.                         this.images        = false;
  244.                 }
  245.                
  246.                 // The PNG alpha channels (shadow transparency) are not
  247.                 // handled properly by IE < 6.  Also, if opacity is set to
  248.                 // < 1 (translucent balloons), any version of IE does not
  249.                 // handle the image properly.
  250.                 // Google chrome is a bit dodgey too
  251.                 // If there is an IE image provided, use that instead.
  252.                 if (this.ieImage && (this.isIE() || this.isChrome())) {
  253.                         if (this.isOldIE() || this.opacity || this.allowFade) {    
  254.                                 this.balloonImage = this.ieImage;
  255.                         }
  256.                 }
  257.                
  258.                 // preload balloon images
  259.                 if (!this.preloadedImages) {
  260.                         var images = [this.balloonImage, this.closeButton];
  261.                         if (this.ieImage) {
  262.                                 images.push(this.ieImage);
  263.                         }
  264.                         if (this.stem) {
  265.                                 images.push(this.upLeftStem,this.upRightStem,this.downLeftStem,this.downRightStem);
  266.                         }
  267.                         var len = images.length;
  268.                         for (var i=0;i<len;i++) {
  269.                                 if ( images[i] ) {
  270.                                         this.preload(images[i]);
  271.                                 }
  272.                         }
  273.                         this.preloadedImages = true;
  274.                 }
  275.                
  276.                 currentBalloonClass = this;
  277.  
  278.                 // Capture coordinates for mousedown or click
  279.                 //if (!mouseOver) {this.setActiveCoordinates(evt);}
  280.                 if (!mouseOver) el.onmouseup  = function() {return false;};
  281.                 // Remember which event started this
  282.                 this.currentEvent = evt;
  283.                
  284.                 // prevent interaction with gbrowse drag and drop
  285.                 evt.cancelBubble  = true;
  286.                
  287.                 // Make delay time short for onmousedown
  288.                 //var delay = mouseOver ? this.delayTime : 1;
  289.                 //this.timeoutTooltip = window.setTimeout(this.doShowTooltip,delay);
  290.                 this.setActiveCoordinates([]);
  291.                 this.doShowTooltip();
  292.                 this.pending = true;
  293. };
  294.  
  295. // Preload the balloon background images
  296. Balloon.prototype.preload = function(src) {
  297.         var i = new Image;
  298.         i.src = src;
  299.        
  300.         // append to the DOM tree so the images have a layout,
  301.         // then remove.
  302.         this.setStyle(i,'position','absolute');
  303.         this.setStyle(i,'top',-8000);
  304.         document.body.appendChild(i);
  305.         document.body.removeChild(i);
  306. };
  307.  
  308.  
  309. /////////////////////////////////////////////////////////////////////
  310. // Tooltip rendering function
  311. /////////////////////////////////////////////////////////////////////
  312. Balloon.prototype.doShowTooltip = function() {
  313.         var self = currentBalloonClass;
  314.        
  315.         // Stop firing if a balloon is already being displayed
  316.         if (balloonIsVisible) {
  317.                 return false;  
  318.         }
  319.         if (!self.parent) {
  320.                 if (self.parentID) {
  321.                         self.parent = document.getElementById(self.parentID);
  322.                 }
  323.                 else {
  324.                         self.parent = document.body;
  325.                 }
  326.                 self.xOffset = self.getLoc(self.parent, 'x1');
  327.                 self.yOffset = self.getLoc(self.parent, 'y1');
  328.         }
  329.        
  330.         // a short delay time might cause some intereference
  331.         // with fading
  332.         window.clearTimeout(self.timeoutFade);
  333.         if (!balloonIsSticky) {
  334.                 self.setStyle('visibleBalloonElement','display','none');
  335.         }
  336.        
  337.         // make sure user-configured numbers are not strings
  338.         self.parseIntAll();
  339.        
  340.         // create the balloon object
  341.         var balloon = self.makeBalloon();
  342.        
  343.         // window dimensions
  344.         var pageWidth   = YAHOO.util.Dom.getViewportWidth();
  345.         var pageCen     = Math.round(pageWidth/2);
  346.         var pageHeight  = YAHOO.util.Dom.getViewportHeight();
  347.         var pageLeft    = YAHOO.util.Dom.getDocumentScrollLeft();
  348.         var pageTop     = YAHOO.util.Dom.getDocumentScrollTop();
  349.         var pageMid     = pageTop + Math.round(pageHeight/2);
  350.         self.pageBottom = pageTop + pageHeight;
  351.         self.pageTop    = pageTop;
  352.         self.pageLeft   = pageLeft;
  353.         self.pageRight  = pageLeft + pageWidth;
  354.        
  355.         // balloon orientation
  356.         var vOrient = self.activeTop > pageMid ? 'up' : 'down';
  357.         var hOrient = self.activeRight > pageCen ? 'left' : 'right';
  358.        
  359.         // get the preloaded balloon contents
  360.         var helpText = self.container.innerHTML;
  361.         self.actualWidth = self.getLoc(self.container,'width');
  362.         if (!isNaN(self.actualWidth)) {
  363.                 self.actualWidth += 10;
  364.         }
  365.         self.parent.removeChild(self.container);
  366.         var wrapper = document.createElement('div');
  367.         wrapper.id = 'contentWrapper';
  368.         self.contents.appendChild(wrapper);
  369.         wrapper.innerHTML = helpText;
  370.        
  371.         // how and where to draw the balloon
  372.         self.setBalloonStyle(vOrient,hOrient,pageWidth,pageLeft);
  373.        
  374.         // close control for balloon or box
  375.         if (balloonIsSticky) {
  376.                 self.addCloseButton();
  377.         }
  378.        
  379.         balloonIsVisible = true;
  380.         self.pending = false;  
  381.        
  382.         // in IE < 7, hide <select> elements
  383.         self.showHide();
  384.        
  385.         self.startX = self.activeLeft;
  386.         self.startY = self.activeTop;
  387.  
  388.         self.fade(0,self.opacity,self.fadeIn);
  389. };
  390.  
  391. Balloon.prototype.addCloseButton = function () {
  392.         var self         = currentBalloonClass;
  393.         var margin       = Math.round(self.padding/2);
  394.         var closeWidth   = self.closeButtonWidth || 16;
  395.         var balloonTop   = self.getLoc('visibleBalloonElement','y1') + margin + self.shadow;
  396.         var BalloonLeft  = self.getLoc('topRight','x2') - self.closeButtonWidth - self.shadow - margin;
  397.         var closeButton  = document.getElementById('closeButton');
  398.        
  399.         if (!closeButton) {
  400.                 closeButton = new Image;
  401.                 closeButton.setAttribute('id','closeButton');
  402.                 closeButton.setAttribute('src',self.closeButton);
  403.                 closeButton.onclick = function() {
  404.                         Balloon.prototype.nukeTooltip();
  405.                         var temp = $i('marcaIdentifica');
  406.                         if(temp)
  407.                         {temp.parentNode.removeChild(temp);}                   
  408.                 };
  409.                 self.setStyle(closeButton,'position','absolute');
  410.                 document.body.appendChild(closeButton);
  411.         }
  412.        
  413.         // I have no idea why
  414.         if (self.isIE()) {
  415.                 BalloonLeft = BalloonLeft - 5;
  416.         }
  417.        
  418.         self.setStyle(closeButton,'top',balloonTop);
  419.         self.setStyle(closeButton,'left',BalloonLeft);
  420.         self.setStyle(closeButton,'display','inline');
  421.         self.setStyle(closeButton,'cursor','pointer');
  422.         self.setStyle(closeButton,'z-index',999999999);
  423. };
  424.  
  425. // use a fresh object every time to make sure style
  426. // is not polluted
  427. Balloon.prototype.makeBalloon = function() {
  428.         var self = currentBalloonClass;
  429.        
  430.         var balloon = document.getElementById('visibleBalloonElement');
  431.         if (balloon) {
  432.                 self.hideTooltip();
  433.         }
  434.        
  435.         balloon = document.createElement('div');
  436.         balloon.setAttribute('id','visibleBalloonElement');
  437.         self.parent.appendChild(balloon);
  438.         self.activeBalloon = balloon;
  439.        
  440.         self.parts = new Array();
  441.         var parts = new Array('contents','topRight','bottomRight','bottomLeft');
  442.         for (var i=0;i<parts.length;i++) {
  443.                 var child = document.createElement('div');
  444.                 child.setAttribute('id',parts[i]);
  445.                 balloon.appendChild(child);
  446.                 if (parts[i] == 'contents') self.contents = child;
  447.                     self.parts.push(child);
  448.         }
  449.         //self.parts.push(balloon);
  450.        
  451.         if (self.displayTime)  {
  452.                 self.timeoutAutoClose = window.setTimeout(this.hideTooltip,self.displayTime);
  453.         }
  454.         return balloon;
  455. };
  456.  
  457. Balloon.prototype.setBalloonStyle = function(vOrient,hOrient,pageWidth,pageLeft) {
  458.         var self = currentBalloonClass;
  459.         var balloon = self.activeBalloon;
  460.        
  461.         if (typeof(self.shadow) != 'number') self.shadow = 0;
  462.             if (!self.stem) self.stemHeight = 0;
  463.            
  464.             var fullPadding   = self.padding + self.shadow;
  465.         var insidePadding = self.padding;
  466.         var outerWidth    = self.actualWidth + fullPadding;
  467.         var innerWidth    = self.actualWidth;  
  468.        
  469.         self.setStyle(balloon,'position','absolute');
  470.         self.setStyle(balloon,'top',-9999);
  471.         self.setStyle(balloon,'z-index',1000000);
  472.        
  473.         if (self.height) {
  474.                 self.setStyle('contentWrapper','height',self.height-fullPadding);
  475.         }
  476.        
  477.         if (self.width) {
  478.                 self.setStyle(balloon,'width',self.width);  
  479.                 innerWidth = self.width - fullPadding;
  480.                 if (balloonIsSticky) {
  481.                         innerWidth -= self.closeButtonWidth;
  482.                 }
  483.                 self.setStyle('contentWrapper','width',innerWidth);
  484.         }
  485.         else {
  486.                 self.setStyle(balloon,'width',outerWidth);
  487.                 self.setStyle('contentWrapper','width',innerWidth);
  488.         }
  489.        
  490.         // not too big...
  491.         if (!self.width && self.maxWidth && outerWidth > self.maxWidth) {
  492.                 self.setStyle(balloon,'width',self.maxWidth);
  493.                 self.setStyle('contentWrapper','width',self.maxWidth-fullPadding);
  494.         }
  495.         // not too small...
  496.         if (!self.width && self.minWidth && outerWidth < self.minWidth) {
  497.                 self.setStyle(balloon,'width',self.minWidth);
  498.                 self.setStyle('contentWrapper','width',self.minWidth-fullPadding);
  499.         }
  500.        
  501.         self.setStyle('contents','z-index',2);
  502.         self.setStyle('contents','color',self.fontColor);
  503.         self.setStyle('contents','font-family',self.fontFamily);
  504.         self.setStyle('contents','font-size',self.fontSize);
  505.         self.setStyle('contents','background','url('+self.balloonImage+') top left no-repeat');
  506.         self.setStyle('contents','padding-top',fullPadding);
  507.         self.setStyle('contents','padding-left',fullPadding);
  508.        
  509.         self.setStyle('bottomRight','background','url('+self.balloonImage+') bottom right no-repeat');
  510.         self.setStyle('bottomRight','position','absolute');
  511.         self.setStyle('bottomRight','right',0-fullPadding);
  512.         self.setStyle('bottomRight','bottom',0-fullPadding);
  513.         self.setStyle('bottomRight','height',fullPadding);
  514.         self.setStyle('bottomRight','width',fullPadding);
  515.         self.setStyle('bottomRight','z-index',-1);
  516.        
  517.         self.setStyle('topRight','background','url('+self.balloonImage+') top right no-repeat');
  518.         self.setStyle('topRight','position','absolute');
  519.         self.setStyle('topRight','right',0-fullPadding);
  520.         self.setStyle('topRight','top',0);
  521.         self.setStyle('topRight','width',fullPadding);
  522.        
  523.         self.setStyle('bottomLeft','background','url('+self.balloonImage+') bottom left no-repeat');
  524.         self.setStyle('bottomLeft','position','absolute');
  525.         self.setStyle('bottomLeft','left',0);
  526.         self.setStyle('bottomLeft','bottom',0-fullPadding);
  527.         self.setStyle('bottomLeft','height',fullPadding);
  528.         self.setStyle('bottomLeft','z-index',-1);
  529.        
  530.         if (this.stem) {
  531.                 var stem = document.createElement('img');
  532.                 stem.style.zIndex = 50000;
  533.                 self.setStyle(stem,'position','absolute');
  534.                 balloon.appendChild(stem);
  535.                
  536.                 if (vOrient == 'up' && hOrient == 'left') {  
  537.                         stem.src = self.upLeftStem;
  538.                         var height = self.stemHeight + insidePadding - self.stemOverlap;
  539.                         self.setStyle(stem,'bottom',0-height);
  540.                         self.setStyle(stem,'right',0);            
  541.                 }
  542.                 else if (vOrient == 'down' && hOrient == 'left') {
  543.                         stem.src = self.downLeftStem;
  544.                         var height = self.stemHeight - (self.shadow + self.stemOverlap);
  545.                         self.setStyle(stem,'top',0-height);
  546.                         self.setStyle(stem,'right',0);
  547.                 }
  548.                 else if (vOrient == 'up' && hOrient == 'right') {
  549.                         stem.src = self.upRightStem;
  550.                         var height = self.stemHeight + insidePadding - self.stemOverlap;
  551.                         self.setStyle(stem,'bottom',0-height);
  552.                         self.setStyle(stem,'left',self.shadow);
  553.                 }
  554.                 else if (vOrient == 'down' && hOrient == 'right') {
  555.                         stem.src = self.downRightStem;
  556.                         var height = self.stemHeight - (self.shadow + self.stemOverlap);
  557.                         self.setStyle(stem,'top',0-height);
  558.                         self.setStyle(stem,'left',self.shadow);
  559.                 }
  560.                 if (self.fadeOK && self.isIE()) {
  561.                         self.parts.push(stem);
  562.                 }
  563.         }
  564.        
  565.         if (self.allowFade) {
  566.                 self.setOpacity(1);
  567.         }
  568.         else if (self.opacity) {
  569.                 self.setOpacity(self.opacity);
  570.         }
  571.        
  572.         // flip left or right, as required
  573.         if (hOrient == 'left') {
  574.                 var pageWidth = self.pageRight - self.pageLeft;
  575.                 var activeRight = pageWidth - self.activeLeft;
  576.                 self.setStyle(balloon,'right',activeRight);
  577.         }
  578.         else {
  579.                 var activeLeft = self.activeRight - self.xOffset;
  580.                 self.setStyle(balloon,'left',activeLeft);
  581.         }
  582.        
  583.         // oversized contents? Scrollbars for sticky balloons, clipped for non-sticky
  584.         var overflow = balloonIsSticky ? 'auto' : 'hidden';
  585.         self.setStyle('contentWrapper','overflow',overflow);
  586.        
  587.         // a bit of room for the closebutton
  588.         if (balloonIsSticky) {
  589.                 self.setStyle('contentWrapper','margin-right',self.closeButtonWidth);
  590.         }
  591.        
  592.         // Make sure the balloon is not offscreen horizontally.
  593.         // We handle vertical sanity checking later, after the final
  594.         // layout is set.
  595.         var balloonLeft   = self.getLoc(balloon,'x1');
  596.         var balloonRight  = self.getLoc(balloon,'x2');
  597.         var scrollBar     = 20;
  598.        
  599.         if (hOrient == 'right' && balloonRight > (self.pageRight - fullPadding)) {
  600.                 var width = (self.pageRight - balloonLeft) - fullPadding - scrollBar;
  601.                 self.setStyle(balloon,'width',width);
  602.                 self.setStyle('contentWrapper','width',width-fullPadding);
  603.         }
  604.         else if (hOrient == 'left' && balloonLeft < (self.pageLeft + fullPadding)) {
  605.                 var width = (balloonRight - self.pageLeft) - fullPadding;
  606.                 self.setStyle(balloon,'width',width);
  607.                 self.setStyle('contentWrapper','width',width-fullPadding);
  608.         }
  609.        
  610.         // Get the width/height for the right and bottom outlines
  611.         var balloonWidth  = self.getLoc(balloon,'width');
  612.         var balloonHeight = self.getLoc(balloon,'height');
  613.        
  614.         // IE7 quirk -- look for unwanted overlap cause by an off by 1px error
  615.         var vOverlap = self.isOverlap('topRight','bottomRight');
  616.         var hOverlap = self.isOverlap('bottomLeft','bottomRight');
  617.         if (vOverlap) {
  618.                 self.setStyle('topRight','height',balloonHeight-vOverlap[1]);
  619.         }
  620.         if (hOverlap) {
  621.                 self.setStyle('bottomLeft','width',balloonWidth-hOverlap[0]);
  622.         }
  623.        
  624.         // vertical position of the balloon
  625.         if (vOrient == 'up') {
  626.                 var activeTop = self.activeTop - balloonHeight;
  627.                 self.setStyle(balloon,'top',activeTop);
  628.         }
  629.         else {
  630.                 var activeTop = self.activeBottom;
  631.                 self.setStyle(balloon,'top',activeTop);
  632.         }
  633.        
  634.         // Make sure the balloon is vertically contained in the window
  635.         var balloonTop    = self.getLoc(balloon,'y1');
  636.         var balloonBottom = self.height ? balloonTop + self.height : self.getLoc(balloon,'y2');
  637.         var deltaTop      = balloonTop < self.pageTop ? self.pageTop - balloonTop : 0;
  638.         var deltaBottom   = balloonBottom > self.pageBottom ? balloonBottom - self.pageBottom : 0;
  639.        
  640.         if (vOrient == 'up' && deltaTop) {
  641.                 var newHeight = balloonHeight - deltaTop;
  642.                 if (newHeight > (self.padding*2)) {
  643.                         self.setStyle('contentWrapper','height',newHeight-fullPadding);
  644.                         self.setStyle(balloon,'top',self.pageTop+self.padding);
  645.                         self.setStyle(balloon,'height',newHeight);
  646.                 }
  647.         }
  648.         if (vOrient == 'down' && deltaBottom) {
  649.                 var newHeight = balloonHeight - deltaBottom - scrollBar;
  650.                 if (newHeight > (self.padding*2) + scrollBar) {
  651.                         self.setStyle('contentWrapper','height',newHeight-fullPadding);
  652.                         self.setStyle(balloon,'height',newHeight);
  653.                 }
  654.         }
  655.        
  656.         // If we have an iframe, make sure it fits properly
  657.         var iframe = balloon.getElementsByTagName('iframe');
  658.         if (iframe[0]) {
  659.                 iframe = iframe[0];
  660.                 var w = self.getLoc('contentWrapper','width');
  661.                 if (balloonIsSticky && !this.isIE()) {
  662.                         w -= self.closeButtonWidth;
  663.                 }
  664.                 var h = self.getLoc('contentWrapper','height');
  665.                 self.setStyle(iframe,'width',w);
  666.                 self.setStyle(iframe,'height',h);
  667.                 self.setStyle('contentWrapper','overflow','hidden');
  668.         }
  669.        
  670.         // Make edges match the main balloon body
  671.         self.setStyle('topRight','height', self.getLoc(balloon,'height'));
  672.         self.setStyle('bottomLeft','width', self.getLoc(balloon,'width'));
  673.        
  674.         self.hOrient = hOrient;
  675.         self.vOrient = vOrient;
  676. };
  677.  
  678.  
  679. // Fade method adapted from an example on
  680. // http://brainerror.net/scripts/javascript/blendtrans/
  681. Balloon.prototype.fade = function(opacStart, opacEnd, millisec) {
  682.         var self = currentBalloonClass || new Balloon;
  683.         if (!millisec || !self.allowFade) {
  684.                 return false;
  685.         }
  686.        
  687.         opacEnd = opacEnd || 100;
  688.        
  689.         //speed for each frame
  690.         var speed = Math.round(millisec / 100);
  691.         var timer = 0;
  692.         for(o = opacStart; o <= opacEnd; o++) {
  693.                 self.timeoutFade = setTimeout('Balloon.prototype.setOpacity('+o+')',(timer*speed));
  694.         timer++;
  695.         }
  696. };
  697.  
  698. Balloon.prototype.setOpacity = function(opc) {
  699.         var self = currentBalloonClass;
  700.         if (!self || !opc) return false;
  701.                              
  702.                               var o = parseFloat(opc/100);
  703.        
  704.         // opacity handled differently for IE
  705.                               var parts = self.isIE() ? self.parts : [self.activeBalloon];
  706.                              
  707.                               var len = parts.length;
  708.                               for (var i=0;i<len;i++) {
  709.                                       self.doOpacity(o,opc,parts[i]);
  710.                               }
  711. };
  712.  
  713. Balloon.prototype.doOpacity = function(op,opc,el) {
  714.         var self = currentBalloonClass;
  715.         if (!el) return false;
  716.                              
  717.                               // CSS standards-compliant browsers!
  718.         self.setStyle(el,'opacity',op);
  719.        
  720.         // old IE
  721.         self.setStyle(el,'filter','alpha(opacity='+opc+')');
  722.        
  723.         // old Mozilla/NN
  724.         self.setStyle(el,'MozOpacity',op);
  725.        
  726.         // old Safari
  727.         self.setStyle(el,'KhtmlOpacity',op);
  728. };
  729.  
  730. Balloon.prototype.nukeTooltip = function() {
  731.         this.hideTooltip(1);
  732. };
  733.  
  734. Balloon.prototype.hideTooltip = function(override) {
  735.         // some browsers pass the event object == we don't want it
  736.         if (override && typeof override == 'object') override = false;
  737.             if (balloonIsSticky && !override) return false;
  738.             var self = currentBalloonClass;
  739.         Balloon.prototype.showHide(1);
  740.         Balloon.prototype.cleanup();
  741.        
  742.         if (self) {
  743.                 window.clearTimeout(self.timeoutTooltip);
  744.                 window.clearTimeout(self.timeoutFade);
  745.                 window.clearTimeout(self.timeoutAutoClose);
  746.                 if (balloonIsSticky) {
  747.                         self.currentElement = null;
  748.                 }
  749.                 self.startX = 0;
  750.                 self.startY = 0;
  751.         }
  752.        
  753.         balloonIsVisible = false;
  754.         balloonIsSticky  = false;
  755. };
  756.  
  757. // Garbage collection
  758. Balloon.prototype.cleanup = function() {
  759.         var self = currentBalloonClass;
  760.         var body;      
  761.         if (self) {
  762.                 body = self.parent   ? self.parent
  763.                 : self.parentID ? document.getElementById(self.parentID) || document.body
  764.                 : document.body;
  765.         }
  766.         else {
  767.                 body = document.body;
  768.         }
  769.         var bubble = document.getElementById('visibleBalloonElement');
  770.         var close  = document.getElementById('closeButton');
  771.         var cont   = document.getElementById('balloonPreloadContainer');
  772.         if (bubble) { body.removeChild(bubble) }
  773.         if (close)  { body.removeChild(close)  }
  774.         if (cont)   { body.removeChild(cont)   }
  775.         //edmar
  776. };
  777.  
  778.  
  779. // this function is meant to be called externally to clear
  780. // any open balloons
  781. hideAllTooltips = function() {
  782.         var self = currentBalloonClass;
  783.         if (!self) return;
  784.                                              window.clearTimeout(self.timeoutTooltip);
  785.         if (self.activeBalloon) self.setStyle(self.activeBalloon,'display','none');
  786.                                               balloonIsVisible    = false;
  787.         balloonIsSticky     = false;
  788.         currentBalloonClass = null;
  789. };
  790.  
  791.  
  792. // Track the active mouseover coordinates
  793. Balloon.prototype.setActiveCoordinates = function(evt) {
  794.         var self = currentBalloonClass;
  795.         if (!self) {
  796.                 return true;
  797.         }
  798.         var evt = evt || window.event || self.currentEvent;
  799.         if (!evt) {
  800.                 return true;
  801.         }
  802.         self.currentEvent = {};
  803.         for (var i in evt) {
  804.                 self.currentEvent[i] = evt[i];
  805.         }
  806.        
  807.         // avoid silent NaN errors
  808.         self.hOffset = self.hOffset || 1;
  809.         self.vOffset = self.vOffset || 1;
  810.         self.stemHeight = self.stem && self.stemHeight ? (self.stemHeight|| 0) : 0;
  811.        
  812.         var scrollTop  = 0;
  813.         var scrollLeft = 0;
  814.        
  815.         //var XY = self.eventXY(evt);
  816.         var XY = [self.x,self.y];
  817.         var adjustment   = self.hOffset < 20 ? 10 : 0;
  818.         self.activeTop    = scrollTop  + XY[1] - adjustment - self.vOffset - self.stemHeight;
  819.         self.activeLeft   = scrollLeft + XY[0] - adjustment - self.hOffset;
  820.         self.activeRight  = scrollLeft + XY[0];
  821.         self.activeBottom = scrollTop  + XY[1] + self.vOffset + 2*adjustment;
  822.        
  823.         // dynamic positioning but only if the balloon is not sticky
  824.         // and cursor tracking is enabled
  825.         if (balloonIsVisible && !balloonIsSticky) {
  826.                 var deltaX = Math.abs(self.activeLeft - self.startX);
  827.                 var deltaY = Math.abs(self.activeTop - self.startY);
  828.                
  829.                 // Close the balloon if the cursor has left the firing element
  830.                 if (  XY[0] < self.elCoords.left || XY[0] > self.elCoords.right
  831.                         || XY[1] < self.elCoords.top  || XY[1] > self.elCoords.bottom ) {
  832.                         //self.hideTooltip();
  833.                         }
  834.                        
  835.                         // In some cases , such as <area> elements in image maps or big elements,
  836.                         // we need to kill the balloon if the mouse has strayed too far.
  837.                         if (deltaX > self.stopTrackingX || deltaY > self.stopTrackingY) {
  838.                                 //self.hideTooltip();
  839.                         }
  840.                         else if (self.trackCursor) {
  841.                                 var b = self.activeBalloon;
  842.                                 var bwidth  = self.getLoc(b,'width');
  843.                                 var bheight = self.getLoc(b,'height');
  844.                                 var btop    = self.getLoc(b,'y1');
  845.                                 var bleft   = self.getLoc(b,'x1');
  846.                                
  847.                                 if (self.hOrient == 'right') {
  848.                                         self.setStyle(b,'left',self.activeRight);
  849.                                 }
  850.                                 else if (self.hOrient == 'left') {
  851.                                         self.setStyle(b,'right',null);
  852.                                         var newLeft = self.activeLeft - bwidth;
  853.                                         self.setStyle(b,'left',newLeft);
  854.                                 }
  855.                                
  856.                                 if (self.vOrient == 'up') {
  857.                                         self.setStyle(b,'top',self.activeTop - bheight);
  858.                                 }
  859.                                 else if (self.vOrient == 'down') {
  860.                                         self.setStyle(b,'top',self.activeBottom);
  861.                                 }
  862.                         }
  863.         }
  864.         return true;
  865. };
  866.  
  867. ////
  868. // event XY and getEventTarget Functions based on examples by Peter-Paul
  869. // Koch http://www.quirksmode.org/js/events_properties.html
  870. Balloon.prototype.eventXY = function(event) {
  871.         var XY = new Array(2);
  872.         var e = event || window.event;
  873.         if (!e) {
  874.                 return false;
  875.         }
  876.         if (e.pageX || e.pageY) {
  877.                 XY[0] = e.pageX;
  878.                 XY[1] = e.pageY;
  879.                 return XY;
  880.         }
  881.         else if ( e.clientX || e.clientY ) {
  882.                 XY[0] = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
  883.                 XY[1] = e.clientY + document.body.scrollTop  + document.documentElement.scrollTop;
  884.                 return XY;
  885.         }
  886. };
  887.  
  888. Balloon.prototype.getEventTarget = function(event) {
  889.         var targ;
  890.         var e = event || window.event;
  891.         if (e.target) targ = e.target;
  892.                                          else if (e.srcElement) targ = e.srcElement;
  893.                                          if (targ.nodeType == 3) targ = targ.parentNode; // Safari
  894.   return targ;
  895. };
  896. ////
  897.  
  898.  
  899. Balloon.prototype.setStyle = function(el,att,val) {
  900.         if (!el) {
  901.                 return false;
  902.         }
  903.         if (typeof(el) != 'object') {
  904.                 el = document.getElementById(el);
  905.         }
  906.         if (!el) {
  907.                 return false;
  908.         }
  909.        
  910.         var v = val;
  911.        
  912.         if (val && att.match(/left|top|bottom|right|width|height|padding|margin/)) {
  913.                 val = new String(val);
  914.                 if (!val.match(/auto/)) {
  915.                         val += 'px';
  916.                 }
  917.         }
  918.        
  919.        
  920.         // z-index does not work as expected
  921.         if (att == 'z-index') {
  922.                 if (el.style) {
  923.                         el.style.zIndex = parseInt(val);
  924.                 }
  925.         }
  926.         else {
  927.                 // Oh just shut up, IE
  928.                 if (this.isIE() && att.match(/^left|right|top|bottom$/)  && !parseInt(val) && val != 0) {
  929.                         val = null;
  930.                 }
  931.                
  932.                 YAHOO.util.Dom.setStyle(el,att,val);
  933.         }
  934. };
  935.  
  936. // Uses YAHOO's region class for element coordinates
  937. Balloon.prototype.getLoc = function(el,request) {
  938.         var region = YAHOO.util.Dom.getRegion(el);
  939.        
  940.         switch(request) {
  941.                 case ('y1') : return parseInt(region.top);
  942.                 case ('y2') : return parseInt(region.bottom);
  943.                 case ('x1') : return parseInt(region.left);
  944.                 case ('x2') : return parseInt(region.right);
  945.                 case ('width')  : return (parseInt(region.right)  - parseInt(region.left));
  946.                 case ('height') : return (parseInt(region.bottom) - parseInt(region.top));
  947.                 case ('region') : return region;
  948.         }
  949.        
  950.         return region;
  951. };
  952.  
  953. // We don't know if numbers are overridden with strings
  954. // so play it safe
  955. Balloon.prototype.parseIntAll = function() {
  956.         this.padding     = parseInt(this.padding);
  957.         this.shadow      = parseInt(this.shadow);
  958.         this.stemHeight  = parseInt(this.stemHeight);
  959.         this.stemOverlap = parseInt(this.stemOverlap);
  960.         this.vOffset     = parseInt(this.vOffset);
  961.         this.delayTime   = parseInt(this.delayTime);
  962.         this.width       = parseInt(this.width);
  963.         this.maxWidth    = parseInt(this.maxWidth);
  964.         this.minWidth    = parseInt(this.minWidth);
  965.         this.fadeIn      = parseInt(this.fadeIn) || 1000;
  966. };
  967.  
  968.  
  969. // show/hide select elements in older IE
  970. // plus user-defined elements
  971. Balloon.prototype.showHide = function(visible) {
  972.         var self = currentBalloonClass || new Balloon;
  973.        
  974.         // IE z-index bug fix (courtesy of Lincoln Stein)
  975.                       if (self.isOldIE()) {
  976.                               var balloonContents = document.getElementById('contentWrapper');
  977.                 if (!visible && balloonContents) {
  978.                         var balloonSelects = balloonContents.getElementsByTagName('select');
  979.                         var myHash = new Object();
  980.                         for (var i=0; i<balloonSelects.length; i++) {
  981.                                 var id = balloonSelects[i].id || balloonSelects[i].name;
  982.                                 myHash[id] = 1;
  983.                         }
  984.                         balloonInvisibleSelects = new Array();
  985.                         var allSelects = document.getElementsByTagName('select');
  986.                         for (var i=0; i<allSelects.length; i++) {
  987.                                 var id = allSelects[i].id || allSelects[i].name;
  988.                                 if (self.isOverlap(allSelects[i],self.activeBalloon) && !myHash[id]) {
  989.                                         balloonInvisibleSelects.push(allSelects[i]);
  990.                                         self.setStyle(allSelects[i],'visibility','hidden');
  991.                                 }
  992.                         }
  993.                 }
  994.                 else if (balloonInvisibleSelects) {
  995.                         for (var i=0; i < balloonInvisibleSelects.length; i++) {
  996.                                 var id = balloonInvisibleSelects[i].id || balloonInvisibleSelects[i].name;
  997.                                 self.setStyle(balloonInvisibleSelects[i],'visibility','visible');
  998.                         }
  999.                         balloonInvisibleSelects = null;
  1000.                 }
  1001.                       }
  1002.                      
  1003.                       // show/hide any user-specified elements that overlap the balloon
  1004.                       if (self.hide) {
  1005.                               var display = visible ? 'inline' : 'none';
  1006.                               for (var n=0;n<self.hide.length;n++) {
  1007.                                       if (self.isOverlap(self.activeBalloon,self.hide[n])) {
  1008.                                               self.setStyle(self.hide[n],'display',display);
  1009.                                       }
  1010.                               }
  1011.                       }
  1012. };
  1013.  
  1014. // Try to find overlap
  1015. Balloon.prototype.isOverlap = function(el1,el2) {
  1016.         if (!el1 || !el2) return false;
  1017.                                               var R1 = this.getLoc(el1,'region');
  1018.         var R2 = this.getLoc(el2,'region');
  1019.         if (!R1 || !R2) return false;
  1020.                              var intersect = R1.intersect(R2);
  1021.         if (intersect) {
  1022.                 // extent of overlap;
  1023.                 intersect = new Array((intersect.right - intersect.left),(intersect.bottom - intersect.top));
  1024.         }
  1025.         return intersect;
  1026. };
  1027.  
  1028. // Coordinate-based test for the same element
  1029. Balloon.prototype.isSameElement = function(el1,el2) {
  1030.         if (!el1 || !el2) return false;
  1031.                              var R1 = this.getLoc(el1,'region');
  1032.         var R2 = this.getLoc(el2,'region');
  1033.         var same = R1.contains(R2) && R2.contains(R1);
  1034.         return same ? true : false;
  1035. };
  1036.  
  1037.  
  1038. ///////////////////////////////////////////////////////
  1039. // Security -- get the balloon contents while checking
  1040. // for disallowed elements.
  1041. //////////////////////////////////////////////////////
  1042. Balloon.prototype.getAndCheckContents = function(caption) {
  1043.         /*
  1044.         var originalCaption = caption;
  1045.         var notAllowed = 'are not allowed in popup balloons in this web site.  \
  1046.         Please contact the site administrator for assistance.';
  1047.         var notSupported = 'AJAX is not supported for popup balloons in this web site.  \
  1048.         Please contact the site administrator for assistance.';
  1049.        
  1050.         // no Help Url without AJAX
  1051.         if (this.helpUrl && !this.allowAJAX) {
  1052.                 alert('Sorry, you have specified help URL '+this.helpUrl+' but '+notSupported);
  1053.                 return null;
  1054.         }
  1055.        
  1056.         // look for a url in the balloon contents
  1057.         if (caption.match(/^url:/)) {
  1058.                 this.activeUrl = caption.replace(/^url:/,'');
  1059.                 caption = '';
  1060.         }
  1061.         // or if the text is a bare hyperlink
  1062.         else if (caption.match(/^(https?:|\/|ftp:)\S+$/i)) {
  1063.                 this.activeUrl = caption;
  1064.                 caption = '';
  1065.         }
  1066.        
  1067.         // Make sure AJAX is allowed
  1068.         if (this.activeUrl && !this.allowAJAX) {
  1069.                 alert('Sorry, you asked for '+originalCaption+' but '+notSupported);
  1070.                 return null;
  1071.         }  
  1072.        
  1073.         // check if the contents are to be retrieved from an element
  1074.         if (caption.match(/^load:/)) {
  1075.                 var load = caption.split(':');
  1076.                 if (!document.getElementById(load[1])) alert ('problem locating element '+load[1]);
  1077.                                          caption = document.getElementById(load[1]).innerHTML;
  1078.                 this.loadedFromElement = true;
  1079.         }
  1080.        
  1081.         // check if iframes are allowed
  1082.         if (caption.match(/\<\s*iframe/i) && !this.allowIframes) {
  1083.                 alert('Sorry: iframe elements '+notAllowed);
  1084.                 return null;
  1085.         }
  1086.        
  1087.         // check if event handlers are allowed
  1088.         if (caption.match(/\bon(load|mouse|click|unload|before)[^=]*=/i) && !this.allowEventHandlers) {
  1089.                 alert('Sorry: JavaScript event handlers '+notAllowed);
  1090.                 return null;
  1091.         }
  1092.        
  1093.         // check for script elements
  1094.         if (caption.match(/\<\s*script/i) && !this.allowScripts) {
  1095.                 alert('Sorry: <script> elements '+notAllowed);
  1096.                 return null;
  1097.         }
  1098.         */
  1099.         // request the contents
  1100.         this.currentHelpText = this.getContents(caption);
  1101.         this.loadedFromElement = false;
  1102.        
  1103.         return this.currentHelpText;;
  1104. };
  1105.  
  1106.  
  1107. ///////////////////////////////////////////////////////
  1108. // AJAX widget to fill the balloons
  1109. // requires prototype.js
  1110. ///////////////////////////////////////////////////////
  1111. Balloon.prototype.getContents = function(section) {
  1112.        
  1113.         // just pass it back if no AJAX handler is required.
  1114.         if (!this.helpUrl && !this.activeUrl) return section;
  1115.            
  1116.             // or if the contents are already loaded from another element
  1117.         if (this.loadedFromElement) return section;
  1118.            
  1119.             // inline URL takes precedence
  1120.         var url = this.activeUrl || this.helpUrl;
  1121.         url    += this.activeUrl ? '' : '?section='+section;
  1122.        
  1123.         // activeUrl is meant to be single-use only
  1124.         this.activeUrl = null;
  1125.        
  1126.         var ajax;
  1127.         if (window.XMLHttpRequest) {
  1128.                 ajax = new XMLHttpRequest();
  1129.         } else {
  1130.                 ajax = new ActiveXObject("Microsoft.XMLHTTP");
  1131.         }
  1132.        
  1133.         if (ajax) {
  1134.                 ajax.open("GET", url, false);
  1135.                 ajax.onreadystatechange=function() {
  1136.                         //alert(ajax.readyState);
  1137.                 };
  1138.                 try {
  1139.                         ajax.send(null);
  1140.                 }
  1141.                 catch (e) {
  1142.                         // alert(e);
  1143.                 }
  1144.                 var txt = this.escapeHTML ? escape(ajax.responseText) : ajax.responseText;
  1145.                 return  txt || section;
  1146.         }
  1147.         else {
  1148.                 return section;
  1149.         }
  1150. };
  1151.  
  1152.  
  1153. // test for internet explorer
  1154. Balloon.prototype.isIE = function() {
  1155.         return document.all && !window.opera;
  1156. };
  1157.  
  1158. // test for internet explorer (but not IE7)
  1159. Balloon.prototype.isOldIE = function() {
  1160.         if (navigator.appVersion.indexOf("MSIE") == -1) return false;
  1161.             var temp=navigator.appVersion.split("MSIE");
  1162.         return parseFloat(temp[1]) < 7;
  1163. };
  1164.  
  1165. // test for Konqueror
  1166. Balloon.prototype.isKonqueror = function() {
  1167.         return navigator.userAgent.toLowerCase().indexOf( 'konqueror' ) != -1;
  1168. };
  1169.  
  1170. // and Google chrome
  1171. Balloon.prototype.isChrome = function() {
  1172.         return navigator.userAgent.toLowerCase().indexOf('chrome') > -1;
  1173. };

Raw Paste


Login or Register to edit or fork this paste. It's free.