~smagoun/whoopsie/whoopsie-lp1017637

« back to all changes in this revision

Viewing changes to backend/stats/static/js/yui/build/anim-base/anim-base-debug.js

  • Committer: Evan Dandrea
  • Date: 2012-05-09 05:53:45 UTC
  • Revision ID: evan.dandrea@canonical.com-20120509055345-z2j41tmcbf4as5uf
The backend now lives in lp:daisy and the website (errors.ubuntu.com) now lives in lp:errors.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
YUI 3.5.0 (build 5089)
3
 
Copyright 2012 Yahoo! Inc. All rights reserved.
4
 
Licensed under the BSD License.
5
 
http://yuilibrary.com/license/
6
 
*/
7
 
YUI.add('anim-base', function(Y) {
8
 
 
9
 
/**
10
 
* The Animation Utility provides an API for creating advanced transitions.
11
 
* @module anim
12
 
*/
13
 
 
14
 
/**
15
 
* Provides the base Anim class, for animating numeric properties.
16
 
*
17
 
* @module anim
18
 
* @submodule anim-base
19
 
*/
20
 
 
21
 
    /**
22
 
     * A class for constructing animation instances.
23
 
     * @class Anim
24
 
     * @for Anim
25
 
     * @constructor
26
 
     * @extends Base
27
 
     */
28
 
 
29
 
    var RUNNING = 'running',
30
 
        START_TIME = 'startTime',
31
 
        ELAPSED_TIME = 'elapsedTime',
32
 
        /**
33
 
        * @for Anim
34
 
        * @event start
35
 
        * @description fires when an animation begins.
36
 
        * @param {Event} ev The start event.
37
 
        * @type Event.Custom
38
 
        */
39
 
        START = 'start',
40
 
 
41
 
        /**
42
 
        * @event tween
43
 
        * @description fires every frame of the animation.
44
 
        * @param {Event} ev The tween event.
45
 
        * @type Event.Custom
46
 
        */
47
 
        TWEEN = 'tween',
48
 
 
49
 
        /**
50
 
        * @event end
51
 
        * @description fires after the animation completes.
52
 
        * @param {Event} ev The end event.
53
 
        * @type Event.Custom
54
 
        */
55
 
        END = 'end',
56
 
        NODE = 'node',
57
 
        PAUSED = 'paused',
58
 
        REVERSE = 'reverse', // TODO: cleanup
59
 
        ITERATION_COUNT = 'iterationCount',
60
 
 
61
 
        NUM = Number;
62
 
 
63
 
    var _running = {},
64
 
        _timer;
65
 
 
66
 
    Y.Anim = function() {
67
 
        Y.Anim.superclass.constructor.apply(this, arguments);
68
 
        Y.Anim._instances[Y.stamp(this)] = this;
69
 
    };
70
 
 
71
 
    Y.Anim.NAME = 'anim';
72
 
 
73
 
    Y.Anim._instances = {};
74
 
 
75
 
    /**
76
 
     * Regex of properties that should use the default unit.
77
 
     *
78
 
     * @property RE_DEFAULT_UNIT
79
 
     * @static
80
 
     */
81
 
    Y.Anim.RE_DEFAULT_UNIT = /^width|height|top|right|bottom|left|margin.*|padding.*|border.*$/i;
82
 
 
83
 
    /**
84
 
     * The default unit to use with properties that pass the RE_DEFAULT_UNIT test.
85
 
     *
86
 
     * @property DEFAULT_UNIT
87
 
     * @static
88
 
     */
89
 
    Y.Anim.DEFAULT_UNIT = 'px';
90
 
 
91
 
    Y.Anim.DEFAULT_EASING = function (t, b, c, d) {
92
 
        return c * t / d + b; // linear easing
93
 
    };
94
 
 
95
 
    /**
96
 
     * Time in milliseconds passed to setInterval for frame processing 
97
 
     *
98
 
     * @property intervalTime
99
 
     * @default 20
100
 
     * @static
101
 
     */
102
 
    Y.Anim._intervalTime = 20;
103
 
 
104
 
    /**
105
 
     * Bucket for custom getters and setters
106
 
     *
107
 
     * @property behaviors
108
 
     * @static
109
 
     */
110
 
    Y.Anim.behaviors = {
111
 
        left: {
112
 
            get: function(anim, attr) {
113
 
                return anim._getOffset(attr);
114
 
            }
115
 
        }
116
 
    };
117
 
 
118
 
    Y.Anim.behaviors.top = Y.Anim.behaviors.left;
119
 
 
120
 
    /**
121
 
     * The default setter to use when setting object properties.
122
 
     *
123
 
     * @property DEFAULT_SETTER
124
 
     * @static
125
 
     */
126
 
    Y.Anim.DEFAULT_SETTER = function(anim, att, from, to, elapsed, duration, fn, unit) {
127
 
        var node = anim._node,
128
 
            domNode = node._node,
129
 
            val = fn(elapsed, NUM(from), NUM(to) - NUM(from), duration);
130
 
        //make sure node instance
131
 
        if (domNode && (domNode.style || domNode.attributes)) {
132
 
            if (att in domNode.style || att in Y.DOM.CUSTOM_STYLES) {
133
 
                unit = unit || '';
134
 
                node.setStyle(att, val + unit);
135
 
            } else if (domNode.attributes[att]) {
136
 
                node.setAttribute(att, val);
137
 
            }
138
 
        } else if (node.set) {
139
 
            node.set(att, val);
140
 
        }
141
 
    };
142
 
 
143
 
    /**
144
 
     * The default getter to use when getting object properties.
145
 
     *
146
 
     * @property DEFAULT_GETTER
147
 
     * @static
148
 
     */
149
 
    Y.Anim.DEFAULT_GETTER = function(anim, att) {
150
 
        var node = anim._node,
151
 
            domNode = node._node,
152
 
            val = '';
153
 
        //make sure node instance
154
 
        if (domNode && (domNode.style || domNode.attributes)) {
155
 
            if (att in domNode.style || att in Y.DOM.CUSTOM_STYLES) {
156
 
                val = node.getComputedStyle(att);
157
 
            } else if (domNode.attributes[att]) {
158
 
                val = node.getAttribute(att);
159
 
            }
160
 
        } else if (node.get) {
161
 
            val = node.get(att);
162
 
        }
163
 
 
164
 
        return val;
165
 
    };
166
 
 
167
 
    Y.Anim.ATTRS = {
168
 
        /**
169
 
         * The object to be animated.
170
 
         * @attribute node
171
 
         * @type Node
172
 
         */
173
 
        node: {
174
 
            setter: function(node) {
175
 
                if (node) {
176
 
                    if (typeof node == 'string' || node.nodeType) {
177
 
                        node = Y.one(node);
178
 
                    }
179
 
                }
180
 
 
181
 
                this._node = node;
182
 
                if (!node) {
183
 
                    Y.log(node + ' is not a valid node', 'warn', 'Anim');
184
 
                }
185
 
                return node;
186
 
            }
187
 
        },
188
 
 
189
 
        /**
190
 
         * The length of the animation.  Defaults to "1" (second).
191
 
         * @attribute duration
192
 
         * @type NUM
193
 
         */
194
 
        duration: {
195
 
            value: 1
196
 
        },
197
 
 
198
 
        /**
199
 
         * The method that will provide values to the attribute(s) during the animation. 
200
 
         * Defaults to "Easing.easeNone".
201
 
         * @attribute easing
202
 
         * @type Function
203
 
         */
204
 
        easing: {
205
 
            value: Y.Anim.DEFAULT_EASING,
206
 
 
207
 
            setter: function(val) {
208
 
                if (typeof val === 'string' && Y.Easing) {
209
 
                    return Y.Easing[val];
210
 
                }
211
 
            }
212
 
        },
213
 
 
214
 
        /**
215
 
         * The starting values for the animated properties.
216
 
         *
217
 
         * Fields may be strings, numbers, or functions.
218
 
         * If a function is used, the return value becomes the from value.
219
 
         * If no from value is specified, the DEFAULT_GETTER will be used.
220
 
         * Supports any unit, provided it matches the "to" (or default)
221
 
         * unit (e.g. `{width: '10em', color: 'rgb(0, 0 0)', borderColor: '#ccc'}`).
222
 
         *
223
 
         * If using the default ('px' for length-based units), the unit may be omitted
224
 
         * (e.g. `{width: 100}, borderColor: 'ccc'}`, which defaults to pixels
225
 
         * and hex, respectively).
226
 
         *
227
 
         * @attribute from
228
 
         * @type Object
229
 
         */
230
 
        from: {},
231
 
 
232
 
        /**
233
 
         * The ending values for the animated properties.
234
 
         *
235
 
         * Fields may be strings, numbers, or functions.
236
 
         * Supports any unit, provided it matches the "from" (or default)
237
 
         * unit (e.g. `{width: '50%', color: 'red', borderColor: '#ccc'}`).
238
 
         *
239
 
         * If using the default ('px' for length-based units), the unit may be omitted
240
 
         * (e.g. `{width: 100, borderColor: 'ccc'}`, which defaults to pixels
241
 
         * and hex, respectively).
242
 
         *
243
 
         * @attribute to
244
 
         * @type Object
245
 
         */
246
 
        to: {},
247
 
 
248
 
        /**
249
 
         * Date stamp for the first frame of the animation.
250
 
         * @attribute startTime
251
 
         * @type Int
252
 
         * @default 0 
253
 
         * @readOnly
254
 
         */
255
 
        startTime: {
256
 
            value: 0,
257
 
            readOnly: true
258
 
        },
259
 
 
260
 
        /**
261
 
         * Current time the animation has been running.
262
 
         * @attribute elapsedTime
263
 
         * @type Int
264
 
         * @default 0 
265
 
         * @readOnly
266
 
         */
267
 
        elapsedTime: {
268
 
            value: 0,
269
 
            readOnly: true
270
 
        },
271
 
 
272
 
        /**
273
 
         * Whether or not the animation is currently running.
274
 
         * @attribute running 
275
 
         * @type Boolean
276
 
         * @default false 
277
 
         * @readOnly
278
 
         */
279
 
        running: {
280
 
            getter: function() {
281
 
                return !!_running[Y.stamp(this)];
282
 
            },
283
 
            value: false,
284
 
            readOnly: true
285
 
        },
286
 
 
287
 
        /**
288
 
         * The number of times the animation should run 
289
 
         * @attribute iterations
290
 
         * @type Int
291
 
         * @default 1 
292
 
         */
293
 
        iterations: {
294
 
            value: 1
295
 
        },
296
 
 
297
 
        /**
298
 
         * The number of iterations that have occurred.
299
 
         * Resets when an animation ends (reaches iteration count or stop() called). 
300
 
         * @attribute iterationCount
301
 
         * @type Int
302
 
         * @default 0
303
 
         * @readOnly
304
 
         */
305
 
        iterationCount: {
306
 
            value: 0,
307
 
            readOnly: true
308
 
        },
309
 
 
310
 
        /**
311
 
         * How iterations of the animation should behave. 
312
 
         * Possible values are "normal" and "alternate".
313
 
         * Normal will repeat the animation, alternate will reverse on every other pass.
314
 
         *
315
 
         * @attribute direction
316
 
         * @type String
317
 
         * @default "normal"
318
 
         */
319
 
        direction: {
320
 
            value: 'normal' // | alternate (fwd on odd, rev on even per spec)
321
 
        },
322
 
 
323
 
        /**
324
 
         * Whether or not the animation is currently paused.
325
 
         * @attribute paused 
326
 
         * @type Boolean
327
 
         * @default false 
328
 
         * @readOnly
329
 
         */
330
 
        paused: {
331
 
            readOnly: true,
332
 
            value: false
333
 
        },
334
 
 
335
 
        /**
336
 
         * If true, animation begins from last frame
337
 
         * @attribute reverse
338
 
         * @type Boolean
339
 
         * @default false 
340
 
         */
341
 
        reverse: {
342
 
            value: false
343
 
        }
344
 
 
345
 
 
346
 
    };
347
 
 
348
 
    /**
349
 
     * Runs all animation instances.
350
 
     * @method run
351
 
     * @static
352
 
     */    
353
 
    Y.Anim.run = function() {
354
 
        var instances = Y.Anim._instances;
355
 
        for (var i in instances) {
356
 
            if (instances[i].run) {
357
 
                instances[i].run();
358
 
            }
359
 
        }
360
 
    };
361
 
 
362
 
    /**
363
 
     * Pauses all animation instances.
364
 
     * @method pause
365
 
     * @static
366
 
     */    
367
 
    Y.Anim.pause = function() {
368
 
        for (var i in _running) { // stop timer if nothing running
369
 
            if (_running[i].pause) {
370
 
                _running[i].pause();
371
 
            }
372
 
        }
373
 
 
374
 
        Y.Anim._stopTimer();
375
 
    };
376
 
 
377
 
    /**
378
 
     * Stops all animation instances.
379
 
     * @method stop
380
 
     * @static
381
 
     */    
382
 
    Y.Anim.stop = function() {
383
 
        for (var i in _running) { // stop timer if nothing running
384
 
            if (_running[i].stop) {
385
 
                _running[i].stop();
386
 
            }
387
 
        }
388
 
        Y.Anim._stopTimer();
389
 
    };
390
 
    
391
 
    Y.Anim._startTimer = function() {
392
 
        if (!_timer) {
393
 
            _timer = setInterval(Y.Anim._runFrame, Y.Anim._intervalTime);
394
 
        }
395
 
    };
396
 
 
397
 
    Y.Anim._stopTimer = function() {
398
 
        clearInterval(_timer);
399
 
        _timer = 0;
400
 
    };
401
 
 
402
 
    /**
403
 
     * Called per Interval to handle each animation frame.
404
 
     * @method _runFrame
405
 
     * @private
406
 
     * @static
407
 
     */    
408
 
    Y.Anim._runFrame = function() {
409
 
        var done = true;
410
 
        for (var anim in _running) {
411
 
            if (_running[anim]._runFrame) {
412
 
                done = false;
413
 
                _running[anim]._runFrame();
414
 
            }
415
 
        }
416
 
 
417
 
        if (done) {
418
 
            Y.Anim._stopTimer();
419
 
        }
420
 
    };
421
 
 
422
 
    Y.Anim.RE_UNITS = /^(-?\d*\.?\d*){1}(em|ex|px|in|cm|mm|pt|pc|%)*$/;
423
 
 
424
 
    var proto = {
425
 
        /**
426
 
         * Starts or resumes an animation.
427
 
         * @method run
428
 
         * @chainable
429
 
         */    
430
 
        run: function() {
431
 
            if (this.get(PAUSED)) {
432
 
                this._resume();
433
 
            } else if (!this.get(RUNNING)) {
434
 
                this._start();
435
 
            }
436
 
            return this;
437
 
        },
438
 
 
439
 
        /**
440
 
         * Pauses the animation and
441
 
         * freezes it in its current state and time.
442
 
         * Calling run() will continue where it left off.
443
 
         * @method pause
444
 
         * @chainable
445
 
         */    
446
 
        pause: function() {
447
 
            if (this.get(RUNNING)) {
448
 
                this._pause();
449
 
            }
450
 
            return this;
451
 
        },
452
 
 
453
 
        /**
454
 
         * Stops the animation and resets its time.
455
 
         * @method stop
456
 
         * @param {Boolean} finish If true, the animation will move to the last frame
457
 
         * @chainable
458
 
         */    
459
 
        stop: function(finish) {
460
 
            if (this.get(RUNNING) || this.get(PAUSED)) {
461
 
                this._end(finish);
462
 
            }
463
 
            return this;
464
 
        },
465
 
 
466
 
        _added: false,
467
 
 
468
 
        _start: function() {
469
 
            this._set(START_TIME, new Date() - this.get(ELAPSED_TIME));
470
 
            this._actualFrames = 0;
471
 
            if (!this.get(PAUSED)) {
472
 
                this._initAnimAttr();
473
 
            }
474
 
            _running[Y.stamp(this)] = this;
475
 
            Y.Anim._startTimer();
476
 
 
477
 
            this.fire(START);
478
 
        },
479
 
 
480
 
        _pause: function() {
481
 
            this._set(START_TIME, null);
482
 
            this._set(PAUSED, true);
483
 
            delete _running[Y.stamp(this)];
484
 
 
485
 
            /**
486
 
            * @event pause
487
 
            * @description fires when an animation is paused.
488
 
            * @param {Event} ev The pause event.
489
 
            * @type Event.Custom
490
 
            */
491
 
            this.fire('pause');
492
 
        },
493
 
 
494
 
        _resume: function() {
495
 
            this._set(PAUSED, false);
496
 
            _running[Y.stamp(this)] = this;
497
 
            this._set(START_TIME, new Date() - this.get(ELAPSED_TIME));
498
 
            Y.Anim._startTimer();
499
 
 
500
 
            /**
501
 
            * @event resume
502
 
            * @description fires when an animation is resumed (run from pause).
503
 
            * @param {Event} ev The pause event.
504
 
            * @type Event.Custom
505
 
            */
506
 
            this.fire('resume');
507
 
        },
508
 
 
509
 
        _end: function(finish) {
510
 
            var duration = this.get('duration') * 1000;
511
 
            if (finish) { // jump to last frame
512
 
                this._runAttrs(duration, duration, this.get(REVERSE));
513
 
            }
514
 
 
515
 
            this._set(START_TIME, null);
516
 
            this._set(ELAPSED_TIME, 0);
517
 
            this._set(PAUSED, false);
518
 
 
519
 
            delete _running[Y.stamp(this)];
520
 
            this.fire(END, {elapsed: this.get(ELAPSED_TIME)});
521
 
        },
522
 
 
523
 
        _runFrame: function() {
524
 
            var d = this._runtimeAttr.duration,
525
 
                t = new Date() - this.get(START_TIME),
526
 
                reverse = this.get(REVERSE),
527
 
                done = (t >= d),
528
 
                attribute,
529
 
                setter;
530
 
                
531
 
            this._runAttrs(t, d, reverse);
532
 
            this._actualFrames += 1;
533
 
            this._set(ELAPSED_TIME, t);
534
 
 
535
 
            this.fire(TWEEN);
536
 
            if (done) {
537
 
                this._lastFrame();
538
 
            }
539
 
        },
540
 
 
541
 
        _runAttrs: function(t, d, reverse) {
542
 
            var attr = this._runtimeAttr,
543
 
                customAttr = Y.Anim.behaviors,
544
 
                easing = attr.easing,
545
 
                lastFrame = d,
546
 
                done = false,
547
 
                attribute,
548
 
                setter,
549
 
                i;
550
 
 
551
 
            if (t >= d) {
552
 
                done = true;
553
 
            }
554
 
 
555
 
            if (reverse) {
556
 
                t = d - t;
557
 
                lastFrame = 0;
558
 
            }
559
 
 
560
 
            for (i in attr) {
561
 
                if (attr[i].to) {
562
 
                    attribute = attr[i];
563
 
                    setter = (i in customAttr && 'set' in customAttr[i]) ?
564
 
                            customAttr[i].set : Y.Anim.DEFAULT_SETTER;
565
 
 
566
 
                    if (!done) {
567
 
                        setter(this, i, attribute.from, attribute.to, t, d, easing, attribute.unit); 
568
 
                    } else {
569
 
                        setter(this, i, attribute.from, attribute.to, lastFrame, d, easing, attribute.unit); 
570
 
                    }
571
 
                }
572
 
            }
573
 
 
574
 
 
575
 
        },
576
 
 
577
 
        _lastFrame: function() {
578
 
            var iter = this.get('iterations'),
579
 
                iterCount = this.get(ITERATION_COUNT);
580
 
 
581
 
            iterCount += 1;
582
 
            if (iter === 'infinite' || iterCount < iter) {
583
 
                if (this.get('direction') === 'alternate') {
584
 
                    this.set(REVERSE, !this.get(REVERSE)); // flip it
585
 
                }
586
 
                /**
587
 
                * @event iteration
588
 
                * @description fires when an animation begins an iteration.
589
 
                * @param {Event} ev The iteration event.
590
 
                * @type Event.Custom
591
 
                */
592
 
                this.fire('iteration');
593
 
            } else {
594
 
                iterCount = 0;
595
 
                this._end();
596
 
            }
597
 
 
598
 
            this._set(START_TIME, new Date());
599
 
            this._set(ITERATION_COUNT, iterCount);
600
 
        },
601
 
 
602
 
        _initAnimAttr: function() {
603
 
            var from = this.get('from') || {},
604
 
                to = this.get('to') || {},
605
 
                attr = {
606
 
                    duration: this.get('duration') * 1000,
607
 
                    easing: this.get('easing')
608
 
                },
609
 
                customAttr = Y.Anim.behaviors,
610
 
                node = this.get(NODE), // implicit attr init
611
 
                unit, begin, end;
612
 
 
613
 
            Y.each(to, function(val, name) {
614
 
                if (typeof val === 'function') {
615
 
                    val = val.call(this, node);
616
 
                }
617
 
 
618
 
                begin = from[name];
619
 
                if (begin === undefined) {
620
 
                    begin = (name in customAttr && 'get' in customAttr[name])  ?
621
 
                            customAttr[name].get(this, name) : Y.Anim.DEFAULT_GETTER(this, name);
622
 
                } else if (typeof begin === 'function') {
623
 
                    begin = begin.call(this, node);
624
 
                }
625
 
 
626
 
                var mFrom = Y.Anim.RE_UNITS.exec(begin);
627
 
                var mTo = Y.Anim.RE_UNITS.exec(val);
628
 
 
629
 
                begin = mFrom ? mFrom[1] : begin;
630
 
                end = mTo ? mTo[1] : val;
631
 
                unit = mTo ? mTo[2] : mFrom ?  mFrom[2] : ''; // one might be zero TODO: mixed units
632
 
 
633
 
                if (!unit && Y.Anim.RE_DEFAULT_UNIT.test(name)) {
634
 
                    unit = Y.Anim.DEFAULT_UNIT;
635
 
                }
636
 
 
637
 
                if (!begin || !end) {
638
 
                    Y.error('invalid "from" or "to" for "' + name + '"', 'Anim');
639
 
                    return;
640
 
                }
641
 
 
642
 
                attr[name] = {
643
 
                    from: begin,
644
 
                    to: end,
645
 
                    unit: unit
646
 
                };
647
 
 
648
 
            }, this);
649
 
 
650
 
            this._runtimeAttr = attr;
651
 
        },
652
 
 
653
 
 
654
 
        // TODO: move to computedStyle? (browsers dont agree on default computed offsets)
655
 
        _getOffset: function(attr) {
656
 
            var node = this._node,
657
 
                val = node.getComputedStyle(attr),
658
 
                get = (attr === 'left') ? 'getX': 'getY',
659
 
                set = (attr === 'left') ? 'setX': 'setY';
660
 
 
661
 
            if (val === 'auto') {
662
 
                var position = node.getStyle('position');
663
 
                if (position === 'absolute' || position === 'fixed') {
664
 
                    val = node[get]();
665
 
                    node[set](val);
666
 
                } else {
667
 
                    val = 0;
668
 
                }
669
 
            }
670
 
 
671
 
            return val;
672
 
        },
673
 
 
674
 
        destructor: function() {
675
 
            delete Y.Anim._instances[Y.stamp(this)];
676
 
        }
677
 
    };
678
 
 
679
 
    Y.extend(Y.Anim, Y.Base, proto);
680
 
 
681
 
 
682
 
}, '3.5.0' ,{requires:['base-base', 'node-style']});