[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/lib/yuilib/3.17.2/scrollview-scrollbars/ -> scrollview-scrollbars.js (source)

   1  /*
   2  YUI 3.17.2 (build 9c3c78e)
   3  Copyright 2014 Yahoo! Inc. All rights reserved.
   4  Licensed under the BSD License.
   5  http://yuilibrary.com/license/
   6  */
   7  
   8  YUI.add('scrollview-scrollbars', function (Y, NAME) {
   9  
  10  /**
  11   * Provides a plugin, which adds support for a scroll indicator to ScrollView instances
  12   *
  13   * @module scrollview
  14   * @submodule scrollview-scrollbars
  15   */
  16  
  17  var getClassName = Y.ClassNameManager.getClassName,
  18      _classNames,
  19  
  20      Transition = Y.Transition,
  21      NATIVE_TRANSITIONS = Transition.useNative,
  22      SCROLLBAR = 'scrollbar',
  23      SCROLLVIEW = 'scrollview',
  24  
  25      VERTICAL_NODE = "verticalNode",
  26      HORIZONTAL_NODE = "horizontalNode",
  27  
  28      CHILD_CACHE = "childCache",
  29  
  30      TOP = "top",
  31      LEFT = "left",
  32      WIDTH = "width",
  33      HEIGHT = "height",
  34  
  35      HORIZ_CACHE = "_sbh",
  36      VERT_CACHE = "_sbv",
  37  
  38      TRANSITION_PROPERTY = Y.ScrollView._TRANSITION.PROPERTY,
  39      TRANSFORM = "transform",
  40  
  41      TRANSLATE_X = "translateX(",
  42      TRANSLATE_Y = "translateY(",
  43  
  44      SCALE_X = "scaleX(",
  45      SCALE_Y = "scaleY(",
  46  
  47      SCROLL_X = "scrollX",
  48      SCROLL_Y = "scrollY",
  49  
  50      PX = "px",
  51      CLOSE = ")",
  52      PX_CLOSE = PX + CLOSE;
  53  
  54  /**
  55   * ScrollView plugin that adds scroll indicators to ScrollView instances
  56   *
  57   * @class ScrollViewScrollbars
  58   * @namespace Plugin
  59   * @extends Plugin.Base
  60   * @constructor
  61   */
  62  function ScrollbarsPlugin() {
  63      ScrollbarsPlugin.superclass.constructor.apply(this, arguments);
  64  }
  65  
  66  ScrollbarsPlugin.CLASS_NAMES = {
  67      showing: getClassName(SCROLLVIEW, SCROLLBAR, 'showing'),
  68      scrollbar: getClassName(SCROLLVIEW, SCROLLBAR),
  69      scrollbarV: getClassName(SCROLLVIEW, SCROLLBAR, 'vert'),
  70      scrollbarH: getClassName(SCROLLVIEW, SCROLLBAR, 'horiz'),
  71      scrollbarVB: getClassName(SCROLLVIEW, SCROLLBAR, 'vert', 'basic'),
  72      scrollbarHB: getClassName(SCROLLVIEW, SCROLLBAR, 'horiz', 'basic'),
  73      child: getClassName(SCROLLVIEW, 'child'),
  74      first: getClassName(SCROLLVIEW, 'first'),
  75      middle: getClassName(SCROLLVIEW, 'middle'),
  76      last: getClassName(SCROLLVIEW, 'last')
  77  };
  78  
  79  _classNames = ScrollbarsPlugin.CLASS_NAMES;
  80  
  81  /**
  82   * The identity of the plugin
  83   *
  84   * @property NAME
  85   * @type String
  86   * @default 'pluginScrollViewScrollbars'
  87   * @static
  88   */
  89  ScrollbarsPlugin.NAME = 'pluginScrollViewScrollbars';
  90  
  91  /**
  92   * The namespace on which the plugin will reside.
  93   *
  94   * @property NS
  95   * @type String
  96   * @default 'scrollbars'
  97   * @static
  98   */
  99  ScrollbarsPlugin.NS = 'scrollbars';
 100  
 101  /**
 102   * HTML template for the scrollbar
 103   *
 104   * @property SCROLLBAR_TEMPLATE
 105   * @type Object
 106   * @static
 107   */
 108  ScrollbarsPlugin.SCROLLBAR_TEMPLATE = [
 109      '<div>',
 110      '<span class="' + _classNames.child + ' ' + _classNames.first + '"></span>',
 111      '<span class="' + _classNames.child + ' ' + _classNames.middle + '"></span>',
 112      '<span class="' + _classNames.child + ' ' + _classNames.last + '"></span>',
 113      '</div>'
 114  ].join('');
 115  
 116  /**
 117   * The default attribute configuration for the plugin
 118   *
 119   * @property ATTRS
 120   * @type Object
 121   * @static
 122   */
 123  ScrollbarsPlugin.ATTRS = {
 124  
 125      /**
 126       * Vertical scrollbar node
 127       *
 128       * @attribute verticalNode
 129       * @type Y.Node
 130       */
 131      verticalNode: {
 132          setter: '_setNode',
 133          valueFn: '_defaultNode'
 134      },
 135  
 136      /**
 137       * Horizontal scrollbar node
 138       *
 139       * @attribute horizontalNode
 140       * @type Y.Node
 141       */
 142      horizontalNode: {
 143          setter: '_setNode',
 144          valueFn: '_defaultNode'
 145      }
 146  };
 147  
 148  Y.namespace("Plugin").ScrollViewScrollbars = Y.extend(ScrollbarsPlugin, Y.Plugin.Base, {
 149  
 150      /**
 151       * Designated initializer
 152       *
 153       * @method initializer
 154       */
 155      initializer: function() {
 156          this._host = this.get("host");
 157  
 158          this.afterHostEvent('scrollEnd', this._hostScrollEnd);
 159          this.afterHostMethod('scrollTo', this._update);
 160          this.afterHostMethod('_uiDimensionsChange', this._hostDimensionsChange);
 161      },
 162  
 163      /**
 164       * Set up the DOM nodes for the scrollbars. This method is invoked whenever the
 165       * host's _uiDimensionsChange fires, giving us the opportunity to remove un-needed
 166       * scrollbars, as well as add one if necessary.
 167       *
 168       * @method _hostDimensionsChange
 169       * @protected
 170       */
 171      _hostDimensionsChange: function() {
 172          var host = this._host,
 173              axis = host._cAxis,
 174              scrollX = host.get(SCROLL_X),
 175              scrollY = host.get(SCROLL_Y);
 176  
 177          this._dims = host._getScrollDims();
 178  
 179          if (axis && axis.y) {
 180              this._renderBar(this.get(VERTICAL_NODE), true, 'vert');
 181          }
 182  
 183          if (axis && axis.x) {
 184              this._renderBar(this.get(HORIZONTAL_NODE), true, 'horiz');
 185          }
 186  
 187          this._update(scrollX, scrollY);
 188  
 189          Y.later(500, this, 'flash', true);
 190      },
 191  
 192      /**
 193       * Handler for the scrollEnd event fired by the host. Default implementation flashes the scrollbar
 194       *
 195       * @method _hostScrollEnd
 196       * @param {EventFacade} e The event facade.
 197       * @protected
 198       */
 199      _hostScrollEnd : function() {
 200          var host = this._host,
 201              scrollX = host.get(SCROLL_X),
 202              scrollY = host.get(SCROLL_Y);
 203  
 204          this.flash();
 205  
 206          this._update(scrollX, scrollY);
 207      },
 208  
 209      /**
 210       * Adds or removes a scrollbar node from the document.
 211       *
 212       * @method _renderBar
 213       * @private
 214       * @param {Node} bar The scrollbar node
 215       * @param {boolean} add true, to add the node, false to remove it
 216       */
 217      _renderBar: function(bar, add) {
 218          var inDoc = bar.inDoc(),
 219              bb = this._host._bb,
 220              className = bar.getData("isHoriz") ? _classNames.scrollbarHB : _classNames.scrollbarVB;
 221  
 222          if (add && !inDoc) {
 223              bb.append(bar);
 224              bar.toggleClass(className, this._basic);
 225              this._setChildCache(bar);
 226          } else if(!add && inDoc) {
 227              bar.remove();
 228              this._clearChildCache(bar);
 229          }
 230      },
 231  
 232      /**
 233       * Caches scrollbar child element information,
 234       * to optimize _update implementation
 235       *
 236       * @method _setChildCache
 237       * @private
 238       * @param {Node} node
 239       */
 240      _setChildCache : function(node) {
 241          var c = node.get("children"),
 242              fc = c.item(0),
 243              mc = c.item(1),
 244              lc = c.item(2),
 245              size = node.getData("isHoriz") ? "offsetWidth" : "offsetHeight";
 246  
 247          node.setStyle(TRANSITION_PROPERTY, TRANSFORM);
 248          mc.setStyle(TRANSITION_PROPERTY, TRANSFORM);
 249          lc.setStyle(TRANSITION_PROPERTY, TRANSFORM);
 250  
 251          node.setData(CHILD_CACHE, {
 252              fc : fc,
 253              lc : lc,
 254              mc : mc,
 255              fcSize : fc && fc.get(size),
 256              lcSize : lc && lc.get(size)
 257          });
 258      },
 259  
 260      /**
 261       * Clears child cache
 262       *
 263       * @method _clearChildCache
 264       * @private
 265       * @param {Node} node
 266       */
 267      _clearChildCache : function(node) {
 268          node.clearData(CHILD_CACHE);
 269      },
 270  
 271      /**
 272       * Utility method, to move/resize either vertical or horizontal scrollbars
 273       *
 274       * @method _updateBar
 275       * @private
 276       *
 277       * @param {Node} scrollbar The scrollbar node.
 278       * @param {Number} current The current scroll position.
 279       * @param {Number} duration The transition duration.
 280       * @param {boolean} horiz true if horizontal, false if vertical.
 281       */
 282      _updateBar : function(scrollbar, current, duration, horiz) {
 283  
 284          var host = this._host,
 285              basic = this._basic,
 286  
 287              scrollbarSize = 0,
 288              scrollbarPos = 1,
 289  
 290              childCache = scrollbar.getData(CHILD_CACHE),
 291              lastChild = childCache.lc,
 292              middleChild = childCache.mc,
 293              firstChildSize = childCache.fcSize,
 294              lastChildSize = childCache.lcSize,
 295              middleChildSize,
 296              lastChildPosition,
 297  
 298              transition,
 299              translate,
 300              scale,
 301  
 302              dim,
 303              dimOffset,
 304              dimCache,
 305              widgetSize,
 306              contentSize;
 307  
 308          if (horiz) {
 309              dim = WIDTH;
 310              dimOffset = LEFT;
 311              dimCache = HORIZ_CACHE;
 312              widgetSize = this._dims.offsetWidth;
 313              contentSize = this._dims.scrollWidth;
 314              translate = TRANSLATE_X;
 315              scale = SCALE_X;
 316              current = (current !== undefined) ? current : host.get(SCROLL_X);
 317          } else {
 318              dim = HEIGHT;
 319              dimOffset = TOP;
 320              dimCache = VERT_CACHE;
 321              widgetSize = this._dims.offsetHeight;
 322              contentSize = this._dims.scrollHeight;
 323              translate = TRANSLATE_Y;
 324              scale = SCALE_Y;
 325              current = (current !== undefined) ? current : host.get(SCROLL_Y);
 326          }
 327  
 328          scrollbarSize = Math.floor(widgetSize * (widgetSize/contentSize));
 329          scrollbarPos = Math.floor((current/(contentSize - widgetSize)) * (widgetSize - scrollbarSize));
 330          if (scrollbarSize > widgetSize) {
 331              scrollbarSize = 1;
 332          }
 333  
 334          if (scrollbarPos > (widgetSize - scrollbarSize)) {
 335              scrollbarSize = scrollbarSize - (scrollbarPos - (widgetSize - scrollbarSize));
 336          } else if (scrollbarPos < 0) {
 337              scrollbarSize = scrollbarPos + scrollbarSize;
 338              scrollbarPos = 0;
 339          } else if (isNaN(scrollbarPos)) {
 340              scrollbarPos = 0;
 341          }
 342  
 343          middleChildSize = (scrollbarSize - (firstChildSize + lastChildSize));
 344  
 345          if (middleChildSize < 0) {
 346              middleChildSize = 0;
 347          }
 348  
 349          if (middleChildSize === 0 && scrollbarPos !== 0) {
 350              scrollbarPos = widgetSize - (firstChildSize + lastChildSize) - 1;
 351          }
 352  
 353          if (duration !== 0) {
 354              // Position Scrollbar
 355              transition = {
 356                  duration : duration
 357              };
 358  
 359              if (NATIVE_TRANSITIONS) {
 360                  transition.transform = translate + scrollbarPos + PX_CLOSE;
 361              } else {
 362                  transition[dimOffset] = scrollbarPos + PX;
 363              }
 364  
 365              scrollbar.transition(transition);
 366  
 367          } else {
 368              if (NATIVE_TRANSITIONS) {
 369                  scrollbar.setStyle(TRANSFORM, translate + scrollbarPos + PX_CLOSE);
 370              } else {
 371                  scrollbar.setStyle(dimOffset, scrollbarPos + PX);
 372              }
 373          }
 374  
 375          // Resize Scrollbar Middle Child
 376          if (this[dimCache] !== middleChildSize) {
 377              this[dimCache] = middleChildSize;
 378  
 379              if (middleChildSize > 0) {
 380  
 381                  if (duration !== 0) {
 382                      transition = {
 383                          duration : duration
 384                      };
 385  
 386                      if(NATIVE_TRANSITIONS) {
 387                          transition.transform = scale + middleChildSize + CLOSE;
 388                      } else {
 389                          transition[dim] = middleChildSize + PX;
 390                      }
 391  
 392                      middleChild.transition(transition);
 393                  } else {
 394                      if (NATIVE_TRANSITIONS) {
 395                          middleChild.setStyle(TRANSFORM, scale + middleChildSize + CLOSE);
 396                      } else {
 397                          middleChild.setStyle(dim, middleChildSize + PX);
 398                      }
 399                  }
 400  
 401                  // Position Last Child
 402                  if (!horiz || !basic) {
 403  
 404                      lastChildPosition = scrollbarSize - lastChildSize;
 405  
 406                      if(duration !== 0) {
 407                          transition = {
 408                              duration : duration
 409                          };
 410  
 411                          if (NATIVE_TRANSITIONS) {
 412                              transition.transform = translate + lastChildPosition + PX_CLOSE;
 413                          } else {
 414                              transition[dimOffset] = lastChildPosition;
 415                          }
 416  
 417                          lastChild.transition(transition);
 418                      } else {
 419                          if (NATIVE_TRANSITIONS) {
 420                              lastChild.setStyle(TRANSFORM, translate + lastChildPosition + PX_CLOSE);
 421                          } else {
 422                              lastChild.setStyle(dimOffset, lastChildPosition + PX);
 423                          }
 424                      }
 425                  }
 426              }
 427          }
 428      },
 429  
 430      /**
 431       * AOP method, invoked after the host's _uiScrollTo method,
 432       *  to position and resize the scroll bars
 433       *
 434       * @method _update
 435       * @param x {Number} The current scrollX value
 436       * @param y {Number} The current scrollY value
 437       * @param duration {Number} Number of ms of animation (optional) - used when snapping to bounds
 438       * @param easing {String} Optional easing equation to use during the animation, if duration is set
 439       * @protected
 440       */
 441      _update: function(x, y, duration) {
 442          var vNode = this.get(VERTICAL_NODE),
 443              hNode = this.get(HORIZONTAL_NODE),
 444              host = this._host,
 445              axis = host._cAxis;
 446  
 447          duration = (duration || 0)/1000;
 448  
 449          if (!this._showing) {
 450              this.show();
 451          }
 452  
 453          if (axis && axis.y && vNode && y !== null) {
 454              this._updateBar(vNode, y, duration, false);
 455          }
 456  
 457          if (axis && axis.x && hNode && x !== null) {
 458              this._updateBar(hNode, x, duration, true);
 459          }
 460      },
 461  
 462      /**
 463       * Show the scroll bar indicators
 464       *
 465       * @method show
 466       * @param animated {Boolean} Whether or not to animate the showing
 467       */
 468      show: function(animated) {
 469          this._show(true, animated);
 470      },
 471  
 472      /**
 473       * Hide the scroll bar indicators
 474       *
 475       * @method hide
 476       * @param animated {Boolean} Whether or not to animate the hiding
 477       */
 478      hide: function(animated) {
 479          this._show(false, animated);
 480      },
 481  
 482      /**
 483       * Internal hide/show implementation utility method
 484       *
 485       * @method _show
 486       * @param {boolean} show Whether to show or hide the scrollbar
 487       * @param {bolean} animated Whether or not to animate while showing/hide
 488       * @protected
 489       */
 490      _show : function(show, animated) {
 491  
 492          var verticalNode = this.get(VERTICAL_NODE),
 493              horizontalNode = this.get(HORIZONTAL_NODE),
 494  
 495              duration = (animated) ? 0.6 : 0,
 496              opacity = (show) ? 1 : 0,
 497  
 498              transition;
 499  
 500          this._showing = show;
 501  
 502          if (this._flashTimer) {
 503              this._flashTimer.cancel();
 504          }
 505  
 506          transition = {
 507              duration : duration,
 508              opacity : opacity
 509          };
 510  
 511          if (verticalNode && verticalNode._node) {
 512              verticalNode.transition(transition);
 513          }
 514  
 515          if (horizontalNode && horizontalNode._node) {
 516              horizontalNode.transition(transition);
 517          }
 518      },
 519  
 520      /**
 521       * Momentarily flash the scroll bars to indicate current scroll position
 522       *
 523       * @method flash
 524       */
 525      flash: function() {
 526          this.show(true);
 527          this._flashTimer = Y.later(800, this, 'hide', true);
 528      },
 529  
 530      /**
 531       * Setter for the verticalNode and horizontalNode attributes
 532       *
 533       * @method _setNode
 534       * @param node {Node} The Y.Node instance for the scrollbar
 535       * @param name {String} The attribute name
 536       * @return {Node} The Y.Node instance for the scrollbar
 537       *
 538       * @protected
 539       */
 540      _setNode: function(node, name) {
 541          var horiz = (name === HORIZONTAL_NODE);
 542              node = Y.one(node);
 543  
 544          if (node) {
 545              node.addClass(_classNames.scrollbar);
 546              node.addClass( (horiz) ? _classNames.scrollbarH : _classNames.scrollbarV );
 547              node.setData("isHoriz", horiz);
 548          }
 549  
 550          return node;
 551      },
 552  
 553      /**
 554       * Creates default node instances for scrollbars
 555       *
 556       * @method _defaultNode
 557       * @return {Node} The Y.Node instance for the scrollbar
 558       *
 559       * @protected
 560       */
 561      _defaultNode: function() {
 562          return Y.Node.create(ScrollbarsPlugin.SCROLLBAR_TEMPLATE);
 563      },
 564  
 565      _basic: Y.UA.ie && Y.UA.ie <= 8
 566  
 567  });
 568  
 569  
 570  }, '3.17.2', {"requires": ["classnamemanager", "transition", "plugin"], "skinnable": true});


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1