~launchpad-pqm/launchpad/devel

« back to all changes in this revision

Viewing changes to lib/lp/app/javascript/lazr/loader/prefetch.js

[r=deryck][bug=803954] Bring lazr-js source into lp tree and package
        yui as a dependency

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (c) 2010, Canonical Ltd. All rights reserved. */
 
2
 
 
3
/**
 
4
 * Prefetch a set of files, deferring calls to 'use' until the
 
5
 * preloaded files are finished loading.
 
6
 *
 
7
 * @public
 
8
 */
 
9
 
 
10
YUI.prototype.prefetch = function prefetch() {
 
11
    var Y = this,
 
12
        deferred = [],
 
13
        preload = arguments,
 
14
        pending = arguments.length;
 
15
 
 
16
    var YArray_each = Y.Array.each,
 
17
        YGet_script = Y.Get.script;
 
18
 
 
19
    /**
 
20
     * Wrap the native 'use' function to add some smarts around
 
21
     * our custom loading of the rolled-up minified files so that
 
22
     * we delay the loader from firing until the rolled-up files
 
23
     * are finished loading, in order to avoid loading the
 
24
     * modules twice.
 
25
     */
 
26
    var native_use = Y.use;
 
27
 
 
28
    /* Now replace the original 'use' function with our own. */
 
29
    Y.use = function use() {
 
30
        /**
 
31
         * If all external dependencies have been loaded, just
 
32
         * call the native 'use' function directly.
 
33
         */
 
34
        if (!pending) {
 
35
            native_use.apply(Y, arguments);
 
36
        } else {
 
37
            /**
 
38
             * If there are things still loading, queue calls to 'use'
 
39
             *  until they are finished.
 
40
             */
 
41
            var ridx = arguments.length,
 
42
            args = [];
 
43
            /* Make a copy of the original arguments. */
 
44
            while (--ridx >= 0) {
 
45
                args[ridx] = arguments[ridx];
 
46
            }
 
47
 
 
48
            /* Push copied arguments into the queue. */
 
49
            deferred.push(args);
 
50
        }
 
51
    };
 
52
 
 
53
    /**
 
54
     * For each item to be preloaded, use the Y.Get utility to
 
55
     * fetch the script (which might fetch them in parallel). When
 
56
     * all the scripts are finished loading, we'll process the
 
57
     * deferred calls to use with the native 'use' function.
 
58
     */
 
59
    YArray_each(preload, function(value) {
 
60
        YGet_script(value, {onEnd: function() {
 
61
            /**
 
62
             * Once an item has finished preloading, we decrement
 
63
             * the pending variable. Once it reaches zero, we
 
64
             * know all preload items have finished loading.
 
65
             */
 
66
            pending--;
 
67
 
 
68
            /**
 
69
             * Once we're done, restore the original 'use'
 
70
             * function and call all of the deferred callbacks in
 
71
             * their original order.
 
72
             */
 
73
            if (!pending) {
 
74
                Y.use = native_use;
 
75
 
 
76
                /**
 
77
                 * Attach the 'loader' module, which *should* be
 
78
                 * already loaded by now.
 
79
                 */
 
80
                Y._attach(["loader"]);
 
81
                YArray_each(deferred, function(value) {
 
82
                    native_use.apply(this, value);
 
83
                });
 
84
            }
 
85
        }, attributes: {defer: "defer"}});
 
86
    });
 
87
};