redmine_extensions 0.2.4 → 0.2.5
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
})();
|