diff options
author | Brian Picciano <mediocregopher@gmail.com> | 2018-11-13 00:24:09 -0500 |
---|---|---|
committer | Brian Picciano <mediocregopher@gmail.com> | 2018-11-13 00:24:09 -0500 |
commit | 2b4757367470d8e36bc00901dac567e375796ed4 (patch) | |
tree | 72368624006c21d28228a100ee88590c7bf95e58 /assets/viz/2/goog/base.js | |
parent | 5ed62d23b4bbbf7717de4adfa0eaf2af19365408 (diff) |
update viz 2 to use the newest version, which has some performance improvements and is easier to read the code for. also update the description
Diffstat (limited to 'assets/viz/2/goog/base.js')
-rw-r--r-- | assets/viz/2/goog/base.js | 622 |
1 files changed, 408 insertions, 214 deletions
diff --git a/assets/viz/2/goog/base.js b/assets/viz/2/goog/base.js index 97a9947..46b2f09 100644 --- a/assets/viz/2/goog/base.js +++ b/assets/viz/2/goog/base.js @@ -15,19 +15,19 @@ /** * @fileoverview Bootstrap for the Google JS Library (Closure). * - * In uncompiled mode base.js will write out Closure's deps file, unless the - * global <code>CLOSURE_NO_DEPS</code> is set to true. This allows projects to - * include their own deps file(s) from different locations. + * In uncompiled mode base.js will attempt to load Closure's deps file, unless + * the global <code>CLOSURE_NO_DEPS</code> is set to true. This allows projects + * to include their own deps file(s) from different locations. * - * @author arv@google.com (Erik Arvidsson) + * Avoid including base.js more than once. This is strictly discouraged and not + * supported. goog.require(...) won't work properly in that case. * * @provideGoog */ /** - * @define {boolean} Overridden to true by the compiler when - * --process_closure_primitives is specified. + * @define {boolean} Overridden to true by the compiler. */ var COMPILED = false; @@ -90,8 +90,6 @@ goog.global.CLOSURE_DEFINES; /** * Returns true if the specified value is not undefined. - * WARNING: Do not use this to test if an object has a property. Use the in - * operator instead. * * @param {?} val Variable to test. * @return {boolean} Whether variable is defined. @@ -102,6 +100,35 @@ goog.isDef = function(val) { return val !== void 0; }; +/** + * Returns true if the specified value is a string. + * @param {?} val Variable to test. + * @return {boolean} Whether variable is a string. + */ +goog.isString = function(val) { + return typeof val == 'string'; +}; + + +/** + * Returns true if the specified value is a boolean. + * @param {?} val Variable to test. + * @return {boolean} Whether variable is boolean. + */ +goog.isBoolean = function(val) { + return typeof val == 'boolean'; +}; + + +/** + * Returns true if the specified value is a number. + * @param {?} val Variable to test. + * @return {boolean} Whether variable is a number. + */ +goog.isNumber = function(val) { + return typeof val == 'number'; +}; + /** * Builds an object structure for the provided namespace path, ensuring that @@ -111,7 +138,7 @@ goog.isDef = function(val) { * @param {string} name name of the object that this file defines. * @param {*=} opt_object the object to expose at the end of the path. * @param {Object=} opt_objectToExportTo The object to add the path to; default - * is |goog.global|. + * is `goog.global`. * @private */ goog.exportPath_ = function(name, opt_object, opt_objectToExportTo) { @@ -125,17 +152,11 @@ goog.exportPath_ = function(name, opt_object, opt_objectToExportTo) { cur.execScript('var ' + parts[0]); } - // Certain browsers cannot parse code in the form for((a in b); c;); - // This pattern is produced by the JSCompiler when it collapses the - // statement above into the conditional loop below. To prevent this from - // happening, use a for-loop and reserve the init logic as below. - - // Parentheses added to eliminate strict JS warning in Firefox. for (var part; parts.length && (part = parts.shift());) { if (!parts.length && goog.isDef(opt_object)) { // last part and we have an object; use it cur[part] = opt_object; - } else if (cur[part]) { + } else if (cur[part] && cur[part] !== Object.prototype[part]) { cur = cur[part]; } else { cur = cur[part] = {}; @@ -158,11 +179,16 @@ goog.define = function(name, defaultValue) { var value = defaultValue; if (!COMPILED) { if (goog.global.CLOSURE_UNCOMPILED_DEFINES && + // Anti DOM-clobbering runtime check (b/37736576). + /** @type {?} */ (goog.global.CLOSURE_UNCOMPILED_DEFINES).nodeType === + undefined && Object.prototype.hasOwnProperty.call( goog.global.CLOSURE_UNCOMPILED_DEFINES, name)) { value = goog.global.CLOSURE_UNCOMPILED_DEFINES[name]; } else if ( goog.global.CLOSURE_DEFINES && + // Anti DOM-clobbering runtime check (b/37736576). + /** @type {?} */ (goog.global.CLOSURE_DEFINES).nodeType === undefined && Object.prototype.hasOwnProperty.call( goog.global.CLOSURE_DEFINES, name)) { value = goog.global.CLOSURE_DEFINES[name]; @@ -174,11 +200,12 @@ goog.define = function(name, defaultValue) { /** * @define {boolean} DEBUG is provided as a convenience so that debugging code - * that should not be included in a production js_binary can be easily stripped - * by specifying --define goog.DEBUG=false to the JSCompiler. For example, most - * toString() methods should be declared inside an "if (goog.DEBUG)" conditional - * because they are generally used for debugging purposes and it is difficult - * for the JSCompiler to statically determine whether they are used. + * that should not be included in a production. It can be easily stripped + * by specifying --define goog.DEBUG=false to the Closure Compiler aka + * JSCompiler. For example, most toString() methods should be declared inside an + * "if (goog.DEBUG)" conditional because they are generally used for debugging + * purposes and it is difficult for the JSCompiler to statically determine + * whether they are used. */ goog.define('goog.DEBUG', true); @@ -186,7 +213,7 @@ goog.define('goog.DEBUG', true); /** * @define {string} LOCALE defines the locale being used for compilation. It is * used to select locale specific data to be compiled in js binary. BUILD rule - * can specify this value by "--define goog.LOCALE=<locale_name>" as JSCompiler + * can specify this value by "--define goog.LOCALE=<locale_name>" as a compiler * option. * * Take into account that the locale code format is important. You should use @@ -200,7 +227,8 @@ goog.define('goog.DEBUG', true); * For language codes you should use values defined by ISO 693-1. See it here * http://www.w3.org/WAI/ER/IG/ert/iso639.htm. There is only one exception from * this rule: the Hebrew language. For legacy reasons the old code (iw) should - * be used instead of the new code (he), see http://wiki/Main/IIISynonyms. + * be used instead of the new code (he). + * */ goog.define('goog.LOCALE', 'en'); // default to en @@ -214,7 +242,7 @@ goog.define('goog.LOCALE', 'en'); // default to en * * If your JavaScript can be loaded by a third party site and you are wary about * relying on non-standard implementations, specify - * "--define goog.TRUSTED_SITE=false" to the JSCompiler. + * "--define goog.TRUSTED_SITE=false" to the compiler. */ goog.define('goog.TRUSTED_SITE', true); @@ -345,6 +373,7 @@ goog.VALID_MODULE_RE_ = /^[a-zA-Z_$][a-zA-Z0-9._$]*$/; * * @param {string} name Namespace provided by this file in the form * "goog.package.part", is expected but not required. + * @return {void} */ goog.module = function(name) { if (!goog.isString(name) || !name || @@ -352,7 +381,13 @@ goog.module = function(name) { throw Error('Invalid module identifier'); } if (!goog.isInModuleLoader_()) { - throw Error('Module ' + name + ' has been loaded incorrectly.'); + throw Error( + 'Module ' + name + ' has been loaded incorrectly. Note, ' + + 'modules cannot be loaded as normal scripts. They require some kind of ' + + 'pre-processing step. You\'re likely trying to load a module via a ' + + 'script tag or as a part of a concatenated bundle without rewriting the ' + + 'module. For more info see: ' + + 'https://github.com/google/closure-library/wiki/goog.module:-an-ES6-module-like-alternative-to-goog.provide.'); } if (goog.moduleLoaderState_.moduleName) { throw Error('goog.module may only be called once per module.'); @@ -393,14 +428,14 @@ goog.module.get = function(name) { */ goog.module.getInternal_ = function(name) { if (!COMPILED) { - if (goog.isProvided_(name)) { - // goog.require only return a value with-in goog.module files. - return name in goog.loadedModules_ ? goog.loadedModules_[name] : - goog.getObjectByName(name); - } else { - return null; + if (name in goog.loadedModules_) { + return goog.loadedModules_[name]; + } else if (!goog.implicitNamespaces_[name]) { + var ns = goog.getObjectByName(name); + return ns != null ? ns : null; } } + return null; }; @@ -473,6 +508,9 @@ goog.setTestOnly = function(opt_message) { * into the JavaScript binary. If it is required elsewhere, it will be type * checked as normal. * + * Before using goog.forwardDeclare, please read the documentation at + * https://github.com/google/closure-compiler/wiki/Bad-Type-Annotation to + * understand the options and tradeoffs when working with forward declarations. * * @param {string} name The namespace to forward declare in the form of * "goog.package.part". @@ -612,7 +650,7 @@ goog.addDependency = function(relPath, provides, requires, opt_loadFlags) { // Externally: https://developers.google.com/closure/library/docs/depswriter // // Because of legacy clients, the DOM loader can't be easily removed from -// base.js. Work is being done to make it disableable or replaceable for +// base.js. Work was done to make it disableable or replaceable for // different environments (DOM-less JavaScript interpreters like Rhino or V8, // for example). See bootstrap/ for more information. @@ -644,8 +682,7 @@ goog.logToConsole_ = function(msg) { /** * Implements a system for the dynamic resolution of dependencies that works in * parallel with the BUILD system. Note that all calls to goog.require will be - * stripped by the JSCompiler when the --process_closure_primitives option is - * used. + * stripped by the compiler. * @see goog.provide * @param {string} name Namespace to include (as was given in goog.provide()) in * the form "goog.package.part". @@ -653,7 +690,7 @@ goog.logToConsole_ = function(msg) { * module otherwise null. */ goog.require = function(name) { - // If the object already exists we do not need do do anything. + // If the object already exists we do not need to do anything. if (!COMPILED) { if (goog.ENABLE_DEBUG_LOADER && goog.IS_OLD_IE_) { goog.maybeProcessDeferredDep_(name); @@ -662,23 +699,20 @@ goog.require = function(name) { if (goog.isProvided_(name)) { if (goog.isInModuleLoader_()) { return goog.module.getInternal_(name); - } else { - return null; } - } - - if (goog.ENABLE_DEBUG_LOADER) { + } else if (goog.ENABLE_DEBUG_LOADER) { var path = goog.getPathFromDeps_(name); if (path) { goog.writeScripts_(path); - return null; + } else { + var errorMessage = 'goog.require could not find: ' + name; + goog.logToConsole_(errorMessage); + + throw Error(errorMessage); } } - var errorMessage = 'goog.require could not find: ' + name; - goog.logToConsole_(errorMessage); - - throw Error(errorMessage); + return null; } }; @@ -698,7 +732,8 @@ goog.global.CLOSURE_BASE_PATH; /** - * Whether to write out Closure's deps file. By default, the deps are written. + * Whether to attempt to load Closure's deps file. By default, when uncompiled, + * deps files will attempt to be loaded. * @type {boolean|undefined} */ goog.global.CLOSURE_NO_DEPS; @@ -731,9 +766,6 @@ goog.nullFunction = function() {}; * Now if a subclass of Foo fails to override bar(), an error will be thrown * when bar() is invoked. * - * Note: This does not take the name of the function to override as an argument - * because that would make it more difficult to obfuscate our JavaScript code. - * * @type {!Function} * @throws {Error} when invoked to indicate the method should be overridden. */ @@ -749,6 +781,10 @@ goog.abstractMethod = function() { * method to. */ goog.addSingletonGetter = function(ctor) { + // instance_ is immediately set to prevent issues with sealed constructors + // such as are encountered when a constructor is returned as the export object + // of a goog.module in unoptimized code. + ctor.instance_ = undefined; ctor.getInstance = function() { if (ctor.instance_) { return ctor.instance_; @@ -870,7 +906,9 @@ if (goog.DEPENDENCIES_ENABLED) { * @private */ goog.findBasePath_ = function() { - if (goog.isDef(goog.global.CLOSURE_BASE_PATH)) { + if (goog.isDef(goog.global.CLOSURE_BASE_PATH) && + // Anti DOM-clobbering runtime check (b/37736576). + goog.isString(goog.global.CLOSURE_BASE_PATH)) { goog.basePath = goog.global.CLOSURE_BASE_PATH; return; } else if (!goog.inHtmlDocument_()) { @@ -878,7 +916,13 @@ if (goog.DEPENDENCIES_ENABLED) { } /** @type {Document} */ var doc = goog.global.document; - var scripts = doc.getElementsByTagName('SCRIPT'); + // If we have a currentScript available, use it exclusively. + var currentScript = doc.currentScript; + if (currentScript) { + var scripts = [currentScript]; + } else { + var scripts = doc.getElementsByTagName('SCRIPT'); + } // Search backwards since the current script is in almost all cases the one // that has base.js. for (var i = scripts.length - 1; i >= 0; --i) { @@ -920,6 +964,17 @@ if (goog.DEPENDENCIES_ENABLED) { /** + * Whether IE9 or earlier is waiting on a dependency. This ensures that + * deferred modules that have no non-deferred dependencies actually get + * loaded, since if we defer them and then never pull in a non-deferred + * script, then `goog.loadQueuedModules_` will never be called. Instead, + * if not waiting on anything we simply don't defer in the first place. + * @private {boolean} + */ + goog.oldIeWaiting_ = false; + + + /** * Given a URL initiate retrieval and execution of a script that needs * pre-processing. * @param {string} src Script source URL. @@ -1003,6 +1058,7 @@ if (goog.DEPENDENCIES_ENABLED) { goog.maybeProcessDeferredPath_(path); } } + goog.oldIeWaiting_ = false; }; @@ -1028,8 +1084,9 @@ if (goog.DEPENDENCIES_ENABLED) { goog.isDeferredModule_ = function(name) { var path = goog.getPathFromDeps_(name); var loadFlags = path && goog.dependencies_.loadFlags[path] || {}; + var languageLevel = loadFlags['lang'] || 'es3'; if (path && (loadFlags['module'] == 'goog' || - goog.needsTranspile_(loadFlags['lang']))) { + goog.needsTranspile_(languageLevel))) { var abspath = goog.basePath + path; return (abspath) in goog.dependencies_.deferred; } @@ -1098,68 +1155,6 @@ if (goog.DEPENDENCIES_ENABLED) { /** - * @param {function(?):?|string} moduleDef The module definition. - */ - goog.loadModule = function(moduleDef) { - // NOTE: we allow function definitions to be either in the from - // of a string to eval (which keeps the original source intact) or - // in a eval forbidden environment (CSP) we allow a function definition - // which in its body must call {@code goog.module}, and return the exports - // of the module. - var previousState = goog.moduleLoaderState_; - try { - goog.moduleLoaderState_ = { - moduleName: undefined, - declareLegacyNamespace: false - }; - var exports; - if (goog.isFunction(moduleDef)) { - exports = moduleDef.call(goog.global, {}); - } else if (goog.isString(moduleDef)) { - exports = goog.loadModuleFromSource_.call(goog.global, moduleDef); - } else { - throw Error('Invalid module definition'); - } - - var moduleName = goog.moduleLoaderState_.moduleName; - if (!goog.isString(moduleName) || !moduleName) { - throw Error('Invalid module name \"' + moduleName + '\"'); - } - - // Don't seal legacy namespaces as they may be uses as a parent of - // another namespace - if (goog.moduleLoaderState_.declareLegacyNamespace) { - goog.constructNamespace_(moduleName, exports); - } else if (goog.SEAL_MODULE_EXPORTS && Object.seal) { - Object.seal(exports); - } - - goog.loadedModules_[moduleName] = exports; - } finally { - goog.moduleLoaderState_ = previousState; - } - }; - - - /** - * @private @const {function(string):?} - * - * The new type inference warns because this function has no formal - * parameters, but its jsdoc says that it takes one argument. - * (The argument is used via arguments[0], but NTI does not detect this.) - * @suppress {newCheckTypes} - */ - goog.loadModuleFromSource_ = function() { - // NOTE: we avoid declaring parameters or local variables here to avoid - // masking globals or leaking values into the module definition. - 'use strict'; - var exports = {}; - eval(arguments[0]); - return exports; - }; - - - /** * Writes a new script pointing to {@code src} directly into the DOM. * * NOTE: This method is not CSP-compliant. @see goog.appendScriptSrcNode_ for @@ -1246,8 +1241,9 @@ if (goog.DEPENDENCIES_ENABLED) { goog.writeScriptSrcNode_(src); } } else { - var state = " onreadystatechange='goog.onScriptLoad_(this, " + - ++goog.lastNonModuleScriptIndex_ + ")' "; + goog.oldIeWaiting_ = true; + var state = ' onreadystatechange=\'goog.onScriptLoad_(this, ' + + ++goog.lastNonModuleScriptIndex_ + ')\' '; doc.write( '<script type="text/javascript" src="' + src + '"' + state + '></' + @@ -1255,7 +1251,8 @@ if (goog.DEPENDENCIES_ENABLED) { } } else { doc.write( - '<script type="text/javascript">' + opt_sourceText + '</' + + '<script type="text/javascript">' + + goog.protectScriptTag_(opt_sourceText) + '</' + 'script>'); } return true; @@ -1264,6 +1261,17 @@ if (goog.DEPENDENCIES_ENABLED) { } }; + /** + * Rewrites closing script tags in input to avoid ending an enclosing script + * tag. + * + * @param {string} str + * @return {string} + * @private + */ + goog.protectScriptTag_ = function(str) { + return str.replace(/<\/(SCRIPT)/ig, '\\x3c/$1'); + }; /** * Determines whether the given language needs to be transpiled. @@ -1276,53 +1284,18 @@ if (goog.DEPENDENCIES_ENABLED) { return true; } else if (goog.TRANSPILE == 'never') { return false; - } else if (!goog.transpiledLanguages_) { - goog.transpiledLanguages_ = {'es5': true, 'es6': true, 'es6-impl': true}; - /** @preserveTry */ - try { - // Perform some quick conformance checks, to distinguish - // between browsers that support es5, es6-impl, or es6. - - // Identify ES3-only browsers by their incorrect treatment of commas. - goog.transpiledLanguages_['es5'] = eval('[1,].length!=1'); - - // As browsers mature, features will be moved from the full test - // into the impl test. This must happen before the corresponding - // features are changed in the Closure Compiler's FeatureSet object. - - // Test 1: es6-impl [FF49, Edge 13, Chrome 49] - // (a) let/const keyword, (b) class expressions, (c) Map object, - // (d) iterable arguments, (e) spread operator - var es6implTest = - 'let a={};const X=class{constructor(){}x(z){return new Map([' + - '...arguments]).get(z[0])==3}};return new X().x([a,3])'; - - // Test 2: es6 [FF50 (?), Edge 14 (?), Chrome 50] - // (a) default params (specifically shadowing locals), - // (b) destructuring, (c) block-scoped functions, - // (d) for-of (const), (e) new.target/Reflect.construct - var es6fullTest = - 'class X{constructor(){if(new.target!=String)throw 1;this.x=42}}' + - 'let q=Reflect.construct(X,[],String);if(q.x!=42||!(q instanceof ' + - 'String))throw 1;for(const a of[2,3]){if(a==2)continue;function ' + - 'f(z={a}){let a=0;return z.a}{function f(){return 0;}}return f()' + - '==3}'; - - if (eval('(()=>{"use strict";' + es6implTest + '})()')) { - goog.transpiledLanguages_['es6-impl'] = false; - } - if (eval('(()=>{"use strict";' + es6fullTest + '})()')) { - goog.transpiledLanguages_['es6'] = false; - } - } catch (err) { - } + } else if (!goog.requiresTranspilation_) { + goog.requiresTranspilation_ = goog.createRequiresTranspilation_(); + } + if (lang in goog.requiresTranspilation_) { + return goog.requiresTranspilation_[lang]; + } else { + throw new Error('Unknown language mode: ' + lang); } - return !!goog.transpiledLanguages_[lang]; }; - /** @private {?Object<string, boolean>} */ - goog.transpiledLanguages_ = null; + goog.requiresTranspilation_ = null; /** @private {number} */ @@ -1331,7 +1304,7 @@ if (goog.DEPENDENCIES_ENABLED) { /** * A readystatechange handler for legacy IE - * @param {!HTMLScriptElement} script + * @param {?} script * @param {number} scriptIndex * @return {boolean} * @private @@ -1411,7 +1384,8 @@ if (goog.DEPENDENCIES_ENABLED) { var path = scripts[i]; if (path) { var loadFlags = deps.loadFlags[path] || {}; - var needsTranspile = goog.needsTranspile_(loadFlags['lang']); + var languageLevel = loadFlags['lang'] || 'es3'; + var needsTranspile = goog.needsTranspile_(languageLevel); if (loadFlags['module'] == 'goog' || needsTranspile) { goog.importProcessedScript_( goog.basePath + path, loadFlags['module'] == 'goog', @@ -1455,6 +1429,111 @@ if (goog.DEPENDENCIES_ENABLED) { /** + * @package {?boolean} + * Visible for testing. + */ +goog.hasBadLetScoping = null; + + +/** + * @return {boolean} + * @package Visible for testing. + */ +goog.useSafari10Workaround = function() { + if (goog.hasBadLetScoping == null) { + var hasBadLetScoping; + try { + hasBadLetScoping = !eval( + '"use strict";' + + 'let x = 1; function f() { return typeof x; };' + + 'f() == "number";'); + } catch (e) { + // Assume that ES6 syntax isn't supported. + hasBadLetScoping = false; + } + goog.hasBadLetScoping = hasBadLetScoping; + } + return goog.hasBadLetScoping; +}; + + +/** + * @param {string} moduleDef + * @return {string} + * @package Visible for testing. + */ +goog.workaroundSafari10EvalBug = function(moduleDef) { + return '(function(){' + moduleDef + + '\n' + // Terminate any trailing single line comment. + ';' + // Terminate any trailing expression. + '})();\n'; +}; + + +/** + * @param {function(?):?|string} moduleDef The module definition. + */ +goog.loadModule = function(moduleDef) { + // NOTE: we allow function definitions to be either in the from + // of a string to eval (which keeps the original source intact) or + // in a eval forbidden environment (CSP) we allow a function definition + // which in its body must call {@code goog.module}, and return the exports + // of the module. + var previousState = goog.moduleLoaderState_; + try { + goog.moduleLoaderState_ = { + moduleName: undefined, + declareLegacyNamespace: false + }; + var exports; + if (goog.isFunction(moduleDef)) { + exports = moduleDef.call(undefined, {}); + } else if (goog.isString(moduleDef)) { + if (goog.useSafari10Workaround()) { + moduleDef = goog.workaroundSafari10EvalBug(moduleDef); + } + + exports = goog.loadModuleFromSource_.call(undefined, moduleDef); + } else { + throw Error('Invalid module definition'); + } + + var moduleName = goog.moduleLoaderState_.moduleName; + if (!goog.isString(moduleName) || !moduleName) { + throw Error('Invalid module name \"' + moduleName + '\"'); + } + + // Don't seal legacy namespaces as they may be uses as a parent of + // another namespace + if (goog.moduleLoaderState_.declareLegacyNamespace) { + goog.constructNamespace_(moduleName, exports); + } else if ( + goog.SEAL_MODULE_EXPORTS && Object.seal && typeof exports == 'object' && + exports != null) { + Object.seal(exports); + } + + goog.loadedModules_[moduleName] = exports; + } finally { + goog.moduleLoaderState_ = previousState; + } +}; + + +/** + * @private @const + */ +goog.loadModuleFromSource_ = /** @type {function(string):?} */ (function() { + // NOTE: we avoid declaring parameters or local variables here to avoid + // masking globals or leaking values into the module definition. + 'use strict'; + var exports = {}; + eval(arguments[0]); + return exports; +}); + + +/** * Normalize a file path by removing redundant ".." and extraneous "." file * path components. * @param {string} path @@ -1480,6 +1559,15 @@ goog.normalizePath_ = function(path) { /** + * Provides a hook for loading a file when using Closure's goog.require() API + * with goog.modules. In particular this hook is provided to support Node.js. + * + * @type {(function(string):string)|undefined} + */ +goog.global.CLOSURE_LOAD_FILE_SYNC; + + +/** * Loads file by synchronous XHR. Should not be used in production environments. * @param {string} src Source URL. * @return {?string} File contents, or null if load failed. @@ -1540,7 +1628,7 @@ goog.retrieveAndExec_ = function(src, isModule, needsTranspile) { scriptText += '\n//# sourceURL=' + src; } var isOldIE = goog.IS_OLD_IE_; - if (isOldIE) { + if (isOldIE && goog.oldIeWaiting_) { goog.dependencies_.deferred[originalPath] = scriptText; goog.queuedModules_.push(originalPath); } else { @@ -1571,7 +1659,20 @@ goog.transpile_ = function(code, path) { // need it, we're about to load and write the ES6 code synchronously, // so a normal script-tag load will be too slow. eval(transpilerCode + '\n//# sourceURL=' + transpilerPath); - // Note: transpile.js reassigns goog.global['$jscomp'] so pull it again. + // Even though the transpiler is optional, if $gwtExport is found, it's + // a sign the transpiler was loaded and the $jscomp.transpile *should* + // be there. + if (goog.global['$gwtExport'] && goog.global['$gwtExport']['$jscomp'] && + !goog.global['$gwtExport']['$jscomp']['transpile']) { + throw new Error( + 'The transpiler did not properly export the "transpile" ' + + 'method. $gwtExport: ' + JSON.stringify(goog.global['$gwtExport'])); + } + // transpile.js only exports a single $jscomp function, transpile. We + // grab just that and add it to the existing definition of $jscomp which + // contains the polyfills. + goog.global['$jscomp'].transpile = + goog.global['$gwtExport']['$jscomp']['transpile']; jscomp = goog.global['$jscomp']; transpile = jscomp.transpile; } @@ -1756,36 +1857,6 @@ goog.isDateLike = function(val) { /** - * Returns true if the specified value is a string. - * @param {?} val Variable to test. - * @return {boolean} Whether variable is a string. - */ -goog.isString = function(val) { - return typeof val == 'string'; -}; - - -/** - * Returns true if the specified value is a boolean. - * @param {?} val Variable to test. - * @return {boolean} Whether variable is boolean. - */ -goog.isBoolean = function(val) { - return typeof val == 'boolean'; -}; - - -/** - * Returns true if the specified value is a number. - * @param {?} val Variable to test. - * @return {boolean} Whether variable is a number. - */ -goog.isNumber = function(val) { - return typeof val == 'number'; -}; - - -/** * Returns true if the specified value is a function. * @param {?} val Variable to test. * @return {boolean} Whether variable is a function. @@ -1858,7 +1929,7 @@ goog.removeUid = function(obj) { if (obj !== null && 'removeAttribute' in obj) { obj.removeAttribute(goog.UID_PROPERTY_); } - /** @preserveTry */ + try { delete obj[goog.UID_PROPERTY_]; } catch (ex) { @@ -1935,17 +2006,15 @@ goog.cloneObject = function(obj) { /** * A native implementation of goog.bind. - * @param {Function} fn A function to partially apply. - * @param {Object|undefined} selfObj Specifies the object which this should - * point to when the function is run. + * @param {?function(this:T, ...)} fn A function to partially apply. + * @param {T} selfObj Specifies the object which this should point to when the + * function is run. * @param {...*} var_args Additional arguments that are partially applied to the * function. - * @return {!Function} A partially-applied form of the function bind() was + * @return {!Function} A partially-applied form of the function goog.bind() was * invoked as a method of. + * @template T * @private - * @suppress {deprecated} The compiler thinks that Function.prototype.bind is - * deprecated because some people have declared a pure-JS version. - * Only the pure-JS version is truly deprecated. */ goog.bindNative_ = function(fn, selfObj, var_args) { return /** @type {!Function} */ (fn.call.apply(fn.bind, arguments)); @@ -1954,13 +2023,14 @@ goog.bindNative_ = function(fn, selfObj, var_args) { /** * A pure-JS implementation of goog.bind. - * @param {Function} fn A function to partially apply. - * @param {Object|undefined} selfObj Specifies the object which this should - * point to when the function is run. + * @param {?function(this:T, ...)} fn A function to partially apply. + * @param {T} selfObj Specifies the object which this should point to when the + * function is run. * @param {...*} var_args Additional arguments that are partially applied to the * function. - * @return {!Function} A partially-applied form of the function bind() was + * @return {!Function} A partially-applied form of the function goog.bind() was * invoked as a method of. + * @template T * @private */ goog.bindJs_ = function(fn, selfObj, var_args) { @@ -1978,7 +2048,9 @@ goog.bindJs_ = function(fn, selfObj, var_args) { }; } else { - return function() { return fn.apply(selfObj, arguments); }; + return function() { + return fn.apply(selfObj, arguments); + }; } }; @@ -2158,6 +2230,17 @@ goog.cssNameMapping_; goog.cssNameMappingStyle_; + +/** + * A hook for modifying the default behavior goog.getCssName. The function + * if present, will recieve the standard output of the goog.getCssName as + * its input. + * + * @type {(function(string):string)|undefined} + */ +goog.global.CLOSURE_CSS_NAME_MAP_FN; + + /** * Handles strings that are intended to be used as CSS class names. * @@ -2190,6 +2273,14 @@ goog.cssNameMappingStyle_; * the modifier. */ goog.getCssName = function(className, opt_modifier) { + // String() is used for compatibility with compiled soy where the passed + // className can be non-string objects. + if (String(className).charAt(0) == '.') { + throw new Error( + 'className passed in goog.getCssName must not start with ".".' + + ' You passed: ' + className); + } + var getMapping = function(cssName) { return goog.cssNameMapping_[cssName] || cssName; }; @@ -2209,14 +2300,21 @@ goog.getCssName = function(className, opt_modifier) { rename = goog.cssNameMappingStyle_ == 'BY_WHOLE' ? getMapping : renameByParts; } else { - rename = function(a) { return a; }; + rename = function(a) { + return a; + }; } - if (opt_modifier) { - return className + '-' + rename(opt_modifier); - } else { - return rename(className); + var result = + opt_modifier ? className + '-' + rename(opt_modifier) : rename(className); + + // The special CLOSURE_CSS_NAME_MAP_FN allows users to specify further + // processing of the class name. + if (goog.global.CLOSURE_CSS_NAME_MAP_FN) { + return goog.global.CLOSURE_CSS_NAME_MAP_FN(result); } + + return result; }; @@ -2443,6 +2541,9 @@ goog.inherits = function(childCtor, parentCtor) { * @return {*} The return value of the superclass method. * @suppress {es5Strict} This method can not be used in strict mode, but * all Closure Library consumers must depend on this file. + * @deprecated goog.base is not strict mode compatible. Prefer the static + * "base" method added to the constructor by goog.inherits + * or ES6 classes and the "super" keyword. */ goog.base = function(me, opt_methodName, var_args) { var caller = arguments.callee.caller; @@ -2593,7 +2694,6 @@ goog.defineClass = function(superClass, def) { * constructor: (!Function|undefined), * statics: (Object|undefined|function(Function):void) * }} - * @suppress {missingProvide} */ goog.defineClass.ClassDescriptor; @@ -2652,7 +2752,7 @@ goog.defineClass.createSealingConstructor_ = function(ctr, superClass) { /** * @param {Function} ctr The constructor to test. - * @returns {boolean} Whether the constructor has been tagged as unsealable + * @return {boolean} Whether the constructor has been tagged as unsealable * using goog.tagUnsealableClass. * @private */ @@ -2725,3 +2825,97 @@ goog.tagUnsealableClass = function(ctr) { * @const @private {string} */ goog.UNSEALABLE_CONSTRUCTOR_PROPERTY_ = 'goog_defineClass_legacy_unsealable'; + + +/** + * Returns a newly created map from language mode string to a boolean + * indicating whether transpilation should be done for that mode. + * + * Guaranteed invariant: + * For any two modes, l1 and l2 where l2 is a newer mode than l1, + * `map[l1] == true` implies that `map[l2] == true`. + * @private + * @return {!Object<string, boolean>} + */ +goog.createRequiresTranspilation_ = function() { + var /** !Object<string, boolean> */ requiresTranspilation = {'es3': false}; + var transpilationRequiredForAllLaterModes = false; + + /** + * Adds an entry to requiresTranspliation for the given language mode. + * + * IMPORTANT: Calls must be made in order from oldest to newest language + * mode. + * @param {string} modeName + * @param {function(): boolean} isSupported Returns true if the JS engine + * supports the given mode. + */ + function addNewerLanguageTranspilationCheck(modeName, isSupported) { + if (transpilationRequiredForAllLaterModes) { + requiresTranspilation[modeName] = true; + } else if (isSupported()) { + requiresTranspilation[modeName] = false; + } else { + requiresTranspilation[modeName] = true; + transpilationRequiredForAllLaterModes = true; + } + } + + /** + * Does the given code evaluate without syntax errors and return a truthy + * result? + */ + function /** boolean */ evalCheck(/** string */ code) { + try { + return !!eval(code); + } catch (ignored) { + return false; + } + } + + var userAgent = goog.global.navigator && goog.global.navigator.userAgent ? + goog.global.navigator.userAgent : + ''; + + // Identify ES3-only browsers by their incorrect treatment of commas. + addNewerLanguageTranspilationCheck('es5', function() { + return evalCheck('[1,].length==1'); + }); + addNewerLanguageTranspilationCheck('es6', function() { + // Edge has a non-deterministic (i.e., not reproducible) bug with ES6: + // https://github.com/Microsoft/ChakraCore/issues/1496. + var re = /Edge\/(\d+)(\.\d)*/i; + var edgeUserAgent = userAgent.match(re); + if (edgeUserAgent && Number(edgeUserAgent[1]) < 15) { + return false; + } + // Test es6: [FF50 (?), Edge 14 (?), Chrome 50] + // (a) default params (specifically shadowing locals), + // (b) destructuring, (c) block-scoped functions, + // (d) for-of (const), (e) new.target/Reflect.construct + var es6fullTest = + 'class X{constructor(){if(new.target!=String)throw 1;this.x=42}}' + + 'let q=Reflect.construct(X,[],String);if(q.x!=42||!(q instanceof ' + + 'String))throw 1;for(const a of[2,3]){if(a==2)continue;function ' + + 'f(z={a}){let a=0;return z.a}{function f(){return 0;}}return f()' + + '==3}'; + + return evalCheck('(()=>{"use strict";' + es6fullTest + '})()'); + }); + // TODO(joeltine): Remove es6-impl references for b/31340605. + // Consider es6-impl (widely-implemented es6 features) to be supported + // whenever es6 is supported. Technically es6-impl is a lower level of + // support than es6, but we don't have tests specifically for it. + addNewerLanguageTranspilationCheck('es6-impl', function() { + return true; + }); + // ** and **= are the only new features in 'es7' + addNewerLanguageTranspilationCheck('es7', function() { + return evalCheck('2 ** 2 == 4'); + }); + // async functions are the only new features in 'es8' + addNewerLanguageTranspilationCheck('es8', function() { + return evalCheck('async () => 1, true'); + }); + return requiresTranspilation; +}; |