[ Index ]

PHP Cross Reference of Drupal 6 (yi-drupal)

title

Body

[close]

/highslide/ -> highslide.js (source)

   1  /** 

   2   * Name:    Highslide JS

   3   * Version: 4.1.12 (2011-03-28)

   4   * Config:  default
   5   * Author:  Torstein Hønsi

   6   * Support: www.highslide.com/support

   7   * License: www.highslide.com/#license

   8   */
   9  if (!hs) { var hs = {
  10  // Language strings

  11  lang : {
  12      cssDirection: 'ltr',
  13      loadingText : 'Loading...',
  14      loadingTitle : 'Click to cancel',
  15      focusTitle : 'Click to bring to front',
  16      fullExpandTitle : 'Expand to actual size (f)',
  17      creditsText : 'Powered by <i>Highslide JS</i>',
  18      creditsTitle : 'Go to the Highslide JS homepage',
  19      restoreTitle : 'Click to close image, click and drag to move. Use arrow keys for next and previous.'
  20  },
  21  // See http://highslide.com/ref for examples of settings  

  22  graphicsDir : 'highslide/graphics/',
  23  expandCursor : 'zoomin.cur', // null disables
  24  restoreCursor : 'zoomout.cur', // null disables
  25  expandDuration : 250, // milliseconds
  26  restoreDuration : 250,
  27  marginLeft : 15,
  28  marginRight : 15,
  29  marginTop : 15,
  30  marginBottom : 15,
  31  zIndexCounter : 1001, // adjust to other absolutely positioned elements
  32  loadingOpacity : 0.75,
  33  allowMultipleInstances: true,
  34  numberOfImagesToPreload : 5,
  35  outlineWhileAnimating : 2, // 0 = never, 1 = always, 2 = HTML only 
  36  outlineStartOffset : 3, // ends at 10
  37  padToMinWidth : false, // pad the popup width to make room for wide caption
  38  fullExpandPosition : 'bottom right',
  39  fullExpandOpacity : 1,
  40  showCredits : true, // you can set this to false if you want
  41  creditsHref : 'http://highslide.com/',
  42  creditsTarget : '_self',
  43  enableKeyListener : true,
  44  openerTagNames : ['a'], // Add more to allow slideshow indexing
  45  
  46  dragByHeading: true,
  47  minWidth: 200,
  48  minHeight: 200,
  49  allowSizeReduction: true, // allow the image to reduce to fit client size. If false, this overrides minWidth and minHeight
  50  outlineType : 'drop-shadow', // set null to disable outlines
  51  // END OF YOUR SETTINGS

  52  
  53  
  54  // declare internal properties

  55  preloadTheseImages : [],
  56  continuePreloading: true,
  57  expanders : [],
  58  overrides : [
  59      'allowSizeReduction',
  60      'useBox',
  61      'outlineType',
  62      'outlineWhileAnimating',
  63      'captionId',
  64      'captionText',
  65      'captionEval',
  66      'captionOverlay',
  67      'headingId',
  68      'headingText',
  69      'headingEval',
  70      'headingOverlay',
  71      'creditsPosition',
  72      'dragByHeading',
  73      
  74      'width',
  75      'height',
  76      
  77      'wrapperClassName',
  78      'minWidth',
  79      'minHeight',
  80      'maxWidth',
  81      'maxHeight',
  82      'pageOrigin',
  83      'slideshowGroup',
  84      'easing',
  85      'easingClose',
  86      'fadeInOut',
  87      'src'
  88  ],
  89  overlays : [],
  90  idCounter : 0,
  91  oPos : {
  92      x: ['leftpanel', 'left', 'center', 'right', 'rightpanel'],
  93      y: ['above', 'top', 'middle', 'bottom', 'below']
  94  },
  95  mouse: {},
  96  headingOverlay: {},
  97  captionOverlay: {},
  98  timers : [],
  99  
 100  pendingOutlines : {},
 101  clones : {},
 102  onReady: [],
 103  uaVersion: /Trident\/4\.0/.test(navigator.userAgent) ? 8 :
 104      parseFloat((navigator.userAgent.toLowerCase().match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [0,'0'])[1]),
 105  ie : (document.all && !window.opera),
 106  //ie : navigator && /MSIE [678]/.test(navigator.userAgent), // ie9 compliant?

 107  safari : /Safari/.test(navigator.userAgent),
 108  geckoMac : /Macintosh.+rv:1\.[0-8].+Gecko/.test(navigator.userAgent),
 109  
 110  $ : function (id) {
 111      if (id) return document.getElementById(id);
 112  },
 113  
 114  push : function (arr, val) {
 115      arr[arr.length] = val;
 116  },
 117  
 118  createElement : function (tag, attribs, styles, parent, nopad) {
 119      var el = document.createElement(tag);
 120      if (attribs) hs.extend(el, attribs);
 121      if (nopad) hs.setStyles(el, {padding: 0, border: 'none', margin: 0});
 122      if (styles) hs.setStyles(el, styles);
 123      if (parent) parent.appendChild(el);    
 124      return el;
 125  },
 126  
 127  extend : function (el, attribs) {
 128      for (var x in attribs) el[x] = attribs[x];
 129      return el;
 130  },
 131  
 132  setStyles : function (el, styles) {
 133      for (var x in styles) {
 134          if (hs.ieLt9 && x == 'opacity') {
 135              if (styles[x] > 0.99) el.style.removeAttribute('filter');
 136              else el.style.filter = 'alpha(opacity='+ (styles[x] * 100) +')';
 137          }
 138          else el.style[x] = styles[x];        
 139      }
 140  },
 141  animate: function(el, prop, opt) {
 142      var start,
 143          end,
 144          unit;
 145      if (typeof opt != 'object' || opt === null) {
 146          var args = arguments;
 147          opt = {
 148              duration: args[2],
 149              easing: args[3],
 150              complete: args[4]
 151          };
 152      }
 153      if (typeof opt.duration != 'number') opt.duration = 250;
 154      opt.easing = Math[opt.easing] || Math.easeInQuad;
 155      opt.curAnim = hs.extend({}, prop);
 156      for (var name in prop) {
 157          var e = new hs.fx(el, opt , name );
 158          
 159          start = parseFloat(hs.css(el, name)) || 0;
 160          end = parseFloat(prop[name]);
 161          unit = name != 'opacity' ? 'px' : '';
 162          
 163          e.custom( start, end, unit );
 164      }    
 165  },
 166  css: function(el, prop) {
 167      if (el.style[prop]) {
 168          return el.style[prop];
 169      } else if (document.defaultView) {
 170          return document.defaultView.getComputedStyle(el, null).getPropertyValue(prop);
 171  
 172      } else {
 173          if (prop == 'opacity') prop = 'filter';
 174          var val = el.currentStyle[prop.replace(/\-(\w)/g, function (a, b){ return b.toUpperCase(); })];
 175          if (prop == 'filter') 
 176              val = val.replace(/alpha\(opacity=([0-9]+)\)/, 
 177                  function (a, b) { return b / 100 });
 178          return val === '' ? 1 : val;
 179      } 
 180  },
 181  
 182  getPageSize : function () {
 183      var d = document, w = window, iebody = d.compatMode && d.compatMode != 'BackCompat' 
 184          ? d.documentElement : d.body;
 185      
 186      var width = hs.ieLt9 ? iebody.clientWidth : 
 187              (d.documentElement.clientWidth || self.innerWidth),
 188          height = hs.ieLt9 ? iebody.clientHeight : self.innerHeight;
 189      
 190      hs.page = {
 191          width: width,
 192          height: height,        
 193          scrollLeft: hs.ieLt9 ? iebody.scrollLeft : pageXOffset,
 194          scrollTop: hs.ieLt9 ? iebody.scrollTop : pageYOffset
 195      };
 196      return hs.page;
 197  },
 198  
 199  getPosition : function(el)    {
 200      var p = { x: el.offsetLeft, y: el.offsetTop };
 201      while (el.offsetParent)    {
 202          el = el.offsetParent;
 203          p.x += el.offsetLeft;
 204          p.y += el.offsetTop;
 205          if (el != document.body && el != document.documentElement) {
 206              p.x -= el.scrollLeft;
 207              p.y -= el.scrollTop;
 208          }
 209      }
 210      return p;
 211  },
 212  
 213  expand : function(a, params, custom, type) {
 214      if (!a) a = hs.createElement('a', null, { display: 'none' }, hs.container);
 215      if (typeof a.getParams == 'function') return params;    
 216      try {    
 217          new hs.Expander(a, params, custom);
 218          return false;
 219      } catch (e) { return true; }
 220  },
 221  
 222  
 223  focusTopmost : function() {
 224      var topZ = 0, 
 225          topmostKey = -1,
 226          expanders = hs.expanders,
 227          exp,
 228          zIndex;
 229      for (var i = 0; i < expanders.length; i++) {
 230          exp = expanders[i];
 231          if (exp) {
 232              zIndex = exp.wrapper.style.zIndex;
 233              if (zIndex && zIndex > topZ) {
 234                  topZ = zIndex;                
 235                  topmostKey = i;
 236              }
 237          }
 238      }
 239      if (topmostKey == -1) hs.focusKey = -1;
 240      else expanders[topmostKey].focus();
 241  },
 242  
 243  getParam : function (a, param) {
 244      a.getParams = a.onclick;
 245      var p = a.getParams ? a.getParams() : null;
 246      a.getParams = null;
 247      
 248      return (p && typeof p[param] != 'undefined') ? p[param] : 
 249          (typeof hs[param] != 'undefined' ? hs[param] : null);
 250  },
 251  
 252  getSrc : function (a) {
 253      var src = hs.getParam(a, 'src');
 254      if (src) return src;
 255      return a.href;
 256  },
 257  
 258  getNode : function (id) {
 259      var node = hs.$(id), clone = hs.clones[id], a = {};
 260      if (!node && !clone) return null;
 261      if (!clone) {
 262          clone = node.cloneNode(true);
 263          clone.id = '';
 264          hs.clones[id] = clone;
 265          return node;
 266      } else {
 267          return clone.cloneNode(true);
 268      }
 269  },
 270  
 271  discardElement : function(d) {
 272      if (d) hs.garbageBin.appendChild(d);
 273      hs.garbageBin.innerHTML = '';
 274  },
 275  transit : function (adj, exp) {
 276      var last = exp || hs.getExpander();
 277      exp = last;
 278      if (hs.upcoming) return false;
 279      else hs.last = last;
 280      hs.removeEventListener(document, window.opera ? 'keypress' : 'keydown', hs.keyHandler);
 281      try {
 282          hs.upcoming = adj;
 283          adj.onclick();         
 284      } catch (e){
 285          hs.last = hs.upcoming = null;
 286      }
 287      try {
 288          exp.close();
 289      } catch (e) {}
 290      return false;
 291  },
 292  
 293  previousOrNext : function (el, op) {
 294      var exp = hs.getExpander(el);
 295      if (exp) return hs.transit(exp.getAdjacentAnchor(op), exp);
 296      else return false;
 297  },
 298  
 299  previous : function (el) {
 300      return hs.previousOrNext(el, -1);
 301  },
 302  
 303  next : function (el) {
 304      return hs.previousOrNext(el, 1);    
 305  },
 306  
 307  keyHandler : function(e) {
 308      if (!e) e = window.event;
 309      if (!e.target) e.target = e.srcElement; // ie

 310      if (typeof e.target.form != 'undefined') return true; // form element has focus

 311      var exp = hs.getExpander();
 312      
 313      var op = null;
 314      switch (e.keyCode) {
 315          case 70: // f
 316              if (exp) exp.doFullExpand();
 317              return true;
 318          case 32: // Space
 319          case 34: // Page Down
 320          case 39: // Arrow right
 321          case 40: // Arrow down
 322              op = 1;
 323              break;
 324          case 8:  // Backspace
 325          case 33: // Page Up
 326          case 37: // Arrow left
 327          case 38: // Arrow up
 328              op = -1;
 329              break;
 330          case 27: // Escape
 331          case 13: // Enter
 332              op = 0;
 333      }
 334      if (op !== null) {
 335          hs.removeEventListener(document, window.opera ? 'keypress' : 'keydown', hs.keyHandler);
 336          if (!hs.enableKeyListener) return true;
 337          
 338          if (e.preventDefault) e.preventDefault();
 339          else e.returnValue = false;
 340          if (exp) {
 341              if (op == 0) {
 342                  exp.close();
 343              } else {
 344                  hs.previousOrNext(exp.key, op);
 345              }
 346              return false;
 347          }
 348      }
 349      return true;
 350  },
 351  
 352  
 353  registerOverlay : function (overlay) {
 354      hs.push(hs.overlays, hs.extend(overlay, { hsId: 'hsId'+ hs.idCounter++ } ));
 355  },
 356  
 357  
 358  getWrapperKey : function (element, expOnly) {
 359      var el, re = /^highslide-wrapper-([0-9]+)$/;
 360      // 1. look in open expanders

 361      el = element;
 362      while (el.parentNode)    {
 363          if (el.id && re.test(el.id)) return el.id.replace(re, "$1");
 364          el = el.parentNode;
 365      }
 366      // 2. look in thumbnail

 367      if (!expOnly) {
 368          el = element;
 369          while (el.parentNode)    {
 370              if (el.tagName && hs.isHsAnchor(el)) {
 371                  for (var key = 0; key < hs.expanders.length; key++) {
 372                      var exp = hs.expanders[key];
 373                      if (exp && exp.a == el) return key;
 374                  }
 375              }
 376              el = el.parentNode;
 377          }
 378      }
 379      return null; 
 380  },
 381  
 382  getExpander : function (el, expOnly) {
 383      if (typeof el == 'undefined') return hs.expanders[hs.focusKey] || null;
 384      if (typeof el == 'number') return hs.expanders[el] || null;
 385      if (typeof el == 'string') el = hs.$(el);
 386      return hs.expanders[hs.getWrapperKey(el, expOnly)] || null;
 387  },
 388  
 389  isHsAnchor : function (a) {
 390      return (a.onclick && a.onclick.toString().replace(/\s/g, ' ').match(/hs.(htmlE|e)xpand/));
 391  },
 392  
 393  reOrder : function () {
 394      for (var i = 0; i < hs.expanders.length; i++)
 395          if (hs.expanders[i] && hs.expanders[i].isExpanded) hs.focusTopmost();
 396  },
 397  
 398  mouseClickHandler : function(e) 
 399  {    
 400      if (!e) e = window.event;
 401      if (e.button > 1) return true;
 402      if (!e.target) e.target = e.srcElement;
 403      
 404      var el = e.target;
 405      while (el.parentNode
 406          && !(/highslide-(image|move|html|resize)/.test(el.className)))
 407      {
 408          el = el.parentNode;
 409      }
 410      var exp = hs.getExpander(el);
 411      if (exp && (exp.isClosing || !exp.isExpanded)) return true;
 412          
 413      if (exp && e.type == 'mousedown') {
 414          if (e.target.form) return true;
 415          var match = el.className.match(/highslide-(image|move|resize)/);
 416          if (match) {
 417              hs.dragArgs = { 
 418                  exp: exp , 
 419                  type: match[1], 
 420                  left: exp.x.pos, 
 421                  width: exp.x.size, 
 422                  top: exp.y.pos, 
 423                  height: exp.y.size, 
 424                  clickX: e.clientX, 
 425                  clickY: e.clientY
 426              };
 427              
 428              
 429              hs.addEventListener(document, 'mousemove', hs.dragHandler);
 430              if (e.preventDefault) e.preventDefault(); // FF

 431              
 432              if (/highslide-(image|html)-blur/.test(exp.content.className)) {
 433                  exp.focus();
 434                  hs.hasFocused = true;
 435              }
 436              return false;
 437          }
 438      } else if (e.type == 'mouseup') {
 439          
 440          hs.removeEventListener(document, 'mousemove', hs.dragHandler);
 441          
 442          if (hs.dragArgs) {
 443              if (hs.styleRestoreCursor && hs.dragArgs.type == 'image') 
 444                  hs.dragArgs.exp.content.style.cursor = hs.styleRestoreCursor;
 445              var hasDragged = hs.dragArgs.hasDragged;
 446              
 447              if (!hasDragged &&!hs.hasFocused && !/(move|resize)/.test(hs.dragArgs.type)) {
 448                  exp.close();
 449              } 
 450              else if (hasDragged || (!hasDragged && hs.hasHtmlExpanders)) {
 451                  hs.dragArgs.exp.doShowHide('hidden');
 452              }
 453              hs.hasFocused = false;
 454              hs.dragArgs = null;
 455          
 456          } else if (/highslide-image-blur/.test(el.className)) {
 457              el.style.cursor = hs.styleRestoreCursor;        
 458          }
 459      }
 460      return false;
 461  },
 462  
 463  dragHandler : function(e)
 464  {
 465      if (!hs.dragArgs) return true;
 466      if (!e) e = window.event;
 467      var a = hs.dragArgs, exp = a.exp;
 468      
 469      a.dX = e.clientX - a.clickX;
 470      a.dY = e.clientY - a.clickY;    
 471      
 472      var distance = Math.sqrt(Math.pow(a.dX, 2) + Math.pow(a.dY, 2));
 473      if (!a.hasDragged) a.hasDragged = (a.type != 'image' && distance > 0)
 474          || (distance > (hs.dragSensitivity || 5));
 475      
 476      if (a.hasDragged && e.clientX > 5 && e.clientY > 5) {
 477          
 478          if (a.type == 'resize') exp.resize(a);
 479          else {
 480              exp.moveTo(a.left + a.dX, a.top + a.dY);
 481              if (a.type == 'image') exp.content.style.cursor = 'move';
 482          }
 483      }
 484      return false;
 485  },
 486  
 487  wrapperMouseHandler : function (e) {
 488      try {
 489          if (!e) e = window.event;
 490          var over = /mouseover/i.test(e.type); 
 491          if (!e.target) e.target = e.srcElement; // ie

 492          if (!e.relatedTarget) e.relatedTarget = 
 493              over ? e.fromElement : e.toElement; // ie

 494          var exp = hs.getExpander(e.target);
 495          if (!exp.isExpanded) return;
 496          if (!exp || !e.relatedTarget || hs.getExpander(e.relatedTarget, true) == exp 
 497              || hs.dragArgs) return;
 498          for (var i = 0; i < exp.overlays.length; i++) (function() {
 499              var o = hs.$('hsId'+ exp.overlays[i]);
 500              if (o && o.hideOnMouseOut) {
 501                  if (over) hs.setStyles(o, { visibility: 'visible', display: '' });
 502                  hs.animate(o, { opacity: over ? o.opacity : 0 }, o.dur);
 503              }
 504          })();    
 505      } catch (e) {}
 506  },
 507  addEventListener : function (el, event, func) {
 508      if (el == document && event == 'ready') {
 509          hs.push(hs.onReady, func);
 510      }
 511      try {
 512          el.addEventListener(event, func, false);
 513      } catch (e) {
 514          try {
 515              el.detachEvent('on'+ event, func);
 516              el.attachEvent('on'+ event, func);
 517          } catch (e) {
 518              el['on'+ event] = func;
 519          }
 520      } 
 521  },
 522  
 523  removeEventListener : function (el, event, func) {
 524      try {
 525          el.removeEventListener(event, func, false);
 526      } catch (e) {
 527          try {
 528              el.detachEvent('on'+ event, func);
 529          } catch (e) {
 530              el['on'+ event] = null;
 531          }
 532      }
 533  },
 534  
 535  preloadFullImage : function (i) {
 536      if (hs.continuePreloading && hs.preloadTheseImages[i] && hs.preloadTheseImages[i] != 'undefined') {
 537          var img = document.createElement('img');
 538          img.onload = function() { 
 539              img = null;
 540              hs.preloadFullImage(i + 1);
 541          };
 542          img.src = hs.preloadTheseImages[i];
 543      }
 544  },
 545  preloadImages : function (number) {
 546      if (number && typeof number != 'object') hs.numberOfImagesToPreload = number;
 547      
 548      var arr = hs.getAnchors();
 549      for (var i = 0; i < arr.images.length && i < hs.numberOfImagesToPreload; i++) {
 550          hs.push(hs.preloadTheseImages, hs.getSrc(arr.images[i]));
 551      }
 552      
 553      // preload outlines

 554      if (hs.outlineType)    new hs.Outline(hs.outlineType, function () { hs.preloadFullImage(0)} );
 555      else
 556      
 557      hs.preloadFullImage(0);
 558      
 559      // preload cursor

 560      if (hs.restoreCursor) var cur = hs.createElement('img', { src: hs.graphicsDir + hs.restoreCursor });
 561  },
 562  
 563  
 564  init : function () {
 565      if (!hs.container) {
 566      
 567          hs.ieLt7 = hs.ie && hs.uaVersion < 7;
 568          hs.ieLt9 = hs.ie && hs.uaVersion < 9;
 569          
 570          hs.getPageSize();
 571          for (var x in hs.langDefaults) {
 572              if (typeof hs[x] != 'undefined') hs.lang[x] = hs[x];
 573              else if (typeof hs.lang[x] == 'undefined' && typeof hs.langDefaults[x] != 'undefined') 
 574                  hs.lang[x] = hs.langDefaults[x];
 575          }
 576          
 577          hs.container = hs.createElement('div', {
 578                  className: 'highslide-container'
 579              }, {
 580                  position: 'absolute',
 581                  left: 0, 
 582                  top: 0, 
 583                  width: '100%', 
 584                  zIndex: hs.zIndexCounter,
 585                  direction: 'ltr'
 586              }, 
 587              document.body,
 588              true
 589          );
 590          hs.loading = hs.createElement('a', {
 591                  className: 'highslide-loading',
 592                  title: hs.lang.loadingTitle,
 593                  innerHTML: hs.lang.loadingText,
 594                  href: 'javascript:;'
 595              }, {
 596                  position: 'absolute',
 597                  top: '-9999px',
 598                  opacity: hs.loadingOpacity,
 599                  zIndex: 1
 600              }, hs.container
 601          );
 602          hs.garbageBin = hs.createElement('div', null, { display: 'none' }, hs.container);
 603          
 604          // http://www.robertpenner.com/easing/ 

 605          Math.linearTween = function (t, b, c, d) {
 606              return c*t/d + b;
 607          };
 608          Math.easeInQuad = function (t, b, c, d) {
 609              return c*(t/=d)*t + b;
 610          };
 611          
 612          hs.hideSelects = hs.ieLt7;
 613          hs.hideIframes = ((window.opera && hs.uaVersion < 9) || navigator.vendor == 'KDE' 
 614              || (hs.ieLt7 && hs.uaVersion < 5.5));
 615      }
 616  },
 617  ready : function() {
 618      if (hs.isReady) return;
 619      hs.isReady = true;
 620      for (var i = 0; i < hs.onReady.length; i++) hs.onReady[i]();
 621  },
 622  
 623  updateAnchors : function() {
 624      var el, els, all = [], images = [],groups = {}, re;
 625          
 626      for (var i = 0; i < hs.openerTagNames.length; i++) {
 627          els = document.getElementsByTagName(hs.openerTagNames[i]);
 628          for (var j = 0; j < els.length; j++) {
 629              el = els[j];
 630              re = hs.isHsAnchor(el);
 631              if (re) {
 632                  hs.push(all, el);
 633                  if (re[0] == 'hs.expand') hs.push(images, el);
 634                  var g = hs.getParam(el, 'slideshowGroup') || 'none';
 635                  if (!groups[g]) groups[g] = [];
 636                  hs.push(groups[g], el);
 637              }
 638          }
 639      }
 640      hs.anchors = { all: all, groups: groups, images: images };
 641      return hs.anchors;
 642      
 643  },
 644  
 645  getAnchors : function() {
 646      return hs.anchors || hs.updateAnchors();
 647  },
 648  
 649  
 650  close : function(el) {
 651      var exp = hs.getExpander(el);
 652      if (exp) exp.close();
 653      return false;
 654  }
 655  }; // end hs object
 656  hs.fx = function( elem, options, prop ){
 657      this.options = options;
 658      this.elem = elem;
 659      this.prop = prop;
 660  
 661      if (!options.orig) options.orig = {};
 662  };
 663  hs.fx.prototype = {
 664      update: function(){
 665          (hs.fx.step[this.prop] || hs.fx.step._default)(this);
 666          
 667          if (this.options.step)
 668              this.options.step.call(this.elem, this.now, this);
 669  
 670      },
 671      custom: function(from, to, unit){
 672          this.startTime = (new Date()).getTime();
 673          this.start = from;
 674          this.end = to;
 675          this.unit = unit;// || this.unit || "px";

 676          this.now = this.start;
 677          this.pos = this.state = 0;
 678  
 679          var self = this;
 680          function t(gotoEnd){
 681              return self.step(gotoEnd);
 682          }
 683  
 684          t.elem = this.elem;
 685  
 686          if ( t() && hs.timers.push(t) == 1 ) {
 687              hs.timerId = setInterval(function(){
 688                  var timers = hs.timers;
 689  
 690                  for ( var i = 0; i < timers.length; i++ )
 691                      if ( !timers[i]() )
 692                          timers.splice(i--, 1);
 693  
 694                  if ( !timers.length ) {
 695                      clearInterval(hs.timerId);
 696                  }
 697              }, 13);
 698          }
 699      },
 700      step: function(gotoEnd){
 701          var t = (new Date()).getTime();
 702          if ( gotoEnd || t >= this.options.duration + this.startTime ) {
 703              this.now = this.end;
 704              this.pos = this.state = 1;
 705              this.update();
 706  
 707              this.options.curAnim[ this.prop ] = true;
 708  
 709              var done = true;
 710              for ( var i in this.options.curAnim )
 711                  if ( this.options.curAnim[i] !== true )
 712                      done = false;
 713  
 714              if ( done ) {
 715                  if (this.options.complete) this.options.complete.call(this.elem);
 716              }
 717              return false;
 718          } else {
 719              var n = t - this.startTime;
 720              this.state = n / this.options.duration;
 721              this.pos = this.options.easing(n, 0, 1, this.options.duration);
 722              this.now = this.start + ((this.end - this.start) * this.pos);
 723              this.update();
 724          }
 725          return true;
 726      }
 727  
 728  };
 729  
 730  hs.extend( hs.fx, {
 731      step: {
 732  
 733          opacity: function(fx){
 734              hs.setStyles(fx.elem, { opacity: fx.now });
 735          },
 736  
 737          _default: function(fx){
 738              try {
 739                  if ( fx.elem.style && fx.elem.style[ fx.prop ] != null )
 740                      fx.elem.style[ fx.prop ] = fx.now + fx.unit;
 741                  else
 742                      fx.elem[ fx.prop ] = fx.now;
 743              } catch (e) {}
 744          }
 745      }
 746  });
 747  
 748  hs.Outline =  function (outlineType, onLoad) {
 749      this.onLoad = onLoad;
 750      this.outlineType = outlineType;
 751      var v = hs.uaVersion, tr;
 752      
 753      this.hasAlphaImageLoader = hs.ie && hs.uaVersion < 7;
 754      if (!outlineType) {
 755          if (onLoad) onLoad();
 756          return;
 757      }
 758      
 759      hs.init();
 760      this.table = hs.createElement(
 761          'table', { 
 762              cellSpacing: 0 
 763          }, {
 764              visibility: 'hidden',
 765              position: 'absolute',
 766              borderCollapse: 'collapse',
 767              width: 0
 768          },
 769          hs.container,
 770          true
 771      );
 772      var tbody = hs.createElement('tbody', null, null, this.table, 1);
 773      
 774      this.td = [];
 775      for (var i = 0; i <= 8; i++) {
 776          if (i % 3 == 0) tr = hs.createElement('tr', null, { height: 'auto' }, tbody, true);
 777          this.td[i] = hs.createElement('td', null, null, tr, true);
 778          var style = i != 4 ? { lineHeight: 0, fontSize: 0} : { position : 'relative' };
 779          hs.setStyles(this.td[i], style);
 780      }
 781      this.td[4].className = outlineType +' highslide-outline';
 782      
 783      this.preloadGraphic(); 
 784  };
 785  
 786  hs.Outline.prototype = {
 787  preloadGraphic : function () {
 788      var src = hs.graphicsDir + (hs.outlinesDir || "outlines/")+ this.outlineType +".png";
 789                  
 790      var appendTo = hs.safari && hs.uaVersion < 525 ? hs.container : null;
 791      this.graphic = hs.createElement('img', null, { position: 'absolute', 
 792          top: '-9999px' }, appendTo, true); // for onload trigger

 793      
 794      var pThis = this;
 795      this.graphic.onload = function() { pThis.onGraphicLoad(); };
 796      
 797      this.graphic.src = src;
 798  },
 799  
 800  onGraphicLoad : function () {
 801      var o = this.offset = this.graphic.width / 4,
 802          pos = [[0,0],[0,-4],[-2,0],[0,-8],0,[-2,-8],[0,-2],[0,-6],[-2,-2]],
 803          dim = { height: (2*o) +'px', width: (2*o) +'px' };
 804      for (var i = 0; i <= 8; i++) {
 805          if (pos[i]) {
 806              if (this.hasAlphaImageLoader) {
 807                  var w = (i == 1 || i == 7) ? '100%' : this.graphic.width +'px';
 808                  var div = hs.createElement('div', null, { width: '100%', height: '100%', position: 'relative', overflow: 'hidden'}, this.td[i], true);
 809                  hs.createElement ('div', null, { 
 810                          filter: "progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod=scale, src='"+ this.graphic.src + "')", 
 811                          position: 'absolute',
 812                          width: w, 
 813                          height: this.graphic.height +'px',
 814                          left: (pos[i][0]*o)+'px',
 815                          top: (pos[i][1]*o)+'px'
 816                      }, 
 817                  div,
 818                  true);
 819              } else {
 820                  hs.setStyles(this.td[i], { background: 'url('+ this.graphic.src +') '+ (pos[i][0]*o)+'px '+(pos[i][1]*o)+'px'});
 821              }
 822              
 823              if (window.opera && (i == 3 || i ==5)) 
 824                  hs.createElement('div', null, dim, this.td[i], true);
 825              
 826              hs.setStyles (this.td[i], dim);
 827          }
 828      }
 829      this.graphic = null;
 830      if (hs.pendingOutlines[this.outlineType]) hs.pendingOutlines[this.outlineType].destroy();
 831      hs.pendingOutlines[this.outlineType] = this;
 832      if (this.onLoad) this.onLoad();
 833  },
 834      
 835  setPosition : function (pos, offset, vis, dur, easing) {
 836      var exp = this.exp,
 837          stl = exp.wrapper.style,
 838          offset = offset || 0,
 839          pos = pos || {
 840              x: exp.x.pos + offset,
 841              y: exp.y.pos + offset,
 842              w: exp.x.get('wsize') - 2 * offset,
 843              h: exp.y.get('wsize') - 2 * offset
 844          };
 845      if (vis) this.table.style.visibility = (pos.h >= 4 * this.offset) 
 846          ? 'visible' : 'hidden';
 847      hs.setStyles(this.table, {
 848          left: (pos.x - this.offset) +'px',
 849          top: (pos.y - this.offset) +'px',
 850          width: (pos.w + 2 * this.offset) +'px'
 851      });
 852      
 853      pos.w -= 2 * this.offset;
 854      pos.h -= 2 * this.offset;
 855      hs.setStyles (this.td[4], {
 856          width: pos.w >= 0 ? pos.w +'px' : 0,
 857          height: pos.h >= 0 ? pos.h +'px' : 0
 858      });
 859      if (this.hasAlphaImageLoader) this.td[3].style.height 
 860          = this.td[5].style.height = this.td[4].style.height;    
 861      
 862  },
 863      
 864  destroy : function(hide) {
 865      if (hide) this.table.style.visibility = 'hidden';
 866      else hs.discardElement(this.table);
 867  }
 868  };
 869  
 870  hs.Dimension = function(exp, dim) {
 871      this.exp = exp;
 872      this.dim = dim;
 873      this.ucwh = dim == 'x' ? 'Width' : 'Height';
 874      this.wh = this.ucwh.toLowerCase();
 875      this.uclt = dim == 'x' ? 'Left' : 'Top';
 876      this.lt = this.uclt.toLowerCase();
 877      this.ucrb = dim == 'x' ? 'Right' : 'Bottom';
 878      this.rb = this.ucrb.toLowerCase();
 879      this.p1 = this.p2 = 0;
 880  };
 881  hs.Dimension.prototype = {
 882  get : function(key) {
 883      switch (key) {
 884          case 'loadingPos':
 885              return this.tpos + this.tb + (this.t - hs.loading['offset'+ this.ucwh]) / 2;
 886          case 'wsize':
 887              return this.size + 2 * this.cb + this.p1 + this.p2;
 888          case 'fitsize':
 889              return this.clientSize - this.marginMin - this.marginMax;
 890          case 'maxsize':
 891              return this.get('fitsize') - 2 * this.cb - this.p1 - this.p2 ;
 892          case 'opos':
 893              return this.pos - (this.exp.outline ? this.exp.outline.offset : 0);
 894          case 'osize':
 895              return this.get('wsize') + (this.exp.outline ? 2*this.exp.outline.offset : 0);
 896          case 'imgPad':
 897              return this.imgSize ? Math.round((this.size - this.imgSize) / 2) : 0;
 898          
 899      }
 900  },
 901  calcBorders: function() {
 902      // correct for borders

 903      this.cb = (this.exp.content['offset'+ this.ucwh] - this.t) / 2;
 904      
 905      this.marginMax = hs['margin'+ this.ucrb];
 906  },
 907  calcThumb: function() {
 908      this.t = this.exp.el[this.wh] ? parseInt(this.exp.el[this.wh]) : 
 909          this.exp.el['offset'+ this.ucwh];
 910      this.tpos = this.exp.tpos[this.dim];
 911      this.tb = (this.exp.el['offset'+ this.ucwh] - this.t) / 2;
 912      if (this.tpos == 0 || this.tpos == -1) {
 913          this.tpos = (hs.page[this.wh] / 2) + hs.page['scroll'+ this.uclt];        
 914      };
 915  },
 916  calcExpanded: function() {
 917      var exp = this.exp;
 918      this.justify = 'auto';
 919      
 920      
 921      // size and position

 922      this.pos = this.tpos - this.cb + this.tb;
 923      
 924      if (this.maxHeight && this.dim == 'x')
 925          exp.maxWidth = Math.min(exp.maxWidth || this.full, exp.maxHeight * this.full / exp.y.full); 
 926          
 927      this.size = Math.min(this.full, exp['max'+ this.ucwh] || this.full);
 928      this.minSize = exp.allowSizeReduction ? 
 929          Math.min(exp['min'+ this.ucwh], this.full) :this.full;
 930      if (exp.isImage && exp.useBox)    {
 931          this.size = exp[this.wh];
 932          this.imgSize = this.full;
 933      }
 934      if (this.dim == 'x' && hs.padToMinWidth) this.minSize = exp.minWidth;
 935      this.marginMin = hs['margin'+ this.uclt];
 936      this.scroll = hs.page['scroll'+ this.uclt];
 937      this.clientSize = hs.page[this.wh];
 938  },
 939  setSize: function(i) {
 940      var exp = this.exp;
 941      if (exp.isImage && (exp.useBox || hs.padToMinWidth)) {
 942          this.imgSize = i;
 943          this.size = Math.max(this.size, this.imgSize);
 944          exp.content.style[this.lt] = this.get('imgPad')+'px';
 945      } else
 946      this.size = i;
 947      
 948      exp.content.style[this.wh] = i +'px';
 949      exp.wrapper.style[this.wh] = this.get('wsize') +'px';
 950      if (exp.outline) exp.outline.setPosition();
 951      if (this.dim == 'x' && exp.overlayBox) exp.sizeOverlayBox(true);
 952  },
 953  setPos: function(i) {
 954      this.pos = i;
 955      this.exp.wrapper.style[this.lt] = i +'px';    
 956      
 957      if (this.exp.outline) this.exp.outline.setPosition();
 958      
 959  }
 960  };
 961  
 962  hs.Expander = function(a, params, custom, contentType) {
 963      if (document.readyState && hs.ie && !hs.isReady) {
 964          hs.addEventListener(document, 'ready', function() {
 965              new hs.Expander(a, params, custom, contentType);
 966          });
 967          return;
 968      } 
 969      this.a = a;
 970      this.custom = custom;
 971      this.contentType = contentType || 'image';
 972      this.isImage = !this.isHtml;
 973      
 974      hs.continuePreloading = false;
 975      this.overlays = [];
 976      hs.init();
 977      var key = this.key = hs.expanders.length;
 978      // override inline parameters

 979      for (var i = 0; i < hs.overrides.length; i++) {
 980          var name = hs.overrides[i];
 981          this[name] = params && typeof params[name] != 'undefined' ?
 982              params[name] : hs[name];
 983      }
 984      if (!this.src) this.src = a.href;
 985      
 986      // get thumb

 987      var el = (params && params.thumbnailId) ? hs.$(params.thumbnailId) : a;
 988      el = this.thumb = el.getElementsByTagName('img')[0] || el;
 989      this.thumbsUserSetId = el.id || a.id;
 990      
 991      // check if already open

 992      for (var i = 0; i < hs.expanders.length; i++) {
 993          if (hs.expanders[i] && hs.expanders[i].a == a) {
 994              hs.expanders[i].focus();
 995              return false;
 996          }
 997      }    
 998  
 999      // cancel other

1000      if (!hs.allowSimultaneousLoading) for (var i = 0; i < hs.expanders.length; i++) {
1001          if (hs.expanders[i] && hs.expanders[i].thumb != el && !hs.expanders[i].onLoadStarted) {
1002              hs.expanders[i].cancelLoading();
1003          }
1004      }
1005      hs.expanders[key] = this;
1006      if (!hs.allowMultipleInstances && !hs.upcoming) {
1007          if (hs.expanders[key-1]) hs.expanders[key-1].close();
1008          if (typeof hs.focusKey != 'undefined' && hs.expanders[hs.focusKey])
1009              hs.expanders[hs.focusKey].close();
1010      }
1011      
1012      // initiate metrics

1013      this.el = el;
1014      this.tpos = this.pageOrigin || hs.getPosition(el);
1015      hs.getPageSize();
1016      var x = this.x = new hs.Dimension(this, 'x');
1017      x.calcThumb();
1018      var y = this.y = new hs.Dimension(this, 'y');
1019      y.calcThumb();
1020      this.wrapper = hs.createElement(
1021          'div', {
1022              id: 'highslide-wrapper-'+ this.key,
1023              className: 'highslide-wrapper '+ this.wrapperClassName
1024          }, {
1025              visibility: 'hidden',
1026              position: 'absolute',
1027              zIndex: hs.zIndexCounter += 2
1028          }, null, true );
1029      
1030      this.wrapper.onmouseover = this.wrapper.onmouseout = hs.wrapperMouseHandler;
1031      if (this.contentType == 'image' && this.outlineWhileAnimating == 2)
1032          this.outlineWhileAnimating = 0;
1033      
1034      // get the outline

1035      if (!this.outlineType) {
1036          this[this.contentType +'Create']();
1037      
1038      } else if (hs.pendingOutlines[this.outlineType]) {
1039          this.connectOutline();
1040          this[this.contentType +'Create']();
1041      
1042      } else {
1043          this.showLoading();
1044          var exp = this;
1045          new hs.Outline(this.outlineType, 
1046              function () {
1047                  exp.connectOutline();
1048                  exp[exp.contentType +'Create']();
1049              } 
1050          );
1051      }
1052      return true;
1053  };
1054  
1055  hs.Expander.prototype = {
1056  error : function(e) {
1057      if (hs.debug) alert ('Line '+ e.lineNumber +': '+ e.message);
1058      else window.location.href = this.src;
1059  },
1060  
1061  connectOutline : function() {
1062      var outline = this.outline = hs.pendingOutlines[this.outlineType];
1063      outline.exp = this;
1064      outline.table.style.zIndex = this.wrapper.style.zIndex - 1;
1065      hs.pendingOutlines[this.outlineType] = null;
1066  },
1067  
1068  showLoading : function() {
1069      if (this.onLoadStarted || this.loading) return;
1070      
1071      this.loading = hs.loading;
1072      var exp = this;
1073      this.loading.onclick = function() {
1074          exp.cancelLoading();
1075      };
1076      var exp = this, 
1077          l = this.x.get('loadingPos') +'px',
1078          t = this.y.get('loadingPos') +'px';
1079      setTimeout(function () { 
1080          if (exp.loading) hs.setStyles(exp.loading, { left: l, top: t, zIndex: hs.zIndexCounter++ })}
1081      , 100);
1082  },
1083  
1084  imageCreate : function() {
1085      var exp = this;
1086      
1087      var img = document.createElement('img');
1088      this.content = img;
1089      img.onload = function () {
1090          if (hs.expanders[exp.key]) exp.contentLoaded(); 
1091      };
1092      if (hs.blockRightClick) img.oncontextmenu = function() { return false; };
1093      img.className = 'highslide-image';
1094      hs.setStyles(img, {
1095          visibility: 'hidden',
1096          display: 'block',
1097          position: 'absolute',
1098          maxWidth: '9999px',
1099          zIndex: 3
1100      });
1101      img.title = hs.lang.restoreTitle;
1102      if (hs.safari && hs.uaVersion < 525) hs.container.appendChild(img);
1103      if (hs.ie && hs.flushImgSize) img.src = null;
1104      img.src = this.src;
1105      
1106      this.showLoading();
1107  },
1108  
1109  contentLoaded : function() {
1110      try {    
1111          if (!this.content) return;
1112          this.content.onload = null;
1113          if (this.onLoadStarted) return;
1114          else this.onLoadStarted = true;
1115          
1116          var x = this.x, y = this.y;
1117          
1118          if (this.loading) {
1119              hs.setStyles(this.loading, { top: '-9999px' });
1120              this.loading = null;
1121          }    
1122              x.full = this.content.width;
1123              y.full = this.content.height;
1124              
1125              hs.setStyles(this.content, {
1126                  width: x.t +'px',
1127                  height: y.t +'px'
1128              });
1129              this.wrapper.appendChild(this.content);
1130              hs.container.appendChild(this.wrapper);
1131          
1132          x.calcBorders();
1133          y.calcBorders();
1134          
1135          hs.setStyles (this.wrapper, {
1136              left: (x.tpos + x.tb - x.cb) +'px',
1137              top: (y.tpos + x.tb - y.cb) +'px'
1138          });
1139          this.getOverlays();
1140          
1141          var ratio = x.full / y.full;
1142          x.calcExpanded();
1143          this.justify(x);
1144          
1145          y.calcExpanded();
1146          this.justify(y);
1147          if (this.overlayBox) this.sizeOverlayBox(0, 1);
1148  
1149          
1150          if (this.allowSizeReduction) {
1151                  this.correctRatio(ratio);
1152              if (this.isImage && this.x.full > (this.x.imgSize || this.x.size)) {
1153                  this.createFullExpand();
1154                  if (this.overlays.length == 1) this.sizeOverlayBox();
1155              }
1156          }
1157          this.show();
1158          
1159      } catch (e) {
1160          this.error(e);
1161      }
1162  },
1163  
1164  justify : function (p, moveOnly) {
1165      var tgtArr, tgt = p.target, dim = p == this.x ? 'x' : 'y';
1166      
1167          var hasMovedMin = false;
1168          
1169          var allowReduce = p.exp.allowSizeReduction;
1170              p.pos = Math.round(p.pos - ((p.get('wsize') - p.t) / 2));
1171          if (p.pos < p.scroll + p.marginMin) {
1172              p.pos = p.scroll + p.marginMin;
1173              hasMovedMin = true;        
1174          }
1175          if (!moveOnly && p.size < p.minSize) {
1176              p.size = p.minSize;
1177              allowReduce = false;
1178          }
1179          if (p.pos + p.get('wsize') > p.scroll + p.clientSize - p.marginMax) {
1180              if (!moveOnly && hasMovedMin && allowReduce) {
1181                  p.size = Math.min(p.size, p.get(dim == 'y' ? 'fitsize' : 'maxsize'));
1182              } else if (p.get('wsize') < p.get('fitsize')) {
1183                  p.pos = p.scroll + p.clientSize - p.marginMax - p.get('wsize');
1184              } else { // image larger than viewport
1185                  p.pos = p.scroll + p.marginMin;
1186                  if (!moveOnly && allowReduce) p.size = p.get(dim == 'y' ? 'fitsize' : 'maxsize');
1187              }            
1188          }
1189          
1190          if (!moveOnly && p.size < p.minSize) {
1191              p.size = p.minSize;
1192              allowReduce = false;
1193          }
1194          
1195      
1196          
1197      if (p.pos < p.marginMin) {
1198          var tmpMin = p.pos;
1199          p.pos = p.marginMin; 
1200          
1201          if (allowReduce && !moveOnly) p.size = p.size - (p.pos - tmpMin);
1202          
1203      }
1204  },
1205  
1206  correctRatio : function(ratio) {
1207      var x = this.x, 
1208          y = this.y,
1209          changed = false,
1210          xSize = Math.min(x.full, x.size),
1211          ySize = Math.min(y.full, y.size),
1212          useBox = (this.useBox || hs.padToMinWidth);
1213      
1214      if (xSize / ySize > ratio) { // width greater
1215          xSize = ySize * ratio;
1216          if (xSize < x.minSize) { // below minWidth
1217              xSize = x.minSize;
1218              ySize = xSize / ratio;
1219          }
1220          changed = true;
1221      
1222      } else if (xSize / ySize < ratio) { // height greater
1223          ySize = xSize / ratio;
1224          changed = true;
1225      }
1226      
1227      if (hs.padToMinWidth && x.full < x.minSize) {
1228          x.imgSize = x.full;
1229          y.size = y.imgSize = y.full;
1230      } else if (this.useBox) {
1231          x.imgSize = xSize;
1232          y.imgSize = ySize;
1233      } else {
1234          x.size = xSize;
1235          y.size = ySize;
1236      }
1237      changed = this.fitOverlayBox(this.useBox ? null : ratio, changed);
1238      if (useBox && y.size < y.imgSize) {
1239          y.imgSize = y.size;
1240          x.imgSize = y.size * ratio;
1241      }
1242      if (changed || useBox) {
1243          x.pos = x.tpos - x.cb + x.tb;
1244          x.minSize = x.size;
1245          this.justify(x, true);
1246      
1247          y.pos = y.tpos - y.cb + y.tb;
1248          y.minSize = y.size;
1249          this.justify(y, true);
1250          if (this.overlayBox) this.sizeOverlayBox();
1251      }
1252      
1253      
1254  },
1255  fitOverlayBox : function(ratio, changed) {
1256      var x = this.x, y = this.y;
1257      if (this.overlayBox) {
1258          while (y.size > this.minHeight && x.size > this.minWidth 
1259                  &&  y.get('wsize') > y.get('fitsize')) {
1260              y.size -= 10;
1261              if (ratio) x.size = y.size * ratio;
1262              this.sizeOverlayBox(0, 1);
1263              changed = true;
1264          }
1265      }
1266      return changed;
1267  },
1268  
1269  show : function () {
1270      var x = this.x, y = this.y;
1271      this.doShowHide('hidden');
1272      
1273      // Apply size change

1274      this.changeSize(
1275          1, {
1276              wrapper: {
1277                  width : x.get('wsize'),
1278                  height : y.get('wsize'),
1279                  left: x.pos,
1280                  top: y.pos
1281              },
1282              content: {
1283                  left: x.p1 + x.get('imgPad'),
1284                  top: y.p1 + y.get('imgPad'),
1285                  width:x.imgSize ||x.size,
1286                  height:y.imgSize ||y.size
1287              }
1288          },
1289          hs.expandDuration
1290      );
1291  },
1292  
1293  changeSize : function(up, to, dur) {
1294      
1295      if (this.outline && !this.outlineWhileAnimating) {
1296          if (up) this.outline.setPosition();
1297          else this.outline.destroy();
1298      }
1299      
1300      
1301      if (!up) this.destroyOverlays();
1302      
1303      var exp = this,
1304          x = exp.x,
1305          y = exp.y,
1306          easing = this.easing;
1307      if (!up) easing = this.easingClose || easing;
1308      var after = up ?
1309          function() {
1310                  
1311              if (exp.outline) exp.outline.table.style.visibility = "visible";
1312              setTimeout(function() {
1313                  exp.afterExpand();
1314              }, 50);
1315          } :
1316          function() {
1317              exp.afterClose();
1318          };
1319      if (up) hs.setStyles( this.wrapper, {
1320          width: x.t +'px',
1321          height: y.t +'px'
1322      });
1323      if (this.fadeInOut) {
1324          hs.setStyles(this.wrapper, { opacity: up ? 0 : 1 });
1325          hs.extend(to.wrapper, { opacity: up });
1326      }
1327      hs.animate( this.wrapper, to.wrapper, {
1328          duration: dur,
1329          easing: easing,
1330          step: function(val, args) {
1331              if (exp.outline && exp.outlineWhileAnimating && args.prop == 'top') {
1332                  var fac = up ? args.pos : 1 - args.pos;
1333                  var pos = {
1334                      w: x.t + (x.get('wsize') - x.t) * fac,
1335                      h: y.t + (y.get('wsize') - y.t) * fac,
1336                      x: x.tpos + (x.pos - x.tpos) * fac,
1337                      y: y.tpos + (y.pos - y.tpos) * fac
1338                  };
1339                  exp.outline.setPosition(pos, 0, 1);                
1340              }
1341          }
1342      });
1343      hs.animate( this.content, to.content, dur, easing, after);
1344      if (up) {
1345          this.wrapper.style.visibility = 'visible';
1346          this.content.style.visibility = 'visible';
1347          this.a.className += ' highslide-active-anchor';
1348      }
1349  },
1350  
1351  
1352  
1353  
1354  afterExpand : function() {
1355      this.isExpanded = true;    
1356      this.focus();
1357      if (hs.upcoming && hs.upcoming == this.a) hs.upcoming = null;
1358      this.prepareNextOutline();
1359      var p = hs.page, mX = hs.mouse.x + p.scrollLeft, mY = hs.mouse.y + p.scrollTop;
1360      this.mouseIsOver = this.x.pos < mX && mX < this.x.pos + this.x.get('wsize')
1361          && this.y.pos < mY && mY < this.y.pos + this.y.get('wsize');    
1362      if (this.overlayBox) this.showOverlays();
1363      
1364  },
1365  
1366  
1367  prepareNextOutline : function() {
1368      var key = this.key;
1369      var outlineType = this.outlineType;
1370      new hs.Outline(outlineType, 
1371          function () { try { hs.expanders[key].preloadNext(); } catch (e) {} });
1372  },
1373  
1374  
1375  preloadNext : function() {
1376      var next = this.getAdjacentAnchor(1);
1377      if (next && next.onclick.toString().match(/hs\.expand/)) 
1378          var img = hs.createElement('img', { src: hs.getSrc(next) });
1379  },
1380  
1381  
1382  getAdjacentAnchor : function(op) {
1383      var current = this.getAnchorIndex(), as = hs.anchors.groups[this.slideshowGroup || 'none'];
1384      return (as && as[current + op]) || null;
1385  },
1386  
1387  getAnchorIndex : function() {
1388      var arr = hs.getAnchors().groups[this.slideshowGroup || 'none'];
1389      if (arr) for (var i = 0; i < arr.length; i++) {
1390          if (arr[i] == this.a) return i; 
1391      }
1392      return null;
1393  },
1394  
1395  
1396  cancelLoading : function() {
1397      hs.discardElement (this.wrapper);
1398      hs.expanders[this.key] = null;
1399      if (this.loading) hs.loading.style.left = '-9999px';
1400  },
1401  
1402  writeCredits : function () {
1403      this.credits = hs.createElement('a', {
1404          href: hs.creditsHref,
1405          target: hs.creditsTarget,
1406          className: 'highslide-credits',
1407          innerHTML: hs.lang.creditsText,
1408          title: hs.lang.creditsTitle
1409      });
1410      this.createOverlay({ 
1411          overlayId: this.credits, 
1412          position: this.creditsPosition || 'top left' 
1413      });
1414  },
1415  
1416  getInline : function(types, addOverlay) {
1417      for (var i = 0; i < types.length; i++) {
1418          var type = types[i], s = null;
1419          if (!this[type +'Id'] && this.thumbsUserSetId)  
1420              this[type +'Id'] = type +'-for-'+ this.thumbsUserSetId;
1421          if (this[type +'Id']) this[type] = hs.getNode(this[type +'Id']);
1422          if (!this[type] && !this[type +'Text'] && this[type +'Eval']) try {
1423              s = eval(this[type +'Eval']);
1424          } catch (e) {}
1425          if (!this[type] && this[type +'Text']) {
1426              s = this[type +'Text'];
1427          }
1428          if (!this[type] && !s) {
1429              this[type] = hs.getNode(this.a['_'+ type + 'Id']);
1430              if (!this[type]) {
1431                  var next = this.a.nextSibling;
1432                  while (next && !hs.isHsAnchor(next)) {
1433                      if ((new RegExp('highslide-'+ type)).test(next.className || null)) {
1434                          if (!next.id) this.a['_'+ type + 'Id'] = next.id = 'hsId'+ hs.idCounter++;
1435                          this[type] = hs.getNode(next.id);
1436                          break;
1437                      }
1438                      next = next.nextSibling;
1439                  }
1440              }
1441          }
1442          
1443          if (!this[type] && s) this[type] = hs.createElement('div', 
1444                  { className: 'highslide-'+ type, innerHTML: s } );
1445          
1446          if (addOverlay && this[type]) {
1447              var o = { position: (type == 'heading') ? 'above' : 'below' };
1448              for (var x in this[type+'Overlay']) o[x] = this[type+'Overlay'][x];
1449              o.overlayId = this[type];
1450              this.createOverlay(o);
1451          }
1452      }
1453  },
1454  
1455  
1456  // on end move and resize

1457  doShowHide : function(visibility) {
1458      if (hs.hideSelects) this.showHideElements('SELECT', visibility);
1459      if (hs.hideIframes) this.showHideElements('IFRAME', visibility);
1460      if (hs.geckoMac) this.showHideElements('*', visibility);
1461  },
1462  showHideElements : function (tagName, visibility) {
1463      var els = document.getElementsByTagName(tagName);
1464      var prop = tagName == '*' ? 'overflow' : 'visibility';
1465      for (var i = 0; i < els.length; i++) {
1466          if (prop == 'visibility' || (document.defaultView.getComputedStyle(
1467                  els[i], "").getPropertyValue('overflow') == 'auto'
1468                  || els[i].getAttribute('hidden-by') != null)) {
1469              var hiddenBy = els[i].getAttribute('hidden-by');
1470              if (visibility == 'visible' && hiddenBy) {
1471                  hiddenBy = hiddenBy.replace('['+ this.key +']', '');
1472                  els[i].setAttribute('hidden-by', hiddenBy);
1473                  if (!hiddenBy) els[i].style[prop] = els[i].origProp;
1474              } else if (visibility == 'hidden') { // hide if behind
1475                  var elPos = hs.getPosition(els[i]);
1476                  elPos.w = els[i].offsetWidth;
1477                  elPos.h = els[i].offsetHeight;
1478              
1479                  
1480                      var clearsX = (elPos.x + elPos.w < this.x.get('opos') 
1481                          || elPos.x > this.x.get('opos') + this.x.get('osize'));
1482                      var clearsY = (elPos.y + elPos.h < this.y.get('opos') 
1483                          || elPos.y > this.y.get('opos') + this.y.get('osize'));
1484                  var wrapperKey = hs.getWrapperKey(els[i]);
1485                  if (!clearsX && !clearsY && wrapperKey != this.key) { // element falls behind image
1486                      if (!hiddenBy) {
1487                          els[i].setAttribute('hidden-by', '['+ this.key +']');
1488                          els[i].origProp = els[i].style[prop];
1489                          els[i].style[prop] = 'hidden';
1490                          
1491                      } else if (hiddenBy.indexOf('['+ this.key +']') == -1) {
1492                          els[i].setAttribute('hidden-by', hiddenBy + '['+ this.key +']');
1493                      }
1494                  } else if ((hiddenBy == '['+ this.key +']' || hs.focusKey == wrapperKey)
1495                          && wrapperKey != this.key) { // on move
1496                      els[i].setAttribute('hidden-by', '');
1497                      els[i].style[prop] = els[i].origProp || '';
1498                  } else if (hiddenBy && hiddenBy.indexOf('['+ this.key +']') > -1) {
1499                      els[i].setAttribute('hidden-by', hiddenBy.replace('['+ this.key +']', ''));
1500                  }
1501                          
1502              }
1503          }
1504      }
1505  },
1506  
1507  focus : function() {
1508      this.wrapper.style.zIndex = hs.zIndexCounter += 2;
1509      // blur others

1510      for (var i = 0; i < hs.expanders.length; i++) {
1511          if (hs.expanders[i] && i == hs.focusKey) {
1512              var blurExp = hs.expanders[i];
1513              blurExp.content.className += ' highslide-'+ blurExp.contentType +'-blur';
1514                  blurExp.content.style.cursor = hs.ieLt7 ? 'hand' : 'pointer';
1515                  blurExp.content.title = hs.lang.focusTitle;
1516          }
1517      }
1518      
1519      // focus this

1520      if (this.outline) this.outline.table.style.zIndex 
1521          = this.wrapper.style.zIndex - 1;
1522      this.content.className = 'highslide-'+ this.contentType;
1523          this.content.title = hs.lang.restoreTitle;
1524          
1525          if (hs.restoreCursor) {
1526              hs.styleRestoreCursor = window.opera ? 'pointer' : 'url('+ hs.graphicsDir + hs.restoreCursor +'), pointer';
1527              if (hs.ieLt7 && hs.uaVersion < 6) hs.styleRestoreCursor = 'hand';
1528              this.content.style.cursor = hs.styleRestoreCursor;
1529          }
1530          
1531      hs.focusKey = this.key;    
1532      hs.addEventListener(document, window.opera ? 'keypress' : 'keydown', hs.keyHandler);    
1533  },
1534  moveTo: function(x, y) {
1535      this.x.setPos(x);
1536      this.y.setPos(y);
1537  },
1538  resize : function (e) {
1539      var w, h, r = e.width / e.height;
1540      w = Math.max(e.width + e.dX, Math.min(this.minWidth, this.x.full));
1541      if (this.isImage && Math.abs(w - this.x.full) < 12) w = this.x.full;
1542      h = w / r;
1543      if (h < Math.min(this.minHeight, this.y.full)) {
1544          h = Math.min(this.minHeight, this.y.full);
1545          if (this.isImage) w = h * r;
1546      }
1547      this.resizeTo(w, h);
1548  },
1549  resizeTo: function(w, h) {
1550      this.y.setSize(h);
1551      this.x.setSize(w);
1552      this.wrapper.style.height = this.y.get('wsize') +'px';
1553  },
1554  
1555  close : function() {
1556      if (this.isClosing || !this.isExpanded) return;
1557      this.isClosing = true;
1558      
1559      hs.removeEventListener(document, window.opera ? 'keypress' : 'keydown', hs.keyHandler);
1560      
1561      try {
1562          this.content.style.cursor = 'default';
1563          this.changeSize(
1564              0, {
1565                  wrapper: {
1566                      width : this.x.t,
1567                      height : this.y.t,
1568                      left: this.x.tpos - this.x.cb + this.x.tb,
1569                      top: this.y.tpos - this.y.cb + this.y.tb
1570                  },
1571                  content: {
1572                      left: 0,
1573                      top: 0,
1574                      width: this.x.t,
1575                      height: this.y.t
1576                  }
1577              }, hs.restoreDuration
1578          );
1579      } catch (e) { this.afterClose(); }
1580  },
1581  
1582  createOverlay : function (o) {
1583      var el = o.overlayId;
1584      if (typeof el == 'string') el = hs.getNode(el);
1585      if (o.html) el = hs.createElement('div', { innerHTML: o.html });
1586      if (!el || typeof el == 'string') return;
1587      el.style.display = 'block';
1588      this.genOverlayBox();
1589      var width = o.width && /^[0-9]+(px|%)$/.test(o.width) ? o.width : 'auto';
1590      if (/^(left|right)panel$/.test(o.position) && !/^[0-9]+px$/.test(o.width)) width = '200px';
1591      var overlay = hs.createElement(
1592          'div', {
1593              id: 'hsId'+ hs.idCounter++,
1594              hsId: o.hsId
1595          }, {
1596              position: 'absolute',
1597              visibility: 'hidden',
1598              width: width,
1599              direction: hs.lang.cssDirection || '',
1600              opacity: 0
1601          },this.overlayBox,
1602          true
1603      );
1604      
1605      overlay.appendChild(el);
1606      hs.extend(overlay, {
1607          opacity: 1,
1608          offsetX: 0,
1609          offsetY: 0,
1610          dur: (o.fade === 0 || o.fade === false || (o.fade == 2 && hs.ie)) ? 0 : 250
1611      });
1612      hs.extend(overlay, o);
1613      
1614          
1615      if (this.gotOverlays) {
1616          this.positionOverlay(overlay);
1617          if (!overlay.hideOnMouseOut || this.mouseIsOver) 
1618              hs.animate(overlay, { opacity: overlay.opacity }, overlay.dur);
1619      }
1620      hs.push(this.overlays, hs.idCounter - 1);
1621  },
1622  positionOverlay : function(overlay) {
1623      var p = overlay.position || 'middle center',
1624          offX = overlay.offsetX,
1625          offY = overlay.offsetY;
1626      if (overlay.parentNode != this.overlayBox) this.overlayBox.appendChild(overlay);
1627      if (/left$/.test(p)) overlay.style.left = offX +'px'; 
1628      
1629      if (/center$/.test(p))    hs.setStyles (overlay, { 
1630          left: '50%',
1631          marginLeft: (offX - Math.round(overlay.offsetWidth / 2)) +'px'
1632      });    
1633      
1634      if (/right$/.test(p)) overlay.style.right = - offX +'px';
1635          
1636      if (/^leftpanel$/.test(p)) { 
1637          hs.setStyles(overlay, {
1638              right: '100%',
1639              marginRight: this.x.cb +'px',
1640              top: - this.y.cb +'px',
1641              bottom: - this.y.cb +'px',
1642              overflow: 'auto'
1643          });         
1644          this.x.p1 = overlay.offsetWidth;
1645      
1646      } else if (/^rightpanel$/.test(p)) {
1647          hs.setStyles(overlay, {
1648              left: '100%',
1649              marginLeft: this.x.cb +'px',
1650              top: - this.y.cb +'px',
1651              bottom: - this.y.cb +'px',
1652              overflow: 'auto'
1653          });
1654          this.x.p2 = overlay.offsetWidth;
1655      }
1656  
1657      if (/^top/.test(p)) overlay.style.top = offY +'px'; 
1658      if (/^middle/.test(p))    hs.setStyles (overlay, { 
1659          top: '50%', 
1660          marginTop: (offY - Math.round(overlay.offsetHeight / 2)) +'px'
1661      });    
1662      if (/^bottom/.test(p)) overlay.style.bottom = - offY +'px';
1663      if (/^above$/.test(p)) {
1664          hs.setStyles(overlay, {
1665              left: (- this.x.p1 - this.x.cb) +'px',
1666              right: (- this.x.p2 - this.x.cb) +'px',
1667              bottom: '100%',
1668              marginBottom: this.y.cb +'px',
1669              width: 'auto'
1670          });
1671          this.y.p1 = overlay.offsetHeight;
1672      
1673      } else if (/^below$/.test(p)) {
1674          hs.setStyles(overlay, {
1675              position: 'relative',
1676              left: (- this.x.p1 - this.x.cb) +'px',
1677              right: (- this.x.p2 - this.x.cb) +'px',
1678              top: '100%',
1679              marginTop: this.y.cb +'px',
1680              width: 'auto'
1681          });
1682          this.y.p2 = overlay.offsetHeight;
1683          overlay.style.position = 'absolute';
1684      }
1685  },
1686  
1687  getOverlays : function() {    
1688      this.getInline(['heading', 'caption'], true);
1689      if (this.heading && this.dragByHeading) this.heading.className += ' highslide-move';
1690      if (hs.showCredits) this.writeCredits();
1691      for (var i = 0; i < hs.overlays.length; i++) {
1692          var o = hs.overlays[i], tId = o.thumbnailId, sg = o.slideshowGroup;
1693          if ((!tId && !sg) || (tId && tId == this.thumbsUserSetId)
1694                  || (sg && sg === this.slideshowGroup)) {
1695              this.createOverlay(o);
1696          }
1697      }
1698      var os = [];
1699      for (var i = 0; i < this.overlays.length; i++) {
1700          var o = hs.$('hsId'+ this.overlays[i]);
1701          if (/panel$/.test(o.position)) this.positionOverlay(o);
1702          else hs.push(os, o);
1703      }
1704      for (var i = 0; i < os.length; i++) this.positionOverlay(os[i]);
1705      this.gotOverlays = true;
1706  },
1707  genOverlayBox : function() {
1708      if (!this.overlayBox) this.overlayBox = hs.createElement (
1709          'div', {
1710              className: this.wrapperClassName
1711          }, {
1712              position : 'absolute',
1713              width: (this.x.size || (this.useBox ? this.width : null) 
1714                  || this.x.full) +'px',
1715              height: (this.y.size || this.y.full) +'px',
1716              visibility : 'hidden',
1717              overflow : 'hidden',
1718              zIndex : hs.ie ? 4 : 'auto'
1719          },
1720          hs.container,
1721          true
1722      );
1723  },
1724  sizeOverlayBox : function(doWrapper, doPanels) {
1725      var overlayBox = this.overlayBox, 
1726          x = this.x,
1727          y = this.y;
1728      hs.setStyles( overlayBox, {
1729          width: x.size +'px', 
1730          height: y.size +'px'
1731      });
1732      if (doWrapper || doPanels) {
1733          for (var i = 0; i < this.overlays.length; i++) {
1734              var o = hs.$('hsId'+ this.overlays[i]);
1735              var ie6 = (hs.ieLt7 || document.compatMode == 'BackCompat');
1736              if (o && /^(above|below)$/.test(o.position)) {
1737                  if (ie6) {
1738                      o.style.width = (overlayBox.offsetWidth + 2 * x.cb
1739                          + x.p1 + x.p2) +'px';
1740                  }
1741                  y[o.position == 'above' ? 'p1' : 'p2'] = o.offsetHeight;
1742              }
1743              if (o && ie6 && /^(left|right)panel$/.test(o.position)) {
1744                  o.style.height = (overlayBox.offsetHeight + 2* y.cb) +'px';
1745              }
1746          }
1747      }
1748      if (doWrapper) {
1749          hs.setStyles(this.content, {
1750              top: y.p1 +'px'
1751          });
1752          hs.setStyles(overlayBox, {
1753              top: (y.p1 + y.cb) +'px'
1754          });
1755      }
1756  },
1757  
1758  showOverlays : function() {
1759      var b = this.overlayBox;
1760      b.className = '';
1761      hs.setStyles(b, {
1762          top: (this.y.p1 + this.y.cb) +'px',
1763          left: (this.x.p1 + this.x.cb) +'px',
1764          overflow : 'visible'
1765      });
1766      if (hs.safari) b.style.visibility = 'visible';
1767      this.wrapper.appendChild (b);
1768      for (var i = 0; i < this.overlays.length; i++) {
1769          var o = hs.$('hsId'+ this.overlays[i]);
1770          o.style.zIndex = o.zIndex || 4;
1771          if (!o.hideOnMouseOut || this.mouseIsOver) {
1772              o.style.visibility = 'visible';
1773              hs.setStyles(o, { visibility: 'visible', display: '' });
1774              hs.animate(o, { opacity: o.opacity }, o.dur);
1775          }
1776      }
1777  },
1778  
1779  destroyOverlays : function() {
1780      if (!this.overlays.length) return;
1781      hs.discardElement(this.overlayBox);
1782  },
1783  
1784  
1785  
1786  createFullExpand : function () {
1787      this.fullExpandLabel = hs.createElement(
1788          'a', {
1789              href: 'javascript:hs.expanders['+ this.key +'].doFullExpand();',
1790              title: hs.lang.fullExpandTitle,
1791              className: 'highslide-full-expand'
1792          }
1793      );
1794      
1795      this.createOverlay({ 
1796          overlayId: this.fullExpandLabel, 
1797          position: hs.fullExpandPosition, 
1798          hideOnMouseOut: true, 
1799          opacity: hs.fullExpandOpacity
1800      });
1801  },
1802  
1803  doFullExpand : function () {
1804      try {
1805          if (this.fullExpandLabel) hs.discardElement(this.fullExpandLabel);
1806          
1807          this.focus();
1808          var xSize = this.x.size;
1809          this.resizeTo(this.x.full, this.y.full);
1810          
1811          var xpos = this.x.pos - (this.x.size - xSize) / 2;
1812          if (xpos < hs.marginLeft) xpos = hs.marginLeft;
1813          
1814          this.moveTo(xpos, this.y.pos);
1815          this.doShowHide('hidden');
1816      
1817      } catch (e) {
1818          this.error(e);
1819      }
1820  },
1821  
1822  
1823  afterClose : function () {
1824      this.a.className = this.a.className.replace('highslide-active-anchor', '');
1825      
1826      this.doShowHide('visible');
1827          if (this.outline && this.outlineWhileAnimating) this.outline.destroy();
1828      
1829          hs.discardElement(this.wrapper);
1830      
1831      hs.expanders[this.key] = null;        
1832      hs.reOrder();
1833  }
1834  
1835  };
1836  hs.langDefaults = hs.lang;
1837  // history

1838  var HsExpander = hs.Expander;
1839  if (hs.ie && window == window.top) {
1840      (function () {
1841          try {
1842              document.documentElement.doScroll('left');
1843          } catch (e) {
1844              setTimeout(arguments.callee, 50);
1845              return;
1846          }
1847          hs.ready();
1848      })();
1849  }
1850  hs.addEventListener(document, 'DOMContentLoaded', hs.ready);
1851  hs.addEventListener(window, 'load', hs.ready);
1852  
1853  // set handlers
1854  hs.addEventListener(document, 'ready', function() {
1855      if (hs.expandCursor) {
1856          var style = hs.createElement('style', { type: 'text/css' }, null, 
1857              document.getElementsByTagName('HEAD')[0]);
1858              
1859  		function addRule(sel, dec) {        
1860              if (hs.ie && hs.uaVersion < 9) {
1861                  var last = document.styleSheets[document.styleSheets.length - 1];
1862                  if (typeof(last.addRule) == "object") last.addRule(sel, dec);
1863              } else {
1864                  style.appendChild(document.createTextNode(sel + " {" + dec + "}"));
1865              }
1866          }
1867  		function fix(prop) {
1868              return 'expression( ( ( ignoreMe = document.documentElement.'+ prop +
1869                  ' ? document.documentElement.'+ prop +' : document.body.'+ prop +' ) ) + \'px\' );';
1870          }
1871          if (hs.expandCursor) addRule ('.highslide img', 
1872              'cursor: url('+ hs.graphicsDir + hs.expandCursor +'), pointer !important;');
1873      }
1874  });
1875  hs.addEventListener(window, 'resize', function() {
1876      hs.getPageSize();
1877  });
1878  hs.addEventListener(document, 'mousemove', function(e) {
1879      hs.mouse = { x: e.clientX, y: e.clientY    };
1880  });
1881  hs.addEventListener(document, 'mousedown', hs.mouseClickHandler);
1882  hs.addEventListener(document, 'mouseup', hs.mouseClickHandler);
1883  
1884  hs.addEventListener(document, 'ready', hs.getAnchors);
1885  hs.addEventListener(window, 'load', hs.preloadImages);
1886  }


Generated: Mon Jul 9 18:01:44 2012 Cross-referenced by PHPXref 0.7