http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/debug/debug.js ---------------------------------------------------------------------- diff --git a/externs/GCL/externs/goog/debug/debug.js b/externs/GCL/externs/goog/debug/debug.js new file mode 100644 index 0000000..ff15374 --- /dev/null +++ b/externs/GCL/externs/goog/debug/debug.js @@ -0,0 +1,653 @@ +// Copyright 2006 The Closure Library Authors. All Rights Reserved. +// +// 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. + +/** + * @fileoverview Logging and debugging utilities. + * + * @see ../demos/debug.html + */ + +goog.provide('goog.debug'); + +goog.require('goog.array'); +goog.require('goog.html.SafeHtml'); +goog.require('goog.html.SafeUrl'); +goog.require('goog.html.uncheckedconversions'); +goog.require('goog.string.Const'); +goog.require('goog.structs.Set'); +goog.require('goog.userAgent'); + + +/** @define {boolean} Whether logging should be enabled. */ +goog.define('goog.debug.LOGGING_ENABLED', goog.DEBUG); + + +/** + * Catches onerror events fired by windows and similar objects. + * @param {function(Object)} logFunc The function to call with the error + * information. + * @param {boolean=} opt_cancel Whether to stop the error from reaching the + * browser. + * @param {Object=} opt_target Object that fires onerror events. + */ +goog.debug.catchErrors = function(logFunc, opt_cancel, opt_target) { + var target = opt_target || goog.global; + var oldErrorHandler = target.onerror; + var retVal = !!opt_cancel; + + // Chrome interprets onerror return value backwards (http://crbug.com/92062) + // until it was fixed in webkit revision r94061 (Webkit 535.3). This + // workaround still needs to be skipped in Safari after the webkit change + // gets pushed out in Safari. + // See https://bugs.webkit.org/show_bug.cgi?id=67119 + if (goog.userAgent.WEBKIT && + !goog.userAgent.isVersionOrHigher('535.3')) { + retVal = !retVal; + } + + /** + * New onerror handler for this target. This onerror handler follows the spec + * according to + * http://www.whatwg.org/specs/web-apps/current-work/#runtime-script-errors + * The spec was changed in August 2013 to support receiving column information + * and an error object for all scripts on the same origin or cross origin + * scripts with the proper headers. See + * https://mikewest.org/2013/08/debugging-runtime-errors-with-window-onerror + * + * @param {string} message The error message. For cross-origin errors, this + * will be scrubbed to just "Script error.". For new browsers that have + * updated to follow the latest spec, errors that come from origins that + * have proper cross origin headers will not be scrubbed. + * @param {string} url The URL of the script that caused the error. The URL + * will be scrubbed to "" for cross origin scripts unless the script has + * proper cross origin headers and the browser has updated to the latest + * spec. + * @param {number} line The line number in the script that the error + * occurred on. + * @param {number=} opt_col The optional column number that the error + * occurred on. Only browsers that have updated to the latest spec will + * include this. + * @param {Error=} opt_error The optional actual error object for this + * error that should include the stack. Only browsers that have updated + * to the latest spec will inlude this parameter. + * @return {boolean} Whether to prevent the error from reaching the browser. + */ + target.onerror = function(message, url, line, opt_col, opt_error) { + if (oldErrorHandler) { + oldErrorHandler(message, url, line, opt_col, opt_error); + } + logFunc({ + message: message, + fileName: url, + line: line, + col: opt_col, + error: opt_error + }); + return retVal; + }; +}; + + +/** + * Creates a string representing an object and all its properties. + * @param {Object|null|undefined} obj Object to expose. + * @param {boolean=} opt_showFn Show the functions as well as the properties, + * default is false. + * @return {string} The string representation of {@code obj}. + */ +goog.debug.expose = function(obj, opt_showFn) { + if (typeof obj == 'undefined') { + return 'undefined'; + } + if (obj == null) { + return 'NULL'; + } + var str = []; + + for (var x in obj) { + if (!opt_showFn && goog.isFunction(obj[x])) { + continue; + } + var s = x + ' = '; + /** @preserveTry */ + try { + s += obj[x]; + } catch (e) { + s += '*** ' + e + ' ***'; + } + str.push(s); + } + return str.join('\n'); +}; + + +/** + * Creates a string representing a given primitive or object, and for an + * object, all its properties and nested objects. WARNING: If an object is + * given, it and all its nested objects will be modified. To detect reference + * cycles, this method identifies objects using goog.getUid() which mutates the + * object. + * @param {*} obj Object to expose. + * @param {boolean=} opt_showFn Also show properties that are functions (by + * default, functions are omitted). + * @return {string} A string representation of {@code obj}. + */ +goog.debug.deepExpose = function(obj, opt_showFn) { + var str = []; + + var helper = function(obj, space, parentSeen) { + var nestspace = space + ' '; + var seen = new goog.structs.Set(parentSeen); + + var indentMultiline = function(str) { + return str.replace(/\n/g, '\n' + space); + }; + + /** @preserveTry */ + try { + if (!goog.isDef(obj)) { + str.push('undefined'); + } else if (goog.isNull(obj)) { + str.push('NULL'); + } else if (goog.isString(obj)) { + str.push('"' + indentMultiline(obj) + '"'); + } else if (goog.isFunction(obj)) { + str.push(indentMultiline(String(obj))); + } else if (goog.isObject(obj)) { + if (seen.contains(obj)) { + str.push('*** reference loop detected ***'); + } else { + seen.add(obj); + str.push('{'); + for (var x in obj) { + if (!opt_showFn && goog.isFunction(obj[x])) { + continue; + } + str.push('\n'); + str.push(nestspace); + str.push(x + ' = '); + helper(obj[x], nestspace, seen); + } + str.push('\n' + space + '}'); + } + } else { + str.push(obj); + } + } catch (e) { + str.push('*** ' + e + ' ***'); + } + }; + + helper(obj, '', new goog.structs.Set()); + return str.join(''); +}; + + +/** + * Recursively outputs a nested array as a string. + * @param {Array<?>} arr The array. + * @return {string} String representing nested array. + */ +goog.debug.exposeArray = function(arr) { + var str = []; + for (var i = 0; i < arr.length; i++) { + if (goog.isArray(arr[i])) { + str.push(goog.debug.exposeArray(arr[i])); + } else { + str.push(arr[i]); + } + } + return '[ ' + str.join(', ') + ' ]'; +}; + + +/** + * Exposes an exception that has been caught by a try...catch and outputs the + * error as HTML with a stack trace. + * @param {Object} err Error object or string. + * @param {Function=} opt_fn Optional function to start stack trace from. + * @return {string} Details of exception, as HTML. + */ +goog.debug.exposeException = function(err, opt_fn) { + var html = goog.debug.exposeExceptionAsHtml(err, opt_fn); + return goog.html.SafeHtml.unwrap(html); +}; + + +/** + * Exposes an exception that has been caught by a try...catch and outputs the + * error with a stack trace. + * @param {Object} err Error object or string. + * @param {Function=} opt_fn Optional function to start stack trace from. + * @return {!goog.html.SafeHtml} Details of exception. + */ +goog.debug.exposeExceptionAsHtml = function(err, opt_fn) { + /** @preserveTry */ + try { + var e = goog.debug.normalizeErrorObject(err); + // Create the error message + var viewSourceUrl = goog.debug.createViewSourceUrl_(e.fileName); + var error = goog.html.SafeHtml.concat( + goog.html.SafeHtml.htmlEscapePreservingNewlinesAndSpaces( + 'Message: ' + e.message + '\nUrl: '), + goog.html.SafeHtml.create('a', + {href: viewSourceUrl, target: '_new'}, e.fileName), + goog.html.SafeHtml.htmlEscapePreservingNewlinesAndSpaces( + '\nLine: ' + e.lineNumber + '\n\nBrowser stack:\n' + + e.stack + '-> ' + '[end]\n\nJS stack traversal:\n' + + goog.debug.getStacktrace(opt_fn) + '-> ')); + return error; + } catch (e2) { + return goog.html.SafeHtml.htmlEscapePreservingNewlinesAndSpaces( + 'Exception trying to expose exception! You win, we lose. ' + e2); + } +}; + + +/** + * @param {?string=} opt_fileName + * @return {!goog.html.SafeUrl} SafeUrl with view-source scheme, pointing at + * fileName. + * @private + */ +goog.debug.createViewSourceUrl_ = function(opt_fileName) { + if (!goog.isDefAndNotNull(opt_fileName)) { + opt_fileName = ''; + } + if (!/^https?:\/\//i.test(opt_fileName)) { + return goog.html.SafeUrl.fromConstant( + goog.string.Const.from('sanitizedviewsrc')); + } + var sanitizedFileName = goog.html.SafeUrl.sanitize(opt_fileName); + return goog.html.uncheckedconversions. + safeUrlFromStringKnownToSatisfyTypeContract( + goog.string.Const.from('view-source scheme plus HTTP/HTTPS URL'), + 'view-source:' + goog.html.SafeUrl.unwrap(sanitizedFileName)); +}; + + +/** + * Normalizes the error/exception object between browsers. + * @param {Object} err Raw error object. + * @return {!Object} Normalized error object. + */ +goog.debug.normalizeErrorObject = function(err) { + var href = goog.getObjectByName('window.location.href'); + if (goog.isString(err)) { + return { + 'message': err, + 'name': 'Unknown error', + 'lineNumber': 'Not available', + 'fileName': href, + 'stack': 'Not available' + }; + } + + var lineNumber, fileName; + var threwError = false; + + try { + lineNumber = err.lineNumber || err.line || 'Not available'; + } catch (e) { + // Firefox 2 sometimes throws an error when accessing 'lineNumber': + // Message: Permission denied to get property UnnamedClass.lineNumber + lineNumber = 'Not available'; + threwError = true; + } + + try { + fileName = err.fileName || err.filename || err.sourceURL || + // $googDebugFname may be set before a call to eval to set the filename + // that the eval is supposed to present. + goog.global['$googDebugFname'] || href; + } catch (e) { + // Firefox 2 may also throw an error when accessing 'filename'. + fileName = 'Not available'; + threwError = true; + } + + // The IE Error object contains only the name and the message. + // The Safari Error object uses the line and sourceURL fields. + if (threwError || !err.lineNumber || !err.fileName || !err.stack || + !err.message || !err.name) { + return { + 'message': err.message || 'Not available', + 'name': err.name || 'UnknownError', + 'lineNumber': lineNumber, + 'fileName': fileName, + 'stack': err.stack || 'Not available' + }; + } + + // Standards error object + return err; +}; + + +/** + * Converts an object to an Error if it's a String, + * adds a stacktrace if there isn't one, + * and optionally adds an extra message. + * @param {Error|string} err the original thrown object or string. + * @param {string=} opt_message optional additional message to add to the + * error. + * @return {!Error} If err is a string, it is used to create a new Error, + * which is enhanced and returned. Otherwise err itself is enhanced + * and returned. + */ +goog.debug.enhanceError = function(err, opt_message) { + var error; + if (typeof err == 'string') { + error = Error(err); + if (Error.captureStackTrace) { + // Trim this function off the call stack, if we can. + Error.captureStackTrace(error, goog.debug.enhanceError); + } + } else { + error = err; + } + + if (!error.stack) { + error.stack = goog.debug.getStacktrace(goog.debug.enhanceError); + } + if (opt_message) { + // find the first unoccupied 'messageX' property + var x = 0; + while (error['message' + x]) { + ++x; + } + error['message' + x] = String(opt_message); + } + return error; +}; + + +/** + * Gets the current stack trace. Simple and iterative - doesn't worry about + * catching circular references or getting the args. + * @param {number=} opt_depth Optional maximum depth to trace back to. + * @return {string} A string with the function names of all functions in the + * stack, separated by \n. + * @suppress {es5Strict} + */ +goog.debug.getStacktraceSimple = function(opt_depth) { + if (goog.STRICT_MODE_COMPATIBLE) { + var stack = goog.debug.getNativeStackTrace_(goog.debug.getStacktraceSimple); + if (stack) { + return stack; + } + // NOTE: browsers that have strict mode support also have native "stack" + // properties. Fall-through for legacy browser support. + } + + var sb = []; + var fn = arguments.callee.caller; + var depth = 0; + + while (fn && (!opt_depth || depth < opt_depth)) { + sb.push(goog.debug.getFunctionName(fn)); + sb.push('()\n'); + /** @preserveTry */ + try { + fn = fn.caller; + } catch (e) { + sb.push('[exception trying to get caller]\n'); + break; + } + depth++; + if (depth >= goog.debug.MAX_STACK_DEPTH) { + sb.push('[...long stack...]'); + break; + } + } + if (opt_depth && depth >= opt_depth) { + sb.push('[...reached max depth limit...]'); + } else { + sb.push('[end]'); + } + + return sb.join(''); +}; + + +/** + * Max length of stack to try and output + * @type {number} + */ +goog.debug.MAX_STACK_DEPTH = 50; + + +/** + * @param {Function} fn The function to start getting the trace from. + * @return {?string} + * @private + */ +goog.debug.getNativeStackTrace_ = function(fn) { + var tempErr = new Error(); + if (Error.captureStackTrace) { + Error.captureStackTrace(tempErr, fn); + return String(tempErr.stack); + } else { + // IE10, only adds stack traces when an exception is thrown. + try { + throw tempErr; + } catch (e) { + tempErr = e; + } + var stack = tempErr.stack; + if (stack) { + return String(stack); + } + } + return null; +}; + + +/** + * Gets the current stack trace, either starting from the caller or starting + * from a specified function that's currently on the call stack. + * @param {Function=} opt_fn Optional function to start getting the trace from. + * If not provided, defaults to the function that called this. + * @return {string} Stack trace. + * @suppress {es5Strict} + */ +goog.debug.getStacktrace = function(opt_fn) { + var stack; + if (goog.STRICT_MODE_COMPATIBLE) { + // Try to get the stack trace from the environment if it is available. + var contextFn = opt_fn || goog.debug.getStacktrace; + stack = goog.debug.getNativeStackTrace_(contextFn); + } + if (!stack) { + // NOTE: browsers that have strict mode support also have native "stack" + // properties. This function will throw in strict mode. + stack = goog.debug.getStacktraceHelper_( + opt_fn || arguments.callee.caller, []); + } + return stack; +}; + + +/** + * Private helper for getStacktrace(). + * @param {Function} fn Function to start getting the trace from. + * @param {Array<!Function>} visited List of functions visited so far. + * @return {string} Stack trace starting from function fn. + * @suppress {es5Strict} + * @private + */ +goog.debug.getStacktraceHelper_ = function(fn, visited) { + var sb = []; + + // Circular reference, certain functions like bind seem to cause a recursive + // loop so we need to catch circular references + if (goog.array.contains(visited, fn)) { + sb.push('[...circular reference...]'); + + // Traverse the call stack until function not found or max depth is reached + } else if (fn && visited.length < goog.debug.MAX_STACK_DEPTH) { + sb.push(goog.debug.getFunctionName(fn) + '('); + var args = fn.arguments; + // Args may be null for some special functions such as host objects or eval. + for (var i = 0; args && i < args.length; i++) { + if (i > 0) { + sb.push(', '); + } + var argDesc; + var arg = args[i]; + switch (typeof arg) { + case 'object': + argDesc = arg ? 'object' : 'null'; + break; + + case 'string': + argDesc = arg; + break; + + case 'number': + argDesc = String(arg); + break; + + case 'boolean': + argDesc = arg ? 'true' : 'false'; + break; + + case 'function': + argDesc = goog.debug.getFunctionName(arg); + argDesc = argDesc ? argDesc : '[fn]'; + break; + + case 'undefined': + default: + argDesc = typeof arg; + break; + } + + if (argDesc.length > 40) { + argDesc = argDesc.substr(0, 40) + '...'; + } + sb.push(argDesc); + } + visited.push(fn); + sb.push(')\n'); + /** @preserveTry */ + try { + sb.push(goog.debug.getStacktraceHelper_(fn.caller, visited)); + } catch (e) { + sb.push('[exception trying to get caller]\n'); + } + + } else if (fn) { + sb.push('[...long stack...]'); + } else { + sb.push('[end]'); + } + return sb.join(''); +}; + + +/** + * Set a custom function name resolver. + * @param {function(Function): string} resolver Resolves functions to their + * names. + */ +goog.debug.setFunctionResolver = function(resolver) { + goog.debug.fnNameResolver_ = resolver; +}; + + +/** + * Gets a function name + * @param {Function} fn Function to get name of. + * @return {string} Function's name. + */ +goog.debug.getFunctionName = function(fn) { + if (goog.debug.fnNameCache_[fn]) { + return goog.debug.fnNameCache_[fn]; + } + if (goog.debug.fnNameResolver_) { + var name = goog.debug.fnNameResolver_(fn); + if (name) { + goog.debug.fnNameCache_[fn] = name; + return name; + } + } + + // Heuristically determine function name based on code. + var functionSource = String(fn); + if (!goog.debug.fnNameCache_[functionSource]) { + var matches = /function ([^\(]+)/.exec(functionSource); + if (matches) { + var method = matches[1]; + goog.debug.fnNameCache_[functionSource] = method; + } else { + goog.debug.fnNameCache_[functionSource] = '[Anonymous]'; + } + } + + return goog.debug.fnNameCache_[functionSource]; +}; + + +/** + * Makes whitespace visible by replacing it with printable characters. + * This is useful in finding diffrences between the expected and the actual + * output strings of a testcase. + * @param {string} string whose whitespace needs to be made visible. + * @return {string} string whose whitespace is made visible. + */ +goog.debug.makeWhitespaceVisible = function(string) { + return string.replace(/ /g, '[_]') + .replace(/\f/g, '[f]') + .replace(/\n/g, '[n]\n') + .replace(/\r/g, '[r]') + .replace(/\t/g, '[t]'); +}; + + +/** + * Returns the type of a value. If a constructor is passed, and a suitable + * string cannot be found, 'unknown type name' will be returned. + * + * <p>Forked rather than moved from {@link goog.asserts.getType_} + * to avoid adding a dependency to goog.asserts. + * @param {*} value A constructor, object, or primitive. + * @return {string} The best display name for the value, or 'unknown type name'. + */ +goog.debug.runtimeType = function(value) { + if (value instanceof Function) { + return value.displayName || value.name || 'unknown type name'; + } else if (value instanceof Object) { + return value.constructor.displayName || value.constructor.name || + Object.prototype.toString.call(value); + } else { + return value === null ? 'null' : typeof value; + } +}; + + +/** + * Hash map for storing function names that have already been looked up. + * @type {Object} + * @private + */ +goog.debug.fnNameCache_ = {}; + + +/** + * Resolves functions to their names. Resolved function names will be cached. + * @type {function(Function):string} + * @private + */ +goog.debug.fnNameResolver_;
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/debug/debugwindow.js ---------------------------------------------------------------------- diff --git a/externs/GCL/externs/goog/debug/debugwindow.js b/externs/GCL/externs/goog/debug/debugwindow.js new file mode 100644 index 0000000..ab251ef --- /dev/null +++ b/externs/GCL/externs/goog/debug/debugwindow.js @@ -0,0 +1,632 @@ +// Copyright 2006 The Closure Library Authors. All Rights Reserved. +// +// 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. + +/** + * @fileoverview Definition of the DebugWindow class. Please minimize + * dependencies this file has on other closure classes as any dependency it + * takes won't be able to use the logging infrastructure. + * + */ + +goog.provide('goog.debug.DebugWindow'); + +goog.require('goog.debug.HtmlFormatter'); +goog.require('goog.debug.LogManager'); +goog.require('goog.debug.Logger'); +goog.require('goog.dom.safe'); +goog.require('goog.html.SafeHtml'); +goog.require('goog.html.SafeStyleSheet'); +goog.require('goog.string.Const'); +goog.require('goog.structs.CircularBuffer'); +goog.require('goog.userAgent'); + + + +/** + * Provides a debug DebugWindow that is bound to the goog.debug.Logger. + * It handles log messages and writes them to the DebugWindow. This doesn't + * provide a lot of functionality that the old Gmail logging infrastructure + * provided like saving debug logs for exporting to the server. Now that we + * have an event-based logging infrastructure, we can encapsulate that + * functionality in a separate class. + * + * @constructor + * @param {string=} opt_identifier Identifier for this logging class. + * @param {string=} opt_prefix Prefix prepended to messages. + */ +goog.debug.DebugWindow = function(opt_identifier, opt_prefix) { + /** + * Identifier for this logging class + * @protected {string} + */ + this.identifier = opt_identifier || ''; + + /** + * Array used to buffer log output + * @protected {!Array<!goog.html.SafeHtml>} + */ + this.outputBuffer = []; + + /** + * Optional prefix to be prepended to error strings + * @private {string} + */ + this.prefix_ = opt_prefix || ''; + + /** + * Buffer for saving the last 1000 messages + * @private {!goog.structs.CircularBuffer} + */ + this.savedMessages_ = + new goog.structs.CircularBuffer(goog.debug.DebugWindow.MAX_SAVED); + + /** + * Save the publish handler so it can be removed + * @private {!Function} + */ + this.publishHandler_ = goog.bind(this.addLogRecord, this); + + /** + * Formatter for formatted output + * @private {goog.debug.Formatter} + */ + this.formatter_ = new goog.debug.HtmlFormatter(this.prefix_); + + /** + * Loggers that we shouldn't output + * @private {!Object} + */ + this.filteredLoggers_ = {}; + + // enable by default + this.setCapturing(true); + + /** + * Whether we are currently enabled. When the DebugWindow is enabled, it tries + * to keep its window open. When it's disabled, it can still be capturing log + * output if, but it won't try to write them to the DebugWindow window until + * it's enabled. + * @private {boolean} + */ + this.enabled_ = goog.debug.DebugWindow.isEnabled(this.identifier); + + // timer to save the DebugWindow's window position in a cookie + goog.global.setInterval(goog.bind(this.saveWindowPositionSize_, this), 7500); +}; + + +/** + * Max number of messages to be saved + * @type {number} + */ +goog.debug.DebugWindow.MAX_SAVED = 500; + + +/** + * How long to keep the cookies for in milliseconds + * @type {number} + */ +goog.debug.DebugWindow.COOKIE_TIME = 30 * 24 * 60 * 60 * 1000; // 30-days + + +/** + * HTML string printed when the debug window opens + * @type {string} + * @protected + */ +goog.debug.DebugWindow.prototype.welcomeMessage = 'LOGGING'; + + +/** + * Whether to force enable the window on a severe log. + * @type {boolean} + * @private + */ +goog.debug.DebugWindow.prototype.enableOnSevere_ = false; + + +/** + * Reference to debug window + * @type {Window} + * @protected + */ +goog.debug.DebugWindow.prototype.win = null; + + +/** + * In the process of opening the window + * @type {boolean} + * @private + */ +goog.debug.DebugWindow.prototype.winOpening_ = false; + + +/** + * Whether we are currently capturing logger output. + * + * @type {boolean} + * @private + */ +goog.debug.DebugWindow.prototype.isCapturing_ = false; + + +/** + * Whether we already showed an alert that the DebugWindow was blocked. + * @type {boolean} + * @private + */ +goog.debug.DebugWindow.showedBlockedAlert_ = false; + + +/** + * Reference to timeout used to buffer the output stream. + * @type {?number} + * @private + */ +goog.debug.DebugWindow.prototype.bufferTimeout_ = null; + + +/** + * Timestamp for the last time the log was written to. + * @protected {number} + */ +goog.debug.DebugWindow.prototype.lastCall = goog.now(); + + +/** + * Sets the welcome message shown when the window is first opened or reset. + * + * @param {string} msg An HTML string. + */ +goog.debug.DebugWindow.prototype.setWelcomeMessage = function(msg) { + this.welcomeMessage = msg; +}; + + +/** + * Initializes the debug window. + */ +goog.debug.DebugWindow.prototype.init = function() { + if (this.enabled_) { + this.openWindow_(); + } +}; + + +/** + * Whether the DebugWindow is enabled. When the DebugWindow is enabled, it + * tries to keep its window open and logs all messages to the window. When the + * DebugWindow is disabled, it stops logging messages to its window. + * + * @return {boolean} Whether the DebugWindow is enabled. + */ +goog.debug.DebugWindow.prototype.isEnabled = function() { + return this.enabled_; +}; + + +/** + * Sets whether the DebugWindow is enabled. When the DebugWindow is enabled, it + * tries to keep its window open and log all messages to the window. When the + * DebugWindow is disabled, it stops logging messages to its window. The + * DebugWindow also saves this state to a cookie so that it's persisted across + * application refreshes. + * @param {boolean} enable Whether the DebugWindow is enabled. + */ +goog.debug.DebugWindow.prototype.setEnabled = function(enable) { + this.enabled_ = enable; + + if (this.enabled_) { + this.openWindow_(); + } + + this.setCookie_('enabled', enable ? '1' : '0'); +}; + + +/** + * Sets whether the debug window should be force enabled when a severe log is + * encountered. + * @param {boolean} enableOnSevere Whether to enable on severe logs.. + */ +goog.debug.DebugWindow.prototype.setForceEnableOnSevere = + function(enableOnSevere) { + this.enableOnSevere_ = enableOnSevere; +}; + + +/** + * Whether we are currently capturing logger output. + * @return {boolean} whether we are currently capturing logger output. + */ +goog.debug.DebugWindow.prototype.isCapturing = function() { + return this.isCapturing_; +}; + + +/** + * Sets whether we are currently capturing logger output. + * @param {boolean} capturing Whether to capture logger output. + */ +goog.debug.DebugWindow.prototype.setCapturing = function(capturing) { + if (capturing == this.isCapturing_) { + return; + } + this.isCapturing_ = capturing; + + // attach or detach handler from the root logger + var rootLogger = goog.debug.LogManager.getRoot(); + if (capturing) { + rootLogger.addHandler(this.publishHandler_); + } else { + rootLogger.removeHandler(this.publishHandler_); + } +}; + + +/** + * Gets the formatter for outputting to the debug window. The default formatter + * is an instance of goog.debug.HtmlFormatter + * @return {goog.debug.Formatter} The formatter in use. + */ +goog.debug.DebugWindow.prototype.getFormatter = function() { + return this.formatter_; +}; + + +/** + * Sets the formatter for outputting to the debug window. + * @param {goog.debug.Formatter} formatter The formatter to use. + */ +goog.debug.DebugWindow.prototype.setFormatter = function(formatter) { + this.formatter_ = formatter; +}; + + +/** + * Adds a separator to the debug window. + */ +goog.debug.DebugWindow.prototype.addSeparator = function() { + this.write_(goog.html.SafeHtml.create('hr')); +}; + + +/** + * @return {boolean} Whether there is an active window. + */ +goog.debug.DebugWindow.prototype.hasActiveWindow = function() { + return !!this.win && !this.win.closed; +}; + + +/** + * Clears the contents of the debug window + * @protected + */ +goog.debug.DebugWindow.prototype.clear = function() { + this.savedMessages_.clear(); + if (this.hasActiveWindow()) { + this.writeInitialDocument(); + } +}; + + +/** + * Adds a log record. + * @param {goog.debug.LogRecord} logRecord the LogRecord. + */ +goog.debug.DebugWindow.prototype.addLogRecord = function(logRecord) { + if (this.filteredLoggers_[logRecord.getLoggerName()]) { + return; + } + var html = this.formatter_.formatRecordAsHtml(logRecord); + this.write_(html); + if (this.enableOnSevere_ && + logRecord.getLevel().value >= goog.debug.Logger.Level.SEVERE.value) { + this.setEnabled(true); + } +}; + + +/** + * Writes a message to the log, possibly opening up the window if it's enabled, + * or saving it if it's disabled. + * @param {!goog.html.SafeHtml} html The HTML to write. + * @private + */ +goog.debug.DebugWindow.prototype.write_ = function(html) { + // If the logger is enabled, open window and write html message to log + // otherwise save it + if (this.enabled_) { + this.openWindow_(); + this.savedMessages_.add(html); + this.writeToLog_(html); + } else { + this.savedMessages_.add(html); + } +}; + + +/** + * Write to the buffer. If a message hasn't been sent for more than 750ms just + * write, otherwise delay for a minimum of 250ms. + * @param {!goog.html.SafeHtml} html HTML to post to the log. + * @private + */ +goog.debug.DebugWindow.prototype.writeToLog_ = function(html) { + this.outputBuffer.push(html); + goog.global.clearTimeout(this.bufferTimeout_); + + if (goog.now() - this.lastCall > 750) { + this.writeBufferToLog(); + } else { + this.bufferTimeout_ = + goog.global.setTimeout(goog.bind(this.writeBufferToLog, this), 250); + } +}; + + +/** + * Write to the log and maybe scroll into view. + * @protected + */ +goog.debug.DebugWindow.prototype.writeBufferToLog = function() { + this.lastCall = goog.now(); + if (this.hasActiveWindow()) { + var body = this.win.document.body; + var scroll = body && + body.scrollHeight - (body.scrollTop + body.clientHeight) <= 100; + + goog.dom.safe.documentWrite( + this.win.document, goog.html.SafeHtml.concat(this.outputBuffer)); + this.outputBuffer.length = 0; + + if (scroll) { + this.win.scrollTo(0, 1000000); + } + } +}; + + +/** + * Writes all saved messages to the DebugWindow. + * @protected + */ +goog.debug.DebugWindow.prototype.writeSavedMessages = function() { + var messages = this.savedMessages_.getValues(); + for (var i = 0; i < messages.length; i++) { + this.writeToLog_(messages[i]); + } +}; + + +/** + * Opens the debug window if it is not already referenced + * @private + */ +goog.debug.DebugWindow.prototype.openWindow_ = function() { + if (this.hasActiveWindow() || this.winOpening_) { + return; + } + + var winpos = this.getCookie_('dbg', '0,0,800,500').split(','); + var x = Number(winpos[0]); + var y = Number(winpos[1]); + var w = Number(winpos[2]); + var h = Number(winpos[3]); + + this.winOpening_ = true; + this.win = window.open('', this.getWindowName_(), 'width=' + w + + ',height=' + h + ',toolbar=no,resizable=yes,' + + 'scrollbars=yes,left=' + x + ',top=' + y + + ',status=no,screenx=' + x + ',screeny=' + y); + + if (!this.win) { + if (!goog.debug.DebugWindow.showedBlockedAlert_) { + // only show this once + alert('Logger popup was blocked'); + goog.debug.DebugWindow.showedBlockedAlert_ = true; + } + } + + this.winOpening_ = false; + + if (this.win) { + this.writeInitialDocument(); + } +}; + + +/** + * Gets a valid window name for the debug window. Replaces invalid characters in + * IE. + * @return {string} Valid window name. + * @private + */ +goog.debug.DebugWindow.prototype.getWindowName_ = function() { + return goog.userAgent.IE ? + this.identifier.replace(/[\s\-\.\,]/g, '_') : this.identifier; +}; + + +/** + * @return {!goog.html.SafeStyleSheet} The stylesheet, for inclusion in the + * initial HTML. + */ +goog.debug.DebugWindow.prototype.getStyleRules = function() { + return goog.html.SafeStyleSheet.fromConstant(goog.string.Const.from( + '*{font:normal 14px monospace;}' + + '.dbg-sev{color:#F00}' + + '.dbg-w{color:#E92}' + + '.dbg-sh{background-color:#fd4;font-weight:bold;color:#000}' + + '.dbg-i{color:#666}' + + '.dbg-f{color:#999}' + + '.dbg-ev{color:#0A0}' + + '.dbg-m{color:#990}')); +}; + + +/** + * Writes the initial HTML of the debug window. + * @protected + */ +goog.debug.DebugWindow.prototype.writeInitialDocument = function() { + if (!this.hasActiveWindow()) { + return; + } + + this.win.document.open(); + + var div = goog.html.SafeHtml.create( + 'div', { + 'class': 'dbg-ev', + 'style': goog.string.Const.from('text-align:center;')}, + goog.html.SafeHtml.concat( + this.welcomeMessage, + goog.html.SafeHtml.create('br'), + goog.html.SafeHtml.create( + 'small', {}, 'Logger: ' + this.identifier))); + var html = goog.html.SafeHtml.concat( + goog.html.SafeHtml.createStyle(this.getStyleRules()), + goog.html.SafeHtml.create('hr'), + div, + goog.html.SafeHtml.create('hr')); + + this.writeToLog_(html); + this.writeSavedMessages(); +}; + + +/** + * Save persistent data (using cookies) for 1 month (cookie specific to this + * logger object). + * @param {string} key Data name. + * @param {string} value Data value. + * @private + */ +goog.debug.DebugWindow.prototype.setCookie_ = function(key, value) { + var fullKey = goog.debug.DebugWindow.getCookieKey_(this.identifier, key); + document.cookie = fullKey + '=' + encodeURIComponent(value) + + ';path=/;expires=' + + (new Date(goog.now() + goog.debug.DebugWindow.COOKIE_TIME)).toUTCString(); +}; + + +/** + * Retrieve data (using cookies). + * @param {string} key Data name. + * @param {string=} opt_default Optional default value if cookie doesn't exist. + * @return {string} Cookie value. + * @private + */ +goog.debug.DebugWindow.prototype.getCookie_ = function(key, opt_default) { + return goog.debug.DebugWindow.getCookieValue_( + this.identifier, key, opt_default); +}; + + +/** + * Creates a valid cookie key name which is scoped to the given identifier. + * Substitutes all occurences of invalid cookie name characters (whitespace, + * ';', and '=') with '_', which is a valid and readable alternative. + * @see goog.net.Cookies#isValidName + * @see <a href="http://tools.ietf.org/html/rfc2109">RFC 2109</a> + * @param {string} identifier Identifier for logging class. + * @param {string} key Data name. + * @return {string} Cookie key name. + * @private + */ +goog.debug.DebugWindow.getCookieKey_ = function(identifier, key) { + var fullKey = key + identifier; + return fullKey.replace(/[;=\s]/g, '_'); +}; + + +/** + * Retrieve data (using cookies). + * @param {string} identifier Identifier for logging class. + * @param {string} key Data name. + * @param {string=} opt_default Optional default value if cookie doesn't exist. + * @return {string} Cookie value. + * @private + */ +goog.debug.DebugWindow.getCookieValue_ = function( + identifier, key, opt_default) { + var fullKey = goog.debug.DebugWindow.getCookieKey_(identifier, key); + var cookie = String(document.cookie); + var start = cookie.indexOf(fullKey + '='); + if (start != -1) { + var end = cookie.indexOf(';', start); + return decodeURIComponent(cookie.substring(start + fullKey.length + 1, + end == -1 ? cookie.length : end)); + } else { + return opt_default || ''; + } +}; + + +/** + * @param {string} identifier Identifier for logging class. + * @return {boolean} Whether the DebugWindow is enabled. + */ +goog.debug.DebugWindow.isEnabled = function(identifier) { + return goog.debug.DebugWindow.getCookieValue_(identifier, 'enabled') == '1'; +}; + + +/** + * Saves the window position size to a cookie + * @private + */ +goog.debug.DebugWindow.prototype.saveWindowPositionSize_ = function() { + if (!this.hasActiveWindow()) { + return; + } + var x = this.win.screenX || this.win.screenLeft || 0; + var y = this.win.screenY || this.win.screenTop || 0; + var w = this.win.outerWidth || 800; + var h = this.win.outerHeight || 500; + this.setCookie_('dbg', x + ',' + y + ',' + w + ',' + h); +}; + + +/** + * Adds a logger name to be filtered. + * @param {string} loggerName the logger name to add. + */ +goog.debug.DebugWindow.prototype.addFilter = function(loggerName) { + this.filteredLoggers_[loggerName] = 1; +}; + + +/** + * Removes a logger name to be filtered. + * @param {string} loggerName the logger name to remove. + */ +goog.debug.DebugWindow.prototype.removeFilter = function(loggerName) { + delete this.filteredLoggers_[loggerName]; +}; + + +/** + * Modify the size of the circular buffer. Allows the log to retain more + * information while the window is closed. + * @param {number} size New size of the circular buffer. + */ +goog.debug.DebugWindow.prototype.resetBufferWithNewSize = function(size) { + if (size > 0 && size < 50000) { + this.clear(); + this.savedMessages_ = new goog.structs.CircularBuffer(size); + } +}; http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/debug/devcss/devcss.js ---------------------------------------------------------------------- diff --git a/externs/GCL/externs/goog/debug/devcss/devcss.js b/externs/GCL/externs/goog/debug/devcss/devcss.js new file mode 100644 index 0000000..8716ca4 --- /dev/null +++ b/externs/GCL/externs/goog/debug/devcss/devcss.js @@ -0,0 +1,445 @@ +// Copyright 2008 The Closure Library Authors. All Rights Reserved. +// +// 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. + +/** + * @fileoverview Runtime development CSS Compiler emulation, via javascript. + * This class provides an approximation to CSSCompiler's functionality by + * hacking the live CSSOM. + * This code is designed to be inserted in the DOM immediately after the last + * style block in HEAD when in development mode, i.e. you are not using a + * running instance of a CSS Compiler to pass your CSS through. + */ + + +goog.provide('goog.debug.DevCss'); +goog.provide('goog.debug.DevCss.UserAgent'); + +goog.require('goog.asserts'); +goog.require('goog.cssom'); +goog.require('goog.dom.classlist'); +goog.require('goog.events'); +goog.require('goog.events.EventType'); +goog.require('goog.string'); +goog.require('goog.userAgent'); + + + +/** + * A class for solving development CSS issues/emulating the CSS Compiler. + * @param {goog.debug.DevCss.UserAgent=} opt_userAgent The user agent, if not + * passed in, will be determined using goog.userAgent. + * @param {number|string=} opt_userAgentVersion The user agent's version. + * If not passed in, will be determined using goog.userAgent. + * @throws {Error} When userAgent detection fails. + * @constructor + * @final + */ +goog.debug.DevCss = function(opt_userAgent, opt_userAgentVersion) { + if (!opt_userAgent) { + // Walks through the known goog.userAgents. + if (goog.userAgent.IE) { + opt_userAgent = goog.debug.DevCss.UserAgent.IE; + } else if (goog.userAgent.GECKO) { + opt_userAgent = goog.debug.DevCss.UserAgent.GECKO; + } else if (goog.userAgent.WEBKIT) { + opt_userAgent = goog.debug.DevCss.UserAgent.WEBKIT; + } else if (goog.userAgent.MOBILE) { + opt_userAgent = goog.debug.DevCss.UserAgent.MOBILE; + } else if (goog.userAgent.OPERA) { + opt_userAgent = goog.debug.DevCss.UserAgent.OPERA; + } + } + switch (opt_userAgent) { + case goog.debug.DevCss.UserAgent.OPERA: + case goog.debug.DevCss.UserAgent.IE: + case goog.debug.DevCss.UserAgent.GECKO: + case goog.debug.DevCss.UserAgent.FIREFOX: + case goog.debug.DevCss.UserAgent.WEBKIT: + case goog.debug.DevCss.UserAgent.SAFARI: + case goog.debug.DevCss.UserAgent.MOBILE: + break; + default: + throw Error('Could not determine the user agent from known UserAgents'); + } + + /** + * One of goog.debug.DevCss.UserAgent. + * @type {string} + * @private + */ + this.userAgent_ = opt_userAgent; + + /** + * @const @private + */ + this.userAgentTokens_ = {}; + + /** + * @type {number|string} + * @private + */ + this.userAgentVersion_ = opt_userAgentVersion || goog.userAgent.VERSION; + this.generateUserAgentTokens_(); + + /** + * @type {boolean} + * @private + */ + this.isIe6OrLess_ = this.userAgent_ == goog.debug.DevCss.UserAgent.IE && + goog.string.compareVersions('7', this.userAgentVersion_) > 0; + + if (this.isIe6OrLess_) { + /** + * @type {Array<{classNames,combinedClassName,els}>} + * @private + */ + this.ie6CombinedMatches_ = []; + } +}; + + +/** + * Rewrites the CSSOM as needed to activate any useragent-specific selectors. + * @param {boolean=} opt_enableIe6ReadyHandler If true(the default), and the + * userAgent is ie6, we set a document "ready" event handler to walk the DOM + * and make combined selector className changes. Having this parameter also + * aids unit testing. + */ +goog.debug.DevCss.prototype.activateBrowserSpecificCssRules = function( + opt_enableIe6ReadyHandler) { + var enableIe6EventHandler = goog.isDef(opt_enableIe6ReadyHandler) ? + opt_enableIe6ReadyHandler : true; + var cssRules = goog.cssom.getAllCssStyleRules(); + + for (var i = 0, cssRule; cssRule = cssRules[i]; i++) { + this.replaceBrowserSpecificClassNames_(cssRule); + } + + // Since we may have manipulated the rules above, we'll have to do a + // complete sweep again if we're in IE6. Luckily performance doesn't + // matter for this tool. + if (this.isIe6OrLess_) { + cssRules = goog.cssom.getAllCssStyleRules(); + for (var i = 0, cssRule; cssRule = cssRules[i]; i++) { + this.replaceIe6CombinedSelectors_(cssRule); + } + } + + // Add an event listener for document ready to rewrite any necessary + // combined classnames in IE6. + if (this.isIe6OrLess_ && enableIe6EventHandler) { + goog.events.listen(document, goog.events.EventType.LOAD, goog.bind( + this.addIe6CombinedClassNames_, this)); + } +}; + + +/** + * A list of possible user agent strings. + * @enum {string} + */ +goog.debug.DevCss.UserAgent = { + OPERA: 'OPERA', + IE: 'IE', + GECKO: 'GECKO', + FIREFOX: 'GECKO', + WEBKIT: 'WEBKIT', + SAFARI: 'WEBKIT', + MOBILE: 'MOBILE' +}; + + +/** + * A list of strings that may be used for matching in CSS files/development. + * @enum {string} + * @private + */ +goog.debug.DevCss.CssToken_ = { + USERAGENT: 'USERAGENT', + SEPARATOR: '-', + LESS_THAN: 'LT', + GREATER_THAN: 'GT', + LESS_THAN_OR_EQUAL: 'LTE', + GREATER_THAN_OR_EQUAL: 'GTE', + IE6_SELECTOR_TEXT: 'goog-ie6-selector', + IE6_COMBINED_GLUE: '_' +}; + + +/** + * Generates user agent token match strings with comparison and version bits. + * For example: + * userAgentTokens_.ANY will be like 'GECKO' + * userAgentTokens_.LESS_THAN will be like 'GECKO-LT3' etc... + * @private + */ +goog.debug.DevCss.prototype.generateUserAgentTokens_ = function() { + this.userAgentTokens_.ANY = goog.debug.DevCss.CssToken_.USERAGENT + + goog.debug.DevCss.CssToken_.SEPARATOR + this.userAgent_; + this.userAgentTokens_.EQUALS = this.userAgentTokens_.ANY + + goog.debug.DevCss.CssToken_.SEPARATOR; + this.userAgentTokens_.LESS_THAN = this.userAgentTokens_.ANY + + goog.debug.DevCss.CssToken_.SEPARATOR + + goog.debug.DevCss.CssToken_.LESS_THAN; + this.userAgentTokens_.LESS_THAN_OR_EQUAL = this.userAgentTokens_.ANY + + goog.debug.DevCss.CssToken_.SEPARATOR + + goog.debug.DevCss.CssToken_.LESS_THAN_OR_EQUAL; + this.userAgentTokens_.GREATER_THAN = this.userAgentTokens_.ANY + + goog.debug.DevCss.CssToken_.SEPARATOR + + goog.debug.DevCss.CssToken_.GREATER_THAN; + this.userAgentTokens_.GREATER_THAN_OR_EQUAL = this.userAgentTokens_.ANY + + goog.debug.DevCss.CssToken_.SEPARATOR + + goog.debug.DevCss.CssToken_.GREATER_THAN_OR_EQUAL; +}; + + +/** + * Gets the version number bit from a selector matching userAgentToken. + * @param {string} selectorText The selector text of a CSS rule. + * @param {string} userAgentToken Includes the LTE/GTE bit to see if it matches. + * @return {string|undefined} The version number. + * @private + */ +goog.debug.DevCss.prototype.getVersionNumberFromSelectorText_ = function( + selectorText, userAgentToken) { + var regex = new RegExp(userAgentToken + '([\\d\\.]+)'); + var matches = regex.exec(selectorText); + if (matches && matches.length == 2) { + return matches[1]; + } +}; + + +/** + * Extracts a rule version from the selector text, and if it finds one, calls + * compareVersions against it and the passed in token string to provide the + * value needed to determine if we have a match or not. + * @param {CSSRule} cssRule The rule to test against. + * @param {string} token The match token to test against the rule. + * @return {!Array|undefined} A tuple with the result of the compareVersions + * call and the matched ruleVersion. + * @private + */ +goog.debug.DevCss.prototype.getRuleVersionAndCompare_ = function(cssRule, + token) { + if (!cssRule.selectorText.match(token)) { + return; + } + var ruleVersion = this.getVersionNumberFromSelectorText_( + cssRule.selectorText, token); + if (!ruleVersion) { + return; + } + + var comparison = goog.string.compareVersions(this.userAgentVersion_, + ruleVersion); + return [comparison, ruleVersion]; +}; + + +/** + * Replaces a CSS selector if we have matches based on our useragent/version. + * Example: With a selector like ".USERAGENT-IE-LTE6 .class { prop: value }" if + * we are running IE6 we'll end up with ".class { prop: value }", thereby + * "activating" the selector. + * @param {CSSRule} cssRule The cssRule to potentially replace. + * @private + */ +goog.debug.DevCss.prototype.replaceBrowserSpecificClassNames_ = function( + cssRule) { + + // If we don't match the browser token, we can stop now. + if (!cssRule.selectorText.match(this.userAgentTokens_.ANY)) { + return; + } + + // We know it will begin as a classname. + var additionalRegexString; + + // Tests "Less than or equals". + var compared = this.getRuleVersionAndCompare_(cssRule, + this.userAgentTokens_.LESS_THAN_OR_EQUAL); + if (compared && compared.length) { + if (compared[0] > 0) { + return; + } + additionalRegexString = this.userAgentTokens_.LESS_THAN_OR_EQUAL + + compared[1]; + } + + // Tests "Less than". + compared = this.getRuleVersionAndCompare_(cssRule, + this.userAgentTokens_.LESS_THAN); + if (compared && compared.length) { + if (compared[0] > -1) { + return; + } + additionalRegexString = this.userAgentTokens_.LESS_THAN + compared[1]; + } + + // Tests "Greater than or equals". + compared = this.getRuleVersionAndCompare_(cssRule, + this.userAgentTokens_.GREATER_THAN_OR_EQUAL); + if (compared && compared.length) { + if (compared[0] < 0) { + return; + } + additionalRegexString = this.userAgentTokens_.GREATER_THAN_OR_EQUAL + + compared[1]; + } + + // Tests "Greater than". + compared = this.getRuleVersionAndCompare_(cssRule, + this.userAgentTokens_.GREATER_THAN); + if (compared && compared.length) { + if (compared[0] < 1) { + return; + } + additionalRegexString = this.userAgentTokens_.GREATER_THAN + compared[1]; + } + + // Tests "Equals". + compared = this.getRuleVersionAndCompare_(cssRule, + this.userAgentTokens_.EQUALS); + if (compared && compared.length) { + if (compared[0] != 0) { + return; + } + additionalRegexString = this.userAgentTokens_.EQUALS + compared[1]; + } + + // If we got to here without generating the additionalRegexString, then + // we did not match any of our comparison token strings, and we want a + // general browser token replacement. + if (!additionalRegexString) { + additionalRegexString = this.userAgentTokens_.ANY; + } + + // We need to match at least a single whitespace character to know that + // we are matching the entire useragent string token. + var regexString = '\\.' + additionalRegexString + '\\s+'; + var re = new RegExp(regexString, 'g'); + + var currentCssText = goog.cssom.getCssTextFromCssRule(cssRule); + + // Replacing the token with '' activates the selector for this useragent. + var newCssText = currentCssText.replace(re, ''); + + if (newCssText != currentCssText) { + goog.cssom.replaceCssRule(cssRule, newCssText); + } +}; + + +/** + * Replaces IE6 combined selector rules with a workable development alternative. + * IE6 actually parses .class1.class2 {} to simply .class2 {} which is nasty. + * To fully support combined selectors in IE6 this function needs to be paired + * with a call to replace the relevant DOM elements classNames as well. + * @see {this.addIe6CombinedClassNames_} + * @param {CSSRule} cssRule The rule to potentially fix. + * @private + */ +goog.debug.DevCss.prototype.replaceIe6CombinedSelectors_ = function(cssRule) { + // This match only ever works in IE because other UA's won't have our + // IE6_SELECTOR_TEXT in the cssText property. + if (cssRule.style.cssText && + cssRule.style.cssText.match( + goog.debug.DevCss.CssToken_.IE6_SELECTOR_TEXT)) { + var cssText = goog.cssom.getCssTextFromCssRule(cssRule); + var combinedSelectorText = this.getIe6CombinedSelectorText_(cssText); + if (combinedSelectorText) { + var newCssText = combinedSelectorText + '{' + cssRule.style.cssText + '}'; + goog.cssom.replaceCssRule(cssRule, newCssText); + } + } +}; + + +/** + * Gets the appropriate new combined selector text for IE6. + * Also adds an entry onto ie6CombinedMatches_ with relevant info for the + * likely following call to walk the DOM and rewrite the class attribute. + * Example: With a selector like + * ".class2 { -goog-ie6-selector: .class1.class2; prop: value }". + * this function will return: + * ".class1_class2 { prop: value }". + * @param {string} cssText The CSS selector text and css rule text combined. + * @return {?string} The rewritten css rule text. + * @private + */ +goog.debug.DevCss.prototype.getIe6CombinedSelectorText_ = function(cssText) { + var regex = new RegExp(goog.debug.DevCss.CssToken_.IE6_SELECTOR_TEXT + + '\\s*:\\s*\\"([^\\"]+)\\"', 'gi'); + var matches = regex.exec(cssText); + if (matches) { + var combinedSelectorText = matches[1]; + // To aid in later fixing the DOM, we need to split up the possible + // selector groups by commas. + var groupedSelectors = combinedSelectorText.split(/\s*\,\s*/); + for (var i = 0, selector; selector = groupedSelectors[i]; i++) { + // Strips off the leading ".". + var combinedClassName = selector.substr(1); + var classNames = combinedClassName.split( + goog.debug.DevCss.CssToken_.IE6_COMBINED_GLUE); + var entry = { + classNames: classNames, + combinedClassName: combinedClassName, + els: [] + }; + this.ie6CombinedMatches_.push(entry); + } + return combinedSelectorText; + } + return null; +}; + + +/** + * Adds combined selectors with underscores to make them "work" in IE6. + * @see {this.replaceIe6CombinedSelectors_} + * @private + */ +goog.debug.DevCss.prototype.addIe6CombinedClassNames_ = function() { + if (!this.ie6CombinedMatches_.length) { + return; + } + var allEls = document.getElementsByTagName('*'); + // Match nodes for all classNames. + for (var i = 0, classNameEntry; classNameEntry = + this.ie6CombinedMatches_[i]; i++) { + for (var j = 0, el; el = allEls[j]; j++) { + var classNamesLength = classNameEntry.classNames.length; + for (var k = 0, className; className = classNameEntry.classNames[k]; + k++) { + if (!goog.dom.classlist.contains(goog.asserts.assert(el), className)) { + break; + } + if (k == classNamesLength - 1) { + classNameEntry.els.push(el); + } + } + } + // Walks over our matching nodes and fixes them. + if (classNameEntry.els.length) { + for (var j = 0, el; el = classNameEntry.els[j]; j++) { + goog.asserts.assert(el); + if (!goog.dom.classlist.contains(el, + classNameEntry.combinedClassName)) { + goog.dom.classlist.add(el, classNameEntry.combinedClassName); + } + } + } + } +}; http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/debug/devcss/devcssrunner.js ---------------------------------------------------------------------- diff --git a/externs/GCL/externs/goog/debug/devcss/devcssrunner.js b/externs/GCL/externs/goog/debug/devcss/devcssrunner.js new file mode 100644 index 0000000..cfe4f39 --- /dev/null +++ b/externs/GCL/externs/goog/debug/devcss/devcssrunner.js @@ -0,0 +1,26 @@ +// Copyright 2008 The Closure Library Authors. All Rights Reserved. +// +// 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. + +/** + * @fileoverview Development CSS Compiler runtime execution. + */ + +goog.provide('goog.debug.devCssRunner'); + +goog.require('goog.debug.DevCss'); + +(function() { + var devCssInstance = new goog.debug.DevCss(); + devCssInstance.activateBrowserSpecificCssRules(); +})(); http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/debug/divconsole.js ---------------------------------------------------------------------- diff --git a/externs/GCL/externs/goog/debug/divconsole.js b/externs/GCL/externs/goog/debug/divconsole.js new file mode 100644 index 0000000..e3eacb9 --- /dev/null +++ b/externs/GCL/externs/goog/debug/divconsole.js @@ -0,0 +1,150 @@ +// Copyright 2006 The Closure Library Authors. All Rights Reserved. +// +// 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. + +/** + * @fileoverview Simple logger that logs a Div Element. + * + */ + +goog.provide('goog.debug.DivConsole'); + +goog.require('goog.debug.HtmlFormatter'); +goog.require('goog.debug.LogManager'); +goog.require('goog.dom.TagName'); +goog.require('goog.dom.safe'); +goog.require('goog.html.SafeHtml'); +goog.require('goog.style'); + + + +/** + * A class for visualising logger calls in a div element. + * @param {Element} element The element to append to. + * @constructor + */ +goog.debug.DivConsole = function(element) { + this.publishHandler_ = goog.bind(this.addLogRecord, this); + this.formatter_ = new goog.debug.HtmlFormatter(); + this.formatter_.showAbsoluteTime = false; + this.isCapturing_ = false; + this.element_ = element; + this.elementOwnerDocument_ = + this.element_.ownerDocument || this.element_.document; + + this.installStyles(); +}; + + +/** + * Installs styles for the log messages and its div + */ +goog.debug.DivConsole.prototype.installStyles = function() { + goog.style.installStyles( + '.dbg-sev{color:#F00}' + + '.dbg-w{color:#C40}' + + '.dbg-sh{font-weight:bold;color:#000}' + + '.dbg-i{color:#444}' + + '.dbg-f{color:#999}' + + '.dbg-ev{color:#0A0}' + + '.dbg-m{color:#990}' + + '.logmsg{border-bottom:1px solid #CCC;padding:2px}' + + '.logsep{background-color: #8C8;}' + + '.logdiv{border:1px solid #CCC;background-color:#FCFCFC;' + + 'font:medium monospace}', + this.element_); + this.element_.className += ' logdiv'; +}; + + +/** + * Sets whether we are currently capturing logger output. + * @param {boolean} capturing Whether to capture logger output. + */ +goog.debug.DivConsole.prototype.setCapturing = function(capturing) { + if (capturing == this.isCapturing_) { + return; + } + + // attach or detach handler from the root logger + var rootLogger = goog.debug.LogManager.getRoot(); + if (capturing) { + rootLogger.addHandler(this.publishHandler_); + } else { + rootLogger.removeHandler(this.publishHandler_); + this.logBuffer = ''; + } + this.isCapturing_ = capturing; +}; + + +/** + * Adds a log record. + * @param {goog.debug.LogRecord} logRecord The log entry. + */ +goog.debug.DivConsole.prototype.addLogRecord = function(logRecord) { + if (!logRecord) { + return; + } + var scroll = this.element_.scrollHeight - this.element_.scrollTop - + this.element_.clientHeight <= 100; + + var div = this.elementOwnerDocument_.createElement(goog.dom.TagName.DIV); + div.className = 'logmsg'; + goog.dom.safe.setInnerHtml( + div, this.formatter_.formatRecordAsHtml(logRecord)); + this.element_.appendChild(div); + + if (scroll) { + this.element_.scrollTop = this.element_.scrollHeight; + } +}; + + +/** + * Gets the formatter for outputting to the console. The default formatter + * is an instance of goog.debug.HtmlFormatter + * @return {!goog.debug.Formatter} The formatter in use. + */ +goog.debug.DivConsole.prototype.getFormatter = function() { + return this.formatter_; +}; + + +/** + * Sets the formatter for outputting to the console. + * @param {goog.debug.HtmlFormatter} formatter The formatter to use. + */ +goog.debug.DivConsole.prototype.setFormatter = function(formatter) { + this.formatter_ = formatter; +}; + + +/** + * Adds a separator to the debug window. + */ +goog.debug.DivConsole.prototype.addSeparator = function() { + var div = this.elementOwnerDocument_.createElement(goog.dom.TagName.DIV); + div.className = 'logmsg logsep'; + this.element_.appendChild(div); +}; + + +/** + * Clears the console. + */ +goog.debug.DivConsole.prototype.clear = function() { + if (this.element_) { + goog.dom.safe.setInnerHtml(this.element_, goog.html.SafeHtml.EMPTY); + } +}; http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/debug/entrypointregistry.js ---------------------------------------------------------------------- diff --git a/externs/GCL/externs/goog/debug/entrypointregistry.js b/externs/GCL/externs/goog/debug/entrypointregistry.js new file mode 100644 index 0000000..3ae7549 --- /dev/null +++ b/externs/GCL/externs/goog/debug/entrypointregistry.js @@ -0,0 +1,158 @@ +// Copyright 2010 The Closure Library Authors. All Rights Reserved. +// +// 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. + +/** + * @fileoverview A global registry for entry points into a program, + * so that they can be instrumented. Each module should register their + * entry points with this registry. Designed to be compiled out + * if no instrumentation is requested. + * + * Entry points may be registered before or after a call to + * goog.debug.entryPointRegistry.monitorAll. If an entry point is registered + * later, the existing monitor will instrument the new entry point. + * + * @author [email protected] (Nick Santos) + */ + +goog.provide('goog.debug.EntryPointMonitor'); +goog.provide('goog.debug.entryPointRegistry'); + +goog.require('goog.asserts'); + + + +/** + * @interface + */ +goog.debug.EntryPointMonitor = function() {}; + + +/** + * Instruments a function. + * + * @param {!Function} fn A function to instrument. + * @return {!Function} The instrumented function. + */ +goog.debug.EntryPointMonitor.prototype.wrap; + + +/** + * Try to remove an instrumentation wrapper created by this monitor. + * If the function passed to unwrap is not a wrapper created by this + * monitor, then we will do nothing. + * + * Notice that some wrappers may not be unwrappable. For example, if other + * monitors have applied their own wrappers, then it will be impossible to + * unwrap them because their wrappers will have captured our wrapper. + * + * So it is important that entry points are unwrapped in the reverse + * order that they were wrapped. + * + * @param {!Function} fn A function to unwrap. + * @return {!Function} The unwrapped function, or {@code fn} if it was not + * a wrapped function created by this monitor. + */ +goog.debug.EntryPointMonitor.prototype.unwrap; + + +/** + * An array of entry point callbacks. + * @type {!Array<function(!Function)>} + * @private + */ +goog.debug.entryPointRegistry.refList_ = []; + + +/** + * Monitors that should wrap all the entry points. + * @type {!Array<!goog.debug.EntryPointMonitor>} + * @private + */ +goog.debug.entryPointRegistry.monitors_ = []; + + +/** + * Whether goog.debug.entryPointRegistry.monitorAll has ever been called. + * Checking this allows the compiler to optimize out the registrations. + * @type {boolean} + * @private + */ +goog.debug.entryPointRegistry.monitorsMayExist_ = false; + + +/** + * Register an entry point with this module. + * + * The entry point will be instrumented when a monitor is passed to + * goog.debug.entryPointRegistry.monitorAll. If this has already occurred, the + * entry point is instrumented immediately. + * + * @param {function(!Function)} callback A callback function which is called + * with a transforming function to instrument the entry point. The callback + * is responsible for wrapping the relevant entry point with the + * transforming function. + */ +goog.debug.entryPointRegistry.register = function(callback) { + // Don't use push(), so that this can be compiled out. + goog.debug.entryPointRegistry.refList_[ + goog.debug.entryPointRegistry.refList_.length] = callback; + // If no one calls monitorAll, this can be compiled out. + if (goog.debug.entryPointRegistry.monitorsMayExist_) { + var monitors = goog.debug.entryPointRegistry.monitors_; + for (var i = 0; i < monitors.length; i++) { + callback(goog.bind(monitors[i].wrap, monitors[i])); + } + } +}; + + +/** + * Configures a monitor to wrap all entry points. + * + * Entry points that have already been registered are immediately wrapped by + * the monitor. When an entry point is registered in the future, it will also + * be wrapped by the monitor when it is registered. + * + * @param {!goog.debug.EntryPointMonitor} monitor An entry point monitor. + */ +goog.debug.entryPointRegistry.monitorAll = function(monitor) { + goog.debug.entryPointRegistry.monitorsMayExist_ = true; + var transformer = goog.bind(monitor.wrap, monitor); + for (var i = 0; i < goog.debug.entryPointRegistry.refList_.length; i++) { + goog.debug.entryPointRegistry.refList_[i](transformer); + } + goog.debug.entryPointRegistry.monitors_.push(monitor); +}; + + +/** + * Try to unmonitor all the entry points that have already been registered. If + * an entry point is registered in the future, it will not be wrapped by the + * monitor when it is registered. Note that this may fail if the entry points + * have additional wrapping. + * + * @param {!goog.debug.EntryPointMonitor} monitor The last monitor to wrap + * the entry points. + * @throws {Error} If the monitor is not the most recently configured monitor. + */ +goog.debug.entryPointRegistry.unmonitorAllIfPossible = function(monitor) { + var monitors = goog.debug.entryPointRegistry.monitors_; + goog.asserts.assert(monitor == monitors[monitors.length - 1], + 'Only the most recent monitor can be unwrapped.'); + var transformer = goog.bind(monitor.unwrap, monitor); + for (var i = 0; i < goog.debug.entryPointRegistry.refList_.length; i++) { + goog.debug.entryPointRegistry.refList_[i](transformer); + } + monitors.length--; +}; http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/debug/error2.js ---------------------------------------------------------------------- diff --git a/externs/GCL/externs/goog/debug/error2.js b/externs/GCL/externs/goog/debug/error2.js new file mode 100644 index 0000000..5f1bd3e --- /dev/null +++ b/externs/GCL/externs/goog/debug/error2.js @@ -0,0 +1,63 @@ +// Copyright 2009 The Closure Library Authors. All Rights Reserved. +// +// 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. + +/** + * @fileoverview Provides a base class for custom Error objects such that the + * stack is correctly maintained. + * + * You should never need to throw goog.debug.Error(msg) directly, Error(msg) is + * sufficient. + * + */ + +goog.provide('goog.debug.Error'); + + + +/** + * Base class for custom error objects. + * @param {*=} opt_msg The message associated with the error. + * @constructor + * @extends {Error} + */ +goog.debug.Error = function(opt_msg) { + + // Attempt to ensure there is a stack trace. + if (Error.captureStackTrace) { + Error.captureStackTrace(this, goog.debug.Error); + } else { + var stack = new Error().stack; + if (stack) { + this.stack = stack; + } + } + + if (opt_msg) { + this.message = String(opt_msg); + } + + /** + * Whether to report this error to the server. Setting this to false will + * cause the error reporter to not report the error back to the server, + * which can be useful if the client knows that the error has already been + * logged on the server. + * @type {boolean} + */ + this.reportErrorToServer = true; +}; +goog.inherits(goog.debug.Error, Error); + + +/** @override */ +goog.debug.Error.prototype.name = 'CustomError'; http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/debug/errorhandler.js ---------------------------------------------------------------------- diff --git a/externs/GCL/externs/goog/debug/errorhandler.js b/externs/GCL/externs/goog/debug/errorhandler.js new file mode 100644 index 0000000..3d8b004 --- /dev/null +++ b/externs/GCL/externs/goog/debug/errorhandler.js @@ -0,0 +1,367 @@ +// Copyright 2007 The Closure Library Authors. All Rights Reserved. +// +// 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. + +/** + * @fileoverview Error handling utilities. + * + */ + +goog.provide('goog.debug.ErrorHandler'); +goog.provide('goog.debug.ErrorHandler.ProtectedFunctionError'); + +goog.require('goog.Disposable'); +goog.require('goog.asserts'); +goog.require('goog.debug'); +goog.require('goog.debug.EntryPointMonitor'); +goog.require('goog.debug.Error'); +goog.require('goog.debug.Trace'); + + + +/** + * The ErrorHandler can be used to to wrap functions with a try/catch + * statement. If an exception is thrown, the given error handler function will + * be called. + * + * When this object is disposed, it will stop handling exceptions and tracing. + * It will also try to restore window.setTimeout and window.setInterval + * if it wrapped them. Notice that in the general case, it is not technically + * possible to remove the wrapper, because functions have no knowledge of + * what they have been assigned to. So the app is responsible for other + * forms of unwrapping. + * + * @param {Function} handler Handler for exceptions. + * @constructor + * @extends {goog.Disposable} + * @implements {goog.debug.EntryPointMonitor} + */ +goog.debug.ErrorHandler = function(handler) { + goog.debug.ErrorHandler.base(this, 'constructor'); + + /** + * Handler for exceptions, which can do logging, reporting, etc. + * @type {Function} + * @private + */ + this.errorHandlerFn_ = handler; + + /** + * Whether errors should be wrapped in + * goog.debug.ErrorHandler.ProtectedFunctionError before rethrowing. + * @type {boolean} + * @private + */ + this.wrapErrors_ = true; // TODO(user) Change default. + + /** + * Whether to add a prefix to all error messages. The prefix is + * goog.debug.ErrorHandler.ProtectedFunctionError.MESSAGE_PREFIX. This option + * only has an effect if this.wrapErrors_ is set to false. + * @type {boolean} + * @private + */ + this.prefixErrorMessages_ = false; +}; +goog.inherits(goog.debug.ErrorHandler, goog.Disposable); + + +/** + * Whether to add tracers when instrumenting entry points. + * @type {boolean} + * @private + */ +goog.debug.ErrorHandler.prototype.addTracersToProtectedFunctions_ = false; + + +/** + * Enable tracers when instrumenting entry points. + * @param {boolean} newVal See above. + */ +goog.debug.ErrorHandler.prototype.setAddTracersToProtectedFunctions = + function(newVal) { + this.addTracersToProtectedFunctions_ = newVal; +}; + + +/** @override */ +goog.debug.ErrorHandler.prototype.wrap = function(fn) { + return this.protectEntryPoint(goog.asserts.assertFunction(fn)); +}; + + +/** @override */ +goog.debug.ErrorHandler.prototype.unwrap = function(fn) { + goog.asserts.assertFunction(fn); + return fn[this.getFunctionIndex_(false)] || fn; +}; + + +/** + * Private helper function to return a span that can be clicked on to display + * an alert with the current stack trace. Newlines are replaced with a + * placeholder so that they will not be html-escaped. + * @param {string} stackTrace The stack trace to create a span for. + * @return {string} A span which can be clicked on to show the stack trace. + * @private + */ +goog.debug.ErrorHandler.prototype.getStackTraceHolder_ = function(stackTrace) { + var buffer = []; + buffer.push('##PE_STACK_START##'); + buffer.push(stackTrace.replace(/(\r\n|\r|\n)/g, '##STACK_BR##')); + buffer.push('##PE_STACK_END##'); + return buffer.join(''); +}; + + +/** + * Get the index for a function. Used for internal indexing. + * @param {boolean} wrapper True for the wrapper; false for the wrapped. + * @return {string} The index where we should store the function in its + * wrapper/wrapped function. + * @private + */ +goog.debug.ErrorHandler.prototype.getFunctionIndex_ = function(wrapper) { + return (wrapper ? '__wrapper_' : '__protected_') + goog.getUid(this) + '__'; +}; + + +/** + * Installs exception protection for an entry point function. When an exception + * is thrown from a protected function, a handler will be invoked to handle it. + * + * @param {Function} fn An entry point function to be protected. + * @return {!Function} A protected wrapper function that calls the entry point + * function. + */ +goog.debug.ErrorHandler.prototype.protectEntryPoint = function(fn) { + var protectedFnName = this.getFunctionIndex_(true); + if (!fn[protectedFnName]) { + var wrapper = fn[protectedFnName] = this.getProtectedFunction(fn); + wrapper[this.getFunctionIndex_(false)] = fn; + } + return fn[protectedFnName]; +}; + + +/** + * Helps {@link #protectEntryPoint} by actually creating the protected + * wrapper function, after {@link #protectEntryPoint} determines that one does + * not already exist for the given function. Can be overriden by subclasses + * that may want to implement different error handling, or add additional + * entry point hooks. + * @param {!Function} fn An entry point function to be protected. + * @return {!Function} protected wrapper function. + * @protected + */ +goog.debug.ErrorHandler.prototype.getProtectedFunction = function(fn) { + var that = this; + var tracers = this.addTracersToProtectedFunctions_; + if (tracers) { + var stackTrace = goog.debug.getStacktraceSimple(15); + } + var googDebugErrorHandlerProtectedFunction = function() { + if (that.isDisposed()) { + return fn.apply(this, arguments); + } + + if (tracers) { + var tracer = goog.debug.Trace.startTracer('protectedEntryPoint: ' + + that.getStackTraceHolder_(stackTrace)); + } + try { + return fn.apply(this, arguments); + } catch (e) { + that.errorHandlerFn_(e); + if (!that.wrapErrors_) { + // Add the prefix to the existing message. + if (that.prefixErrorMessages_) { + if (typeof e === 'object') { + e.message = + goog.debug.ErrorHandler.ProtectedFunctionError.MESSAGE_PREFIX + + e.message; + } else { + e = goog.debug.ErrorHandler.ProtectedFunctionError.MESSAGE_PREFIX + + e; + } + } + if (goog.DEBUG) { + // Work around for https://code.google.com/p/v8/issues/detail?id=2625 + // and https://code.google.com/p/chromium/issues/detail?id=237059 + // Custom errors and errors with custom stack traces show the wrong + // stack trace + // If it has a stack and Error.captureStackTrace is supported (only + // supported in V8 as of May 2013) log the stack to the console. + if (e && e.stack && Error.captureStackTrace && + goog.global['console']) { + goog.global['console']['error'](e.message, e.stack); + } + } + // Re-throw original error. This is great for debugging as it makes + // browser JS dev consoles show the correct error and stack trace. + throw e; + } + // Re-throw it since this may be expected by the caller. + throw new goog.debug.ErrorHandler.ProtectedFunctionError(e); + } finally { + if (tracers) { + goog.debug.Trace.stopTracer(tracer); + } + } + }; + googDebugErrorHandlerProtectedFunction[this.getFunctionIndex_(false)] = fn; + return googDebugErrorHandlerProtectedFunction; +}; + + +// TODO(mknichel): Allow these functions to take in the window to protect. +/** + * Installs exception protection for window.setTimeout to handle exceptions. + */ +goog.debug.ErrorHandler.prototype.protectWindowSetTimeout = + function() { + this.protectWindowFunctionsHelper_('setTimeout'); +}; + + +/** + * Install exception protection for window.setInterval to handle exceptions. + */ +goog.debug.ErrorHandler.prototype.protectWindowSetInterval = + function() { + this.protectWindowFunctionsHelper_('setInterval'); +}; + + +/** + * Install exception protection for window.requestAnimationFrame to handle + * exceptions. + */ +goog.debug.ErrorHandler.prototype.protectWindowRequestAnimationFrame = + function() { + var win = goog.getObjectByName('window'); + var fnNames = [ + 'requestAnimationFrame', + 'mozRequestAnimationFrame', + 'webkitAnimationFrame', + 'msRequestAnimationFrame' + ]; + for (var i = 0; i < fnNames.length; i++) { + var fnName = fnNames[i]; + if (fnNames[i] in win) { + this.protectWindowFunctionsHelper_(fnName); + } + } +}; + + +/** + * Helper function for protecting a function that causes a function to be + * asynchronously called, for example setTimeout or requestAnimationFrame. + * @param {string} fnName The name of the function to protect. + * @private + */ +goog.debug.ErrorHandler.prototype.protectWindowFunctionsHelper_ = + function(fnName) { + var win = goog.getObjectByName('window'); + var originalFn = win[fnName]; + var that = this; + win[fnName] = function(fn, time) { + // Don't try to protect strings. In theory, we could try to globalEval + // the string, but this seems to lead to permission errors on IE6. + if (goog.isString(fn)) { + fn = goog.partial(goog.globalEval, fn); + } + fn = that.protectEntryPoint(fn); + + // IE doesn't support .call for setInterval/setTimeout, but it + // also doesn't care what "this" is, so we can just call the + // original function directly + if (originalFn.call) { + return originalFn.call(this, fn, time); + } else { + return originalFn(fn, time); + } + }; + win[fnName][this.getFunctionIndex_(false)] = originalFn; +}; + + +/** + * Set whether to wrap errors that occur in protected functions in a + * goog.debug.ErrorHandler.ProtectedFunctionError. + * @param {boolean} wrapErrors Whether to wrap errors. + */ +goog.debug.ErrorHandler.prototype.setWrapErrors = function(wrapErrors) { + this.wrapErrors_ = wrapErrors; +}; + + +/** + * Set whether to add a prefix to all error messages that occur in protected + * functions. + * @param {boolean} prefixErrorMessages Whether to add a prefix to error + * messages. + */ +goog.debug.ErrorHandler.prototype.setPrefixErrorMessages = + function(prefixErrorMessages) { + this.prefixErrorMessages_ = prefixErrorMessages; +}; + + +/** @override */ +goog.debug.ErrorHandler.prototype.disposeInternal = function() { + // Try to unwrap window.setTimeout and window.setInterval. + var win = goog.getObjectByName('window'); + win.setTimeout = this.unwrap(win.setTimeout); + win.setInterval = this.unwrap(win.setInterval); + + goog.debug.ErrorHandler.base(this, 'disposeInternal'); +}; + + + +/** + * Error thrown to the caller of a protected entry point if the entry point + * throws an error. + * @param {*} cause The error thrown by the entry point. + * @constructor + * @extends {goog.debug.Error} + * @final + */ +goog.debug.ErrorHandler.ProtectedFunctionError = function(cause) { + var message = goog.debug.ErrorHandler.ProtectedFunctionError.MESSAGE_PREFIX + + (cause && cause.message ? String(cause.message) : String(cause)); + goog.debug.ErrorHandler.ProtectedFunctionError.base( + this, 'constructor', message); + + /** + * The error thrown by the entry point. + * @type {*} + */ + this.cause = cause; + + var stack = cause && cause.stack; + if (stack && goog.isString(stack)) { + this.stack = /** @type {string} */ (stack); + } +}; +goog.inherits(goog.debug.ErrorHandler.ProtectedFunctionError, goog.debug.Error); + + +/** + * Text to prefix the message with. + * @type {string} + */ +goog.debug.ErrorHandler.ProtectedFunctionError.MESSAGE_PREFIX = + 'Error in protected function: '; http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/debug/errorhandlerweakdep.js ---------------------------------------------------------------------- diff --git a/externs/GCL/externs/goog/debug/errorhandlerweakdep.js b/externs/GCL/externs/goog/debug/errorhandlerweakdep.js new file mode 100644 index 0000000..284ddb0 --- /dev/null +++ b/externs/GCL/externs/goog/debug/errorhandlerweakdep.js @@ -0,0 +1,38 @@ +// Copyright 2008 The Closure Library Authors. All Rights Reserved. +// +// 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. + +/** + * @fileoverview File which defines dummy object to work around undefined + * properties compiler warning for weak dependencies on + * {@link goog.debug.ErrorHandler#protectEntryPoint}. + * + */ + +goog.provide('goog.debug.errorHandlerWeakDep'); + + +/** + * Dummy object to work around undefined properties compiler warning. + * @type {!Object<string,Function>} + */ +goog.debug.errorHandlerWeakDep = { + /** + * @param {Function} fn An entry point function to be protected. + * @param {boolean=} opt_tracers Whether to install tracers around the + * fn. + * @return {Function} A protected wrapper function that calls the + * entry point function. + */ + protectEntryPoint: function(fn, opt_tracers) { return fn; } +};
