/loggerhead/trunk

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/loggerhead/trunk
229.1.3 by Paul Hummer
Added forgotten library
1
/*
2
Copyright (c) 2008, Yahoo! Inc. All rights reserved.
3
Code licensed under the BSD License:
4
http://developer.yahoo.net/yui/license.txt
5
version: 3.0.0pr1
6
*/
7
YUI.add('queue', function(Y) {
8
9
/**
10
 * Mechanism to execute a series of callbacks in a non-blocking queue.  Each
11
 * callback is executed via setTimout unless configured with a negative
12
 * timeout, in which case it is run in blocking mode in the same execution
13
 * thread as the previous callback.  Callbacks can be function references or
14
 * object literals with the following keys:
15
 * <ul>
16
 *    <li><code>fn</code> - {Function} REQUIRED the callback function.</li>
17
 *    <li><code>timeout</code> - {number} millisecond delay to wait after previous callback completion before executing this callback.  Negative values cause immediate blocking execution.  Default 0.</li>
18
 *    <li><code>until</code> - {Function} boolean function executed before each iteration.  Return true to indicate callback completion.</li>
19
 *    <li><code>iterations</code> - {Number} number of times to execute the callback before proceeding to the next callback in the queue. Incompatible with <code>until</code>.</li>
20
 * </ul>
21
 *
22
 * @module queue
23
 * @class Queue
24
 * @constructor
25
 * @param callback* {Function|Object} Any number of callbacks to initialize the queue
26
 */
27
Y.Queue = function () {
28
    // Factory or Constructor
29
    var me = this instanceof Y.Queue ? this : new Y.Queue();
30
31
    /**
32
     * The callback queue
33
     * @property q
34
     * @type {Array}
35
     * @protected
36
     */
37
    me.q = [];
38
39
    return me.add.apply(me,arguments);
40
};
41
42
Y.Queue.prototype = {
43
    /**
44
     * Timeout id used to pause or stop execution and indicate the execution
45
     * state of the Queue.  0 indicates paused or stopped, negatives indicate
46
     * blocking execution, and positives indicate non-blocking execution.
47
     * @property id
48
     * @type {number}
49
     * @protected
50
     */
51
    id   : 0,
52
53
    /**
54
     * Execute the queue callbacks (also resumes paused Queue).
55
     * @method run
56
     * @return {Queue} the Queue instance
57
     */
58
    run : function () {
59
        // Grab the first callback in the queue
60
        var c  = this.q[0],
61
            fn;
62
63
        // If there is no callback in the queue or the Queue is currently
64
        // in an execution mode, return
65
        if (!c) {
66
            /**
67
             * Event fired after the last queued callback is executed.  Not
68
             * fired if the Queue is stopped via q.stop().
69
             * @event end
70
             */
71
            this.fire('end');
72
            return this;
73
        } else if (this.id) {
74
            return this;
75
        }
76
77
        fn = c.fn || c;
78
79
        if (typeof fn === 'function') {
80
            var ms   = c.timeout || 0,
81
                me   = this;
82
83
            // Execute immediately if the callback timeout is negative.
84
            if (ms < 0) {
85
                this.id = ms;
86
                if (c.until) { // test .until condition
87
                    for (;!c.until();) {
88
                        this._exec(fn,c);
89
                    }
90
                } else if (c.iterations) { // test .iterations
91
                    for (;c.iterations-- > 0;) {
92
                        this._exec(fn,c);
93
                    }
94
                } else { // single shot callback
95
                    this._exec(fn,c);
96
                }
97
                this._shift();
98
                this.id = 0;
99
                return this.run();
100
            } else {
101
                if (c.until) { // test .until condition
102
                    if (c.until()) {
103
                        // Move to the next callback
104
                        this._shift();
105
                        return this.run();
106
                    }
107
                } else if (!c.iterations || !--c.iterations) { // .iterations
108
                    this._shift();
109
                }
110
111
                // Set to execute after the configured timeout
112
                this.id = setTimeout(function () {
113
                    me._exec(fn,c);
114
115
                    // Loop unless the Queue was paused from inside the callback
116
                    if (me.id) {
117
                        // Indicate ready to run state
118
                        me.id = 0;
119
                        // Start the fun all over again
120
                        me.run();
121
                    }
122
                },ms);
123
            }
124
        }
125
126
        return this;
127
    },
128
129
    /**
130
     * Executes the callback function
131
     * @method _exec
132
     * @param fn {Function} the function to execute
133
     * @param c {Object|Function} the callback as defined during add(c)
134
     * @protected
135
     */
136
    _exec : function (fn,c) {
137
        /**
138
         * Fired before a callback is executed
139
         * @event beforeCallback
140
         * @param o {Object} Object literal with the following keys:
141
         * <dl>
142
         * <dt>fn</dt><dd>The function about to be executed</dd>
143
         * <dt>callback</dt><dd>The callback as provided to <code>add(..)</code></dd>
144
         * </dl>
145
         */
146
        this.fire('beforeCallback',{fn:fn,callback:c});
147
148
        fn.call(this);
149
150
        /**
151
         * Fired before a callback is executed
152
         * @event afterCallback
153
         * @param o {Object} Object literal with the following keys:
154
         * <dl>
155
         * <dt>fn</dt><dd>The function just executed</dd>
156
         * <dt>callback</dt><dd>The callback as provided to <code>add(..)</code></dd>
157
         * </dl>
158
         */
159
        this.fire('afterCallback',{fn:fn,callback:c});
160
    },
161
162
    /**
163
     * Shifts the first callback off the Queue
164
     * @method _shift
165
     * @private
166
     */
167
    _shift : function () {
168
        /**
169
         * Fired after a callback is shifted from the Queue
170
         * @event shiftCallback
171
         * @param callback {Function|Object} The callback passed to <code>add(..)</code>
172
         */
173
        this.fire('shiftCallback',this.q.shift());
174
    },
175
    
176
    /**
177
     * Add any number of callbacks to the end of the queue
178
     * @method add
179
     * @param callback* {Function|Object} Any number of callbacks
180
     * @return {Queue} the Queue instance
181
     */
182
    add  : function () {
183
        var callbacks = Y.Array(arguments,0,true);
184
        this.q.splice.apply(this.q,[this.q.length,0].concat(callbacks));
185
186
        /**
187
         * Fired from within <code>add(..)</code> after callbacks are queued
188
         * @event addCallback
189
         * @param callbacks {Array} Array of callbacks passed to <code>add(..)</code>
190
         */
191
        this.fire('addCallback',callbacks);
192
        return this;
193
    },
194
195
    /**
196
     * Pause the execution of the Queue after the execution of the current
197
     * callback completes.  If called from code outside of a queued callback,
198
     * clears the timeout for the pending callback. Paused Queue can be
199
     * restarted with q.run()
200
     * @method pause
201
     * @return {Queue} the Queue instance
202
     */
203
    pause: function () {
204
        clearTimeout(this.id);
205
        this.id = 0;
206
207
        /**
208
         * Fired after Queue is paused
209
         * @event pause
210
         */
211
        this.fire('pause');
212
        return this;
213
    },
214
215
    /**
216
     * Stop and clear the Queue's queue after the current execution of the
217
     * current callback completes.
218
     * @method stop
219
     * @return {Queue} the Queue instance
220
     */
221
    stop : function () { 
222
        this.pause();
223
        this.q = [];
224
225
        /**
226
         * Fired after Queue is stopped
227
         * @event stop
228
         */
229
        this.fire('stop');
230
        return this;
231
    }
232
};
233
Y.augment(Y.Queue,Y.Event.Target);
234
235
236
}, '3.0.0pr1' );