Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
YUI.add('timers', function (Y, NAME) {
2
 
3
/**
4
Provides utilities for timed asynchronous callback execution.
5
Y.soon is a setImmediate/process.nextTick/setTimeout wrapper.
6
 
7
This module includes [asap.js](https://github.com/kriskowal/asap) for scheduling
8
asynchronous tasks.
9
 
10
@module timers
11
@main timers
12
@author Steven Olmsted
13
**/
14
 
15
// Hack. asap.js is written as a Node module and expects require, module and
16
// global to be available in the module's scope.
17
var module = {},
18
    global = Y.config.global;
19
 
20
// `asap` only requires a `queue` module that is bundled into this same file.
21
function require(mod) {
22
    return Queue;
23
}
24
"use strict";
25
 
26
module.exports = Queue;
27
function Queue(capacity) {
28
    this.capacity = this.snap(capacity);
29
    this.length = 0;
30
    this.front = 0;
31
    this.initialize();
32
}
33
 
34
Queue.prototype.push = function (value) {
35
    var length = this.length;
36
    if (this.capacity <= length) {
37
        this.grow(this.snap(this.capacity * this.growFactor));
38
    }
39
    var index = (this.front + length) & (this.capacity - 1);
40
    this[index] = value;
41
    this.length = length + 1;
42
};
43
 
44
Queue.prototype.shift = function () {
45
    var front = this.front;
46
    var result = this[front];
47
 
48
    this[front] = void 0;
49
    this.front = (front + 1) & (this.capacity - 1);
50
    this.length--;
51
    return result;
52
};
53
 
54
Queue.prototype.grow = function (capacity) {
55
    var oldFront = this.front;
56
    var oldCapacity = this.capacity;
57
    var oldQueue = new Array(oldCapacity);
58
    var length = this.length;
59
 
60
    copy(this, 0, oldQueue, 0, oldCapacity);
61
    this.capacity = capacity;
62
    this.initialize();
63
    this.front = 0;
64
    if (oldFront + length <= oldCapacity) {
65
        // Can perform direct linear copy
66
        copy(oldQueue, oldFront, this, 0, length);
67
    } else {
68
        // Cannot perform copy directly, perform as much as possible at the
69
        // end, and then copy the rest to the beginning of the buffer
70
        var lengthBeforeWrapping =
71
            length - ((oldFront + length) & (oldCapacity - 1));
72
        copy(
73
            oldQueue,
74
            oldFront,
75
            this,
76
            0,
77
            lengthBeforeWrapping
78
        );
79
        copy(
80
            oldQueue,
81
            0,
82
            this,
83
            lengthBeforeWrapping,
84
            length - lengthBeforeWrapping
85
        );
86
    }
87
};
88
 
89
Queue.prototype.initialize = function () {
90
    var length = this.capacity;
91
    for (var i = 0; i < length; ++i) {
92
        this[i] = void 0;
93
    }
94
};
95
 
96
Queue.prototype.snap = function (capacity) {
97
    if (typeof capacity !== "number") {
98
        return this.minCapacity;
99
    }
100
    return pow2AtLeast(
101
        Math.min(this.maxCapacity, Math.max(this.minCapacity, capacity))
102
    );
103
};
104
 
105
Queue.prototype.maxCapacity = (1 << 30) | 0;
106
Queue.prototype.minCapacity = 16;
107
Queue.prototype.growFactor = 8;
108
 
109
function copy(source, sourceIndex, target, targetIndex, length) {
110
    for (var index = 0; index < length; ++index) {
111
        target[index + targetIndex] = source[index + sourceIndex];
112
    }
113
}
114
 
115
function pow2AtLeast(n) {
116
    n = n >>> 0;
117
    n = n - 1;
118
    n = n | (n >> 1);
119
    n = n | (n >> 2);
120
    n = n | (n >> 4);
121
    n = n | (n >> 8);
122
    n = n | (n >> 16);
123
    return n + 1;
124
}
125
"use strict";
126
 
127
// Use the fastest possible means to execute a task in a future turn
128
// of the event loop.
129
 
130
// Queue is a circular buffer with good locality of reference and doesn't
131
// allocate new memory unless there are more than `InitialCapacity` parallel
132
// tasks in which case it will resize itself generously to x8 more capacity.
133
// The use case of asap should require no or few amount of resizes during
134
// runtime.
135
// Calling a task frees a slot immediately so if the calling
136
// has a side effect of queuing itself again, it can be sustained
137
// without additional memory
138
// Queue specifically uses
139
// http://en.wikipedia.org/wiki/Circular_buffer#Use_a_Fill_Count
140
// Because:
141
// 1. We need fast .length operation, since queue
142
//   could have changed after every iteration
143
// 2. Modulus can be negated by using power-of-two
144
//   capacities and replacing it with bitwise AND
145
// 3. It will not be used in a multi-threaded situation.
146
 
147
var Queue = require("./queue");
148
 
149
//1024 = InitialCapacity
150
var queue = new Queue(1024);
151
var flushing = false;
152
var requestFlush = void 0;
153
var hasSetImmediate = typeof setImmediate === "function";
154
var domain;
155
 
156
// Avoid shims from browserify.
157
// The existence of `global` in browsers is guaranteed by browserify.
158
var process = global.process;
159
 
160
// Note that some fake-Node environments,
161
// like the Mocha test runner, introduce a `process` global.
162
var isNodeJS = !!process && ({}).toString.call(process) === "[object process]";
163
 
164
function flush() {
165
    /* jshint loopfunc: true */
166
 
167
    while (queue.length > 0) {
168
        var task = queue.shift();
169
 
170
        try {
171
            task.call();
172
 
173
        } catch (e) {
174
            if (isNodeJS) {
175
                // In node, uncaught exceptions are considered fatal errors.
176
                // Re-throw them to interrupt flushing!
177
 
178
                // Ensure continuation if an uncaught exception is suppressed
179
                // listening process.on("uncaughtException") or domain("error").
180
                requestFlush();
181
 
182
                throw e;
183
 
184
            } else {
185
                // In browsers, uncaught exceptions are not fatal.
186
                // Re-throw them asynchronously to avoid slow-downs.
187
                setTimeout(function () {
188
                    throw e;
189
                }, 0);
190
            }
191
        }
192
    }
193
 
194
    flushing = false;
195
}
196
 
197
if (isNodeJS) {
198
    // Node.js
199
    requestFlush = function () {
200
        // Ensure flushing is not bound to any domain.
201
        var currentDomain = process.domain;
202
        if (currentDomain) {
203
            domain = domain || (1,require)("domain");
204
            domain.active = process.domain = null;
205
        }
206
 
207
        // Avoid tick recursion - use setImmediate if it exists.
208
        if (flushing && hasSetImmediate) {
209
            setImmediate(flush);
210
        } else {
211
            process.nextTick(flush);
212
        }
213
 
214
        if (currentDomain) {
215
            domain.active = process.domain = currentDomain;
216
        }
217
    };
218
 
219
} else if (hasSetImmediate) {
220
    // In IE10, or https://github.com/NobleJS/setImmediate
221
    requestFlush = function () {
222
        setImmediate(flush);
223
    };
224
 
225
} else if (typeof MessageChannel !== "undefined") {
226
    // modern browsers
227
    // http://www.nonblocking.io/2011/06/windownexttick.html
228
    var channel = new MessageChannel();
229
    // At least Safari Version 6.0.5 (8536.30.1) intermittently cannot create
230
    // working message ports the first time a page loads.
231
    channel.port1.onmessage = function () {
232
        requestFlush = requestPortFlush;
233
        channel.port1.onmessage = flush;
234
        flush();
235
    };
236
    var requestPortFlush = function () {
237
        // Opera requires us to provide a message payload, regardless of
238
        // whether we use it.
239
        channel.port2.postMessage(0);
240
    };
241
    requestFlush = function () {
242
        setTimeout(flush, 0);
243
        requestPortFlush();
244
    };
245
 
246
} else {
247
    // old browsers
248
    requestFlush = function () {
249
        setTimeout(flush, 0);
250
    };
251
}
252
 
253
function asap(task) {
254
    if (isNodeJS && process.domain) {
255
        task = process.domain.bind(task);
256
    }
257
 
258
    queue.push(task);
259
 
260
    if (!flushing) {
261
        requestFlush();
262
        flushing = true;
263
    }
264
};
265
 
266
module.exports = asap;
267
/**
268
@module timers
269
**/
270
 
271
/**
272
Y.soon accepts a callback function.  The callback function will be called
273
once in a future turn of the JavaScript event loop.  If the function
274
requires a specific execution context or arguments, wrap it with Y.bind.
275
Y.soon returns an object with a cancel method.  If the cancel method is
276
called before the callback function, the callback function won't be
277
called.
278
 
279
@method soon
280
@for YUI
281
@param {Function} callbackFunction
282
@return {Object} An object with a cancel method.  If the cancel method is
283
    called before the callback function, the callback function won't be
284
    called.
285
**/
286
function soon(callbackFunction) {
287
    var canceled;
288
 
289
    soon._asynchronizer(function () {
290
        // Some asynchronizers may provide their own cancellation
291
        // methods such as clearImmediate or clearTimeout but some
292
        // asynchronizers do not.  For simplicity, cancellation is
293
        // entirely handled here rather than wrapping the other methods.
294
        // All asynchronizers are expected to always call this anonymous
295
        // function.
296
        if (!canceled) {
297
            callbackFunction();
298
        }
299
    });
300
 
301
    return {
302
        cancel: function () {
303
            canceled = 1;
304
        }
305
    };
306
}
307
 
308
soon._asynchronizer = asap;
309
soon._impl = 'asap';
310
 
311
Y.soon = soon;
312
 
313
 
314
}, '3.18.1', {"requires": ["yui-base"]});