[ Index ]

PHP Cross Reference of Drupal 6 (yi-drupal)

title

Body

[close]

/sites/all/libraries/jquery.ui/ui/ -> ui.accordion.js (source)

   1  /*

   2   * jQuery UI Accordion 1.7.3

   3   *

   4   * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)

   5   * Dual licensed under the MIT (MIT-LICENSE.txt)

   6   * and GPL (GPL-LICENSE.txt) licenses.

   7   *

   8   * http://docs.jquery.com/UI/Accordion

   9   *

  10   * Depends:

  11   *    ui.core.js

  12   */
  13  (function($) {
  14  
  15  $.widget("ui.accordion", {
  16  
  17      _init: function() {
  18  
  19          var o = this.options, self = this;
  20          this.running = 0;
  21  
  22          // if the user set the alwaysOpen option on init

  23          // then we need to set the collapsible option

  24          // if they set both on init, collapsible will take priority

  25          if (o.collapsible == $.ui.accordion.defaults.collapsible &&
  26              o.alwaysOpen != $.ui.accordion.defaults.alwaysOpen) {
  27              o.collapsible = !o.alwaysOpen;
  28          }
  29  
  30          if ( o.navigation ) {
  31              var current = this.element.find("a").filter(o.navigationFilter);
  32              if ( current.length ) {
  33                  if ( current.filter(o.header).length ) {
  34                      this.active = current;
  35                  } else {
  36                      this.active = current.parent().parent().prev();
  37                      current.addClass("ui-accordion-content-active");
  38                  }
  39              }
  40          }
  41  
  42          this.element.addClass("ui-accordion ui-widget ui-helper-reset");
  43          
  44          // in lack of child-selectors in CSS we need to mark top-LIs in a UL-accordion for some IE-fix

  45          if (this.element[0].nodeName == "UL") {
  46              this.element.children("li").addClass("ui-accordion-li-fix");
  47          }
  48  
  49          this.headers = this.element.find(o.header).addClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-all")
  50              .bind("mouseenter.accordion", function(){ $(this).addClass('ui-state-hover'); })
  51              .bind("mouseleave.accordion", function(){ $(this).removeClass('ui-state-hover'); })
  52              .bind("focus.accordion", function(){ $(this).addClass('ui-state-focus'); })
  53              .bind("blur.accordion", function(){ $(this).removeClass('ui-state-focus'); });
  54  
  55          this.headers
  56              .next()
  57                  .addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom");
  58  
  59          this.active = this._findActive(this.active || o.active).toggleClass("ui-state-default").toggleClass("ui-state-active").toggleClass("ui-corner-all").toggleClass("ui-corner-top");
  60          this.active.next().addClass('ui-accordion-content-active');
  61  
  62          //Append icon elements

  63          $("<span/>").addClass("ui-icon " + o.icons.header).prependTo(this.headers);
  64          this.active.find(".ui-icon").toggleClass(o.icons.header).toggleClass(o.icons.headerSelected);
  65  
  66          // IE7-/Win - Extra vertical space in lists fixed

  67          if ($.browser.msie) {
  68              this.element.find('a').css('zoom', '1');
  69          }
  70  
  71          this.resize();
  72  
  73          //ARIA

  74          this.element.attr('role','tablist');
  75  
  76          this.headers
  77              .attr('role','tab')
  78              .bind('keydown', function(event) { return self._keydown(event); })
  79              .next()
  80              .attr('role','tabpanel');
  81  
  82          this.headers
  83              .not(this.active || "")
  84              .attr('aria-expanded','false')
  85              .attr("tabIndex", "-1")
  86              .next()
  87              .hide();
  88  
  89          // make sure at least one header is in the tab order

  90          if (!this.active.length) {
  91              this.headers.eq(0).attr('tabIndex','0');
  92          } else {
  93              this.active
  94                  .attr('aria-expanded','true')
  95                  .attr('tabIndex', '0');
  96          }
  97  
  98          // only need links in taborder for Safari

  99          if (!$.browser.safari)
 100              this.headers.find('a').attr('tabIndex','-1');
 101  
 102          if (o.event) {
 103              this.headers.bind((o.event) + ".accordion", function(event) { return self._clickHandler.call(self, event, this); });
 104          }
 105  
 106      },
 107  
 108      destroy: function() {
 109          var o = this.options;
 110  
 111          this.element
 112              .removeClass("ui-accordion ui-widget ui-helper-reset")
 113              .removeAttr("role")
 114              .unbind('.accordion')
 115              .removeData('accordion');
 116  
 117          this.headers
 118              .unbind(".accordion")
 119              .removeClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-corner-top")
 120              .removeAttr("role").removeAttr("aria-expanded").removeAttr("tabindex");
 121  
 122          this.headers.find("a").removeAttr("tabindex");
 123          this.headers.children(".ui-icon").remove();
 124          var contents = this.headers.next().css("display", "").removeAttr("role").removeClass("ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active");
 125          if (o.autoHeight || o.fillHeight) {
 126              contents.css("height", "");
 127          }
 128      },
 129      
 130      _setData: function(key, value) {
 131          if(key == 'alwaysOpen') { key = 'collapsible'; value = !value; }
 132          $.widget.prototype._setData.apply(this, arguments);    
 133      },
 134  
 135      _keydown: function(event) {
 136  
 137          var o = this.options, keyCode = $.ui.keyCode;
 138  
 139          if (o.disabled || event.altKey || event.ctrlKey)
 140              return;
 141  
 142          var length = this.headers.length;
 143          var currentIndex = this.headers.index(event.target);
 144          var toFocus = false;
 145  
 146          switch(event.keyCode) {
 147              case keyCode.RIGHT:
 148              case keyCode.DOWN:
 149                  toFocus = this.headers[(currentIndex + 1) % length];
 150                  break;
 151              case keyCode.LEFT:
 152              case keyCode.UP:
 153                  toFocus = this.headers[(currentIndex - 1 + length) % length];
 154                  break;
 155              case keyCode.SPACE:
 156              case keyCode.ENTER:
 157                  return this._clickHandler({ target: event.target }, event.target);
 158          }
 159  
 160          if (toFocus) {
 161              $(event.target).attr('tabIndex','-1');
 162              $(toFocus).attr('tabIndex','0');
 163              toFocus.focus();
 164              return false;
 165          }
 166  
 167          return true;
 168  
 169      },
 170  
 171      resize: function() {
 172  
 173          var o = this.options, maxHeight;
 174  
 175          if (o.fillSpace) {
 176              
 177              if($.browser.msie) { var defOverflow = this.element.parent().css('overflow'); this.element.parent().css('overflow', 'hidden'); }
 178              maxHeight = this.element.parent().height();
 179              if($.browser.msie) { this.element.parent().css('overflow', defOverflow); }
 180      
 181              this.headers.each(function() {
 182                  maxHeight -= $(this).outerHeight();
 183              });
 184  
 185              var maxPadding = 0;
 186              this.headers.next().each(function() {
 187                  maxPadding = Math.max(maxPadding, $(this).innerHeight() - $(this).height());
 188              }).height(Math.max(0, maxHeight - maxPadding))
 189              .css('overflow', 'auto');
 190  
 191          } else if ( o.autoHeight ) {
 192              maxHeight = 0;
 193              this.headers.next().each(function() {
 194                  maxHeight = Math.max(maxHeight, $(this).outerHeight());
 195              }).height(maxHeight);
 196          }
 197  
 198      },
 199  
 200      activate: function(index) {
 201          // call clickHandler with custom event

 202          var active = this._findActive(index)[0];
 203          this._clickHandler({ target: active }, active);
 204      },
 205  
 206      _findActive: function(selector) {
 207          return selector
 208              ? typeof selector == "number"
 209                  ? this.headers.filter(":eq(" + selector + ")")
 210                  : this.headers.not(this.headers.not(selector))
 211              : selector === false
 212                  ? $([])
 213                  : this.headers.filter(":eq(0)");
 214      },
 215  
 216      _clickHandler: function(event, target) {
 217  
 218          var o = this.options;
 219          if (o.disabled) return false;
 220  
 221          // called only when using activate(false) to close all parts programmatically

 222          if (!event.target && o.collapsible) {
 223              this.active.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all")
 224                  .find(".ui-icon").removeClass(o.icons.headerSelected).addClass(o.icons.header);
 225              this.active.next().addClass('ui-accordion-content-active');
 226              var toHide = this.active.next(),
 227                  data = {
 228                      options: o,
 229                      newHeader: $([]),
 230                      oldHeader: o.active,
 231                      newContent: $([]),
 232                      oldContent: toHide
 233                  },
 234                  toShow = (this.active = $([]));
 235              this._toggle(toShow, toHide, data);
 236              return false;
 237          }
 238  
 239          // get the click target

 240          var clicked = $(event.currentTarget || target);
 241          var clickedIsActive = clicked[0] == this.active[0];
 242  
 243          // if animations are still active, or the active header is the target, ignore click

 244          if (this.running || (!o.collapsible && clickedIsActive)) {
 245              return false;
 246          }
 247  
 248          // switch classes

 249          this.active.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all")
 250              .find(".ui-icon").removeClass(o.icons.headerSelected).addClass(o.icons.header);
 251          this.active.next().addClass('ui-accordion-content-active');
 252          if (!clickedIsActive) {
 253              clicked.removeClass("ui-state-default ui-corner-all").addClass("ui-state-active ui-corner-top")
 254                  .find(".ui-icon").removeClass(o.icons.header).addClass(o.icons.headerSelected);
 255              clicked.next().addClass('ui-accordion-content-active');
 256          }
 257  
 258          // find elements to show and hide

 259          var toShow = clicked.next(),
 260              toHide = this.active.next(),
 261              data = {
 262                  options: o,
 263                  newHeader: clickedIsActive && o.collapsible ? $([]) : clicked,
 264                  oldHeader: this.active,
 265                  newContent: clickedIsActive && o.collapsible ? $([]) : toShow.find('> *'),
 266                  oldContent: toHide.find('> *')
 267              },
 268              down = this.headers.index( this.active[0] ) > this.headers.index( clicked[0] );
 269  
 270          this.active = clickedIsActive ? $([]) : clicked;
 271          this._toggle(toShow, toHide, data, clickedIsActive, down);
 272  
 273          return false;
 274  
 275      },
 276  
 277      _toggle: function(toShow, toHide, data, clickedIsActive, down) {
 278  
 279          var o = this.options, self = this;
 280  
 281          this.toShow = toShow;
 282          this.toHide = toHide;
 283          this.data = data;
 284  
 285          var complete = function() { if(!self) return; return self._completed.apply(self, arguments); };
 286  
 287          // trigger changestart event

 288          this._trigger("changestart", null, this.data);
 289  
 290          // count elements to animate

 291          this.running = toHide.size() === 0 ? toShow.size() : toHide.size();
 292  
 293          if (o.animated) {
 294  
 295              var animOptions = {};
 296  
 297              if ( o.collapsible && clickedIsActive ) {
 298                  animOptions = {
 299                      toShow: $([]),
 300                      toHide: toHide,
 301                      complete: complete,
 302                      down: down,
 303                      autoHeight: o.autoHeight || o.fillSpace
 304                  };
 305              } else {
 306                  animOptions = {
 307                      toShow: toShow,
 308                      toHide: toHide,
 309                      complete: complete,
 310                      down: down,
 311                      autoHeight: o.autoHeight || o.fillSpace
 312                  };
 313              }
 314  
 315              if (!o.proxied) {
 316                  o.proxied = o.animated;
 317              }
 318  
 319              if (!o.proxiedDuration) {
 320                  o.proxiedDuration = o.duration;
 321              }
 322  
 323              o.animated = $.isFunction(o.proxied) ?
 324                  o.proxied(animOptions) : o.proxied;
 325  
 326              o.duration = $.isFunction(o.proxiedDuration) ?
 327                  o.proxiedDuration(animOptions) : o.proxiedDuration;
 328  
 329              var animations = $.ui.accordion.animations,
 330                  duration = o.duration,
 331                  easing = o.animated;
 332  
 333              if (!animations[easing]) {
 334                  animations[easing] = function(options) {
 335                      this.slide(options, {
 336                          easing: easing,
 337                          duration: duration || 700
 338                      });
 339                  };
 340              }
 341  
 342              animations[easing](animOptions);
 343  
 344          } else {
 345  
 346              if (o.collapsible && clickedIsActive) {
 347                  toShow.toggle();
 348              } else {
 349                  toHide.hide();
 350                  toShow.show();
 351              }
 352  
 353              complete(true);
 354  
 355          }
 356  
 357          toHide.prev().attr('aria-expanded','false').attr("tabIndex", "-1").blur();
 358          toShow.prev().attr('aria-expanded','true').attr("tabIndex", "0").focus();
 359  
 360      },
 361  
 362      _completed: function(cancel) {
 363  
 364          var o = this.options;
 365  
 366          this.running = cancel ? 0 : --this.running;
 367          if (this.running) return;
 368  
 369          if (o.clearStyle) {
 370              this.toShow.add(this.toHide).css({
 371                  height: "",
 372                  overflow: ""
 373              });
 374          }
 375  
 376          this._trigger('change', null, this.data);
 377      }
 378  
 379  });
 380  
 381  
 382  $.extend($.ui.accordion, {
 383      version: "1.7.3",
 384      defaults: {
 385          active: null,
 386          alwaysOpen: true, //deprecated, use collapsible
 387          animated: 'slide',
 388          autoHeight: true,
 389          clearStyle: false,
 390          collapsible: false,
 391          event: "click",
 392          fillSpace: false,
 393          header: "> li > :first-child,> :not(li):even",
 394          icons: {
 395              header: "ui-icon-triangle-1-e",
 396              headerSelected: "ui-icon-triangle-1-s"
 397          },
 398          navigation: false,
 399          navigationFilter: function() {
 400              return this.href.toLowerCase() == location.href.toLowerCase();
 401          }
 402      },
 403      animations: {
 404          slide: function(options, additions) {
 405              options = $.extend({
 406                  easing: "swing",
 407                  duration: 300
 408              }, options, additions);
 409              if ( !options.toHide.size() ) {
 410                  options.toShow.animate({height: "show"}, options);
 411                  return;
 412              }
 413              if ( !options.toShow.size() ) {
 414                  options.toHide.animate({height: "hide"}, options);
 415                  return;
 416              }
 417              var overflow = options.toShow.css('overflow'),
 418                  percentDone,
 419                  showProps = {},
 420                  hideProps = {},
 421                  fxAttrs = [ "height", "paddingTop", "paddingBottom" ],
 422                  originalWidth;
 423              // fix width before calculating height of hidden element

 424              var s = options.toShow;
 425              originalWidth = s[0].style.width;
 426              s.width( parseInt(s.parent().width(),10) - parseInt(s.css("paddingLeft"),10) - parseInt(s.css("paddingRight"),10) - (parseInt(s.css("borderLeftWidth"),10) || 0) - (parseInt(s.css("borderRightWidth"),10) || 0) );
 427              
 428              $.each(fxAttrs, function(i, prop) {
 429                  hideProps[prop] = 'hide';
 430                  
 431                  var parts = ('' + $.css(options.toShow[0], prop)).match(/^([\d+-.]+)(.*)$/);
 432                  showProps[prop] = {
 433                      value: parts[1],
 434                      unit: parts[2] || 'px'
 435                  };
 436              });
 437              options.toShow.css({ height: 0, overflow: 'hidden' }).show();
 438              options.toHide.filter(":hidden").each(options.complete).end().filter(":visible").animate(hideProps,{
 439                  step: function(now, settings) {
 440                      // only calculate the percent when animating height

 441                      // IE gets very inconsistent results when animating elements

 442                      // with small values, which is common for padding

 443                      if (settings.prop == 'height') {
 444                          percentDone = (settings.now - settings.start) / (settings.end - settings.start);
 445                      }
 446                      
 447                      options.toShow[0].style[settings.prop] =
 448                          (percentDone * showProps[settings.prop].value) + showProps[settings.prop].unit;
 449                  },
 450                  duration: options.duration,
 451                  easing: options.easing,
 452                  complete: function() {
 453                      if ( !options.autoHeight ) {
 454                          options.toShow.css("height", "");
 455                      }
 456                      options.toShow.css("width", originalWidth);
 457                      options.toShow.css({overflow: overflow});
 458                      options.complete();
 459                  }
 460              });
 461          },
 462          bounceslide: function(options) {
 463              this.slide(options, {
 464                  easing: options.down ? "easeOutBounce" : "swing",
 465                  duration: options.down ? 1000 : 200
 466              });
 467          },
 468          easeslide: function(options) {
 469              this.slide(options, {
 470                  easing: "easeinout",
 471                  duration: 700
 472              });
 473          }
 474      }
 475  });
 476  
 477  })(jQuery);


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