~ubuntu-branches/ubuntu/utopic/moodle/utopic

« back to all changes in this revision

Viewing changes to lib/yuilib/3.13.0/scrollview-scrollbars/scrollview-scrollbars-debug.js

  • Committer: Package Import Robot
  • Author(s): Thijs Kinkhorst
  • Date: 2014-05-12 16:10:38 UTC
  • mfrom: (36.1.3 sid)
  • Revision ID: package-import@ubuntu.com-20140512161038-puyqf65k4e0s8ytz
Tags: 2.6.3-1
New upstream release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
YUI 3.13.0 (build 508226d)
 
3
Copyright 2013 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 {Event.Facade} 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.13.0', {"requires": ["classnamemanager", "transition", "plugin"], "skinnable": true});