redmine_extensions 0.2.4 → 0.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/assets/javascripts/redmine_extensions/application.js +2 -0
- data/app/assets/javascripts/redmine_extensions/blocking.js +6 -2
- data/app/assets/javascripts/redmine_extensions/blocking_module.js +145 -40
- data/app/assets/javascripts/redmine_extensions/blocking_namespace.js +3 -0
- data/app/assets/javascripts/redmine_extensions/blocking_polyfill.js +9 -29
- data/app/assets/javascripts/redmine_extensions/blocking_render.js +112 -0
- data/app/assets/javascripts/redmine_extensions/blocking_schedule.js +155 -41
- data/app/assets/javascripts/redmine_extensions/blocking_utils.js +40 -0
- data/app/assets/javascripts/redmine_extensions/dynamic_loading.js +26 -0
- data/app/assets/javascripts/redmine_extensions/event_bus.js +61 -0
- data/app/assets/javascripts/redmine_extensions/redmine_extensions.js +376 -376
- data/app/assets/javascripts/redmine_extensions/render_polyfill.js +20 -0
- data/lib/redmine_extensions/hooks.rb +32 -21
- data/lib/redmine_extensions/version.rb +1 -1
- metadata +8 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 002eb7a53213f9d31059a1c7bcc099463893c3b4
|
4
|
+
data.tar.gz: 3e26d2836b750e51d43361822f6c2f9da2453e5a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c04c0b3b80337845436b639be277afba66b7322613f57973cccfe58fd640de034c3cad54120de67237967f1455873990667a7604ec894a901f951dda4a94a6eb
|
7
|
+
data.tar.gz: 642bf45996d775e20dad82f5c56fbb4d1e6f5252ec371a8a6104e8e3138a7ebd03948c8ccc0df21f5eec52527326b1993e4b742a81b343d1a25777b3fbce94cf
|
@@ -1,6 +1,10 @@
|
|
1
1
|
/**
|
2
2
|
* code, that cannot be delayed after window.onload or deferred
|
3
3
|
*/
|
4
|
-
//= require ./
|
4
|
+
//= require ./blocking_namespace
|
5
|
+
// require ./event_bus
|
5
6
|
//= require ./blocking_schedule
|
6
|
-
|
7
|
+
// require ./blocking_module
|
8
|
+
//= require ./blocking_polyfill
|
9
|
+
//= require ./blocking_render
|
10
|
+
//= require ./blocking_utils
|
@@ -1,58 +1,163 @@
|
|
1
1
|
(function () {
|
2
2
|
"use strict";
|
3
|
+
return;
|
4
|
+
|
5
|
+
var modules = {};
|
6
|
+
var waiters = {};
|
7
|
+
var modulesOrdered = {};
|
8
|
+
|
9
|
+
window.EASY = window.EASY || {};
|
10
|
+
EASY.modules = {};
|
11
|
+
|
12
|
+
var getMissingModule = function (dependencyNames) {
|
13
|
+
for (var i = 0; i < dependencyNames.length; i++) {
|
14
|
+
var dependencyName = dependencyNames[i];
|
15
|
+
var dependency = modules[dependencyName];
|
16
|
+
if (!dependency || !dependency.instance) return dependencyName;
|
17
|
+
}
|
18
|
+
return null;
|
19
|
+
};
|
20
|
+
|
21
|
+
EASY.eventBus.on("moduleReady", function (moduleName) {
|
22
|
+
if (waiters[moduleName]) {
|
23
|
+
var subWaiters = waiters[moduleName];
|
24
|
+
delete waiters[moduleName];
|
25
|
+
delete modulesOrdered[moduleName];
|
26
|
+
subWaiters.forEach(function (pack) {
|
27
|
+
requireTry(pack);
|
28
|
+
})
|
29
|
+
}
|
30
|
+
});
|
31
|
+
|
32
|
+
|
3
33
|
/**
|
4
|
-
* @
|
34
|
+
* @property {Function} factory
|
35
|
+
* @property {String} name
|
36
|
+
* @property {Array.<Module>} dependencies
|
37
|
+
* @constructor
|
5
38
|
*/
|
6
|
-
|
39
|
+
function Module(moduleName, dependencies, factory) {
|
40
|
+
this.name = moduleName;
|
41
|
+
this.dependencies = dependencies;
|
42
|
+
this.factory = factory;
|
43
|
+
if (modulesOrdered[moduleName]) {
|
44
|
+
this.construct();
|
45
|
+
}
|
46
|
+
}
|
47
|
+
|
48
|
+
Module.prototype.instance = null;
|
49
|
+
Module.prototype.factory = function () {
|
50
|
+
return {};
|
51
|
+
};
|
52
|
+
Module.prototype.name = "unnamed";
|
53
|
+
Module.prototype.dependencies = [];
|
54
|
+
Module.prototype.construct = function (visited) {
|
55
|
+
var dependencyInstances;
|
56
|
+
visited = visited || [];
|
57
|
+
if(visited.indexOf(this.name)>-1){
|
58
|
+
throw "Cyclic dependency: " + this.name + " -> " + visited[visited.length - 1] + " -> " + this.name;
|
59
|
+
}
|
60
|
+
|
61
|
+
if (this.dependencies) {
|
62
|
+
dependencyInstances = [];
|
63
|
+
/** @type {Module} */
|
64
|
+
var dependency;
|
65
|
+
for (var i = 0; i < this.dependencies.length; i++) {
|
66
|
+
dependency = this.dependencies[i];
|
67
|
+
if (dependency.instance) {
|
68
|
+
dependencyInstances.push(dependency.instance);
|
69
|
+
} else {
|
70
|
+
return dependency.construct(visited.concat([this.name]));
|
71
|
+
}
|
72
|
+
}
|
73
|
+
}
|
74
|
+
this.instance = this.factory(dependencyInstances);
|
75
|
+
if (this.instance) {
|
76
|
+
EASY.eventBus.fire("moduleReady", this.name);
|
77
|
+
} else {
|
78
|
+
var self = this;
|
79
|
+
setTimeout(function () {
|
80
|
+
self.construct();
|
81
|
+
}, 10);
|
82
|
+
}
|
83
|
+
};
|
84
|
+
|
85
|
+
var getDependencies = function (dependencyNames) {
|
86
|
+
var dependencyInstances = [];
|
87
|
+
for (var i = 0; i < dependencyNames.length; i++) {
|
88
|
+
var dependencyName = dependencyNames[i];
|
89
|
+
var dependency = modules[dependencyName];
|
90
|
+
if (!dependency) return null;
|
91
|
+
if (!dependency.instance) {
|
92
|
+
dependency.construct();
|
93
|
+
}
|
94
|
+
if (!dependency.instance) {
|
95
|
+
return null;
|
96
|
+
}
|
97
|
+
dependencyInstances.push(dependency.instance);
|
98
|
+
}
|
99
|
+
return dependencyInstances;
|
100
|
+
};
|
7
101
|
/**
|
8
|
-
* @
|
102
|
+
* @param {{dependencies:Array.<String>,body:Function,context:Object}} pack
|
9
103
|
*/
|
10
|
-
var
|
104
|
+
var requireTry = function (pack) {
|
105
|
+
var dependencyInstances = getDependencies(pack.dependencies);
|
106
|
+
if (dependencyInstances !== null) {
|
107
|
+
return pack.body.apply([pack.context || window].concat(dependencyInstances));
|
108
|
+
}
|
109
|
+
var missingModule = getMissingModule(pack.dependencies);
|
110
|
+
if (missingModule === null) return;
|
111
|
+
if (!modules[missingModule]) {
|
112
|
+
modulesOrdered[missingModule] = true;
|
113
|
+
}
|
114
|
+
|
115
|
+
if (!waiters[missingModule]) {
|
116
|
+
waiters[missingModule] = [];
|
117
|
+
}
|
118
|
+
waiters[missingModule].push(pack);
|
119
|
+
};
|
11
120
|
|
12
121
|
|
13
|
-
|
122
|
+
//####################################################################################################################
|
123
|
+
|
14
124
|
/**
|
15
|
-
* Module constructor. Execute [
|
125
|
+
* Module constructor. Execute [factory] only if [moduleName] is registered
|
16
126
|
* Works also, if EASY.registerModule is called after module definition
|
17
127
|
* @param {String} moduleName
|
18
|
-
* @param {
|
19
|
-
* @param {
|
128
|
+
* @param {Array.<String>} dependencies
|
129
|
+
* @param {Function} factory
|
20
130
|
*/
|
21
|
-
EASY.module = function easyModule(moduleName,
|
22
|
-
|
23
|
-
if (rest !== undefined) {
|
24
|
-
func.apply(window, Array.prototype.slice.call(arguments, 2));
|
25
|
-
} else {
|
26
|
-
func();
|
27
|
-
}
|
28
|
-
return;
|
29
|
-
}
|
30
|
-
var modules = waitingModules[moduleName];
|
31
|
-
if (!modules) {
|
32
|
-
waitingModules[moduleName] = modules = [];
|
33
|
-
}
|
34
|
-
if (rest) {
|
35
|
-
var args = Array.prototype.slice.call(arguments, 2);
|
36
|
-
modules.push(function () {
|
37
|
-
func.apply(window, args);
|
38
|
-
})
|
39
|
-
} else {
|
40
|
-
modules.push(func);
|
41
|
-
}
|
131
|
+
EASY.modules.module = function easyModule(moduleName, dependencies, factory) {
|
132
|
+
modules[moduleName] = new Module(moduleName, dependencies, factory);
|
42
133
|
};
|
43
134
|
/**
|
44
|
-
* Enables modules with [moduleName] name
|
45
|
-
* If any modules are in waitingModules, they are executed immediately.
|
46
135
|
* @param {String} moduleName
|
136
|
+
* @param {Function} getter
|
47
137
|
*/
|
48
|
-
EASY.
|
49
|
-
|
50
|
-
if (waitingModules[moduleName]) {
|
51
|
-
var modules = waitingModules[moduleName];
|
52
|
-
for (var i = 0; i < modules.length; i++) {
|
53
|
-
modules[i]();
|
54
|
-
}
|
55
|
-
delete waitingModules[moduleName];
|
56
|
-
}
|
138
|
+
EASY.modules.toModule = function (moduleName, getter) {
|
139
|
+
modules[moduleName] = new Module(moduleName, null, getter);
|
57
140
|
};
|
141
|
+
/**
|
142
|
+
* @param {Array.<String>} dependencies
|
143
|
+
* @param {Function} body
|
144
|
+
* @param {Object} [context]
|
145
|
+
*/
|
146
|
+
EASY.modules.require = function (dependencies, body, context) {
|
147
|
+
if (!dependencies || dependencies.length === 0) body.call(context || window);
|
148
|
+
requireTry({dependencies: dependencies, body: body, context: context});
|
149
|
+
};
|
150
|
+
//####################################################################################################################
|
151
|
+
|
152
|
+
EASY.modules.toModule("jQuery", function () {
|
153
|
+
return window.jQuery;
|
154
|
+
});
|
155
|
+
EASY.modules.toModule("$", function () {
|
156
|
+
return window.jQuery;
|
157
|
+
});
|
158
|
+
EASY.modules.toModule("jQueryUI", function () {
|
159
|
+
if (window.jQuery && window.jQuery.widget) {
|
160
|
+
return window.jQuery;
|
161
|
+
}
|
162
|
+
});
|
58
163
|
})();
|
@@ -1,5 +1,4 @@
|
|
1
|
-
|
2
|
-
(function($, window, undefined) {
|
1
|
+
(function (window, undefined) {
|
3
2
|
// http://paulirish.com/2011/requestanimationframe-for-smart-animating/
|
4
3
|
// http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating
|
5
4
|
|
@@ -7,28 +6,21 @@
|
|
7
6
|
// fixes from Paul Irish and Tino Zijdel
|
8
7
|
|
9
8
|
var lastTime = 0,
|
10
|
-
running,
|
11
|
-
animate = function (elem) {
|
12
|
-
if (running) {
|
13
|
-
window.requestAnimationFrame(animate, elem);
|
14
|
-
jQuery.fx.tick();
|
15
|
-
}
|
16
|
-
},
|
17
9
|
vendors = ['ms', 'moz', 'webkit', 'o'];
|
18
10
|
|
19
|
-
for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
|
20
|
-
window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
|
21
|
-
window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame']
|
22
|
-
|| window[vendors[x]+'CancelRequestAnimationFrame'];
|
11
|
+
for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
|
12
|
+
window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame'];
|
13
|
+
window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame']
|
14
|
+
|| window[vendors[x] + 'CancelRequestAnimationFrame'];
|
23
15
|
}
|
24
16
|
|
25
17
|
if (!window.requestAnimationFrame)
|
26
|
-
window.requestAnimationFrame = function(fn, element) {
|
18
|
+
window.requestAnimationFrame = function (fn, element) {
|
27
19
|
var currTime = new Date().getTime(),
|
28
20
|
delta = currTime - lastTime,
|
29
21
|
timeToCall = Math.max(0, 16 - delta);
|
30
22
|
|
31
|
-
var id = window.setTimeout(function() {
|
23
|
+
var id = window.setTimeout(function () {
|
32
24
|
fn(currTime + timeToCall);
|
33
25
|
},
|
34
26
|
timeToCall
|
@@ -40,20 +32,8 @@
|
|
40
32
|
};
|
41
33
|
|
42
34
|
if (!window.cancelAnimationFrame) {
|
43
|
-
window.cancelAnimationFrame = function(id) {
|
35
|
+
window.cancelAnimationFrame = function (id) {
|
44
36
|
clearTimeout(id);
|
45
37
|
};
|
46
38
|
}
|
47
|
-
|
48
|
-
jQuery.fx.timer = function (timer) {
|
49
|
-
if (timer() && jQuery.timers.push(timer) && !running) {
|
50
|
-
running = true;
|
51
|
-
animate(timer.elem);
|
52
|
-
}
|
53
|
-
};
|
54
|
-
|
55
|
-
jQuery.fx.stop = function() {
|
56
|
-
running = false;
|
57
|
-
};
|
58
|
-
|
59
|
-
}(jQuery, this));
|
39
|
+
}(this));
|
@@ -0,0 +1,112 @@
|
|
1
|
+
(function () {
|
2
|
+
/**
|
3
|
+
* @callback RenderFunction
|
4
|
+
*/
|
5
|
+
// noinspection JSMismatchedCollectionQueryUpdate
|
6
|
+
/**
|
7
|
+
* @type {Array.<{body:RenderFunction,ctx:Object}>}
|
8
|
+
*/
|
9
|
+
var readQueue = [];
|
10
|
+
// noinspection JSMismatchedCollectionQueryUpdate
|
11
|
+
/**
|
12
|
+
* @type {Array.<{body:RenderFunction,ctx:Object,value:*}>}
|
13
|
+
*/
|
14
|
+
var renderQueue = [];
|
15
|
+
var renderPhase = false;
|
16
|
+
var lastTime = 0.0;
|
17
|
+
/**
|
18
|
+
* @param {RenderFunction} body
|
19
|
+
* @param {Object} [context]
|
20
|
+
*/
|
21
|
+
EasyGem.read = function (body, context) {
|
22
|
+
if (renderPhase) {
|
23
|
+
readQueue.push({body: body, ctx: context});
|
24
|
+
} else {
|
25
|
+
body.call(context);
|
26
|
+
}
|
27
|
+
};
|
28
|
+
/**
|
29
|
+
* @param {RenderFunction} body
|
30
|
+
* @param {Object} [context]
|
31
|
+
*/
|
32
|
+
EasyGem.render = function (body, context) {
|
33
|
+
if (renderPhase) {
|
34
|
+
body.call(context, lastTime);
|
35
|
+
} else {
|
36
|
+
renderQueue.push({body: body, ctx: context});
|
37
|
+
}
|
38
|
+
};
|
39
|
+
/**
|
40
|
+
* @param {RenderFunction} read
|
41
|
+
* @param {RenderFunction} render
|
42
|
+
* @param {Object} [context]
|
43
|
+
*/
|
44
|
+
EasyGem.readAndRender = function (read, render, context) {
|
45
|
+
if (renderPhase) {
|
46
|
+
readQueue.push({
|
47
|
+
body: function () {
|
48
|
+
var value = read.call(context);
|
49
|
+
renderQueue.push({body: render, ctx: context, value: value});
|
50
|
+
}, ctx: context
|
51
|
+
});
|
52
|
+
} else {
|
53
|
+
var value = read.call(context);
|
54
|
+
renderQueue.push({body: render, ctx: context, value: value});
|
55
|
+
}
|
56
|
+
};
|
57
|
+
EasyGem.schedule.main(function () {
|
58
|
+
var loop = function (time) {
|
59
|
+
renderPhase = true;
|
60
|
+
lastTime=time;
|
61
|
+
|
62
|
+
setTimeout(function () {
|
63
|
+
renderPhase = false;
|
64
|
+
if (readQueue.length) {
|
65
|
+
var queue = readQueue;
|
66
|
+
readQueue = [];
|
67
|
+
for (i = 0; i < queue.length; i++) {
|
68
|
+
var pack = queue[i];
|
69
|
+
pack.body.call(pack.ctx);
|
70
|
+
}
|
71
|
+
}
|
72
|
+
}, 0);
|
73
|
+
if (renderQueue.length) {
|
74
|
+
var queue = renderQueue;
|
75
|
+
renderQueue = [];
|
76
|
+
for (var i = 0; i < queue.length; i++) {
|
77
|
+
var pack = queue[i];
|
78
|
+
pack.body.call(pack.ctx, time, pack.value);
|
79
|
+
}
|
80
|
+
renderQueue = [];
|
81
|
+
}
|
82
|
+
requestAnimationFrame(loop);
|
83
|
+
};
|
84
|
+
requestAnimationFrame(loop);
|
85
|
+
});
|
86
|
+
EasyGem.test.render = {
|
87
|
+
getPhase: function () {
|
88
|
+
return renderPhase ? "render" : "read";
|
89
|
+
}
|
90
|
+
// ,
|
91
|
+
// test1: function () {
|
92
|
+
// console.log("Phase "+this.getPhase());
|
93
|
+
// EasyGem.render(function (time) {
|
94
|
+
// console.assert(this.getPhase() === "render", "Phase should be render, not ", this.getPhase());
|
95
|
+
// console.assert(typeof time === "number", "Time ", time, " should be number, not ", typeof time);
|
96
|
+
// console.log("render done");
|
97
|
+
// }, this);
|
98
|
+
// EasyGem.read(function () {
|
99
|
+
// console.assert(this.getPhase() === "read", "Phase should be read, not ", this.getPhase());
|
100
|
+
// console.log("read done");
|
101
|
+
// }, this);
|
102
|
+
// EasyGem.readAndRender(function () {
|
103
|
+
// console.assert(this.getPhase() === "read", "Phase should be read, not ", this.getPhase());
|
104
|
+
// return 562;
|
105
|
+
// }, function (time, value) {
|
106
|
+
// console.assert(this.getPhase() === "render", "Phase should be render, not ", this.getPhase());
|
107
|
+
// console.assert(value === 562, "Value should be 562, not ", value);
|
108
|
+
// console.log("readAndRender done");
|
109
|
+
// }, this)
|
110
|
+
// }
|
111
|
+
};
|
112
|
+
})();
|
@@ -1,20 +1,35 @@
|
|
1
1
|
(function () {
|
2
2
|
"use strict";
|
3
3
|
/**
|
4
|
-
* @
|
4
|
+
* @callback SchedulePrerequisite
|
5
5
|
* @return {boolean}
|
6
6
|
*/
|
7
7
|
/**
|
8
|
-
* @typedef {{func:Function,[priority]:number,[pre]:SchedulePrerequisite}} ScheduleTask
|
8
|
+
* @typedef {{func:Function,[priority]:number,[pre]:SchedulePrerequisite,[pres]:Array.<SchedulePrerequisite>}} ScheduleTask
|
9
9
|
*/
|
10
|
-
|
11
|
-
var lateDelay = lateMaxDelay;
|
10
|
+
// noinspection JSMismatchedCollectionQueryUpdate
|
12
11
|
/** @type {Array.<ScheduleTask>} */
|
13
12
|
var mainArray = [];
|
14
13
|
/** @type {Array.<ScheduleTask>} */
|
15
14
|
var lateArray = [];
|
16
|
-
/** @type {Array
|
15
|
+
/** @type {Array.<?ScheduleTask>} */
|
17
16
|
var prerequisiteArray = [];
|
17
|
+
var moduleGetters = {
|
18
|
+
jquery: function () {
|
19
|
+
return window.jQuery;
|
20
|
+
},
|
21
|
+
jqueryui: function () {
|
22
|
+
return window.jQuery && jQuery.Widget;
|
23
|
+
},
|
24
|
+
c3:function () {
|
25
|
+
return window.c3;
|
26
|
+
},
|
27
|
+
ckeditor:function () {
|
28
|
+
return window.CKEDITOR;
|
29
|
+
}
|
30
|
+
};
|
31
|
+
var moduleInstances = {};
|
32
|
+
var writeOut = false;
|
18
33
|
|
19
34
|
/** @param {ScheduleTask} a
|
20
35
|
* @param {ScheduleTask} b
|
@@ -28,39 +43,35 @@
|
|
28
43
|
if (mainArray.length > 0) {
|
29
44
|
count1 = mainArray.length;
|
30
45
|
mainArray.sort(sortFunction);
|
31
|
-
|
32
|
-
mainArray[i].func();
|
33
|
-
}
|
46
|
+
var queue = mainArray;
|
34
47
|
mainArray = [];
|
35
|
-
|
48
|
+
for (var i = 0; i < queue.length; i++) {
|
49
|
+
queue[i].func();
|
50
|
+
}
|
36
51
|
}
|
37
52
|
var count2 = executePrerequisites();
|
38
53
|
var count3 = 0;
|
39
|
-
if (lateArray.length) {
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
}
|
50
|
-
if (i === lateArray.length) {
|
51
|
-
count3 = lateArray.length;
|
52
|
-
lateArray = [];
|
53
|
-
lateDelay = lateMaxDelay;
|
54
|
-
} else {
|
55
|
-
lateArray = lateArray.slice(i);
|
56
|
-
count3 = i;
|
57
|
-
}
|
54
|
+
if (lateArray.length && count1 === 0 && count2 === 0) {
|
55
|
+
lateArray.sort(sortFunction);
|
56
|
+
var limitPriority = lateArray[0].priority - 5;
|
57
|
+
for (i = 0; i < lateArray.length; i++) {
|
58
|
+
if (lateArray[i].priority <= limitPriority) break;
|
59
|
+
}
|
60
|
+
count3 = i;
|
61
|
+
if (i === lateArray.length) {
|
62
|
+
queue = lateArray;
|
63
|
+
lateArray = [];
|
58
64
|
} else {
|
59
|
-
|
65
|
+
queue = lateArray.slice(0, i);
|
66
|
+
lateArray = lateArray.slice(i);
|
67
|
+
}
|
68
|
+
for (i = 0; i < queue.length; i++) {
|
69
|
+
if (queue[i].priority <= limitPriority) break;
|
70
|
+
queue[i].func.call(window);
|
60
71
|
}
|
61
72
|
}
|
62
|
-
if (
|
63
|
-
console.log("
|
73
|
+
if (writeOut && (count1 || count2 || count3)) {
|
74
|
+
console.log("MAIN: " + count1 + " REQ: " + count2 + " LATE: " + count3);
|
64
75
|
}
|
65
76
|
};
|
66
77
|
var isNotNull = function (a) {
|
@@ -71,9 +82,8 @@
|
|
71
82
|
if (prerequisiteArray.length === 0) return 0;
|
72
83
|
var count = 0;
|
73
84
|
for (var i = 0; i < prerequisiteArray.length; i++) {
|
74
|
-
if
|
85
|
+
if(executeOnePrerequisite(prerequisiteArray[i])) {
|
75
86
|
count++;
|
76
|
-
prerequisiteArray[i].func.call(window);
|
77
87
|
prerequisiteArray[i] = null;
|
78
88
|
}
|
79
89
|
}
|
@@ -83,19 +93,60 @@
|
|
83
93
|
}
|
84
94
|
return count;
|
85
95
|
};
|
96
|
+
var executeOnePrerequisite = function (pack) {
|
97
|
+
var getter, getters, instance, instances;
|
98
|
+
if (getter = pack.pre) {
|
99
|
+
instance = preparePrerequisite(getter);
|
100
|
+
if (instance) {
|
101
|
+
pack.func.call(window, instance);
|
102
|
+
return true;
|
103
|
+
}
|
104
|
+
return false;
|
105
|
+
} else if (getters = pack.pres) {
|
106
|
+
instances = [];
|
107
|
+
for (var j = 0; j < getters.length; j++) {
|
108
|
+
getter = getters[j];
|
109
|
+
instance = preparePrerequisite(getter);
|
110
|
+
if (!instance) break;
|
111
|
+
instances.push(instance);
|
112
|
+
}
|
113
|
+
if (instances.length !== getters.length) return false;
|
114
|
+
pack.func.apply(window, instances);
|
115
|
+
return true;
|
116
|
+
}
|
117
|
+
};
|
118
|
+
/**
|
119
|
+
* @param {(Function|string)} getter
|
120
|
+
* @return {(Object|null)}
|
121
|
+
*/
|
122
|
+
var preparePrerequisite = function (getter) {
|
123
|
+
var instance;
|
124
|
+
if (typeof getter === "string") {
|
125
|
+
if (moduleInstances[getter]) {
|
126
|
+
return moduleInstances[getter];
|
127
|
+
} else if (moduleGetters[getter]) {
|
128
|
+
instance = moduleGetters[getter]();
|
129
|
+
if (instance) {
|
130
|
+
moduleInstances[getter] = instance;
|
131
|
+
}
|
132
|
+
return instance;
|
133
|
+
}
|
134
|
+
return null;
|
135
|
+
} else {
|
136
|
+
return getter();
|
137
|
+
}
|
138
|
+
};
|
86
139
|
|
87
140
|
var cycle = function scheduleCycle() {
|
141
|
+
setTimeout(cycle, 30);
|
88
142
|
tick();
|
89
|
-
window.requestAnimationFrame(cycle);
|
90
143
|
};
|
91
144
|
document.addEventListener("DOMContentLoaded", cycle);
|
92
|
-
window.EASY = window.EASY || {};
|
93
145
|
/**
|
94
146
|
*
|
95
|
-
* @type {{out: boolean, late: EASY.schedule.late, require: EASY.schedule.require, main: EASY.schedule.main}}
|
147
|
+
* @type {{out: boolean, late: EASY.schedule.late, require: EASY.schedule.require, main: EASY.schedule.main, define: EASY.schedule.define}}
|
96
148
|
*/
|
97
|
-
|
98
|
-
out: false,
|
149
|
+
EasyGem.schedule = {
|
99
150
|
/**
|
100
151
|
* Functions, which should be executed right after "DOMContentLoaded" event
|
101
152
|
* @param {Function} func
|
@@ -105,20 +156,83 @@
|
|
105
156
|
mainArray.push({func: func, priority: priority || 0})
|
106
157
|
},
|
107
158
|
/**
|
108
|
-
* Functions, which should wait for prerequisite fulfillment
|
159
|
+
* Functions, which should wait for [prerequisite] fulfillment
|
160
|
+
* After that [func] is executed with return value of [prerequisite] as parameter
|
109
161
|
* @param {Function} func
|
110
|
-
* @param {SchedulePrerequisite} prerequisite
|
162
|
+
* @param {...(SchedulePrerequisite|string)} prerequisite
|
111
163
|
*/
|
112
164
|
require: function (func, prerequisite) {
|
113
|
-
|
165
|
+
if (arguments.length > 2) {
|
166
|
+
var pres = [];
|
167
|
+
for (var i = 1; i < arguments.length; i++) {
|
168
|
+
if (typeof arguments[i] === "string") {
|
169
|
+
pres.push(arguments[i].toLocaleLowerCase());
|
170
|
+
} else {
|
171
|
+
pres.push(arguments[i]);
|
172
|
+
}
|
173
|
+
}
|
174
|
+
var pack = {func: func, pres: pres};
|
175
|
+
if (!executeOnePrerequisite(pack)) {
|
176
|
+
prerequisiteArray.push(pack);
|
177
|
+
}
|
178
|
+
} else {
|
179
|
+
if (typeof prerequisite === "string") {
|
180
|
+
prerequisite = prerequisite.toLocaleLowerCase();
|
181
|
+
}
|
182
|
+
pack = {func: func, pre: prerequisite};
|
183
|
+
if (!executeOnePrerequisite(pack)) {
|
184
|
+
prerequisiteArray.push(pack);
|
185
|
+
}
|
186
|
+
}
|
114
187
|
},
|
115
188
|
/**
|
116
189
|
* Functions, which should be executed after several render loops after "DOMContentLoaded" event
|
190
|
+
* each 5 levels of priority increase delay by one stack
|
117
191
|
* @param {Function} func
|
118
192
|
* @param {number} [priority]
|
119
193
|
*/
|
120
194
|
late: function (func, priority) {
|
121
195
|
lateArray.push({func: func, priority: priority || 0})
|
196
|
+
},
|
197
|
+
/**
|
198
|
+
* Define module, which will be loaded by [require] function with [name] argument
|
199
|
+
* Only one instance will be created
|
200
|
+
* @param {string} name
|
201
|
+
* @param {Function} getter
|
202
|
+
*/
|
203
|
+
define: function (name, getter) {
|
204
|
+
moduleGetters[name.toLocaleLowerCase()] = getter;
|
205
|
+
}
|
206
|
+
};
|
207
|
+
EASY.schedule = EasyGem.schedule;
|
208
|
+
EasyGem.test.schedule = {
|
209
|
+
setOut: function (state) {
|
210
|
+
writeOut = state;
|
211
|
+
},
|
212
|
+
isLoaded: function () {
|
213
|
+
if (mainArray.length > 0) return false;
|
214
|
+
if (prerequisiteArray.length > 0) return false;
|
215
|
+
return lateArray.length <= 0;
|
216
|
+
},
|
217
|
+
lateIsLoaded: function () {
|
218
|
+
return lateArray.length <= 0;
|
219
|
+
},
|
220
|
+
queueContents: function () {
|
221
|
+
var modules = [];
|
222
|
+
for (var i = 0; i < prerequisiteArray.length; i++) {
|
223
|
+
var prerequisite = prerequisiteArray[i];
|
224
|
+
if (typeof prerequisite.pre === "string") {
|
225
|
+
modules.push(prerequisite.pre);
|
226
|
+
} else if (prerequisite.pres) {
|
227
|
+
for (var j = 0; j < prerequisite.pres.length; j++) {
|
228
|
+
var pre = prerequisite.pres[j];
|
229
|
+
if (typeof pre === "string") {
|
230
|
+
modules.push(pre);
|
231
|
+
}
|
232
|
+
}
|
233
|
+
}
|
234
|
+
}
|
235
|
+
return {main: mainArray.length, late: lateArray, require: prerequisiteArray.length, waitsFor: modules};
|
122
236
|
}
|
123
237
|
};
|
124
238
|
})();
|