| <html> |
| <head> |
| <title>outline_javascript example</title> |
| <script type="text/javascript" id="small"> var hello = 1; </script> |
| <script type="text/javascript" id="large"> |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| // Copyright 2006 Google Inc. All Rights Reserved. |
| |
| /** |
| * @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. |
| * |
| */ |
| |
| /** |
| * @define {boolean} Overridden to true by the compiler when --closure_pass |
| * or --mark_as_compiled is specified. |
| */ |
| var COMPILED = false; |
| |
| |
| /** |
| * Base namespace for the Closure library. Checks to see goog is |
| * already defined in the current scope before assigning to prevent |
| * clobbering if base.js is loaded more than once. |
| */ |
| var goog = goog || {}; // Check to see if already defined in current scope |
| |
| |
| /** |
| * Reference to the global context. In most cases this will be 'window'. |
| */ |
| goog.global = this; |
| |
| |
| /** |
| * @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. |
| */ |
| 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 |
| * option. |
| * |
| * Take into account that the locale code format is important. You should use |
| * the canonical Unicode format with hyphen as a delimiter. Language must be |
| * lowercase, Language Script - Capitalized, Region - UPPERCASE. |
| * There are few examples: pt-BR, en, en-US, sr-Latin-BO, zh-Hans-CN. |
| * |
| * See more info about locale codes here: |
| * http://www.unicode.org/reports/tr35/#Unicode_Language_and_Locale_Identifiers |
| * |
| * 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. |
| */ |
| goog.LOCALE = 'en'; // default to en |
| |
| |
| /** |
| * Indicates whether or not we can call 'eval' directly to eval code in the |
| * global scope. Set to a Boolean by the first call to goog.globalEval (which |
| * empirically tests whether eval works for globals). @see goog.globalEval |
| * @type {boolean?} |
| * @private |
| */ |
| goog.evalWorksForGlobals_ = null; |
| |
| |
| /** |
| * Creates object stubs for a namespace. When present in a file, goog.provide |
| * also indicates that the file defines the indicated object. Calls to |
| * goog.provide are resolved by the compiler if --closure_pass is set. |
| * @param {string} name name of the object that this file defines. |
| */ |
| goog.provide = function(name) { |
| if (!COMPILED) { |
| // Ensure that the same namespace isn't provided twice. This is intended |
| // to teach new developers that 'goog.provide' is effectively a variable |
| // declaration. And when JSCompiler transforms goog.provide into a real |
| // variable declaration, the compiled JS should work the same as the raw |
| // JS--even when the raw JS uses goog.provide incorrectly. |
| if (goog.getObjectByName(name) && !goog.implicitNamespaces_[name]) { |
| throw Error('Namespace "' + name + '" already declared.'); |
| } |
| |
| var namespace = name; |
| while ((namespace = namespace.substring(0, namespace.lastIndexOf('.')))) { |
| goog.implicitNamespaces_[namespace] = true; |
| } |
| } |
| |
| goog.exportPath_(name); |
| }; |
| |
| |
| if (!COMPILED) { |
| /** |
| * Namespaces implicitly defined by goog.provide. For example, |
| * goog.provide('goog.events.Event') implicitly declares |
| * that 'goog' and 'goog.events' must be namespaces. |
| * |
| * @type {Object} |
| * @private |
| */ |
| goog.implicitNamespaces_ = {}; |
| } |
| |
| |
| /** |
| * Builds an object structure for the provided namespace path, |
| * ensuring that names that already exist are not overwritten. For |
| * example: |
| * "a.b.c" -> a = {};a.b={};a.b.c={}; |
| * Used by goog.provide and goog.exportSymbol. |
| * @param {string} name name of the object that this file defines. |
| * @param {Object} 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|. |
| * @private |
| */ |
| goog.exportPath_ = function(name, opt_object, opt_objectToExportTo) { |
| var parts = name.split('.'); |
| var cur = opt_objectToExportTo || goog.global; |
| |
| // Internet Explorer exhibits strange behavior when throwing errors from |
| // methods externed in this manner. See the testExportSymbolExceptions in |
| // base_test.html for an example. |
| if (!(parts[0] in cur) && cur.execScript) { |
| 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]) { |
| cur = cur[part]; |
| } else { |
| cur = cur[part] = {}; |
| } |
| } |
| }; |
| |
| |
| /** |
| * Returns an object based on its fully qualified external name. If you are |
| * using a compilation pass that renames property names beware that using this |
| * function will not find renamed properties. |
| * |
| * @param {string} name The fully qualified name. |
| * @param {Object} opt_obj The object within which to look; default is |
| * |goog.global|. |
| * @return {Object?} The object or, if not found, null. |
| */ |
| goog.getObjectByName = function(name, opt_obj) { |
| var parts = name.split('.'); |
| var cur = opt_obj || goog.global; |
| for (var part; part = parts.shift(); ) { |
| if (cur[part]) { |
| cur = cur[part]; |
| } else { |
| return null; |
| } |
| } |
| return cur; |
| }; |
| |
| |
| /** |
| * Globalizes a whole namespace, such as goog or goog.lang. |
| * |
| * @param {Object} obj The namespace to globalize. |
| * @param {Object} opt_global The object to add the properties to. |
| * @deprecated Properties may be explicitly exported to the global scope, but |
| * this should no longer be done in bulk. |
| */ |
| goog.globalize = function(obj, opt_global) { |
| var global = opt_global || goog.global; |
| for (var x in obj) { |
| global[x] = obj[x]; |
| } |
| }; |
| |
| |
| /** |
| * Adds a dependency from a file to the files it requires. |
| * @param {string} relPath The path to the js file. |
| * @param {Array} provides An array of strings with the names of the objects |
| * this file provides. |
| * @param {Array} requires An array of strings with the names of the objects |
| * this file requires. |
| */ |
| goog.addDependency = function(relPath, provides, requires) { |
| if (!COMPILED) { |
| var provide, require; |
| var path = relPath.replace(/\\/g, '/'); |
| var deps = goog.dependencies_; |
| for (var i = 0; provide = provides[i]; i++) { |
| deps.nameToPath[provide] = path; |
| if (!(path in deps.pathToNames)) { |
| deps.pathToNames[path] = {}; |
| } |
| deps.pathToNames[path][provide] = true; |
| } |
| for (var j = 0; require = requires[j]; j++) { |
| if (!(path in deps.requires)) { |
| deps.requires[path] = {}; |
| } |
| deps.requires[path][require] = true; |
| } |
| } |
| }; |
| |
| |
| /** |
| * 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 |
| * --closure_pass option is used. |
| * @param {string} rule Rule to include, in the form goog.package.part. |
| */ |
| goog.require = function(rule) { |
| |
| // if the object already exists we do not need do do anything |
| // TODO(abliss): If we start to support require based on file name this has |
| // to change. |
| // TODO(abliss): If we allow goog.foo.* this has to change. |
| // TODO(abliss): If we implement dynamic load after page load we should |
| // probably not remove this code for the compiled output. |
| if (!COMPILED) { |
| if (goog.getObjectByName(rule)) { |
| return; |
| } |
| var path = goog.getPathFromDeps_(rule); |
| if (path) { |
| goog.included_[path] = true; |
| goog.writeScripts_(); |
| } else { |
| var errorMessage = 'goog.require could not find: ' + rule; |
| if (goog.global.console) { |
| goog.global.console['error'](errorMessage); |
| } |
| |
| throw Error(errorMessage); |
| } |
| } |
| }; |
| |
| |
| /** |
| * Whether goog.require should throw an exception if it fails. |
| * @type {boolean} |
| */ |
| goog.useStrictRequires = false; |
| |
| |
| /** |
| * Path for included scripts |
| * @type {string} |
| */ |
| goog.basePath = ''; |
| |
| |
| /** |
| * A hook for overriding the base path. |
| * @type {string|undefined} |
| */ |
| goog.global.CLOSURE_BASE_PATH; |
| |
| |
| /** |
| * Whether to write out Closure's deps file. By default, |
| * the deps are written. |
| * @type {boolean|undefined} |
| */ |
| goog.global.CLOSURE_NO_DEPS; |
| |
| |
| /** |
| * Null function used for default values of callbacks, etc. |
| * @type {!Function} |
| */ |
| goog.nullFunction = function() {}; |
| |
| |
| /** |
| * The identity function. Returns its first argument. |
| * |
| * @param {*} var_args The arguments of the function. |
| * @return {*} The first argument. |
| * @deprecated Use goog.functions.identity instead. |
| */ |
| goog.identityFunction = function(var_args) { |
| return arguments[0]; |
| }; |
| |
| |
| /** |
| * When defining a class Foo with an abstract method bar(), you can do: |
| * |
| * Foo.prototype.bar = goog.abstractMethod |
| * |
| * 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. |
| */ |
| goog.abstractMethod = function() { |
| throw Error('unimplemented abstract method'); |
| }; |
| |
| |
| /** |
| * Adds a {@code getInstance} static method that always return the same instance |
| * object. |
| * @param {!Function} ctor The constructor for the class to add the static |
| * method to. |
| */ |
| goog.addSingletonGetter = function(ctor) { |
| ctor.getInstance = function() { |
| return ctor.instance_ || (ctor.instance_ = new ctor()); |
| }; |
| }; |
| |
| |
| if (!COMPILED) { |
| /** |
| * Object used to keep track of urls that have already been added. This |
| * record allows the prevention of circular dependencies. |
| * @type {Object} |
| * @private |
| */ |
| goog.included_ = {}; |
| |
| |
| /** |
| * This object is used to keep track of dependencies and other data that is |
| * used for loading scripts |
| * @private |
| * @type {Object} |
| */ |
| goog.dependencies_ = { |
| pathToNames: {}, // 1 to many |
| nameToPath: {}, // 1 to 1 |
| requires: {}, // 1 to many |
| visited: {}, // used when resolving dependencies to prevent us from |
| // visiting the file twice |
| written: {} // used to keep track of script files we have written |
| }; |
| |
| |
| /** |
| * Tries to detect whether is in the context of an HTML document. |
| * @return {boolean} True if it looks like HTML document. |
| * @private |
| */ |
| goog.inHtmlDocument_ = function() { |
| var doc = goog.global.document; |
| return typeof doc != 'undefined' && |
| 'write' in doc; // XULDocument misses write. |
| }; |
| |
| |
| /** |
| * Tries to detect the base path of the base.js script that bootstraps Closure |
| * @private |
| */ |
| goog.findBasePath_ = function() { |
| if (!goog.inHtmlDocument_()) { |
| return; |
| } |
| var doc = goog.global.document; |
| if (goog.global.CLOSURE_BASE_PATH) { |
| goog.basePath = goog.global.CLOSURE_BASE_PATH; |
| return; |
| } |
| var scripts = doc.getElementsByTagName('script'); |
| for (var script, i = 0; script = scripts[i]; i++) { |
| var src = script.src; |
| var l = src.length; |
| if (src.substr(l - 7) == 'base.js') { |
| goog.basePath = src.substr(0, l - 7); |
| return; |
| } |
| } |
| }; |
| |
| |
| /** |
| * Writes a script tag if, and only if, that script hasn't already been added |
| * to the document. (Must be called at execution time) |
| * @param {string} src Script source. |
| * @private |
| */ |
| goog.writeScriptTag_ = function(src) { |
| if (goog.inHtmlDocument_() && |
| !goog.dependencies_.written[src]) { |
| goog.dependencies_.written[src] = true; |
| var doc = goog.global.document; |
| doc.write('<script type="text/javascript" src="' + |
| src + '"></' + 'script>'); |
| } |
| }; |
| |
| |
| /** |
| * Resolves dependencies based on the dependencies added using addDependency |
| * and calls writeScriptTag_ in the correct order. |
| * @private |
| */ |
| goog.writeScripts_ = function() { |
| // the scripts we need to write this time |
| var scripts = []; |
| var seenScript = {}; |
| var deps = goog.dependencies_; |
| |
| function visitNode(path) { |
| if (path in deps.written) { |
| return; |
| } |
| |
| // we have already visited this one. We can get here if we have cyclic |
| // dependencies |
| if (path in deps.visited) { |
| if (!(path in seenScript)) { |
| seenScript[path] = true; |
| scripts.push(path); |
| } |
| return; |
| } |
| |
| deps.visited[path] = true; |
| |
| if (path in deps.requires) { |
| for (var requireName in deps.requires[path]) { |
| if (requireName in deps.nameToPath) { |
| visitNode(deps.nameToPath[requireName]); |
| } else if (!goog.getObjectByName(requireName)) { |
| // If the required name is defined, we assume that this |
| // dependency was bootstapped by other means. Otherwise, |
| // throw an exception. |
| throw Error('Undefined nameToPath for ' + requireName); |
| } |
| } |
| } |
| |
| if (!(path in seenScript)) { |
| seenScript[path] = true; |
| scripts.push(path); |
| } |
| } |
| |
| for (var path in goog.included_) { |
| if (!deps.written[path]) { |
| visitNode(path); |
| } |
| } |
| |
| for (var i = 0; i < scripts.length; i++) { |
| if (scripts[i]) { |
| goog.writeScriptTag_(goog.basePath + scripts[i]); |
| } else { |
| throw Error('Undefined script input'); |
| } |
| } |
| }; |
| |
| |
| /** |
| * Looks at the dependency rules and tries to determine the script file that |
| * fulfills a particular rule. |
| * @param {string} rule In the form goog.namespace.Class or project.script. |
| * @return {string?} Url corresponding to the rule, or null. |
| * @private |
| */ |
| goog.getPathFromDeps_ = function(rule) { |
| if (rule in goog.dependencies_.nameToPath) { |
| return goog.dependencies_.nameToPath[rule]; |
| } else { |
| return null; |
| } |
| }; |
| |
| goog.findBasePath_(); |
| |
| // Allow projects to manage the deps files themselves. |
| if (!goog.global.CLOSURE_NO_DEPS) { |
| // [MODIFIED FOR MOD_PAGESPEED_DEMO] goog.writeScriptTag_(goog.basePath + 'deps.js'); |
| } |
| } |
| |
| |
| |
| //============================================================================== |
| // Language Enhancements |
| //============================================================================== |
| |
| |
| /** |
| * This is a "fixed" version of the typeof operator. It differs from the typeof |
| * operator in such a way that null returns 'null' and arrays return 'array'. |
| * @param {*} value The value to get the type of. |
| * @return {string} The name of the type. |
| */ |
| goog.typeOf = function(value) { |
| var s = typeof value; |
| if (s == 'object') { |
| if (value) { |
| // We cannot use constructor == Array or instanceof Array because |
| // different frames have different Array objects. In IE6, if the iframe |
| // where the array was created is destroyed, the array loses its |
| // prototype. Then dereferencing val.splice here throws an exception, so |
| // we can't use goog.isFunction. Calling typeof directly returns 'unknown' |
| // so that will work. In this case, this function will return false and |
| // most array functions will still work because the array is still |
| // array-like (supports length and []) even though it has lost its |
| // prototype. |
| // Mark Miller noticed that Object.prototype.toString |
| // allows access to the unforgeable [[Class]] property. |
| // 15.2.4.2 Object.prototype.toString ( ) |
| // When the toString method is called, the following steps are taken: |
| // 1. Get the [[Class]] property of this object. |
| // 2. Compute a string value by concatenating the three strings |
| // "[object ", Result(1), and "]". |
| // 3. Return Result(2). |
| // and this behavior survives the destruction of the execution context. |
| if (value instanceof Array || // Works quickly in same execution context. |
| // If value is from a different execution context then |
| // !(value instanceof Object), which lets us early out in the common |
| // case when value is from the same context but not an array. |
| // The {if (value)} check above means we don't have to worry about |
| // undefined behavior of Object.prototype.toString on null/undefined. |
| // |
| // HACK: In order to use an Object prototype method on the arbitrary |
| // value, the compiler requires the value be cast to type Object, |
| // even though the ECMA spec explicitly allows it. |
| (!(value instanceof Object) && |
| (Object.prototype.toString.call( |
| /** @type {Object} */ (value)) == '[object Array]') || |
| |
| // In IE all non value types are wrapped as objects across window |
| // boundaries (not iframe though) so we have to do object detection |
| // for this edge case |
| typeof value.length == 'number' && |
| typeof value.splice != 'undefined' && |
| typeof value.propertyIsEnumerable != 'undefined' && |
| !value.propertyIsEnumerable('splice') |
| |
| )) { |
| return 'array'; |
| } |
| // HACK: There is still an array case that fails. |
| // function ArrayImpostor() {} |
| // ArrayImpostor.prototype = []; |
| // var impostor = new ArrayImpostor; |
| // this can be fixed by getting rid of the fast path |
| // (value instanceof Array) and solely relying on |
| // (value && Object.prototype.toString.vall(value) === '[object Array]') |
| // but that would require many more function calls and is not warranted |
| // unless closure code is receiving objects from untrusted sources. |
| |
| // IE in cross-window calls does not correctly marshal the function type |
| // (it appears just as an object) so we cannot use just typeof val == |
| // 'function'. However, if the object has a call property, it is a |
| // function. |
| if (!(value instanceof Object) && |
| (Object.prototype.toString.call( |
| /** @type {Object} */ (value)) == '[object Function]' || |
| typeof value.call != 'undefined' && |
| typeof value.propertyIsEnumerable != 'undefined' && |
| !value.propertyIsEnumerable('call'))) { |
| return 'function'; |
| } |
| |
| |
| } else { |
| return 'null'; |
| } |
| |
| // In Safari typeof nodeList returns 'function', and on Firefox |
| // typeof behaves similarly for HTML{Applet,Embed,Object}Elements |
| // and RegExps. We would like to return object for those and we can |
| // detect an invalid function by making sure that the function |
| // object has a call method. |
| } else if (s == 'function' && typeof value.call == 'undefined') { |
| return 'object'; |
| } |
| return s; |
| }; |
| |
| |
| /** |
| * Safe way to test whether a property is enumarable. It allows testing |
| * for enumerable on objects where 'propertyIsEnumerable' is overridden or |
| * does not exist (like DOM nodes in IE). Does not use browser native |
| * Object.propertyIsEnumerable. |
| * @param {Object} object The object to test if the property is enumerable. |
| * @param {string} propName The property name to check for. |
| * @return {boolean} True if the property is enumarable. |
| * @private |
| */ |
| goog.propertyIsEnumerableCustom_ = function(object, propName) { |
| // KJS in Safari 2 is not ECMAScript compatible and lacks crucial methods |
| // such as propertyIsEnumerable. We therefore use a workaround. |
| // Does anyone know a more efficient work around? |
| if (propName in object) { |
| for (var key in object) { |
| if (key == propName && |
| Object.prototype.hasOwnProperty.call(object, propName)) { |
| return true; |
| } |
| } |
| } |
| return false; |
| }; |
| |
| |
| /** |
| * Safe way to test whether a property is enumarable. It allows testing |
| * for enumerable on objects where 'propertyIsEnumerable' is overridden or |
| * does not exist (like DOM nodes in IE). |
| * @param {Object} object The object to test if the property is enumerable. |
| * @param {string} propName The property name to check for. |
| * @return {boolean} True if the property is enumarable. |
| * @private |
| */ |
| goog.propertyIsEnumerable_ = function(object, propName) { |
| // In IE if object is from another window, cannot use propertyIsEnumerable |
| // from this window's Object. Will raise a 'JScript object expected' error. |
| if (object instanceof Object) { |
| return Object.prototype.propertyIsEnumerable.call(object, propName); |
| } else { |
| return goog.propertyIsEnumerableCustom_(object, propName); |
| } |
| }; |
| |
| |
| /** |
| * 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. Additionally, this function assumes that the global |
| * undefined variable has not been redefined. |
| * @param {*} val Variable to test. |
| * @return {boolean} Whether variable is defined. |
| */ |
| goog.isDef = function(val) { |
| return val !== undefined; |
| }; |
| |
| |
| /** |
| * Returns true if the specified value is |null| |
| * @param {*} val Variable to test. |
| * @return {boolean} Whether variable is null. |
| */ |
| goog.isNull = function(val) { |
| return val === null; |
| }; |
| |
| |
| /** |
| * Returns true if the specified value is defined and not null |
| * @param {*} val Variable to test. |
| * @return {boolean} Whether variable is defined and not null. |
| */ |
| goog.isDefAndNotNull = function(val) { |
| // Note that undefined == null. |
| return val != null; |
| }; |
| |
| |
| /** |
| * Returns true if the specified value is an array |
| * @param {*} val Variable to test. |
| * @return {boolean} Whether variable is an array. |
| */ |
| goog.isArray = function(val) { |
| return goog.typeOf(val) == 'array'; |
| }; |
| |
| |
| /** |
| * Returns true if the object looks like an array. To qualify as array like |
| * the value needs to be either a NodeList or an object with a Number length |
| * property. |
| * @param {*} val Variable to test. |
| * @return {boolean} Whether variable is an array. |
| */ |
| goog.isArrayLike = function(val) { |
| var type = goog.typeOf(val); |
| return type == 'array' || type == 'object' && typeof val.length == 'number'; |
| }; |
| |
| |
| /** |
| * Returns true if the object looks like a Date. To qualify as Date-like |
| * the value needs to be an object and have a getFullYear() function. |
| * @param {*} val Variable to test. |
| * @return {boolean} Whether variable is a like a Date. |
| */ |
| goog.isDateLike = function(val) { |
| return goog.isObject(val) && typeof val.getFullYear == 'function'; |
| }; |
| |
| |
| /** |
| * 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. |
| */ |
| goog.isFunction = function(val) { |
| return goog.typeOf(val) == 'function'; |
| }; |
| |
| |
| /** |
| * Returns true if the specified value is an object. This includes arrays |
| * and functions. |
| * @param {*} val Variable to test. |
| * @return {boolean} Whether variable is an object. |
| */ |
| goog.isObject = function(val) { |
| var type = goog.typeOf(val); |
| return type == 'object' || type == 'array' || type == 'function'; |
| }; |
| |
| |
| /** |
| * Adds a hash code field to an object. The hash code is unique for the |
| * given object. |
| * @param {Object} obj The object to get the hash code for. |
| * @return {number} The hash code for the object. |
| */ |
| goog.getHashCode = function(obj) { |
| // In IE, DOM nodes do not extend Object so they do not have this method. |
| // we need to check hasOwnProperty because the proto might have this set. |
| |
| // TODO(abliss): There is a proposal to add hashcode as a global function to |
| // JS2 we should keep track of this process so we can use that |
| // whenever it starts to show up in the real world. |
| if (obj.hasOwnProperty && obj.hasOwnProperty(goog.HASH_CODE_PROPERTY_)) { |
| return obj[goog.HASH_CODE_PROPERTY_]; |
| } |
| if (!obj[goog.HASH_CODE_PROPERTY_]) { |
| obj[goog.HASH_CODE_PROPERTY_] = ++goog.hashCodeCounter_; |
| } |
| return obj[goog.HASH_CODE_PROPERTY_]; |
| }; |
| |
| |
| /** |
| * Removes the hash code field from an object. |
| * @param {Object} obj The object to remove the field from. |
| */ |
| goog.removeHashCode = function(obj) { |
| // DOM nodes in IE are not instance of Object and throws exception |
| // for delete. Instead we try to use removeAttribute |
| if ('removeAttribute' in obj) { |
| obj.removeAttribute(goog.HASH_CODE_PROPERTY_); |
| } |
| /** @preserveTry */ |
| try { |
| delete obj[goog.HASH_CODE_PROPERTY_]; |
| } catch (ex) { |
| } |
| }; |
| |
| |
| /** |
| * Name for hash code property. Initialized in a way to help avoid collisions |
| * with other closure javascript on the same page. |
| * @type {string} |
| * @private |
| */ |
| goog.HASH_CODE_PROPERTY_ = 'closure_hashCode_' + |
| Math.floor(Math.random() * 2147483648).toString(36); |
| |
| |
| /** |
| * Counter for hash codes. |
| * @type {number} |
| * @private |
| */ |
| goog.hashCodeCounter_ = 0; |
| |
| |
| /** |
| * Clone an object/array (recursively) |
| * @param {Object} proto Object to clone. |
| * @return {Object} Clone of x;. |
| */ |
| goog.cloneObject = function(proto) { |
| var type = goog.typeOf(proto); |
| if (type == 'object' || type == 'array') { |
| if (proto.clone) { |
| // TODO(abliss): Change to proto.clone() once # args warn is removed |
| return proto.clone.call(proto); |
| } |
| var clone = type == 'array' ? [] : {}; |
| for (var key in proto) { |
| clone[key] = goog.cloneObject(proto[key]); |
| } |
| return clone; |
| } |
| |
| return proto; |
| }; |
| |
| |
| /** |
| * Forward declaration for the clone method. This is necessary until the |
| * compiler can better support duck-typing constructs as used in |
| * goog.cloneObject. |
| * |
| * TODO(abliss): Remove once the JSCompiler can infer that the check for |
| * proto.clone is safe in goog.cloneObject. |
| * |
| * @type {Function} |
| */ |
| Object.prototype.clone; |
| |
| |
| /** |
| * Partially applies this function to a particular 'this object' and zero or |
| * more arguments. The result is a new function with some arguments of the first |
| * function pre-filled and the value of |this| 'pre-specified'.<br><br> |
| * |
| * Remaining arguments specified at call-time are appended to the pre- |
| * specified ones.<br><br> |
| * |
| * Also see: {@link #partial}.<br><br> |
| * |
| * Usage: |
| * <pre>var barMethBound = bind(myFunction, myObj, 'arg1', 'arg2'); |
| * barMethBound('arg3', 'arg4');</pre> |
| * |
| * @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. If the value is null or undefined, it |
| * will default to the global object. |
| * @param {*} var_args Additional arguments that are partially |
| * applied to the function. |
| * |
| * @return {!Function} A partially-applied form of the function bind() was |
| * invoked as a method of. |
| */ |
| goog.bind = function(fn, selfObj, var_args) { |
| var context = selfObj || goog.global; |
| |
| if (arguments.length > 2) { |
| var boundArgs = Array.prototype.slice.call(arguments, 2); |
| return function() { |
| // Prepend the bound arguments to the current arguments. |
| var newArgs = Array.prototype.slice.call(arguments); |
| Array.prototype.unshift.apply(newArgs, boundArgs); |
| return fn.apply(context, newArgs); |
| }; |
| |
| } else { |
| return function() { |
| return fn.apply(context, arguments); |
| }; |
| } |
| }; |
| |
| |
| /** |
| * Like bind(), except that a 'this object' is not required. Useful when the |
| * target function is already bound. |
| * |
| * Usage: |
| * var g = partial(f, arg1, arg2); |
| * g(arg3, arg4); |
| * |
| * @param {Function} fn A function to partially apply. |
| * @param {*} var_args Additional arguments that are partially |
| * applied to fn. |
| * @return {!Function} A partially-applied form of the function bind() was |
| * invoked as a method of. |
| */ |
| goog.partial = function(fn, var_args) { |
| var args = Array.prototype.slice.call(arguments, 1); |
| return function() { |
| // Prepend the bound arguments to the current arguments. |
| var newArgs = Array.prototype.slice.call(arguments); |
| newArgs.unshift.apply(newArgs, args); |
| return fn.apply(this, newArgs); |
| }; |
| }; |
| |
| |
| /** |
| * Copies all the members of a source object to a target object. |
| * @param {Object} target Target. |
| * @param {Object} source Source. |
| * @deprecated Use goog.object.extend instead. |
| */ |
| goog.mixin = function(target, source) { |
| for (var x in source) { |
| target[x] = source[x]; |
| } |
| |
| // For IE the for-in-loop does not contain any properties that are not |
| // enumerable on the prototype object (for example, isPrototypeOf from |
| // Object.prototype) but also it will not include 'replace' on objects that |
| // extend String and change 'replace' (not that it is common for anyone to |
| // extend anything except Object). |
| }; |
| |
| |
| /** |
| * A simple wrapper for new Date().getTime(). |
| * |
| * @return {number} An integer value representing the number of milliseconds |
| * between midnight, January 1, 1970 and the current time. |
| */ |
| goog.now = Date.now || (function() { |
| return new Date().getTime(); |
| }); |
| |
| |
| /** |
| * Evals javascript in the global scope. In IE this uses execScript, other |
| * browsers use goog.global.eval. If goog.global.eval does not evaluate in the |
| * global scope (for example, in Safari), appends a script tag instead. |
| * Throws an exception if neither execScript or eval is defined. |
| * @param {string} script JavaScript string. |
| */ |
| goog.globalEval = function(script) { |
| if (goog.global.execScript) { |
| goog.global.execScript(script, 'JavaScript'); |
| } else if (goog.global.eval) { |
| // Test to see if eval works |
| if (goog.evalWorksForGlobals_ == null) { |
| goog.global.eval('var _et_ = 1;'); |
| if (typeof goog.global['_et_'] != 'undefined') { |
| delete goog.global['_et_']; |
| goog.evalWorksForGlobals_ = true; |
| } else { |
| goog.evalWorksForGlobals_ = false; |
| } |
| } |
| |
| if (goog.evalWorksForGlobals_) { |
| goog.global.eval(script); |
| } else { |
| var doc = goog.global.document; |
| var scriptElt = doc.createElement('script'); |
| scriptElt.type = 'text/javascript'; |
| scriptElt.defer = false; |
| // NOTE: can't use .innerHTML since "t('<test>')" will fail and |
| // .text doesn't work in Safari 2. Therefore we append a text node. |
| scriptElt.appendChild(doc.createTextNode(script)); |
| doc.body.appendChild(scriptElt); |
| doc.body.removeChild(scriptElt); |
| } |
| } else { |
| throw Error('goog.globalEval not available'); |
| } |
| }; |
| |
| |
| /** |
| * A macro for defining composite types. |
| * |
| * By assigning goog.typedef to a name, this tells JSCompiler that this is not |
| * the name of a class, but rather it's the name of a composite type. |
| * |
| * For example, |
| * /** @type {Array|NodeList} / goog.ArrayLike = goog.typedef; |
| * will tell JSCompiler to replace all appearances of goog.ArrayLike in type |
| * definitions with the union of Array and NodeList. |
| * |
| * Does nothing in uncompiled code. |
| */ |
| goog.typedef = true; |
| |
| |
| /** |
| * Optional map of CSS class names to obfuscated names used with |
| * goog.getCssName(). |
| * @type {Object|undefined} |
| * @private |
| * @see goog.setCssNameMapping |
| */ |
| goog.cssNameMapping_; |
| |
| |
| /** |
| * Handles strings that are intended to be used as CSS class names. |
| * |
| * Without JS Compiler the arguments are simple joined with a hyphen and passed |
| * through unaltered. |
| * |
| * With the JS Compiler the arguments are inlined, e.g: |
| * var x = goog.getCssName('foo'); |
| * var y = goog.getCssName(this.baseClass, 'active'); |
| * becomes: |
| * var x= 'foo'; |
| * var y = this.baseClass + '-active'; |
| * |
| * If a CSS renaming map is passed to the compiler it will replace symbols in |
| * the classname. If one argument is passed it will be processed, if two are |
| * passed only the modifier will be processed, as it is assumed the first |
| * argument was generated as a result of calling goog.getCssName. |
| * |
| * Names are split on 'hyphen' and processed in parts such that the following |
| * are equivalent: |
| * var base = goog.getCssName('baseclass'); |
| * goog.getCssName(base, 'modifier'); |
| * goog.getCSsName('baseclass-modifier'); |
| * |
| * If any part does not appear in the renaming map a warning is logged and the |
| * original, unobfuscated class name is inlined. |
| * |
| * @param {string} className The class name. |
| * @param {string} opt_modifier A modifier to be appended to the class name. |
| * @return {string} The class name or the concatenation of the class name and |
| * the modifier. |
| */ |
| goog.getCssName = function(className, opt_modifier) { |
| var cssName = className + (opt_modifier ? '-' + opt_modifier : ''); |
| return (goog.cssNameMapping_ && (cssName in goog.cssNameMapping_)) ? |
| goog.cssNameMapping_[cssName] : cssName; |
| }; |
| |
| |
| /** |
| * Sets the map to check when returning a value from goog.getCssName(). Example: |
| * <pre> |
| * goog.setCssNameMapping({ |
| * "goog-menu": "a", |
| * "goog-menu-disabled": "a-b", |
| * "CSS_LOGO": "b", |
| * "hidden": "c" |
| * }); |
| * |
| * // The following evaluates to: "a a-b". |
| * goog.getCssName('goog-menu') + ' ' + goog.getCssName('goog-menu', 'disabled') |
| * </pre> |
| * When declared as a map of string literals to string literals, the JSCompiler |
| * will replace all calls to goog.getCssName() using the supplied map if the |
| * --closure_pass flag is set. |
| * |
| * @param {!Object} mapping A map of strings to strings where keys are possible |
| * arguments to goog.getCssName() and values are the corresponding values |
| * that should be returned. |
| */ |
| goog.setCssNameMapping = function(mapping) { |
| goog.cssNameMapping_ = mapping; |
| }; |
| |
| |
| /** |
| * Abstract implementation of goog.getMsg for use with localized messages. |
| * @param {string} str Translatable string, places holders in the form {$foo}. |
| * @param {Object} opt_values Map of place holder name to value. |
| * @return {string} message with placeholders filled. |
| */ |
| goog.getMsg = function(str, opt_values) { |
| var values = opt_values || {}; |
| for (var key in values) { |
| str = str.replace(new RegExp('\\{\\$' + key + '\\}', 'gi'), values[key]); |
| } |
| return str; |
| }; |
| |
| |
| /** |
| * Exposes an unobfuscated global namespace path for the given object. |
| * Note that fields of the exported object *will* be obfuscated, |
| * unless they are exported in turn via this function or |
| * goog.exportProperty |
| * |
| * <p>Also handy for making public items that are defined in anonymous |
| * closures. |
| * |
| * ex. goog.exportSymbol('Foo', Foo); |
| * |
| * ex. goog.exportSymbol('public.path.Foo.staticFunction', |
| * Foo.staticFunction); |
| * public.path.Foo.staticFunction(); |
| * |
| * ex. goog.exportSymbol('public.path.Foo.prototype.myMethod', |
| * Foo.prototype.myMethod); |
| * new public.path.Foo().myMethod(); |
| * |
| * @param {string} publicPath Unobfuscated name to export. |
| * @param {Object} object Object the name should point to. |
| * @param {Object} opt_objectToExportTo The object to add the path to; default |
| * is |goog.global|. |
| */ |
| goog.exportSymbol = function(publicPath, object, opt_objectToExportTo) { |
| goog.exportPath_(publicPath, object, opt_objectToExportTo); |
| }; |
| |
| |
| /** |
| * Exports a property unobfuscated into the object's namespace. |
| * ex. goog.exportProperty(Foo, 'staticFunction', Foo.staticFunction); |
| * ex. goog.exportProperty(Foo.prototype, 'myMethod', Foo.prototype.myMethod); |
| * @param {Object} object Object whose static property is being exported. |
| * @param {string} publicName Unobfuscated name to export. |
| * @param {Object} symbol Object the name should point to. |
| */ |
| goog.exportProperty = function(object, publicName, symbol) { |
| object[publicName] = symbol; |
| }; |
| |
| |
| /** |
| * Inherit the prototype methods from one constructor into another. |
| * |
| * Usage: |
| * <pre> |
| * function ParentClass(a, b) { } |
| * ParentClass.prototype.foo = function(a) { } |
| * |
| * function ChildClass(a, b, c) { |
| * ParentClass.call(this, a, b); |
| * } |
| * |
| * goog.inherits(ChildClass, ParentClass); |
| * |
| * var child = new ChildClass('a', 'b', 'see'); |
| * child.foo(); // works |
| * </pre> |
| * |
| * In addition, a superclass' implementation of a method can be invoked |
| * as follows: |
| * |
| * <pre> |
| * ChildClass.prototype.foo = function(a) { |
| * ChildClass.superClass_.foo.call(this, a); |
| * // other code |
| * }; |
| * </pre> |
| * |
| * @param {Function} childCtor Child class. |
| * @param {Function} parentCtor Parent class. |
| */ |
| goog.inherits = function(childCtor, parentCtor) { |
| /** @constructor */ |
| function tempCtor() {}; |
| tempCtor.prototype = parentCtor.prototype; |
| childCtor.superClass_ = parentCtor.prototype; |
| childCtor.prototype = new tempCtor(); |
| childCtor.prototype.constructor = childCtor; |
| }; |
| </script> |
| </head> |
| <body> |
| <div> |
| JavaScript which was inline should be linked. |
| </div> |
| </body> |
| </html> |