webfontloader 1.6.16 → 1.6.18

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2c8b0ed55d7d0987103410b36d6a83c594863321
4
- data.tar.gz: ef98fbbc93f81cacbef8029e54d37b1337ff0c2b
3
+ metadata.gz: 9740f9fd7799d5bacfc635b1a72de4d82e2e6593
4
+ data.tar.gz: dca07267fc62b2b25d93b7d7f9ca2306621799fd
5
5
  SHA512:
6
- metadata.gz: f071e8f200f9ec23d45152c6a2923f0f365887f98b4f8aa48ff3ba99e542c04a143bed3dce59471735f7cb5fc01e08622ef37127c3e6bab1d003493f874ab2a4
7
- data.tar.gz: d596c7ceffa31045c01f27cbbd89e4034cdc0ac7bfecea0237bf0a0ddfad4cd38b9517d0ffd643ae265a32584778200cb8326415feeab1a65acb5bf512c0caa5
6
+ metadata.gz: 0b3c68c01b2a9d085184b6ff6f27af8ed6ec2d998a6f1ea22931426e8decf827b99b59221d7b73dd064f1654c7a6993ea8ad6300fff9444388f4e28102ed99dc
7
+ data.tar.gz: 73d21cbe6881a6f555139955f99f80b6f4bfa20063adf994e0d45be56c14f2dc7bdb9dd7944a1c6e091f3bfaf050a7f9c79bc40392a49e592a86c3290522f108
data/CHANGELOG CHANGED
@@ -1,3 +1,11 @@
1
+ v1.6.18 (January 4, 2015)
2
+
3
+ * Version bump.
4
+
5
+ v1.6.17 (January 4, 2015)
6
+
7
+ * Upgrade closure compiler and base.js to latest version (no code changes).
8
+
1
9
  v1.6.16 (December 8, 2015)
2
10
 
3
11
  * Add support for detecting font loads even if the font isn't in the CSSOM yet (workaround for a Chrome bug).
data/README.md CHANGED
@@ -323,7 +323,7 @@ You can also supply the `text` parameter to perform character subsetting:
323
323
  WebFontConfig = {
324
324
  google: {
325
325
  families: ['Droid Sans', 'Droid Serif'],
326
- text: 'abcdedfghijklmopqrstuvwxyz!'
326
+ text: 'abcdefghijklmnopqrstuvwxyz!'
327
327
  }
328
328
  };
329
329
  ```
@@ -3,7 +3,7 @@ require 'yaml'
3
3
  require 'webfontloader/modules'
4
4
 
5
5
  module WebFontLoader
6
- VERSION = '1.6.16'
6
+ VERSION = '1.6.18'
7
7
 
8
8
  ProjectRoot = File.expand_path(File.dirname(__FILE__) + "/..")
9
9
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "webfontloader",
3
- "version": "1.6.15",
3
+ "version": "1.6.17",
4
4
  "description": "Web Font Loader gives you added control when using linked fonts via @font-face.",
5
5
  "main": "webfontloader.js",
6
6
  "scripts": {
@@ -542,7 +542,18 @@ describe('DomHelper', function () {
542
542
 
543
543
  beforeEach(function () {
544
544
  domHelper = new DomHelper({
545
- document: {}
545
+ document: {
546
+ addEventListener: function (event, callback) {
547
+ function check() {
548
+ if (domHelper.document_.body) {
549
+ callback();
550
+ } else {
551
+ setTimeout(check, 10);
552
+ }
553
+ }
554
+ check();
555
+ }
556
+ }
546
557
  });
547
558
 
548
559
  callback = jasmine.createSpy('callback');
@@ -92,14 +92,20 @@ goog.scope(function () {
92
92
  */
93
93
  DomHelper.prototype.whenBodyExists = function(callback) {
94
94
  var that = this;
95
- var check = function() {
96
- if (that.document_.body) {
97
- callback();
95
+
96
+ if (that.document_.body) {
97
+ callback();
98
+ } else {
99
+ if (that.document_.addEventListener) {
100
+ that.document_.addEventListener('DOMContentLoaded', callback);
98
101
  } else {
99
- setTimeout(check, 0);
102
+ that.document_.onreadystatechange = function () {
103
+ if (that.document_.readyState == 'interactive') {
104
+ callback();
105
+ }
106
+ };
100
107
  }
101
108
  }
102
- check();
103
109
  };
104
110
 
105
111
  /**
@@ -19,26 +19,27 @@
19
19
  * global <code>CLOSURE_NO_DEPS</code> is set to true. This allows projects to
20
20
  * include their own deps file(s) from different locations.
21
21
  *
22
+ * @author arv@google.com (Erik Arvidsson)
22
23
  *
23
24
  * @provideGoog
24
25
  */
25
26
 
26
27
 
27
28
  /**
28
- * @define {boolean} Overridden to true by the compiler when --closure_pass
29
- * or --mark_as_compiled is specified.
29
+ * @define {boolean} Overridden to true by the compiler when
30
+ * --process_closure_primitives is specified.
30
31
  */
31
32
  var COMPILED = false;
32
33
 
33
34
 
34
35
  /**
35
- * Base namespace for the Closure library. Checks to see goog is
36
- * already defined in the current scope before assigning to prevent
37
- * clobbering if base.js is loaded more than once.
36
+ * Base namespace for the Closure library. Checks to see goog is already
37
+ * defined in the current scope before assigning to prevent clobbering if
38
+ * base.js is loaded more than once.
38
39
  *
39
40
  * @const
40
41
  */
41
- var goog = goog || {}; // Identifies this file as the Closure base.
42
+ var goog = goog || {};
42
43
 
43
44
 
44
45
  /**
@@ -47,6 +48,129 @@ var goog = goog || {}; // Identifies this file as the Closure base.
47
48
  goog.global = this;
48
49
 
49
50
 
51
+ /**
52
+ * A hook for overriding the define values in uncompiled mode.
53
+ *
54
+ * In uncompiled mode, {@code CLOSURE_UNCOMPILED_DEFINES} may be defined before
55
+ * loading base.js. If a key is defined in {@code CLOSURE_UNCOMPILED_DEFINES},
56
+ * {@code goog.define} will use the value instead of the default value. This
57
+ * allows flags to be overwritten without compilation (this is normally
58
+ * accomplished with the compiler's "define" flag).
59
+ *
60
+ * Example:
61
+ * <pre>
62
+ * var CLOSURE_UNCOMPILED_DEFINES = {'goog.DEBUG': false};
63
+ * </pre>
64
+ *
65
+ * @type {Object<string, (string|number|boolean)>|undefined}
66
+ */
67
+ goog.global.CLOSURE_UNCOMPILED_DEFINES;
68
+
69
+
70
+ /**
71
+ * A hook for overriding the define values in uncompiled or compiled mode,
72
+ * like CLOSURE_UNCOMPILED_DEFINES but effective in compiled code. In
73
+ * uncompiled code CLOSURE_UNCOMPILED_DEFINES takes precedence.
74
+ *
75
+ * Also unlike CLOSURE_UNCOMPILED_DEFINES the values must be number, boolean or
76
+ * string literals or the compiler will emit an error.
77
+ *
78
+ * While any @define value may be set, only those set with goog.define will be
79
+ * effective for uncompiled code.
80
+ *
81
+ * Example:
82
+ * <pre>
83
+ * var CLOSURE_DEFINES = {'goog.DEBUG': false} ;
84
+ * </pre>
85
+ *
86
+ * @type {Object<string, (string|number|boolean)>|undefined}
87
+ */
88
+ goog.global.CLOSURE_DEFINES;
89
+
90
+
91
+ /**
92
+ * Returns true if the specified value is not undefined.
93
+ * WARNING: Do not use this to test if an object has a property. Use the in
94
+ * operator instead.
95
+ *
96
+ * @param {?} val Variable to test.
97
+ * @return {boolean} Whether variable is defined.
98
+ */
99
+ goog.isDef = function(val) {
100
+ // void 0 always evaluates to undefined and hence we do not need to depend on
101
+ // the definition of the global variable named 'undefined'.
102
+ return val !== void 0;
103
+ };
104
+
105
+
106
+ /**
107
+ * Builds an object structure for the provided namespace path, ensuring that
108
+ * names that already exist are not overwritten. For example:
109
+ * "a.b.c" -> a = {};a.b={};a.b.c={};
110
+ * Used by goog.provide and goog.exportSymbol.
111
+ * @param {string} name name of the object that this file defines.
112
+ * @param {*=} opt_object the object to expose at the end of the path.
113
+ * @param {Object=} opt_objectToExportTo The object to add the path to; default
114
+ * is |goog.global|.
115
+ * @private
116
+ */
117
+ goog.exportPath_ = function(name, opt_object, opt_objectToExportTo) {
118
+ var parts = name.split('.');
119
+ var cur = opt_objectToExportTo || goog.global;
120
+
121
+ // Internet Explorer exhibits strange behavior when throwing errors from
122
+ // methods externed in this manner. See the testExportSymbolExceptions in
123
+ // base_test.html for an example.
124
+ if (!(parts[0] in cur) && cur.execScript) {
125
+ cur.execScript('var ' + parts[0]);
126
+ }
127
+
128
+ // Certain browsers cannot parse code in the form for((a in b); c;);
129
+ // This pattern is produced by the JSCompiler when it collapses the
130
+ // statement above into the conditional loop below. To prevent this from
131
+ // happening, use a for-loop and reserve the init logic as below.
132
+
133
+ // Parentheses added to eliminate strict JS warning in Firefox.
134
+ for (var part; parts.length && (part = parts.shift());) {
135
+ if (!parts.length && goog.isDef(opt_object)) {
136
+ // last part and we have an object; use it
137
+ cur[part] = opt_object;
138
+ } else if (cur[part]) {
139
+ cur = cur[part];
140
+ } else {
141
+ cur = cur[part] = {};
142
+ }
143
+ }
144
+ };
145
+
146
+
147
+ /**
148
+ * Defines a named value. In uncompiled mode, the value is retrieved from
149
+ * CLOSURE_DEFINES or CLOSURE_UNCOMPILED_DEFINES if the object is defined and
150
+ * has the property specified, and otherwise used the defined defaultValue.
151
+ * When compiled the default can be overridden using the compiler
152
+ * options or the value set in the CLOSURE_DEFINES object.
153
+ *
154
+ * @param {string} name The distinguished name to provide.
155
+ * @param {string|number|boolean} defaultValue
156
+ */
157
+ goog.define = function(name, defaultValue) {
158
+ var value = defaultValue;
159
+ if (!COMPILED) {
160
+ if (goog.global.CLOSURE_UNCOMPILED_DEFINES &&
161
+ Object.prototype.hasOwnProperty.call(
162
+ goog.global.CLOSURE_UNCOMPILED_DEFINES, name)) {
163
+ value = goog.global.CLOSURE_UNCOMPILED_DEFINES[name];
164
+ } else if (goog.global.CLOSURE_DEFINES &&
165
+ Object.prototype.hasOwnProperty.call(
166
+ goog.global.CLOSURE_DEFINES, name)) {
167
+ value = goog.global.CLOSURE_DEFINES[name];
168
+ }
169
+ }
170
+ goog.exportPath_(name, value);
171
+ };
172
+
173
+
50
174
  /**
51
175
  * @define {boolean} DEBUG is provided as a convenience so that debugging code
52
176
  * that should not be included in a production js_binary can be easily stripped
@@ -55,7 +179,7 @@ goog.global = this;
55
179
  * because they are generally used for debugging purposes and it is difficult
56
180
  * for the JSCompiler to statically determine whether they are used.
57
181
  */
58
- goog.DEBUG = true;
182
+ goog.define('goog.DEBUG', true);
59
183
 
60
184
 
61
185
  /**
@@ -77,7 +201,7 @@ goog.DEBUG = true;
77
201
  * this rule: the Hebrew language. For legacy reasons the old code (iw) should
78
202
  * be used instead of the new code (he), see http://wiki/Main/IIISynonyms.
79
203
  */
80
- goog.LOCALE = 'en'; // default to en
204
+ goog.define('goog.LOCALE', 'en'); // default to en
81
205
 
82
206
 
83
207
  /**
@@ -87,32 +211,81 @@ goog.LOCALE = 'en'; // default to en
87
211
  * external libraries like Prototype, Datejs, and JQuery and setting this flag
88
212
  * to false forces closure to use its own implementations when possible.
89
213
  *
90
- * If your javascript can be loaded by a third party site and you are wary about
214
+ * If your JavaScript can be loaded by a third party site and you are wary about
91
215
  * relying on non-standard implementations, specify
92
216
  * "--define goog.TRUSTED_SITE=false" to the JSCompiler.
93
217
  */
94
- goog.TRUSTED_SITE = true;
218
+ goog.define('goog.TRUSTED_SITE', true);
219
+
220
+
221
+ /**
222
+ * @define {boolean} Whether a project is expected to be running in strict mode.
223
+ *
224
+ * This define can be used to trigger alternate implementations compatible with
225
+ * running in EcmaScript Strict mode or warn about unavailable functionality.
226
+ * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions_and_function_scope/Strict_mode
227
+ *
228
+ */
229
+ goog.define('goog.STRICT_MODE_COMPATIBLE', false);
230
+
231
+
232
+ /**
233
+ * @define {boolean} Whether code that calls {@link goog.setTestOnly} should
234
+ * be disallowed in the compilation unit.
235
+ */
236
+ goog.define('goog.DISALLOW_TEST_ONLY_CODE', COMPILED && !goog.DEBUG);
237
+
238
+
239
+ /**
240
+ * @define {boolean} Whether to use a Chrome app CSP-compliant method for
241
+ * loading scripts via goog.require. @see appendScriptSrcNode_.
242
+ */
243
+ goog.define('goog.ENABLE_CHROME_APP_SAFE_SCRIPT_LOADING', false);
95
244
 
96
245
 
97
246
  /**
98
- * Creates object stubs for a namespace. The presence of one or more
99
- * goog.provide() calls indicate that the file defines the given
100
- * objects/namespaces. Build tools also scan for provide/require statements
247
+ * Defines a namespace in Closure.
248
+ *
249
+ * A namespace may only be defined once in a codebase. It may be defined using
250
+ * goog.provide() or goog.module().
251
+ *
252
+ * The presence of one or more goog.provide() calls in a file indicates
253
+ * that the file defines the given objects/namespaces.
254
+ * Provided symbols must not be null or undefined.
255
+ *
256
+ * In addition, goog.provide() creates the object stubs for a namespace
257
+ * (for example, goog.provide("goog.foo.bar") will create the object
258
+ * goog.foo.bar if it does not already exist).
259
+ *
260
+ * Build tools also scan for provide/require/module statements
101
261
  * to discern dependencies, build dependency files (see deps.js), etc.
262
+ *
102
263
  * @see goog.require
264
+ * @see goog.module
103
265
  * @param {string} name Namespace provided by this file in the form
104
266
  * "goog.package.part".
105
267
  */
106
268
  goog.provide = function(name) {
107
269
  if (!COMPILED) {
108
- // Ensure that the same namespace isn't provided twice. This is intended
109
- // to teach new developers that 'goog.provide' is effectively a variable
110
- // declaration. And when JSCompiler transforms goog.provide into a real
111
- // variable declaration, the compiled JS should work the same as the raw
112
- // JS--even when the raw JS uses goog.provide incorrectly.
270
+ // Ensure that the same namespace isn't provided twice.
271
+ // A goog.module/goog.provide maps a goog.require to a specific file
113
272
  if (goog.isProvided_(name)) {
114
273
  throw Error('Namespace "' + name + '" already declared.');
115
274
  }
275
+ }
276
+
277
+ goog.constructNamespace_(name);
278
+ };
279
+
280
+
281
+ /**
282
+ * @param {string} name Namespace provided by this file in the form
283
+ * "goog.package.part".
284
+ * @param {Object=} opt_obj The object to embed in the namespace.
285
+ * @private
286
+ */
287
+ goog.constructNamespace_ = function(name, opt_obj) {
288
+ if (!COMPILED) {
116
289
  delete goog.implicitNamespaces_[name];
117
290
 
118
291
  var namespace = name;
@@ -124,25 +297,194 @@ goog.provide = function(name) {
124
297
  }
125
298
  }
126
299
 
127
- goog.exportPath_(name);
300
+ goog.exportPath_(name, opt_obj);
301
+ };
302
+
303
+
304
+ /**
305
+ * Module identifier validation regexp.
306
+ * Note: This is a conservative check, it is very possible to be more lenient,
307
+ * the primary exclusion here is "/" and "\" and a leading ".", these
308
+ * restrictions are intended to leave the door open for using goog.require
309
+ * with relative file paths rather than module identifiers.
310
+ * @private
311
+ */
312
+ goog.VALID_MODULE_RE_ = /^[a-zA-Z_$][a-zA-Z0-9._$]*$/;
313
+
314
+
315
+ /**
316
+ * Defines a module in Closure.
317
+ *
318
+ * Marks that this file must be loaded as a module and claims the namespace.
319
+ *
320
+ * A namespace may only be defined once in a codebase. It may be defined using
321
+ * goog.provide() or goog.module().
322
+ *
323
+ * goog.module() has three requirements:
324
+ * - goog.module may not be used in the same file as goog.provide.
325
+ * - goog.module must be the first statement in the file.
326
+ * - only one goog.module is allowed per file.
327
+ *
328
+ * When a goog.module annotated file is loaded, it is enclosed in
329
+ * a strict function closure. This means that:
330
+ * - any variables declared in a goog.module file are private to the file
331
+ * (not global), though the compiler is expected to inline the module.
332
+ * - The code must obey all the rules of "strict" JavaScript.
333
+ * - the file will be marked as "use strict"
334
+ *
335
+ * NOTE: unlike goog.provide, goog.module does not declare any symbols by
336
+ * itself. If declared symbols are desired, use
337
+ * goog.module.declareLegacyNamespace().
338
+ *
339
+ *
340
+ * See the public goog.module proposal: http://goo.gl/Va1hin
341
+ *
342
+ * @param {string} name Namespace provided by this file in the form
343
+ * "goog.package.part", is expected but not required.
344
+ */
345
+ goog.module = function(name) {
346
+ if (!goog.isString(name) ||
347
+ !name ||
348
+ name.search(goog.VALID_MODULE_RE_) == -1) {
349
+ throw Error('Invalid module identifier');
350
+ }
351
+ if (!goog.isInModuleLoader_()) {
352
+ throw Error('Module ' + name + ' has been loaded incorrectly.');
353
+ }
354
+ if (goog.moduleLoaderState_.moduleName) {
355
+ throw Error('goog.module may only be called once per module.');
356
+ }
357
+
358
+ // Store the module name for the loader.
359
+ goog.moduleLoaderState_.moduleName = name;
360
+ if (!COMPILED) {
361
+ // Ensure that the same namespace isn't provided twice.
362
+ // A goog.module/goog.provide maps a goog.require to a specific file
363
+ if (goog.isProvided_(name)) {
364
+ throw Error('Namespace "' + name + '" already declared.');
365
+ }
366
+ delete goog.implicitNamespaces_[name];
367
+ }
368
+ };
369
+
370
+
371
+ /**
372
+ * @param {string} name The module identifier.
373
+ * @return {?} The module exports for an already loaded module or null.
374
+ *
375
+ * Note: This is not an alternative to goog.require, it does not
376
+ * indicate a hard dependency, instead it is used to indicate
377
+ * an optional dependency or to access the exports of a module
378
+ * that has already been loaded.
379
+ * @suppress {missingProvide}
380
+ */
381
+ goog.module.get = function(name) {
382
+ return goog.module.getInternal_(name);
383
+ };
384
+
385
+
386
+ /**
387
+ * @param {string} name The module identifier.
388
+ * @return {?} The module exports for an already loaded module or null.
389
+ * @private
390
+ */
391
+ goog.module.getInternal_ = function(name) {
392
+ if (!COMPILED) {
393
+ if (goog.isProvided_(name)) {
394
+ // goog.require only return a value with-in goog.module files.
395
+ return name in goog.loadedModules_ ?
396
+ goog.loadedModules_[name] :
397
+ goog.getObjectByName(name);
398
+ } else {
399
+ return null;
400
+ }
401
+ }
402
+ };
403
+
404
+
405
+ /**
406
+ * @private {?{moduleName: (string|undefined), declareLegacyNamespace:boolean}}
407
+ */
408
+ goog.moduleLoaderState_ = null;
409
+
410
+
411
+ /**
412
+ * @private
413
+ * @return {boolean} Whether a goog.module is currently being initialized.
414
+ */
415
+ goog.isInModuleLoader_ = function() {
416
+ return goog.moduleLoaderState_ != null;
417
+ };
418
+
419
+
420
+ /**
421
+ * Provide the module's exports as a globally accessible object under the
422
+ * module's declared name. This is intended to ease migration to goog.module
423
+ * for files that have existing usages.
424
+ * @suppress {missingProvide}
425
+ */
426
+ goog.module.declareLegacyNamespace = function() {
427
+ if (!COMPILED && !goog.isInModuleLoader_()) {
428
+ throw new Error('goog.module.declareLegacyNamespace must be called from ' +
429
+ 'within a goog.module');
430
+ }
431
+ if (!COMPILED && !goog.moduleLoaderState_.moduleName) {
432
+ throw Error('goog.module must be called prior to ' +
433
+ 'goog.module.declareLegacyNamespace.');
434
+ }
435
+ goog.moduleLoaderState_.declareLegacyNamespace = true;
128
436
  };
129
437
 
130
438
 
131
439
  /**
132
440
  * Marks that the current file should only be used for testing, and never for
133
441
  * live code in production.
442
+ *
443
+ * In the case of unit tests, the message may optionally be an exact namespace
444
+ * for the test (e.g. 'goog.stringTest'). The linter will then ignore the extra
445
+ * provide (if not explicitly defined in the code).
446
+ *
134
447
  * @param {string=} opt_message Optional message to add to the error that's
135
448
  * raised when used in production code.
136
449
  */
137
450
  goog.setTestOnly = function(opt_message) {
138
- if (COMPILED && !goog.DEBUG) {
451
+ if (goog.DISALLOW_TEST_ONLY_CODE) {
139
452
  opt_message = opt_message || '';
140
453
  throw Error('Importing test-only code into non-debug environment' +
141
- opt_message ? ': ' + opt_message : '.');
454
+ (opt_message ? ': ' + opt_message : '.'));
142
455
  }
143
456
  };
144
457
 
145
458
 
459
+ /**
460
+ * Forward declares a symbol. This is an indication to the compiler that the
461
+ * symbol may be used in the source yet is not required and may not be provided
462
+ * in compilation.
463
+ *
464
+ * The most common usage of forward declaration is code that takes a type as a
465
+ * function parameter but does not need to require it. By forward declaring
466
+ * instead of requiring, no hard dependency is made, and (if not required
467
+ * elsewhere) the namespace may never be required and thus, not be pulled
468
+ * into the JavaScript binary. If it is required elsewhere, it will be type
469
+ * checked as normal.
470
+ *
471
+ *
472
+ * @param {string} name The namespace to forward declare in the form of
473
+ * "goog.package.part".
474
+ */
475
+ goog.forwardDeclare = function(name) {};
476
+
477
+
478
+ /**
479
+ * Forward declare type information. Used to assign types to goog.global
480
+ * referenced object that would otherwise result in unknown type references
481
+ * and thus block property disambiguation.
482
+ */
483
+ goog.forwardDeclare('Document');
484
+ goog.forwardDeclare('HTMLScriptElement');
485
+ goog.forwardDeclare('XMLHttpRequest');
486
+
487
+
146
488
  if (!COMPILED) {
147
489
 
148
490
  /**
@@ -153,67 +495,33 @@ if (!COMPILED) {
153
495
  * @private
154
496
  */
155
497
  goog.isProvided_ = function(name) {
156
- return !goog.implicitNamespaces_[name] && !!goog.getObjectByName(name);
498
+ return (name in goog.loadedModules_) ||
499
+ (!goog.implicitNamespaces_[name] &&
500
+ goog.isDefAndNotNull(goog.getObjectByName(name)));
157
501
  };
158
502
 
159
503
  /**
160
504
  * Namespaces implicitly defined by goog.provide. For example,
161
- * goog.provide('goog.events.Event') implicitly declares
162
- * that 'goog' and 'goog.events' must be namespaces.
505
+ * goog.provide('goog.events.Event') implicitly declares that 'goog' and
506
+ * 'goog.events' must be namespaces.
163
507
  *
164
- * @type {Object}
508
+ * @type {!Object<string, (boolean|undefined)>}
165
509
  * @private
166
510
  */
167
- goog.implicitNamespaces_ = {};
168
- }
511
+ goog.implicitNamespaces_ = {'goog.module': true};
169
512
 
170
-
171
- /**
172
- * Builds an object structure for the provided namespace path,
173
- * ensuring that names that already exist are not overwritten. For
174
- * example:
175
- * "a.b.c" -> a = {};a.b={};a.b.c={};
176
- * Used by goog.provide and goog.exportSymbol.
177
- * @param {string} name name of the object that this file defines.
178
- * @param {*=} opt_object the object to expose at the end of the path.
179
- * @param {Object=} opt_objectToExportTo The object to add the path to; default
180
- * is |goog.global|.
181
- * @private
182
- */
183
- goog.exportPath_ = function(name, opt_object, opt_objectToExportTo) {
184
- var parts = name.split('.');
185
- var cur = opt_objectToExportTo || goog.global;
186
-
187
- // Internet Explorer exhibits strange behavior when throwing errors from
188
- // methods externed in this manner. See the testExportSymbolExceptions in
189
- // base_test.html for an example.
190
- if (!(parts[0] in cur) && cur.execScript) {
191
- cur.execScript('var ' + parts[0]);
192
- }
193
-
194
- // Certain browsers cannot parse code in the form for((a in b); c;);
195
- // This pattern is produced by the JSCompiler when it collapses the
196
- // statement above into the conditional loop below. To prevent this from
197
- // happening, use a for-loop and reserve the init logic as below.
198
-
199
- // Parentheses added to eliminate strict JS warning in Firefox.
200
- for (var part; parts.length && (part = parts.shift());) {
201
- if (!parts.length && goog.isDef(opt_object)) {
202
- // last part and we have an object; use it
203
- cur[part] = opt_object;
204
- } else if (cur[part]) {
205
- cur = cur[part];
206
- } else {
207
- cur = cur[part] = {};
208
- }
209
- }
210
- };
513
+ // NOTE: We add goog.module as an implicit namespace as goog.module is defined
514
+ // here and because the existing module package has not been moved yet out of
515
+ // the goog.module namespace. This satisifies both the debug loader and
516
+ // ahead-of-time dependency management.
517
+ }
211
518
 
212
519
 
213
520
  /**
214
- * Returns an object based on its fully qualified external name. If you are
215
- * using a compilation pass that renames property names beware that using this
216
- * function will not find renamed properties.
521
+ * Returns an object based on its fully qualified external name. The object
522
+ * is not found if null or undefined. If you are using a compilation pass that
523
+ * renames property names beware that using this function will not find renamed
524
+ * properties.
217
525
  *
218
526
  * @param {string} name The fully qualified name.
219
527
  * @param {Object=} opt_obj The object within which to look; default is
@@ -237,7 +545,7 @@ goog.getObjectByName = function(name, opt_obj) {
237
545
  /**
238
546
  * Globalizes a whole namespace, such as goog or goog.lang.
239
547
  *
240
- * @param {Object} obj The namespace to globalize.
548
+ * @param {!Object} obj The namespace to globalize.
241
549
  * @param {Object=} opt_global The object to add the properties to.
242
550
  * @deprecated Properties may be explicitly exported to the global scope, but
243
551
  * this should no longer be done in bulk.
@@ -253,22 +561,21 @@ goog.globalize = function(obj, opt_global) {
253
561
  /**
254
562
  * Adds a dependency from a file to the files it requires.
255
563
  * @param {string} relPath The path to the js file.
256
- * @param {Array} provides An array of strings with the names of the objects
257
- * this file provides.
258
- * @param {Array} requires An array of strings with the names of the objects
259
- * this file requires.
564
+ * @param {!Array<string>} provides An array of strings with
565
+ * the names of the objects this file provides.
566
+ * @param {!Array<string>} requires An array of strings with
567
+ * the names of the objects this file requires.
568
+ * @param {boolean=} opt_isModule Whether this dependency must be loaded as
569
+ * a module as declared by goog.module.
260
570
  */
261
- goog.addDependency = function(relPath, provides, requires) {
262
- if (!COMPILED) {
571
+ goog.addDependency = function(relPath, provides, requires, opt_isModule) {
572
+ if (goog.DEPENDENCIES_ENABLED) {
263
573
  var provide, require;
264
574
  var path = relPath.replace(/\\/g, '/');
265
575
  var deps = goog.dependencies_;
266
576
  for (var i = 0; provide = provides[i]; i++) {
267
577
  deps.nameToPath[provide] = path;
268
- if (!(path in deps.pathToNames)) {
269
- deps.pathToNames[path] = {};
270
- }
271
- deps.pathToNames[path][provide] = true;
578
+ deps.pathIsModule[path] = !!opt_isModule;
272
579
  }
273
580
  for (var j = 0; require = requires[j]; j++) {
274
581
  if (!(path in deps.requires)) {
@@ -282,17 +589,18 @@ goog.addDependency = function(relPath, provides, requires) {
282
589
 
283
590
 
284
591
 
285
- // NOTE(nnaze): The debug DOM loader was included in base.js as an orignal
286
- // way to do "debug-mode" development. The dependency system can sometimes
287
- // be confusing, as can the debug DOM loader's asyncronous nature.
592
+ // NOTE(nnaze): The debug DOM loader was included in base.js as an original way
593
+ // to do "debug-mode" development. The dependency system can sometimes be
594
+ // confusing, as can the debug DOM loader's asynchronous nature.
595
+ //
596
+ // With the DOM loader, a call to goog.require() is not blocking -- the script
597
+ // will not load until some point after the current script. If a namespace is
598
+ // needed at runtime, it needs to be defined in a previous script, or loaded via
599
+ // require() with its registered dependencies.
288
600
  //
289
- // With the DOM loader, a call to goog.require() is not blocking -- the
290
- // script will not load until some point after the current script. If a
291
- // namespace is needed at runtime, it needs to be defined in a previous
292
- // script, or loaded via require() with its registered dependencies.
293
- // User-defined namespaces may need their own deps file. See http://go/js_deps,
294
- // http://go/genjsdeps, or, externally, DepsWriter.
295
- // http://code.google.com/closure/library/docs/depswriter.html
601
+ // User-defined namespaces may need their own deps file. For a reference on
602
+ // creating a deps file, see:
603
+ // Externally: https://developers.google.com/closure/library/docs/depswriter
296
604
  //
297
605
  // Because of legacy clients, the DOM loader can't be easily removed from
298
606
  // base.js. Work is being done to make it disableable or replaceable for
@@ -310,54 +618,64 @@ goog.addDependency = function(relPath, provides, requires) {
310
618
  * provided (and depend on the fact that some outside tool correctly ordered
311
619
  * the script).
312
620
  */
313
- goog.ENABLE_DEBUG_LOADER = true;
621
+ goog.define('goog.ENABLE_DEBUG_LOADER', true);
622
+
623
+
624
+ /**
625
+ * @param {string} msg
626
+ * @private
627
+ */
628
+ goog.logToConsole_ = function(msg) {
629
+ if (goog.global.console) {
630
+ goog.global.console['error'](msg);
631
+ }
632
+ };
314
633
 
315
634
 
316
635
  /**
317
- * Implements a system for the dynamic resolution of dependencies
318
- * that works in parallel with the BUILD system. Note that all calls
319
- * to goog.require will be stripped by the JSCompiler when the
320
- * --closure_pass option is used.
636
+ * Implements a system for the dynamic resolution of dependencies that works in
637
+ * parallel with the BUILD system. Note that all calls to goog.require will be
638
+ * stripped by the JSCompiler when the --process_closure_primitives option is
639
+ * used.
321
640
  * @see goog.provide
322
- * @param {string} name Namespace to include (as was given in goog.provide())
323
- * in the form "goog.package.part".
641
+ * @param {string} name Namespace to include (as was given in goog.provide()) in
642
+ * the form "goog.package.part".
643
+ * @return {?} If called within a goog.module file, the associated namespace or
644
+ * module otherwise null.
324
645
  */
325
646
  goog.require = function(name) {
326
-
327
- // if the object already exists we do not need do do anything
328
- // TODO(arv): If we start to support require based on file name this has
329
- // to change
330
- // TODO(arv): If we allow goog.foo.* this has to change
331
- // TODO(arv): If we implement dynamic load after page load we should probably
332
- // not remove this code for the compiled output
647
+ // If the object already exists we do not need do do anything.
333
648
  if (!COMPILED) {
649
+ if (goog.ENABLE_DEBUG_LOADER && goog.IS_OLD_IE_) {
650
+ goog.maybeProcessDeferredDep_(name);
651
+ }
652
+
334
653
  if (goog.isProvided_(name)) {
335
- return;
654
+ if (goog.isInModuleLoader_()) {
655
+ return goog.module.getInternal_(name);
656
+ } else {
657
+ return null;
658
+ }
336
659
  }
337
660
 
338
661
  if (goog.ENABLE_DEBUG_LOADER) {
339
662
  var path = goog.getPathFromDeps_(name);
340
663
  if (path) {
341
- goog.included_[path] = true;
342
- goog.writeScripts_();
343
- return;
664
+ goog.writeScripts_(path);
665
+ return null;
344
666
  }
345
667
  }
346
668
 
347
669
  var errorMessage = 'goog.require could not find: ' + name;
348
- if (goog.global.console) {
349
- goog.global.console['error'](errorMessage);
350
- }
351
-
352
-
353
- throw Error(errorMessage);
670
+ goog.logToConsole_(errorMessage);
354
671
 
672
+ throw Error(errorMessage);
355
673
  }
356
674
  };
357
675
 
358
676
 
359
677
  /**
360
- * Path for included scripts
678
+ * Path for included scripts.
361
679
  * @type {string}
362
680
  */
363
681
  goog.basePath = '';
@@ -371,8 +689,7 @@ goog.global.CLOSURE_BASE_PATH;
371
689
 
372
690
 
373
691
  /**
374
- * Whether to write out Closure's deps file. By default,
375
- * the deps are written.
692
+ * Whether to write out Closure's deps file. By default, the deps are written.
376
693
  * @type {boolean|undefined}
377
694
  */
378
695
  goog.global.CLOSURE_NO_DEPS;
@@ -386,6 +703,7 @@ goog.global.CLOSURE_NO_DEPS;
386
703
  *
387
704
  * The function is passed the script source, which is a relative URI. It should
388
705
  * return true if the script was imported, false otherwise.
706
+ * @type {(function(string): boolean)|undefined}
389
707
  */
390
708
  goog.global.CLOSURE_IMPORT_SCRIPT;
391
709
 
@@ -397,35 +715,18 @@ goog.global.CLOSURE_IMPORT_SCRIPT;
397
715
  goog.nullFunction = function() {};
398
716
 
399
717
 
400
- /**
401
- * The identity function. Returns its first argument.
402
- *
403
- * @param {*=} opt_returnValue The single value that will be returned.
404
- * @param {...*} var_args Optional trailing arguments. These are ignored.
405
- * @return {?} The first argument. We can't know the type -- just pass it along
406
- * without type.
407
- * @deprecated Use goog.functions.identity instead.
408
- */
409
- goog.identityFunction = function(opt_returnValue, var_args) {
410
- return opt_returnValue;
411
- };
412
-
413
-
414
718
  /**
415
719
  * When defining a class Foo with an abstract method bar(), you can do:
416
- *
417
720
  * Foo.prototype.bar = goog.abstractMethod
418
721
  *
419
- * Now if a subclass of Foo fails to override bar(), an error
420
- * will be thrown when bar() is invoked.
722
+ * Now if a subclass of Foo fails to override bar(), an error will be thrown
723
+ * when bar() is invoked.
421
724
  *
422
- * Note: This does not take the name of the function to override as
423
- * an argument because that would make it more difficult to obfuscate
424
- * our JavaScript code.
725
+ * Note: This does not take the name of the function to override as an argument
726
+ * because that would make it more difficult to obfuscate our JavaScript code.
425
727
  *
426
728
  * @type {!Function}
427
- * @throws {Error} when invoked to indicate the method should be
428
- * overridden.
729
+ * @throws {Error} when invoked to indicate the method should be overridden.
429
730
  */
430
731
  goog.abstractMethod = function() {
431
732
  throw Error('unimplemented abstract method');
@@ -433,8 +734,8 @@ goog.abstractMethod = function() {
433
734
 
434
735
 
435
736
  /**
436
- * Adds a {@code getInstance} static method that always return the same instance
437
- * object.
737
+ * Adds a {@code getInstance} static method that always returns the same
738
+ * instance object.
438
739
  * @param {!Function} ctor The constructor for the class to add the static
439
740
  * method to.
440
741
  */
@@ -447,99 +748,427 @@ goog.addSingletonGetter = function(ctor) {
447
748
  // NOTE: JSCompiler can't optimize away Array#push.
448
749
  goog.instantiatedSingletons_[goog.instantiatedSingletons_.length] = ctor;
449
750
  }
450
- return ctor.instance_ = new ctor;
751
+ return ctor.instance_ = new ctor;
752
+ };
753
+ };
754
+
755
+
756
+ /**
757
+ * All singleton classes that have been instantiated, for testing. Don't read
758
+ * it directly, use the {@code goog.testing.singleton} module. The compiler
759
+ * removes this variable if unused.
760
+ * @type {!Array<!Function>}
761
+ * @private
762
+ */
763
+ goog.instantiatedSingletons_ = [];
764
+
765
+
766
+ /**
767
+ * @define {boolean} Whether to load goog.modules using {@code eval} when using
768
+ * the debug loader. This provides a better debugging experience as the
769
+ * source is unmodified and can be edited using Chrome Workspaces or similar.
770
+ * However in some environments the use of {@code eval} is banned
771
+ * so we provide an alternative.
772
+ */
773
+ goog.define('goog.LOAD_MODULE_USING_EVAL', true);
774
+
775
+
776
+ /**
777
+ * @define {boolean} Whether the exports of goog.modules should be sealed when
778
+ * possible.
779
+ */
780
+ goog.define('goog.SEAL_MODULE_EXPORTS', goog.DEBUG);
781
+
782
+
783
+ /**
784
+ * The registry of initialized modules:
785
+ * the module identifier to module exports map.
786
+ * @private @const {!Object<string, ?>}
787
+ */
788
+ goog.loadedModules_ = {};
789
+
790
+
791
+ /**
792
+ * True if goog.dependencies_ is available.
793
+ * @const {boolean}
794
+ */
795
+ goog.DEPENDENCIES_ENABLED = !COMPILED && goog.ENABLE_DEBUG_LOADER;
796
+
797
+
798
+ if (goog.DEPENDENCIES_ENABLED) {
799
+
800
+ /**
801
+ * This object is used to keep track of dependencies and other data that is
802
+ * used for loading scripts.
803
+ * @private
804
+ * @type {{
805
+ * pathIsModule: !Object<string, boolean>,
806
+ * nameToPath: !Object<string, string>,
807
+ * requires: !Object<string, !Object<string, boolean>>,
808
+ * visited: !Object<string, boolean>,
809
+ * written: !Object<string, boolean>,
810
+ * deferred: !Object<string, string>
811
+ * }}
812
+ */
813
+ goog.dependencies_ = {
814
+ pathIsModule: {}, // 1 to 1
815
+
816
+ nameToPath: {}, // 1 to 1
817
+
818
+ requires: {}, // 1 to many
819
+
820
+ // Used when resolving dependencies to prevent us from visiting file twice.
821
+ visited: {},
822
+
823
+ written: {}, // Used to keep track of script files we have written.
824
+
825
+ deferred: {} // Used to track deferred module evaluations in old IEs
826
+ };
827
+
828
+
829
+ /**
830
+ * Tries to detect whether is in the context of an HTML document.
831
+ * @return {boolean} True if it looks like HTML document.
832
+ * @private
833
+ */
834
+ goog.inHtmlDocument_ = function() {
835
+ /** @type {Document} */
836
+ var doc = goog.global.document;
837
+ return doc != null && 'write' in doc; // XULDocument misses write.
838
+ };
839
+
840
+
841
+ /**
842
+ * Tries to detect the base path of base.js script that bootstraps Closure.
843
+ * @private
844
+ */
845
+ goog.findBasePath_ = function() {
846
+ if (goog.isDef(goog.global.CLOSURE_BASE_PATH)) {
847
+ goog.basePath = goog.global.CLOSURE_BASE_PATH;
848
+ return;
849
+ } else if (!goog.inHtmlDocument_()) {
850
+ return;
851
+ }
852
+ /** @type {Document} */
853
+ var doc = goog.global.document;
854
+ var scripts = doc.getElementsByTagName('SCRIPT');
855
+ // Search backwards since the current script is in almost all cases the one
856
+ // that has base.js.
857
+ for (var i = scripts.length - 1; i >= 0; --i) {
858
+ var script = /** @type {!HTMLScriptElement} */ (scripts[i]);
859
+ var src = script.src;
860
+ var qmark = src.lastIndexOf('?');
861
+ var l = qmark == -1 ? src.length : qmark;
862
+ if (src.substr(l - 7, 7) == 'base.js') {
863
+ goog.basePath = src.substr(0, l - 7);
864
+ return;
865
+ }
866
+ }
867
+ };
868
+
869
+
870
+ /**
871
+ * Imports a script if, and only if, that script hasn't already been imported.
872
+ * (Must be called at execution time)
873
+ * @param {string} src Script source.
874
+ * @param {string=} opt_sourceText The optionally source text to evaluate
875
+ * @private
876
+ */
877
+ goog.importScript_ = function(src, opt_sourceText) {
878
+ var importScript = goog.global.CLOSURE_IMPORT_SCRIPT ||
879
+ goog.writeScriptTag_;
880
+ if (importScript(src, opt_sourceText)) {
881
+ goog.dependencies_.written[src] = true;
882
+ }
883
+ };
884
+
885
+
886
+ /** @const @private {boolean} */
887
+ goog.IS_OLD_IE_ = !!(!goog.global.atob && goog.global.document &&
888
+ goog.global.document.all);
889
+
890
+
891
+ /**
892
+ * Given a URL initiate retrieval and execution of the module.
893
+ * @param {string} src Script source URL.
894
+ * @private
895
+ */
896
+ goog.importModule_ = function(src) {
897
+ // In an attempt to keep browsers from timing out loading scripts using
898
+ // synchronous XHRs, put each load in its own script block.
899
+ var bootstrap = 'goog.retrieveAndExecModule_("' + src + '");';
900
+
901
+ if (goog.importScript_('', bootstrap)) {
902
+ goog.dependencies_.written[src] = true;
903
+ }
904
+ };
905
+
906
+
907
+ /** @private {!Array<string>} */
908
+ goog.queuedModules_ = [];
909
+
910
+
911
+ /**
912
+ * Return an appropriate module text. Suitable to insert into
913
+ * a script tag (that is unescaped).
914
+ * @param {string} srcUrl
915
+ * @param {string} scriptText
916
+ * @return {string}
917
+ * @private
918
+ */
919
+ goog.wrapModule_ = function(srcUrl, scriptText) {
920
+ if (!goog.LOAD_MODULE_USING_EVAL || !goog.isDef(goog.global.JSON)) {
921
+ return '' +
922
+ 'goog.loadModule(function(exports) {' +
923
+ '"use strict";' +
924
+ scriptText +
925
+ '\n' + // terminate any trailing single line comment.
926
+ ';return exports' +
927
+ '});' +
928
+ '\n//# sourceURL=' + srcUrl + '\n';
929
+ } else {
930
+ return '' +
931
+ 'goog.loadModule(' +
932
+ goog.global.JSON.stringify(
933
+ scriptText + '\n//# sourceURL=' + srcUrl + '\n') +
934
+ ');';
935
+ }
936
+ };
937
+
938
+ // On IE9 and earlier, it is necessary to handle
939
+ // deferred module loads. In later browsers, the
940
+ // code to be evaluated is simply inserted as a script
941
+ // block in the correct order. To eval deferred
942
+ // code at the right time, we piggy back on goog.require to call
943
+ // goog.maybeProcessDeferredDep_.
944
+ //
945
+ // The goog.requires are used both to bootstrap
946
+ // the loading process (when no deps are available) and
947
+ // declare that they should be available.
948
+ //
949
+ // Here we eval the sources, if all the deps are available
950
+ // either already eval'd or goog.require'd. This will
951
+ // be the case when all the dependencies have already
952
+ // been loaded, and the dependent module is loaded.
953
+ //
954
+ // But this alone isn't sufficient because it is also
955
+ // necessary to handle the case where there is no root
956
+ // that is not deferred. For that there we register for an event
957
+ // and trigger goog.loadQueuedModules_ handle any remaining deferred
958
+ // evaluations.
959
+
960
+ /**
961
+ * Handle any remaining deferred goog.module evals.
962
+ * @private
963
+ */
964
+ goog.loadQueuedModules_ = function() {
965
+ var count = goog.queuedModules_.length;
966
+ if (count > 0) {
967
+ var queue = goog.queuedModules_;
968
+ goog.queuedModules_ = [];
969
+ for (var i = 0; i < count; i++) {
970
+ var path = queue[i];
971
+ goog.maybeProcessDeferredPath_(path);
972
+ }
973
+ }
974
+ };
975
+
976
+
977
+ /**
978
+ * Eval the named module if its dependencies are
979
+ * available.
980
+ * @param {string} name The module to load.
981
+ * @private
982
+ */
983
+ goog.maybeProcessDeferredDep_ = function(name) {
984
+ if (goog.isDeferredModule_(name) &&
985
+ goog.allDepsAreAvailable_(name)) {
986
+ var path = goog.getPathFromDeps_(name);
987
+ goog.maybeProcessDeferredPath_(goog.basePath + path);
988
+ }
989
+ };
990
+
991
+ /**
992
+ * @param {string} name The module to check.
993
+ * @return {boolean} Whether the name represents a
994
+ * module whose evaluation has been deferred.
995
+ * @private
996
+ */
997
+ goog.isDeferredModule_ = function(name) {
998
+ var path = goog.getPathFromDeps_(name);
999
+ if (path && goog.dependencies_.pathIsModule[path]) {
1000
+ var abspath = goog.basePath + path;
1001
+ return (abspath) in goog.dependencies_.deferred;
1002
+ }
1003
+ return false;
1004
+ };
1005
+
1006
+ /**
1007
+ * @param {string} name The module to check.
1008
+ * @return {boolean} Whether the name represents a
1009
+ * module whose declared dependencies have all been loaded
1010
+ * (eval'd or a deferred module load)
1011
+ * @private
1012
+ */
1013
+ goog.allDepsAreAvailable_ = function(name) {
1014
+ var path = goog.getPathFromDeps_(name);
1015
+ if (path && (path in goog.dependencies_.requires)) {
1016
+ for (var requireName in goog.dependencies_.requires[path]) {
1017
+ if (!goog.isProvided_(requireName) &&
1018
+ !goog.isDeferredModule_(requireName)) {
1019
+ return false;
1020
+ }
1021
+ }
1022
+ }
1023
+ return true;
451
1024
  };
452
- };
453
1025
 
454
1026
 
455
- /**
456
- * All singleton classes that have been instantiated, for testing. Don't read
457
- * it directly, use the {@code goog.testing.singleton} module. The compiler
458
- * removes this variable if unused.
459
- * @type {!Array.<!Function>}
460
- * @private
461
- */
462
- goog.instantiatedSingletons_ = [];
1027
+ /**
1028
+ * @param {string} abspath
1029
+ * @private
1030
+ */
1031
+ goog.maybeProcessDeferredPath_ = function(abspath) {
1032
+ if (abspath in goog.dependencies_.deferred) {
1033
+ var src = goog.dependencies_.deferred[abspath];
1034
+ delete goog.dependencies_.deferred[abspath];
1035
+ goog.globalEval(src);
1036
+ }
1037
+ };
463
1038
 
464
1039
 
465
- if (!COMPILED && goog.ENABLE_DEBUG_LOADER) {
466
1040
  /**
467
- * Object used to keep track of urls that have already been added. This
468
- * record allows the prevention of circular dependencies.
469
- * @type {Object}
470
- * @private
1041
+ * Load a goog.module from the provided URL. This is not a general purpose
1042
+ * code loader and does not support late loading code, that is it should only
1043
+ * be used during page load. This method exists to support unit tests and
1044
+ * "debug" loaders that would otherwise have inserted script tags. Under the
1045
+ * hood this needs to use a synchronous XHR and is not recommeneded for
1046
+ * production code.
1047
+ *
1048
+ * The module's goog.requires must have already been satisified; an exception
1049
+ * will be thrown if this is not the case. This assumption is that no
1050
+ * "deps.js" file exists, so there is no way to discover and locate the
1051
+ * module-to-be-loaded's dependencies and no attempt is made to do so.
1052
+ *
1053
+ * There should only be one attempt to load a module. If
1054
+ * "goog.loadModuleFromUrl" is called for an already loaded module, an
1055
+ * exception will be throw.
1056
+ *
1057
+ * @param {string} url The URL from which to attempt to load the goog.module.
471
1058
  */
472
- goog.included_ = {};
1059
+ goog.loadModuleFromUrl = function(url) {
1060
+ // Because this executes synchronously, we don't need to do any additional
1061
+ // bookkeeping. When "goog.loadModule" the namespace will be marked as
1062
+ // having been provided which is sufficient.
1063
+ goog.retrieveAndExecModule_(url);
1064
+ };
473
1065
 
474
1066
 
475
1067
  /**
476
- * This object is used to keep track of dependencies and other data that is
477
- * used for loading scripts
478
- * @private
479
- * @type {Object}
1068
+ * @param {function(?):?|string} moduleDef The module definition.
480
1069
  */
481
- goog.dependencies_ = {
482
- pathToNames: {}, // 1 to many
483
- nameToPath: {}, // 1 to 1
484
- requires: {}, // 1 to many
485
- // used when resolving dependencies to prevent us from
486
- // visiting the file twice
487
- visited: {},
488
- written: {} // used to keep track of script files we have written
1070
+ goog.loadModule = function(moduleDef) {
1071
+ // NOTE: we allow function definitions to be either in the from
1072
+ // of a string to eval (which keeps the original source intact) or
1073
+ // in a eval forbidden environment (CSP) we allow a function definition
1074
+ // which in its body must call {@code goog.module}, and return the exports
1075
+ // of the module.
1076
+ var previousState = goog.moduleLoaderState_;
1077
+ try {
1078
+ goog.moduleLoaderState_ = {
1079
+ moduleName: undefined,
1080
+ declareLegacyNamespace: false
1081
+ };
1082
+ var exports;
1083
+ if (goog.isFunction(moduleDef)) {
1084
+ exports = moduleDef.call(goog.global, {});
1085
+ } else if (goog.isString(moduleDef)) {
1086
+ exports = goog.loadModuleFromSource_.call(goog.global, moduleDef);
1087
+ } else {
1088
+ throw Error('Invalid module definition');
1089
+ }
1090
+
1091
+ var moduleName = goog.moduleLoaderState_.moduleName;
1092
+ if (!goog.isString(moduleName) || !moduleName) {
1093
+ throw Error('Invalid module name \"' + moduleName + '\"');
1094
+ }
1095
+
1096
+ // Don't seal legacy namespaces as they may be uses as a parent of
1097
+ // another namespace
1098
+ if (goog.moduleLoaderState_.declareLegacyNamespace) {
1099
+ goog.constructNamespace_(moduleName, exports);
1100
+ } else if (goog.SEAL_MODULE_EXPORTS && Object.seal) {
1101
+ Object.seal(exports);
1102
+ }
1103
+
1104
+ goog.loadedModules_[moduleName] = exports;
1105
+ } finally {
1106
+ goog.moduleLoaderState_ = previousState;
1107
+ }
489
1108
  };
490
1109
 
491
1110
 
492
1111
  /**
493
- * Tries to detect whether is in the context of an HTML document.
494
- * @return {boolean} True if it looks like HTML document.
495
- * @private
1112
+ * @private @const {function(string):?}
1113
+ *
1114
+ * The new type inference warns because this function has no formal
1115
+ * parameters, but its jsdoc says that it takes one argument.
1116
+ * (The argument is used via arguments[0], but NTI does not detect this.)
1117
+ * @suppress {newCheckTypes}
496
1118
  */
497
- goog.inHtmlDocument_ = function() {
498
- var doc = goog.global.document;
499
- return typeof doc != 'undefined' &&
500
- 'write' in doc; // XULDocument misses write.
1119
+ goog.loadModuleFromSource_ = function() {
1120
+ // NOTE: we avoid declaring parameters or local variables here to avoid
1121
+ // masking globals or leaking values into the module definition.
1122
+ 'use strict';
1123
+ var exports = {};
1124
+ eval(arguments[0]);
1125
+ return exports;
501
1126
  };
502
1127
 
503
1128
 
504
1129
  /**
505
- * Tries to detect the base path of the base.js script that bootstraps Closure
1130
+ * Writes a new script pointing to {@code src} directly into the DOM.
1131
+ *
1132
+ * NOTE: This method is not CSP-compliant. @see goog.appendScriptSrcNode_ for
1133
+ * the fallback mechanism.
1134
+ *
1135
+ * @param {string} src The script URL.
506
1136
  * @private
507
1137
  */
508
- goog.findBasePath_ = function() {
509
- if (goog.global.CLOSURE_BASE_PATH) {
510
- goog.basePath = goog.global.CLOSURE_BASE_PATH;
511
- return;
512
- } else if (!goog.inHtmlDocument_()) {
513
- return;
514
- }
515
- var doc = goog.global.document;
516
- var scripts = doc.getElementsByTagName('script');
517
- // Search backwards since the current script is in almost all cases the one
518
- // that has base.js.
519
- for (var i = scripts.length - 1; i >= 0; --i) {
520
- var src = scripts[i].src;
521
- var qmark = src.lastIndexOf('?');
522
- var l = qmark == -1 ? src.length : qmark;
523
- if (src.substr(l - 7, 7) == 'base.js') {
524
- goog.basePath = src.substr(0, l - 7);
525
- return;
526
- }
527
- }
1138
+ goog.writeScriptSrcNode_ = function(src) {
1139
+ goog.global.document.write(
1140
+ '<script type="text/javascript" src="' + src + '"></' + 'script>');
528
1141
  };
529
1142
 
530
1143
 
531
1144
  /**
532
- * Imports a script if, and only if, that script hasn't already been imported.
533
- * (Must be called at execution time)
534
- * @param {string} src Script source.
1145
+ * Appends a new script node to the DOM using a CSP-compliant mechanism. This
1146
+ * method exists as a fallback for document.write (which is not allowed in a
1147
+ * strict CSP context, e.g., Chrome apps).
1148
+ *
1149
+ * NOTE: This method is not analogous to using document.write to insert a
1150
+ * <script> tag; specifically, the user agent will execute a script added by
1151
+ * document.write immediately after the current script block finishes
1152
+ * executing, whereas the DOM-appended script node will not be executed until
1153
+ * the entire document is parsed and executed. That is to say, this script is
1154
+ * added to the end of the script execution queue.
1155
+ *
1156
+ * The page must not attempt to call goog.required entities until after the
1157
+ * document has loaded, e.g., in or after the window.onload callback.
1158
+ *
1159
+ * @param {string} src The script URL.
535
1160
  * @private
536
1161
  */
537
- goog.importScript_ = function(src) {
538
- var importScript = goog.global.CLOSURE_IMPORT_SCRIPT ||
539
- goog.writeScriptTag_;
540
- if (!goog.dependencies_.written[src] && importScript(src)) {
541
- goog.dependencies_.written[src] = true;
542
- }
1162
+ goog.appendScriptSrcNode_ = function(src) {
1163
+ /** @type {Document} */
1164
+ var doc = goog.global.document;
1165
+ var scriptEl = /** @type {HTMLScriptElement} */ (
1166
+ doc.createElement('script'));
1167
+ scriptEl.type = 'text/javascript';
1168
+ scriptEl.src = src;
1169
+ scriptEl.defer = false;
1170
+ scriptEl.async = false;
1171
+ doc.head.appendChild(scriptEl);
543
1172
  };
544
1173
 
545
1174
 
@@ -547,18 +1176,22 @@ if (!COMPILED && goog.ENABLE_DEBUG_LOADER) {
547
1176
  * The default implementation of the import function. Writes a script tag to
548
1177
  * import the script.
549
1178
  *
550
- * @param {string} src The script source.
1179
+ * @param {string} src The script url.
1180
+ * @param {string=} opt_sourceText The optionally source text to evaluate
551
1181
  * @return {boolean} True if the script was imported, false otherwise.
552
1182
  * @private
553
1183
  */
554
- goog.writeScriptTag_ = function(src) {
1184
+ goog.writeScriptTag_ = function(src, opt_sourceText) {
555
1185
  if (goog.inHtmlDocument_()) {
1186
+ /** @type {!HTMLDocument} */
556
1187
  var doc = goog.global.document;
557
1188
 
558
1189
  // If the user tries to require a new symbol after document load,
559
1190
  // something has gone terribly wrong. Doing a document.write would
560
- // wipe out the page.
561
- if (doc.readyState == 'complete') {
1191
+ // wipe out the page. This does not apply to the CSP-compliant method
1192
+ // of writing script tags.
1193
+ if (!goog.ENABLE_CHROME_APP_SAFE_SCRIPT_LOADING &&
1194
+ doc.readyState == 'complete') {
562
1195
  // Certain test frameworks load base.js multiple times, which tries
563
1196
  // to write deps.js each time. If that happens, just fail silently.
564
1197
  // These frameworks wipe the page between each load of base.js, so this
@@ -571,8 +1204,28 @@ if (!COMPILED && goog.ENABLE_DEBUG_LOADER) {
571
1204
  }
572
1205
  }
573
1206
 
574
- doc.write(
575
- '<script type="text/javascript" src="' + src + '"></' + 'script>');
1207
+ var isOldIE = goog.IS_OLD_IE_;
1208
+
1209
+ if (opt_sourceText === undefined) {
1210
+ if (!isOldIE) {
1211
+ if (goog.ENABLE_CHROME_APP_SAFE_SCRIPT_LOADING) {
1212
+ goog.appendScriptSrcNode_(src);
1213
+ } else {
1214
+ goog.writeScriptSrcNode_(src);
1215
+ }
1216
+ } else {
1217
+ var state = " onreadystatechange='goog.onScriptLoad_(this, " +
1218
+ ++goog.lastNonModuleScriptIndex_ + ")' ";
1219
+ doc.write(
1220
+ '<script type="text/javascript" src="' +
1221
+ src + '"' + state + '></' + 'script>');
1222
+ }
1223
+ } else {
1224
+ doc.write(
1225
+ '<script type="text/javascript">' +
1226
+ opt_sourceText +
1227
+ '</' + 'script>');
1228
+ }
576
1229
  return true;
577
1230
  } else {
578
1231
  return false;
@@ -580,29 +1233,49 @@ if (!COMPILED && goog.ENABLE_DEBUG_LOADER) {
580
1233
  };
581
1234
 
582
1235
 
1236
+ /** @private {number} */
1237
+ goog.lastNonModuleScriptIndex_ = 0;
1238
+
1239
+
1240
+ /**
1241
+ * A readystatechange handler for legacy IE
1242
+ * @param {!HTMLScriptElement} script
1243
+ * @param {number} scriptIndex
1244
+ * @return {boolean}
1245
+ * @private
1246
+ */
1247
+ goog.onScriptLoad_ = function(script, scriptIndex) {
1248
+ // for now load the modules when we reach the last script,
1249
+ // later allow more inter-mingling.
1250
+ if (script.readyState == 'complete' &&
1251
+ goog.lastNonModuleScriptIndex_ == scriptIndex) {
1252
+ goog.loadQueuedModules_();
1253
+ }
1254
+ return true;
1255
+ };
1256
+
583
1257
  /**
584
1258
  * Resolves dependencies based on the dependencies added using addDependency
585
1259
  * and calls importScript_ in the correct order.
1260
+ * @param {string} pathToLoad The path from which to start discovering
1261
+ * dependencies.
586
1262
  * @private
587
1263
  */
588
- goog.writeScripts_ = function() {
589
- // the scripts we need to write this time
1264
+ goog.writeScripts_ = function(pathToLoad) {
1265
+ /** @type {!Array<string>} The scripts we need to write this time. */
590
1266
  var scripts = [];
591
1267
  var seenScript = {};
592
1268
  var deps = goog.dependencies_;
593
1269
 
1270
+ /** @param {string} path */
594
1271
  function visitNode(path) {
595
1272
  if (path in deps.written) {
596
1273
  return;
597
1274
  }
598
1275
 
599
- // we have already visited this one. We can get here if we have cyclic
600
- // dependencies
1276
+ // We have already visited this one. We can get here if we have cyclic
1277
+ // dependencies.
601
1278
  if (path in deps.visited) {
602
- if (!(path in seenScript)) {
603
- seenScript[path] = true;
604
- scripts.push(path);
605
- }
606
1279
  return;
607
1280
  }
608
1281
 
@@ -628,19 +1301,36 @@ if (!COMPILED && goog.ENABLE_DEBUG_LOADER) {
628
1301
  }
629
1302
  }
630
1303
 
631
- for (var path in goog.included_) {
632
- if (!deps.written[path]) {
633
- visitNode(path);
634
- }
1304
+ visitNode(pathToLoad);
1305
+
1306
+ // record that we are going to load all these scripts.
1307
+ for (var i = 0; i < scripts.length; i++) {
1308
+ var path = scripts[i];
1309
+ goog.dependencies_.written[path] = true;
635
1310
  }
636
1311
 
1312
+ // If a module is loaded synchronously then we need to
1313
+ // clear the current inModuleLoader value, and restore it when we are
1314
+ // done loading the current "requires".
1315
+ var moduleState = goog.moduleLoaderState_;
1316
+ goog.moduleLoaderState_ = null;
1317
+
637
1318
  for (var i = 0; i < scripts.length; i++) {
638
- if (scripts[i]) {
639
- goog.importScript_(goog.basePath + scripts[i]);
1319
+ var path = scripts[i];
1320
+ if (path) {
1321
+ if (!deps.pathIsModule[path]) {
1322
+ goog.importScript_(goog.basePath + path);
1323
+ } else {
1324
+ goog.importModule_(goog.basePath + path);
1325
+ }
640
1326
  } else {
1327
+ goog.moduleLoaderState_ = moduleState;
641
1328
  throw Error('Undefined script input');
642
1329
  }
643
1330
  }
1331
+
1332
+ // restore the current "module loading state"
1333
+ goog.moduleLoaderState_ = moduleState;
644
1334
  };
645
1335
 
646
1336
 
@@ -668,6 +1358,82 @@ if (!COMPILED && goog.ENABLE_DEBUG_LOADER) {
668
1358
  }
669
1359
 
670
1360
 
1361
+ /**
1362
+ * Normalize a file path by removing redundant ".." and extraneous "." file
1363
+ * path components.
1364
+ * @param {string} path
1365
+ * @return {string}
1366
+ * @private
1367
+ */
1368
+ goog.normalizePath_ = function(path) {
1369
+ var components = path.split('/');
1370
+ var i = 0;
1371
+ while (i < components.length) {
1372
+ if (components[i] == '.') {
1373
+ components.splice(i, 1);
1374
+ } else if (i && components[i] == '..' &&
1375
+ components[i - 1] && components[i - 1] != '..') {
1376
+ components.splice(--i, 2);
1377
+ } else {
1378
+ i++;
1379
+ }
1380
+ }
1381
+ return components.join('/');
1382
+ };
1383
+
1384
+
1385
+ /**
1386
+ * Loads file by synchronous XHR. Should not be used in production environments.
1387
+ * @param {string} src Source URL.
1388
+ * @return {string} File contents.
1389
+ * @private
1390
+ */
1391
+ goog.loadFileSync_ = function(src) {
1392
+ if (goog.global.CLOSURE_LOAD_FILE_SYNC) {
1393
+ return goog.global.CLOSURE_LOAD_FILE_SYNC(src);
1394
+ } else {
1395
+ /** @type {XMLHttpRequest} */
1396
+ var xhr = new goog.global['XMLHttpRequest']();
1397
+ xhr.open('get', src, false);
1398
+ xhr.send();
1399
+ return xhr.responseText;
1400
+ }
1401
+ };
1402
+
1403
+
1404
+ /**
1405
+ * Retrieve and execute a module.
1406
+ * @param {string} src Script source URL.
1407
+ * @private
1408
+ */
1409
+ goog.retrieveAndExecModule_ = function(src) {
1410
+ if (!COMPILED) {
1411
+ // The full but non-canonicalized URL for later use.
1412
+ var originalPath = src;
1413
+ // Canonicalize the path, removing any /./ or /../ since Chrome's debugging
1414
+ // console doesn't auto-canonicalize XHR loads as it does <script> srcs.
1415
+ src = goog.normalizePath_(src);
1416
+
1417
+ var importScript = goog.global.CLOSURE_IMPORT_SCRIPT ||
1418
+ goog.writeScriptTag_;
1419
+
1420
+ var scriptText = goog.loadFileSync_(src);
1421
+
1422
+ if (scriptText != null) {
1423
+ var execModuleScript = goog.wrapModule_(src, scriptText);
1424
+ var isOldIE = goog.IS_OLD_IE_;
1425
+ if (isOldIE) {
1426
+ goog.dependencies_.deferred[originalPath] = execModuleScript;
1427
+ goog.queuedModules_.push(originalPath);
1428
+ } else {
1429
+ importScript(src, execModuleScript);
1430
+ }
1431
+ } else {
1432
+ throw new Error('load of ' + src + 'failed');
1433
+ }
1434
+ }
1435
+ };
1436
+
671
1437
 
672
1438
  //==============================================================================
673
1439
  // Language Enhancements
@@ -677,7 +1443,7 @@ if (!COMPILED && goog.ENABLE_DEBUG_LOADER) {
677
1443
  /**
678
1444
  * This is a "fixed" version of the typeof operator. It differs from the typeof
679
1445
  * operator in such a way that null returns 'null' and arrays return 'array'.
680
- * @param {*} value The value to get the type of.
1446
+ * @param {?} value The value to get the type of.
681
1447
  * @return {string} The name of the type.
682
1448
  */
683
1449
  goog.typeOf = function(value) {
@@ -687,7 +1453,7 @@ goog.typeOf = function(value) {
687
1453
  // Check these first, so we can avoid calling Object.prototype.toString if
688
1454
  // possible.
689
1455
  //
690
- // IE improperly marshals tyepof across execution contexts, but a
1456
+ // IE improperly marshals typeof across execution contexts, but a
691
1457
  // cross-context object will still return false for "instanceof Object".
692
1458
  if (value instanceof Array) {
693
1459
  return 'array';
@@ -699,7 +1465,7 @@ goog.typeOf = function(value) {
699
1465
  // value, the compiler requires the value be cast to type Object,
700
1466
  // even though the ECMA spec explicitly allows it.
701
1467
  var className = Object.prototype.toString.call(
702
- /** @type {Object} */ (value));
1468
+ /** @type {!Object} */ (value));
703
1469
  // In Firefox 3.6, attempting to access iframe window objects' length
704
1470
  // property throws an NS_ERROR_FAILURE, so we need to special-case it
705
1471
  // here.
@@ -728,7 +1494,7 @@ goog.typeOf = function(value) {
728
1494
  if ((className == '[object Array]' ||
729
1495
  // In IE all non value types are wrapped as objects across window
730
1496
  // boundaries (not iframe though) so we have to do object detection
731
- // for this edge case
1497
+ // for this edge case.
732
1498
  typeof value.length == 'number' &&
733
1499
  typeof value.splice != 'undefined' &&
734
1500
  typeof value.propertyIsEnumerable != 'undefined' &&
@@ -758,17 +1524,15 @@ goog.typeOf = function(value) {
758
1524
  return 'function';
759
1525
  }
760
1526
 
761
-
762
1527
  } else {
763
1528
  return 'null';
764
1529
  }
765
1530
 
766
1531
  } else if (s == 'function' && typeof value.call == 'undefined') {
767
- // In Safari typeof nodeList returns 'function', and on Firefox
768
- // typeof behaves similarly for HTML{Applet,Embed,Object}Elements
769
- // and RegExps. We would like to return object for those and we can
770
- // detect an invalid function by making sure that the function
771
- // object has a call method.
1532
+ // In Safari typeof nodeList returns 'function', and on Firefox typeof
1533
+ // behaves similarly for HTML{Applet,Embed,Object}, Elements and RegExps. We
1534
+ // would like to return object for those and we can detect an invalid
1535
+ // function by making sure that the function object has a call method.
772
1536
  return 'object';
773
1537
  }
774
1538
  return s;
@@ -776,21 +1540,8 @@ goog.typeOf = function(value) {
776
1540
 
777
1541
 
778
1542
  /**
779
- * Returns true if the specified value is not |undefined|.
780
- * WARNING: Do not use this to test if an object has a property. Use the in
781
- * operator instead. Additionally, this function assumes that the global
782
- * undefined variable has not been redefined.
783
- * @param {*} val Variable to test.
784
- * @return {boolean} Whether variable is defined.
785
- */
786
- goog.isDef = function(val) {
787
- return val !== undefined;
788
- };
789
-
790
-
791
- /**
792
- * Returns true if the specified value is |null|
793
- * @param {*} val Variable to test.
1543
+ * Returns true if the specified value is null.
1544
+ * @param {?} val Variable to test.
794
1545
  * @return {boolean} Whether variable is null.
795
1546
  */
796
1547
  goog.isNull = function(val) {
@@ -799,8 +1550,8 @@ goog.isNull = function(val) {
799
1550
 
800
1551
 
801
1552
  /**
802
- * Returns true if the specified value is defined and not null
803
- * @param {*} val Variable to test.
1553
+ * Returns true if the specified value is defined and not null.
1554
+ * @param {?} val Variable to test.
804
1555
  * @return {boolean} Whether variable is defined and not null.
805
1556
  */
806
1557
  goog.isDefAndNotNull = function(val) {
@@ -810,8 +1561,8 @@ goog.isDefAndNotNull = function(val) {
810
1561
 
811
1562
 
812
1563
  /**
813
- * Returns true if the specified value is an array
814
- * @param {*} val Variable to test.
1564
+ * Returns true if the specified value is an array.
1565
+ * @param {?} val Variable to test.
815
1566
  * @return {boolean} Whether variable is an array.
816
1567
  */
817
1568
  goog.isArray = function(val) {
@@ -822,20 +1573,22 @@ goog.isArray = function(val) {
822
1573
  /**
823
1574
  * Returns true if the object looks like an array. To qualify as array like
824
1575
  * the value needs to be either a NodeList or an object with a Number length
825
- * property.
826
- * @param {*} val Variable to test.
1576
+ * property. As a special case, a function value is not array like, because its
1577
+ * length property is fixed to correspond to the number of expected arguments.
1578
+ * @param {?} val Variable to test.
827
1579
  * @return {boolean} Whether variable is an array.
828
1580
  */
829
1581
  goog.isArrayLike = function(val) {
830
1582
  var type = goog.typeOf(val);
1583
+ // We do not use goog.isObject here in order to exclude function values.
831
1584
  return type == 'array' || type == 'object' && typeof val.length == 'number';
832
1585
  };
833
1586
 
834
1587
 
835
1588
  /**
836
- * Returns true if the object looks like a Date. To qualify as Date-like
837
- * the value needs to be an object and have a getFullYear() function.
838
- * @param {*} val Variable to test.
1589
+ * Returns true if the object looks like a Date. To qualify as Date-like the
1590
+ * value needs to be an object and have a getFullYear() function.
1591
+ * @param {?} val Variable to test.
839
1592
  * @return {boolean} Whether variable is a like a Date.
840
1593
  */
841
1594
  goog.isDateLike = function(val) {
@@ -844,8 +1597,8 @@ goog.isDateLike = function(val) {
844
1597
 
845
1598
 
846
1599
  /**
847
- * Returns true if the specified value is a string
848
- * @param {*} val Variable to test.
1600
+ * Returns true if the specified value is a string.
1601
+ * @param {?} val Variable to test.
849
1602
  * @return {boolean} Whether variable is a string.
850
1603
  */
851
1604
  goog.isString = function(val) {
@@ -854,8 +1607,8 @@ goog.isString = function(val) {
854
1607
 
855
1608
 
856
1609
  /**
857
- * Returns true if the specified value is a boolean
858
- * @param {*} val Variable to test.
1610
+ * Returns true if the specified value is a boolean.
1611
+ * @param {?} val Variable to test.
859
1612
  * @return {boolean} Whether variable is boolean.
860
1613
  */
861
1614
  goog.isBoolean = function(val) {
@@ -864,8 +1617,8 @@ goog.isBoolean = function(val) {
864
1617
 
865
1618
 
866
1619
  /**
867
- * Returns true if the specified value is a number
868
- * @param {*} val Variable to test.
1620
+ * Returns true if the specified value is a number.
1621
+ * @param {?} val Variable to test.
869
1622
  * @return {boolean} Whether variable is a number.
870
1623
  */
871
1624
  goog.isNumber = function(val) {
@@ -874,8 +1627,8 @@ goog.isNumber = function(val) {
874
1627
 
875
1628
 
876
1629
  /**
877
- * Returns true if the specified value is a function
878
- * @param {*} val Variable to test.
1630
+ * Returns true if the specified value is a function.
1631
+ * @param {?} val Variable to test.
879
1632
  * @return {boolean} Whether variable is a function.
880
1633
  */
881
1634
  goog.isFunction = function(val) {
@@ -884,9 +1637,9 @@ goog.isFunction = function(val) {
884
1637
 
885
1638
 
886
1639
  /**
887
- * Returns true if the specified value is an object. This includes arrays
888
- * and functions.
889
- * @param {*} val Variable to test.
1640
+ * Returns true if the specified value is an object. This includes arrays and
1641
+ * functions.
1642
+ * @param {?} val Variable to test.
890
1643
  * @return {boolean} Whether variable is an object.
891
1644
  */
892
1645
  goog.isObject = function(val) {
@@ -898,12 +1651,12 @@ goog.isObject = function(val) {
898
1651
 
899
1652
 
900
1653
  /**
901
- * Gets a unique ID for an object. This mutates the object so that further
902
- * calls with the same object as a parameter returns the same value. The unique
903
- * ID is guaranteed to be unique across the current session amongst objects that
904
- * are passed into {@code getUid}. There is no guarantee that the ID is unique
905
- * or consistent across sessions. It is unsafe to generate unique ID for
906
- * function prototypes.
1654
+ * Gets a unique ID for an object. This mutates the object so that further calls
1655
+ * with the same object as a parameter returns the same value. The unique ID is
1656
+ * guaranteed to be unique across the current session amongst objects that are
1657
+ * passed into {@code getUid}. There is no guarantee that the ID is unique or
1658
+ * consistent across sessions. It is unsafe to generate unique ID for function
1659
+ * prototypes.
907
1660
  *
908
1661
  * @param {Object} obj The object to get the unique ID for.
909
1662
  * @return {number} The unique ID for the object.
@@ -919,6 +1672,19 @@ goog.getUid = function(obj) {
919
1672
  };
920
1673
 
921
1674
 
1675
+ /**
1676
+ * Whether the given object is already assigned a unique ID.
1677
+ *
1678
+ * This does not modify the object.
1679
+ *
1680
+ * @param {!Object} obj The object to check.
1681
+ * @return {boolean} Whether there is an assigned unique id for the object.
1682
+ */
1683
+ goog.hasUid = function(obj) {
1684
+ return !!obj[goog.UID_PROPERTY_];
1685
+ };
1686
+
1687
+
922
1688
  /**
923
1689
  * Removes the unique ID from an object. This is useful if the object was
924
1690
  * previously mutated using {@code goog.getUid} in which case the mutation is
@@ -928,9 +1694,9 @@ goog.getUid = function(obj) {
928
1694
  goog.removeUid = function(obj) {
929
1695
  // TODO(arv): Make the type stricter, do not accept null.
930
1696
 
931
- // DOM nodes in IE are not instance of Object and throws exception
932
- // for delete. Instead we try to use removeAttribute
933
- if ('removeAttribute' in obj) {
1697
+ // In IE, DOM nodes are not instances of Object and throw an exception if we
1698
+ // try to delete. Instead we try to use removeAttribute.
1699
+ if (obj !== null && 'removeAttribute' in obj) {
934
1700
  obj.removeAttribute(goog.UID_PROPERTY_);
935
1701
  }
936
1702
  /** @preserveTry */
@@ -943,7 +1709,7 @@ goog.removeUid = function(obj) {
943
1709
 
944
1710
  /**
945
1711
  * Name for unique ID property. Initialized in a way to help avoid collisions
946
- * with other closure javascript on the same page.
1712
+ * with other closure JavaScript on the same page.
947
1713
  * @type {string}
948
1714
  * @private
949
1715
  */
@@ -1011,15 +1777,15 @@ goog.cloneObject = function(obj) {
1011
1777
  /**
1012
1778
  * A native implementation of goog.bind.
1013
1779
  * @param {Function} fn A function to partially apply.
1014
- * @param {Object|undefined} selfObj Specifies the object which |this| should
1780
+ * @param {Object|undefined} selfObj Specifies the object which this should
1015
1781
  * point to when the function is run.
1016
- * @param {...*} var_args Additional arguments that are partially
1017
- * applied to the function.
1782
+ * @param {...*} var_args Additional arguments that are partially applied to the
1783
+ * function.
1018
1784
  * @return {!Function} A partially-applied form of the function bind() was
1019
1785
  * invoked as a method of.
1020
1786
  * @private
1021
- * @suppress {deprecated} The compiler thinks that Function.prototype.bind
1022
- * is deprecated because some people have declared a pure-JS version.
1787
+ * @suppress {deprecated} The compiler thinks that Function.prototype.bind is
1788
+ * deprecated because some people have declared a pure-JS version.
1023
1789
  * Only the pure-JS version is truly deprecated.
1024
1790
  */
1025
1791
  goog.bindNative_ = function(fn, selfObj, var_args) {
@@ -1030,10 +1796,10 @@ goog.bindNative_ = function(fn, selfObj, var_args) {
1030
1796
  /**
1031
1797
  * A pure-JS implementation of goog.bind.
1032
1798
  * @param {Function} fn A function to partially apply.
1033
- * @param {Object|undefined} selfObj Specifies the object which |this| should
1799
+ * @param {Object|undefined} selfObj Specifies the object which this should
1034
1800
  * point to when the function is run.
1035
- * @param {...*} var_args Additional arguments that are partially
1036
- * applied to the function.
1801
+ * @param {...*} var_args Additional arguments that are partially applied to the
1802
+ * function.
1037
1803
  * @return {!Function} A partially-applied form of the function bind() was
1038
1804
  * invoked as a method of.
1039
1805
  * @private
@@ -1063,36 +1829,36 @@ goog.bindJs_ = function(fn, selfObj, var_args) {
1063
1829
  /**
1064
1830
  * Partially applies this function to a particular 'this object' and zero or
1065
1831
  * more arguments. The result is a new function with some arguments of the first
1066
- * function pre-filled and the value of |this| 'pre-specified'.<br><br>
1832
+ * function pre-filled and the value of this 'pre-specified'.
1067
1833
  *
1068
- * Remaining arguments specified at call-time are appended to the pre-
1069
- * specified ones.<br><br>
1834
+ * Remaining arguments specified at call-time are appended to the pre-specified
1835
+ * ones.
1070
1836
  *
1071
- * Also see: {@link #partial}.<br><br>
1837
+ * Also see: {@link #partial}.
1072
1838
  *
1073
1839
  * Usage:
1074
- * <pre>var barMethBound = bind(myFunction, myObj, 'arg1', 'arg2');
1840
+ * <pre>var barMethBound = goog.bind(myFunction, myObj, 'arg1', 'arg2');
1075
1841
  * barMethBound('arg3', 'arg4');</pre>
1076
1842
  *
1077
- * @param {Function} fn A function to partially apply.
1078
- * @param {Object|undefined} selfObj Specifies the object which |this| should
1079
- * point to when the function is run.
1080
- * @param {...*} var_args Additional arguments that are partially
1081
- * applied to the function.
1082
- * @return {!Function} A partially-applied form of the function bind() was
1843
+ * @param {?function(this:T, ...)} fn A function to partially apply.
1844
+ * @param {T} selfObj Specifies the object which this should point to when the
1845
+ * function is run.
1846
+ * @param {...*} var_args Additional arguments that are partially applied to the
1847
+ * function.
1848
+ * @return {!Function} A partially-applied form of the function goog.bind() was
1083
1849
  * invoked as a method of.
1850
+ * @template T
1084
1851
  * @suppress {deprecated} See above.
1085
1852
  */
1086
1853
  goog.bind = function(fn, selfObj, var_args) {
1087
1854
  // TODO(nicksantos): narrow the type signature.
1088
1855
  if (Function.prototype.bind &&
1089
- // NOTE(nicksantos): Somebody pulled base.js into the default
1090
- // Chrome extension environment. This means that for Chrome extensions,
1091
- // they get the implementation of Function.prototype.bind that
1092
- // calls goog.bind instead of the native one. Even worse, we don't want
1093
- // to introduce a circular dependency between goog.bind and
1094
- // Function.prototype.bind, so we have to hack this to make sure it
1095
- // works correctly.
1856
+ // NOTE(nicksantos): Somebody pulled base.js into the default Chrome
1857
+ // extension environment. This means that for Chrome extensions, they get
1858
+ // the implementation of Function.prototype.bind that calls goog.bind
1859
+ // instead of the native one. Even worse, we don't want to introduce a
1860
+ // circular dependency between goog.bind and Function.prototype.bind, so
1861
+ // we have to hack this to make sure it works correctly.
1096
1862
  Function.prototype.bind.toString().indexOf('native code') != -1) {
1097
1863
  goog.bind = goog.bindNative_;
1098
1864
  } else {
@@ -1103,25 +1869,25 @@ goog.bind = function(fn, selfObj, var_args) {
1103
1869
 
1104
1870
 
1105
1871
  /**
1106
- * Like bind(), except that a 'this object' is not required. Useful when the
1107
- * target function is already bound.
1872
+ * Like goog.bind(), except that a 'this object' is not required. Useful when
1873
+ * the target function is already bound.
1108
1874
  *
1109
1875
  * Usage:
1110
- * var g = partial(f, arg1, arg2);
1876
+ * var g = goog.partial(f, arg1, arg2);
1111
1877
  * g(arg3, arg4);
1112
1878
  *
1113
1879
  * @param {Function} fn A function to partially apply.
1114
- * @param {...*} var_args Additional arguments that are partially
1115
- * applied to fn.
1116
- * @return {!Function} A partially-applied form of the function bind() was
1117
- * invoked as a method of.
1880
+ * @param {...*} var_args Additional arguments that are partially applied to fn.
1881
+ * @return {!Function} A partially-applied form of the function goog.partial()
1882
+ * was invoked as a method of.
1118
1883
  */
1119
1884
  goog.partial = function(fn, var_args) {
1120
1885
  var args = Array.prototype.slice.call(arguments, 1);
1121
1886
  return function() {
1122
- // Prepend the bound arguments to the current arguments.
1123
- var newArgs = Array.prototype.slice.call(arguments);
1124
- newArgs.unshift.apply(newArgs, args);
1887
+ // Clone the array (with slice()) and append additional arguments
1888
+ // to the existing arguments.
1889
+ var newArgs = args.slice();
1890
+ newArgs.push.apply(newArgs, arguments);
1125
1891
  return fn.apply(this, newArgs);
1126
1892
  };
1127
1893
  };
@@ -1159,7 +1925,7 @@ goog.now = (goog.TRUSTED_SITE && Date.now) || (function() {
1159
1925
 
1160
1926
 
1161
1927
  /**
1162
- * Evals javascript in the global scope. In IE this uses execScript, other
1928
+ * Evals JavaScript in the global scope. In IE this uses execScript, other
1163
1929
  * browsers use goog.global.eval. If goog.global.eval does not evaluate in the
1164
1930
  * global scope (for example, in Safari), appends a script tag instead.
1165
1931
  * Throws an exception if neither execScript or eval is defined.
@@ -1171,9 +1937,13 @@ goog.globalEval = function(script) {
1171
1937
  } else if (goog.global.eval) {
1172
1938
  // Test to see if eval works
1173
1939
  if (goog.evalWorksForGlobals_ == null) {
1174
- goog.global.eval('var _et_ = 1;');
1175
- if (typeof goog.global['_et_'] != 'undefined') {
1176
- delete goog.global['_et_'];
1940
+ goog.global.eval('var _evalTest_ = 1;');
1941
+ if (typeof goog.global['_evalTest_'] != 'undefined') {
1942
+ try {
1943
+ delete goog.global['_evalTest_'];
1944
+ } catch (ignore) {
1945
+ // Microsoft edge fails the deletion above in strict mode.
1946
+ }
1177
1947
  goog.evalWorksForGlobals_ = true;
1178
1948
  } else {
1179
1949
  goog.evalWorksForGlobals_ = false;
@@ -1183,8 +1953,10 @@ goog.globalEval = function(script) {
1183
1953
  if (goog.evalWorksForGlobals_) {
1184
1954
  goog.global.eval(script);
1185
1955
  } else {
1956
+ /** @type {Document} */
1186
1957
  var doc = goog.global.document;
1187
- var scriptElt = doc.createElement('script');
1958
+ var scriptElt = /** @type {!HTMLScriptElement} */ (
1959
+ doc.createElement('SCRIPT'));
1188
1960
  scriptElt.type = 'text/javascript';
1189
1961
  scriptElt.defer = false;
1190
1962
  // Note(user): can't use .innerHTML since "t('<test>')" will fail and
@@ -1212,8 +1984,7 @@ goog.evalWorksForGlobals_ = null;
1212
1984
  /**
1213
1985
  * Optional map of CSS class names to obfuscated names used with
1214
1986
  * goog.getCssName().
1215
- * @type {Object|undefined}
1216
- * @private
1987
+ * @private {!Object<string, string>|undefined}
1217
1988
  * @see goog.setCssNameMapping
1218
1989
  */
1219
1990
  goog.cssNameMapping_;
@@ -1234,27 +2005,26 @@ goog.cssNameMappingStyle_;
1234
2005
  *
1235
2006
  * This function works in tandem with @see goog.setCssNameMapping.
1236
2007
  *
1237
- * Without any mapping set, the arguments are simple joined with a
1238
- * hyphen and passed through unaltered.
2008
+ * Without any mapping set, the arguments are simple joined with a hyphen and
2009
+ * passed through unaltered.
1239
2010
  *
1240
- * When there is a mapping, there are two possible styles in which
1241
- * these mappings are used. In the BY_PART style, each part (i.e. in
1242
- * between hyphens) of the passed in css name is rewritten according
1243
- * to the map. In the BY_WHOLE style, the full css name is looked up in
1244
- * the map directly. If a rewrite is not specified by the map, the
1245
- * compiler will output a warning.
2011
+ * When there is a mapping, there are two possible styles in which these
2012
+ * mappings are used. In the BY_PART style, each part (i.e. in between hyphens)
2013
+ * of the passed in css name is rewritten according to the map. In the BY_WHOLE
2014
+ * style, the full css name is looked up in the map directly. If a rewrite is
2015
+ * not specified by the map, the compiler will output a warning.
1246
2016
  *
1247
- * When the mapping is passed to the compiler, it will replace calls
1248
- * to goog.getCssName with the strings from the mapping, e.g.
2017
+ * When the mapping is passed to the compiler, it will replace calls to
2018
+ * goog.getCssName with the strings from the mapping, e.g.
1249
2019
  * var x = goog.getCssName('foo');
1250
2020
  * var y = goog.getCssName(this.baseClass, 'active');
1251
2021
  * becomes:
1252
- * var x= 'foo';
2022
+ * var x = 'foo';
1253
2023
  * var y = this.baseClass + '-active';
1254
2024
  *
1255
- * If one argument is passed it will be processed, if two are passed
1256
- * only the modifier will be processed, as it is assumed the first
1257
- * argument was generated as a result of calling goog.getCssName.
2025
+ * If one argument is passed it will be processed, if two are passed only the
2026
+ * modifier will be processed, as it is assumed the first argument was generated
2027
+ * as a result of calling goog.getCssName.
1258
2028
  *
1259
2029
  * @param {string} className The class name.
1260
2030
  * @param {string=} opt_modifier A modifier to be appended to the class name.
@@ -1308,7 +2078,7 @@ goog.getCssName = function(className, opt_modifier) {
1308
2078
  * </pre>
1309
2079
  * When declared as a map of string literals to string literals, the JSCompiler
1310
2080
  * will replace all calls to goog.getCssName() using the supplied map if the
1311
- * --closure_pass flag is set.
2081
+ * --process_closure_primitives flag is set.
1312
2082
  *
1313
2083
  * @param {!Object} mapping A map of strings to strings where keys are possible
1314
2084
  * arguments to goog.getCssName() and values are the corresponding values
@@ -1333,7 +2103,7 @@ goog.setCssNameMapping = function(mapping, opt_style) {
1333
2103
  * are made in uncompiled mode.
1334
2104
  *
1335
2105
  * A hook for overriding the CSS name mapping.
1336
- * @type {Object|undefined}
2106
+ * @type {!Object<string, string>|undefined}
1337
2107
  */
1338
2108
  goog.global.CLOSURE_CSS_NAME_MAPPING;
1339
2109
 
@@ -1358,14 +2128,15 @@ if (!COMPILED && goog.global.CLOSURE_CSS_NAME_MAPPING) {
1358
2128
  * </code>
1359
2129
  *
1360
2130
  * @param {string} str Translatable string, places holders in the form {$foo}.
1361
- * @param {Object=} opt_values Map of place holder name to value.
2131
+ * @param {Object<string, string>=} opt_values Maps place holder name to value.
1362
2132
  * @return {string} message with placeholders filled.
1363
2133
  */
1364
2134
  goog.getMsg = function(str, opt_values) {
1365
- var values = opt_values || {};
1366
- for (var key in values) {
1367
- var value = ('' + values[key]).replace(/\$/g, '$$$$');
1368
- str = str.replace(new RegExp('\\{\\$' + key + '\\}', 'gi'), value);
2135
+ if (opt_values) {
2136
+ str = str.replace(/\{\$([^}]+)}/g, function(match, key) {
2137
+ return (opt_values != null && key in opt_values) ?
2138
+ opt_values[key] : match;
2139
+ });
1369
2140
  }
1370
2141
  return str;
1371
2142
  };
@@ -1378,7 +2149,7 @@ goog.getMsg = function(str, opt_values) {
1378
2149
  * This is useful when introducing a new message that has not yet been
1379
2150
  * translated into all languages.
1380
2151
  *
1381
- * This function is a compiler primtive. Must be used in the form:
2152
+ * This function is a compiler primitive. Must be used in the form:
1382
2153
  * <code>var x = goog.getMsgWithFallback(MSG_A, MSG_B);</code>
1383
2154
  * where MSG_A and MSG_B were initialized with goog.getMsg.
1384
2155
  *
@@ -1393,17 +2164,14 @@ goog.getMsgWithFallback = function(a, b) {
1393
2164
 
1394
2165
  /**
1395
2166
  * Exposes an unobfuscated global namespace path for the given object.
1396
- * Note that fields of the exported object *will* be obfuscated,
1397
- * unless they are exported in turn via this function or
1398
- * goog.exportProperty
2167
+ * Note that fields of the exported object *will* be obfuscated, unless they are
2168
+ * exported in turn via this function or goog.exportProperty.
1399
2169
  *
1400
- * <p>Also handy for making public items that are defined in anonymous
1401
- * closures.
2170
+ * Also handy for making public items that are defined in anonymous closures.
1402
2171
  *
1403
2172
  * ex. goog.exportSymbol('public.path.Foo', Foo);
1404
2173
  *
1405
- * ex. goog.exportSymbol('public.path.Foo.staticFunction',
1406
- * Foo.staticFunction);
2174
+ * ex. goog.exportSymbol('public.path.Foo.staticFunction', Foo.staticFunction);
1407
2175
  * public.path.Foo.staticFunction();
1408
2176
  *
1409
2177
  * ex. goog.exportSymbol('public.path.Foo.prototype.myMethod',
@@ -1413,7 +2181,7 @@ goog.getMsgWithFallback = function(a, b) {
1413
2181
  * @param {string} publicPath Unobfuscated name to export.
1414
2182
  * @param {*} object Object the name should point to.
1415
2183
  * @param {Object=} opt_objectToExportTo The object to add the path to; default
1416
- * is |goog.global|.
2184
+ * is goog.global.
1417
2185
  */
1418
2186
  goog.exportSymbol = function(publicPath, object, opt_objectToExportTo) {
1419
2187
  goog.exportPath_(publicPath, object, opt_objectToExportTo);
@@ -1439,51 +2207,343 @@ goog.exportProperty = function(object, publicName, symbol) {
1439
2207
  * Usage:
1440
2208
  * <pre>
1441
2209
  * function ParentClass(a, b) { }
1442
- * ParentClass.prototype.foo = function(a) { }
2210
+ * ParentClass.prototype.foo = function(a) { };
1443
2211
  *
1444
2212
  * function ChildClass(a, b, c) {
1445
- * goog.base(this, a, b);
2213
+ * ChildClass.base(this, 'constructor', a, b);
1446
2214
  * }
1447
2215
  * goog.inherits(ChildClass, ParentClass);
1448
2216
  *
1449
2217
  * var child = new ChildClass('a', 'b', 'see');
1450
- * child.foo(); // works
1451
- * </pre>
1452
- *
1453
- * In addition, a superclass' implementation of a method can be invoked
1454
- * as follows:
1455
- *
1456
- * <pre>
1457
- * ChildClass.prototype.foo = function(a) {
1458
- * ChildClass.superClass_.foo.call(this, a);
1459
- * // other code
1460
- * };
2218
+ * child.foo(); // This works.
1461
2219
  * </pre>
1462
2220
  *
1463
- * @param {Function} childCtor Child class.
1464
- * @param {Function} parentCtor Parent class.
2221
+ * @param {!Function} childCtor Child class.
2222
+ * @param {!Function} parentCtor Parent class.
1465
2223
  */
1466
2224
  goog.inherits = function(childCtor, parentCtor) {
1467
2225
  /** @constructor */
1468
- function tempCtor() {};
2226
+ function tempCtor() {}
1469
2227
  tempCtor.prototype = parentCtor.prototype;
1470
2228
  childCtor.superClass_ = parentCtor.prototype;
1471
2229
  childCtor.prototype = new tempCtor();
1472
2230
  /** @override */
1473
2231
  childCtor.prototype.constructor = childCtor;
2232
+
2233
+ /**
2234
+ * Calls superclass constructor/method.
2235
+ *
2236
+ * This function is only available if you use goog.inherits to
2237
+ * express inheritance relationships between classes.
2238
+ *
2239
+ * NOTE: This is a replacement for goog.base and for superClass_
2240
+ * property defined in childCtor.
2241
+ *
2242
+ * @param {!Object} me Should always be "this".
2243
+ * @param {string} methodName The method name to call. Calling
2244
+ * superclass constructor can be done with the special string
2245
+ * 'constructor'.
2246
+ * @param {...*} var_args The arguments to pass to superclass
2247
+ * method/constructor.
2248
+ * @return {*} The return value of the superclass method/constructor.
2249
+ */
2250
+ childCtor.base = function(me, methodName, var_args) {
2251
+ // Copying using loop to avoid deop due to passing arguments object to
2252
+ // function. This is faster in many JS engines as of late 2014.
2253
+ var args = new Array(arguments.length - 2);
2254
+ for (var i = 2; i < arguments.length; i++) {
2255
+ args[i - 2] = arguments[i];
2256
+ }
2257
+ return parentCtor.prototype[methodName].apply(me, args);
2258
+ };
2259
+ };
2260
+
2261
+
2262
+ /**
2263
+ * Call up to the superclass.
2264
+ *
2265
+ * If this is called from a constructor, then this calls the superclass
2266
+ * constructor with arguments 1-N.
2267
+ *
2268
+ * If this is called from a prototype method, then you must pass the name of the
2269
+ * method as the second argument to this function. If you do not, you will get a
2270
+ * runtime error. This calls the superclass' method with arguments 2-N.
2271
+ *
2272
+ * This function only works if you use goog.inherits to express inheritance
2273
+ * relationships between your classes.
2274
+ *
2275
+ * This function is a compiler primitive. At compile-time, the compiler will do
2276
+ * macro expansion to remove a lot of the extra overhead that this function
2277
+ * introduces. The compiler will also enforce a lot of the assumptions that this
2278
+ * function makes, and treat it as a compiler error if you break them.
2279
+ *
2280
+ * @param {!Object} me Should always be "this".
2281
+ * @param {*=} opt_methodName The method name if calling a super method.
2282
+ * @param {...*} var_args The rest of the arguments.
2283
+ * @return {*} The return value of the superclass method.
2284
+ * @suppress {es5Strict} This method can not be used in strict mode, but
2285
+ * all Closure Library consumers must depend on this file.
2286
+ */
2287
+ goog.base = function(me, opt_methodName, var_args) {
2288
+ var caller = arguments.callee.caller;
2289
+
2290
+ if (goog.STRICT_MODE_COMPATIBLE || (goog.DEBUG && !caller)) {
2291
+ throw Error('arguments.caller not defined. goog.base() cannot be used ' +
2292
+ 'with strict mode code. See ' +
2293
+ 'http://www.ecma-international.org/ecma-262/5.1/#sec-C');
2294
+ }
2295
+
2296
+ if (caller.superClass_) {
2297
+ // Copying using loop to avoid deop due to passing arguments object to
2298
+ // function. This is faster in many JS engines as of late 2014.
2299
+ var ctorArgs = new Array(arguments.length - 1);
2300
+ for (var i = 1; i < arguments.length; i++) {
2301
+ ctorArgs[i - 1] = arguments[i];
2302
+ }
2303
+ // This is a constructor. Call the superclass constructor.
2304
+ return caller.superClass_.constructor.apply(me, ctorArgs);
2305
+ }
2306
+
2307
+ // Copying using loop to avoid deop due to passing arguments object to
2308
+ // function. This is faster in many JS engines as of late 2014.
2309
+ var args = new Array(arguments.length - 2);
2310
+ for (var i = 2; i < arguments.length; i++) {
2311
+ args[i - 2] = arguments[i];
2312
+ }
2313
+ var foundCaller = false;
2314
+ for (var ctor = me.constructor;
2315
+ ctor; ctor = ctor.superClass_ && ctor.superClass_.constructor) {
2316
+ if (ctor.prototype[opt_methodName] === caller) {
2317
+ foundCaller = true;
2318
+ } else if (foundCaller) {
2319
+ return ctor.prototype[opt_methodName].apply(me, args);
2320
+ }
2321
+ }
2322
+
2323
+ // If we did not find the caller in the prototype chain, then one of two
2324
+ // things happened:
2325
+ // 1) The caller is an instance method.
2326
+ // 2) This method was not called by the right caller.
2327
+ if (me[opt_methodName] === caller) {
2328
+ return me.constructor.prototype[opt_methodName].apply(me, args);
2329
+ } else {
2330
+ throw Error(
2331
+ 'goog.base called from a method of one name ' +
2332
+ 'to a method of a different name');
2333
+ }
1474
2334
  };
1475
2335
 
2336
+
1476
2337
  /**
1477
2338
  * Allow for aliasing within scope functions. This function exists for
1478
- * uncompiled code - in compiled code the calls will be inlined and the
1479
- * aliases applied. In uncompiled code the function is simply run since the
1480
- * aliases as written are valid JavaScript.
2339
+ * uncompiled code - in compiled code the calls will be inlined and the aliases
2340
+ * applied. In uncompiled code the function is simply run since the aliases as
2341
+ * written are valid JavaScript.
2342
+ *
2343
+ *
1481
2344
  * @param {function()} fn Function to call. This function can contain aliases
1482
2345
  * to namespaces (e.g. "var dom = goog.dom") or classes
1483
- * (e.g. "var Timer = goog.Timer").
2346
+ * (e.g. "var Timer = goog.Timer").
1484
2347
  */
1485
2348
  goog.scope = function(fn) {
1486
2349
  fn.call(goog.global);
1487
2350
  };
1488
2351
 
1489
2352
 
2353
+ /*
2354
+ * To support uncompiled, strict mode bundles that use eval to divide source
2355
+ * like so:
2356
+ * eval('someSource;//# sourceUrl sourcefile.js');
2357
+ * We need to export the globally defined symbols "goog" and "COMPILED".
2358
+ * Exporting "goog" breaks the compiler optimizations, so we required that
2359
+ * be defined externally.
2360
+ * NOTE: We don't use goog.exportSymbol here because we don't want to trigger
2361
+ * extern generation when that compiler option is enabled.
2362
+ */
2363
+ if (!COMPILED) {
2364
+ goog.global['COMPILED'] = COMPILED;
2365
+ }
2366
+
2367
+
2368
+ //==============================================================================
2369
+ // goog.defineClass implementation
2370
+ //==============================================================================
2371
+
2372
+
2373
+ /**
2374
+ * Creates a restricted form of a Closure "class":
2375
+ * - from the compiler's perspective, the instance returned from the
2376
+ * constructor is sealed (no new properties may be added). This enables
2377
+ * better checks.
2378
+ * - the compiler will rewrite this definition to a form that is optimal
2379
+ * for type checking and optimization (initially this will be a more
2380
+ * traditional form).
2381
+ *
2382
+ * @param {Function} superClass The superclass, Object or null.
2383
+ * @param {goog.defineClass.ClassDescriptor} def
2384
+ * An object literal describing
2385
+ * the class. It may have the following properties:
2386
+ * "constructor": the constructor function
2387
+ * "statics": an object literal containing methods to add to the constructor
2388
+ * as "static" methods or a function that will receive the constructor
2389
+ * function as its only parameter to which static properties can
2390
+ * be added.
2391
+ * all other properties are added to the prototype.
2392
+ * @return {!Function} The class constructor.
2393
+ */
2394
+ goog.defineClass = function(superClass, def) {
2395
+ // TODO(johnlenz): consider making the superClass an optional parameter.
2396
+ var constructor = def.constructor;
2397
+ var statics = def.statics;
2398
+ // Wrap the constructor prior to setting up the prototype and static methods.
2399
+ if (!constructor || constructor == Object.prototype.constructor) {
2400
+ constructor = function() {
2401
+ throw Error('cannot instantiate an interface (no constructor defined).');
2402
+ };
2403
+ }
2404
+
2405
+ var cls = goog.defineClass.createSealingConstructor_(constructor, superClass);
2406
+ if (superClass) {
2407
+ goog.inherits(cls, superClass);
2408
+ }
2409
+
2410
+ // Remove all the properties that should not be copied to the prototype.
2411
+ delete def.constructor;
2412
+ delete def.statics;
2413
+
2414
+ goog.defineClass.applyProperties_(cls.prototype, def);
2415
+ if (statics != null) {
2416
+ if (statics instanceof Function) {
2417
+ statics(cls);
2418
+ } else {
2419
+ goog.defineClass.applyProperties_(cls, statics);
2420
+ }
2421
+ }
2422
+
2423
+ return cls;
2424
+ };
2425
+
2426
+
2427
+ /**
2428
+ * @typedef {{
2429
+ * constructor: (!Function|undefined),
2430
+ * statics: (Object|undefined|function(Function):void)
2431
+ * }}
2432
+ * @suppress {missingProvide}
2433
+ */
2434
+ goog.defineClass.ClassDescriptor;
2435
+
2436
+
2437
+ /**
2438
+ * @define {boolean} Whether the instances returned by
2439
+ * goog.defineClass should be sealed when possible.
2440
+ */
2441
+ goog.define('goog.defineClass.SEAL_CLASS_INSTANCES', goog.DEBUG);
2442
+
2443
+
2444
+ /**
2445
+ * If goog.defineClass.SEAL_CLASS_INSTANCES is enabled and Object.seal is
2446
+ * defined, this function will wrap the constructor in a function that seals the
2447
+ * results of the provided constructor function.
2448
+ *
2449
+ * @param {!Function} ctr The constructor whose results maybe be sealed.
2450
+ * @param {Function} superClass The superclass constructor.
2451
+ * @return {!Function} The replacement constructor.
2452
+ * @private
2453
+ */
2454
+ goog.defineClass.createSealingConstructor_ = function(ctr, superClass) {
2455
+ if (goog.defineClass.SEAL_CLASS_INSTANCES &&
2456
+ Object.seal instanceof Function) {
2457
+ // Don't seal subclasses of unsealable-tagged legacy classes.
2458
+ if (superClass && superClass.prototype &&
2459
+ superClass.prototype[goog.UNSEALABLE_CONSTRUCTOR_PROPERTY_]) {
2460
+ return ctr;
2461
+ }
2462
+ /**
2463
+ * @this {Object}
2464
+ * @return {?}
2465
+ */
2466
+ var wrappedCtr = function() {
2467
+ // Don't seal an instance of a subclass when it calls the constructor of
2468
+ // its super class as there is most likely still setup to do.
2469
+ var instance = ctr.apply(this, arguments) || this;
2470
+ instance[goog.UID_PROPERTY_] = instance[goog.UID_PROPERTY_];
2471
+ if (this.constructor === wrappedCtr) {
2472
+ Object.seal(instance);
2473
+ }
2474
+ return instance;
2475
+ };
2476
+ return wrappedCtr;
2477
+ }
2478
+ return ctr;
2479
+ };
2480
+
2481
+
2482
+ // TODO(johnlenz): share these values with the goog.object
2483
+ /**
2484
+ * The names of the fields that are defined on Object.prototype.
2485
+ * @type {!Array<string>}
2486
+ * @private
2487
+ * @const
2488
+ */
2489
+ goog.defineClass.OBJECT_PROTOTYPE_FIELDS_ = [
2490
+ 'constructor',
2491
+ 'hasOwnProperty',
2492
+ 'isPrototypeOf',
2493
+ 'propertyIsEnumerable',
2494
+ 'toLocaleString',
2495
+ 'toString',
2496
+ 'valueOf'
2497
+ ];
2498
+
2499
+
2500
+ // TODO(johnlenz): share this function with the goog.object
2501
+ /**
2502
+ * @param {!Object} target The object to add properties to.
2503
+ * @param {!Object} source The object to copy properties from.
2504
+ * @private
2505
+ */
2506
+ goog.defineClass.applyProperties_ = function(target, source) {
2507
+ // TODO(johnlenz): update this to support ES5 getters/setters
2508
+
2509
+ var key;
2510
+ for (key in source) {
2511
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
2512
+ target[key] = source[key];
2513
+ }
2514
+ }
2515
+
2516
+ // For IE the for-in-loop does not contain any properties that are not
2517
+ // enumerable on the prototype object (for example isPrototypeOf from
2518
+ // Object.prototype) and it will also not include 'replace' on objects that
2519
+ // extend String and change 'replace' (not that it is common for anyone to
2520
+ // extend anything except Object).
2521
+ for (var i = 0; i < goog.defineClass.OBJECT_PROTOTYPE_FIELDS_.length; i++) {
2522
+ key = goog.defineClass.OBJECT_PROTOTYPE_FIELDS_[i];
2523
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
2524
+ target[key] = source[key];
2525
+ }
2526
+ }
2527
+ };
2528
+
2529
+
2530
+ /**
2531
+ * Sealing classes breaks the older idiom of assigning properties on the
2532
+ * prototype rather than in the constructor. As such, goog.defineClass
2533
+ * must not seal subclasses of these old-style classes until they are fixed.
2534
+ * Until then, this marks a class as "broken", instructing defineClass
2535
+ * not to seal subclasses.
2536
+ * @param {!Function} ctr The legacy constructor to tag as unsealable.
2537
+ */
2538
+ goog.tagUnsealableClass = function(ctr) {
2539
+ if (!COMPILED && goog.defineClass.SEAL_CLASS_INSTANCES) {
2540
+ ctr.prototype[goog.UNSEALABLE_CONSTRUCTOR_PROPERTY_] = true;
2541
+ }
2542
+ };
2543
+
2544
+
2545
+ /**
2546
+ * Name for unsealable tag property.
2547
+ * @const @private {string}
2548
+ */
2549
+ goog.UNSEALABLE_CONSTRUCTOR_PROPERTY_ = 'goog_defineClass_legacy_unsealable';