[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
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});
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |