Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
seleniumhq
GitHub Repository: seleniumhq/selenium
Path: blob/trunk/third_party/closure/goog/module/moduleinfo.js
2868 views
1
// Copyright 2008 The Closure Library Authors. All Rights Reserved.
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
// http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS-IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
15
/**
16
* @fileoverview Defines the goog.module.ModuleInfo class.
17
*
18
*/
19
20
goog.provide('goog.module.ModuleInfo');
21
22
goog.require('goog.Disposable');
23
goog.require('goog.async.throwException');
24
goog.require('goog.functions');
25
/** @suppress {extraRequire} */
26
goog.require('goog.module');
27
goog.require('goog.module.BaseModule');
28
goog.require('goog.module.ModuleLoadCallback');
29
30
// TODO(johnlenz): goog.module.ModuleManager.FailureType into its own file.
31
goog.forwardDeclare('goog.module.ModuleManager.FailureType');
32
33
34
35
/**
36
* A ModuleInfo object is used by the ModuleManager to hold information about a
37
* module of js code that may or may not yet be loaded into the environment.
38
*
39
* @param {Array<string>} deps Ids of the modules that must be loaded before
40
* this one. The ids must be in dependency order (i.e. if the ith module
41
* depends on the jth module, then i > j).
42
* @param {string} id The module's ID.
43
* @constructor
44
* @extends {goog.Disposable}
45
* @final
46
*/
47
goog.module.ModuleInfo = function(deps, id) {
48
goog.Disposable.call(this);
49
50
/**
51
* A list of the ids of the modules that must be loaded before this module.
52
* @type {Array<string>}
53
* @private
54
*/
55
this.deps_ = deps;
56
57
/**
58
* The module's ID.
59
* @type {string}
60
* @private
61
*/
62
this.id_ = id;
63
64
/**
65
* Callbacks to execute once this module is loaded.
66
* @type {Array<goog.module.ModuleLoadCallback>}
67
* @private
68
*/
69
this.onloadCallbacks_ = [];
70
71
/**
72
* Callbacks to execute if the module load errors.
73
* @type {Array<goog.module.ModuleLoadCallback>}
74
* @private
75
*/
76
this.onErrorCallbacks_ = [];
77
78
/**
79
* Early callbacks to execute once this module is loaded. Called after
80
* module initialization but before regular onload callbacks.
81
* @type {Array<goog.module.ModuleLoadCallback>}
82
* @private
83
*/
84
this.earlyOnloadCallbacks_ = [];
85
};
86
goog.inherits(goog.module.ModuleInfo, goog.Disposable);
87
88
89
/**
90
* The uris that can be used to retrieve this module's code.
91
* @type {Array<string>?}
92
* @private
93
*/
94
goog.module.ModuleInfo.prototype.uris_ = null;
95
96
97
/**
98
* The constructor to use to instantiate the module object after the module
99
* code is loaded. This must be either goog.module.BaseModule or a subclass of
100
* it.
101
* @type {Function}
102
* @private
103
*/
104
goog.module.ModuleInfo.prototype.moduleConstructor_ = goog.module.BaseModule;
105
106
107
/**
108
* The module object. This will be null until the module is loaded.
109
* @type {goog.module.BaseModule?}
110
* @private
111
*/
112
goog.module.ModuleInfo.prototype.module_ = null;
113
114
115
/**
116
* Gets the dependencies of this module.
117
* @return {Array<string>} The ids of the modules that this module depends on.
118
*/
119
goog.module.ModuleInfo.prototype.getDependencies = function() {
120
return this.deps_;
121
};
122
123
124
/**
125
* Gets the ID of this module.
126
* @return {string} The ID.
127
*/
128
goog.module.ModuleInfo.prototype.getId = function() {
129
return this.id_;
130
};
131
132
133
/**
134
* Sets the uris of this module.
135
* @param {Array<string>} uris Uris for this module's code.
136
*/
137
goog.module.ModuleInfo.prototype.setUris = function(uris) {
138
this.uris_ = uris;
139
};
140
141
142
/**
143
* Gets the uris of this module.
144
* @return {Array<string>?} Uris for this module's code.
145
*/
146
goog.module.ModuleInfo.prototype.getUris = function() {
147
return this.uris_;
148
};
149
150
151
/**
152
* Sets the constructor to use to instantiate the module object after the
153
* module code is loaded.
154
* @param {Function} constructor The constructor of a goog.module.BaseModule
155
* subclass.
156
*/
157
goog.module.ModuleInfo.prototype.setModuleConstructor = function(constructor) {
158
if (this.moduleConstructor_ === goog.module.BaseModule) {
159
this.moduleConstructor_ = constructor;
160
} else {
161
throw Error('Cannot set module constructor more than once.');
162
}
163
};
164
165
166
/**
167
* Registers a function that should be called after the module is loaded. These
168
* early callbacks are called after {@link Module#initialize} is called but
169
* before the other callbacks are called.
170
* @param {Function} fn A callback function that takes a single argument which
171
* is the module context.
172
* @param {Object=} opt_handler Optional handler under whose scope to execute
173
* the callback.
174
* @return {!goog.module.ModuleLoadCallback} Reference to the callback
175
* object.
176
*/
177
goog.module.ModuleInfo.prototype.registerEarlyCallback = function(
178
fn, opt_handler) {
179
return this.registerCallback_(this.earlyOnloadCallbacks_, fn, opt_handler);
180
};
181
182
183
/**
184
* Registers a function that should be called after the module is loaded.
185
* @param {Function} fn A callback function that takes a single argument which
186
* is the module context.
187
* @param {Object=} opt_handler Optional handler under whose scope to execute
188
* the callback.
189
* @return {!goog.module.ModuleLoadCallback} Reference to the callback
190
* object.
191
*/
192
goog.module.ModuleInfo.prototype.registerCallback = function(fn, opt_handler) {
193
return this.registerCallback_(this.onloadCallbacks_, fn, opt_handler);
194
};
195
196
197
/**
198
* Registers a function that should be called if the module load fails.
199
* @param {Function} fn A callback function that takes a single argument which
200
* is the failure type.
201
* @param {Object=} opt_handler Optional handler under whose scope to execute
202
* the callback.
203
* @return {!goog.module.ModuleLoadCallback} Reference to the callback
204
* object.
205
*/
206
goog.module.ModuleInfo.prototype.registerErrback = function(fn, opt_handler) {
207
return this.registerCallback_(this.onErrorCallbacks_, fn, opt_handler);
208
};
209
210
211
/**
212
* Registers a function that should be called after the module is loaded.
213
* @param {Array<goog.module.ModuleLoadCallback>} callbacks The array to
214
* add the callback to.
215
* @param {Function} fn A callback function that takes a single argument which
216
* is the module context.
217
* @param {Object=} opt_handler Optional handler under whose scope to execute
218
* the callback.
219
* @return {!goog.module.ModuleLoadCallback} Reference to the callback
220
* object.
221
* @private
222
*/
223
goog.module.ModuleInfo.prototype.registerCallback_ = function(
224
callbacks, fn, opt_handler) {
225
var callback = new goog.module.ModuleLoadCallback(fn, opt_handler);
226
callbacks.push(callback);
227
return callback;
228
};
229
230
231
/**
232
* Determines whether the module has been loaded.
233
* @return {boolean} Whether the module has been loaded.
234
*/
235
goog.module.ModuleInfo.prototype.isLoaded = function() {
236
return !!this.module_;
237
};
238
239
240
/**
241
* Gets the module.
242
* @return {goog.module.BaseModule?} The module if it has been loaded.
243
* Otherwise, null.
244
*/
245
goog.module.ModuleInfo.prototype.getModule = function() {
246
return this.module_;
247
};
248
249
250
/**
251
* Sets this module as loaded.
252
* @param {function() : Object} contextProvider A function that provides the
253
* module context.
254
* @return {boolean} Whether any errors occurred while executing the onload
255
* callbacks.
256
*/
257
goog.module.ModuleInfo.prototype.onLoad = function(contextProvider) {
258
// Instantiate and initialize the module object.
259
var module = new this.moduleConstructor_;
260
module.initialize(contextProvider());
261
262
// Keep an internal reference to the module.
263
this.module_ = module;
264
265
// Fire any early callbacks that were waiting for the module to be loaded.
266
var errors =
267
!!this.callCallbacks_(this.earlyOnloadCallbacks_, contextProvider());
268
269
// Fire any callbacks that were waiting for the module to be loaded.
270
errors =
271
errors || !!this.callCallbacks_(this.onloadCallbacks_, contextProvider());
272
273
if (!errors) {
274
// Clear the errbacks.
275
this.onErrorCallbacks_.length = 0;
276
}
277
278
return errors;
279
};
280
281
282
/**
283
* Calls the error callbacks for the module.
284
* @param {goog.module.ModuleManager.FailureType} cause What caused the error.
285
*/
286
goog.module.ModuleInfo.prototype.onError = function(cause) {
287
var result = this.callCallbacks_(this.onErrorCallbacks_, cause);
288
if (result) {
289
// Throw an exception asynchronously. Do not let the exception leak
290
// up to the caller, or it will blow up the module loading framework.
291
window.setTimeout(
292
goog.functions.error('Module errback failures: ' + result), 0);
293
}
294
this.earlyOnloadCallbacks_.length = 0;
295
this.onloadCallbacks_.length = 0;
296
};
297
298
299
/**
300
* Helper to call the callbacks after module load.
301
* @param {Array<goog.module.ModuleLoadCallback>} callbacks The callbacks
302
* to call and then clear.
303
* @param {*} context The module context.
304
* @return {Array<*>} Any errors encountered while calling the callbacks,
305
* or null if there were no errors.
306
* @private
307
*/
308
goog.module.ModuleInfo.prototype.callCallbacks_ = function(callbacks, context) {
309
// NOTE(nicksantos):
310
// In practice, there are two error-handling scenarios:
311
// 1) The callback does some mandatory initialization of the module.
312
// 2) The callback is for completion of some optional UI event.
313
// There's no good way to handle both scenarios.
314
//
315
// Our strategy here is to protect module manager from exceptions, so that
316
// the failure of one module doesn't affect the loading of other modules.
317
// Errors are thrown outside of the current stack frame, so they still
318
// get reported but don't interrupt execution.
319
320
// Call each callback in the order they were registered
321
var errors = [];
322
for (var i = 0; i < callbacks.length; i++) {
323
try {
324
callbacks[i].execute(context);
325
} catch (e) {
326
goog.async.throwException(e);
327
errors.push(e);
328
}
329
}
330
331
// Clear the list of callbacks.
332
callbacks.length = 0;
333
return errors.length ? errors : null;
334
};
335
336
337
/** @override */
338
goog.module.ModuleInfo.prototype.disposeInternal = function() {
339
goog.module.ModuleInfo.superClass_.disposeInternal.call(this);
340
goog.dispose(this.module_);
341
};
342
343