Update wmts-hidpi, add nicer-api-docs
This commit is contained in:
207
nicer-api-docs/closure-library/closure/goog/debug/console.js
Normal file
207
nicer-api-docs/closure-library/closure/goog/debug/console.js
Normal file
@@ -0,0 +1,207 @@
|
||||
// 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 to the window console if available.
|
||||
*
|
||||
* Has an autoInstall option which can be put into initialization code, which
|
||||
* will start logging if "Debug=true" is in document.location.href
|
||||
*
|
||||
*/
|
||||
|
||||
goog.provide('goog.debug.Console');
|
||||
|
||||
goog.require('goog.debug.LogManager');
|
||||
goog.require('goog.debug.Logger.Level');
|
||||
goog.require('goog.debug.TextFormatter');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Create and install a log handler that logs to window.console if available
|
||||
* @constructor
|
||||
*/
|
||||
goog.debug.Console = function() {
|
||||
this.publishHandler_ = goog.bind(this.addLogRecord, this);
|
||||
|
||||
/**
|
||||
* Formatter for formatted output.
|
||||
* @type {!goog.debug.TextFormatter}
|
||||
* @private
|
||||
*/
|
||||
this.formatter_ = new goog.debug.TextFormatter();
|
||||
this.formatter_.showAbsoluteTime = false;
|
||||
this.formatter_.showExceptionText = false;
|
||||
|
||||
this.isCapturing_ = false;
|
||||
this.logBuffer_ = '';
|
||||
|
||||
/**
|
||||
* Loggers that we shouldn't output.
|
||||
* @type {!Object.<boolean>}
|
||||
* @private
|
||||
*/
|
||||
this.filteredLoggers_ = {};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the text formatter used by this console
|
||||
* @return {!goog.debug.TextFormatter} The text formatter.
|
||||
*/
|
||||
goog.debug.Console.prototype.getFormatter = function() {
|
||||
return this.formatter_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets whether we are currently capturing logger output.
|
||||
* @param {boolean} capturing Whether to capture logger output.
|
||||
*/
|
||||
goog.debug.Console.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.Console.prototype.addLogRecord = function(logRecord) {
|
||||
|
||||
// Check to see if the log record is filtered or not.
|
||||
if (this.filteredLoggers_[logRecord.getLoggerName()]) {
|
||||
return;
|
||||
}
|
||||
|
||||
var record = this.formatter_.formatRecord(logRecord);
|
||||
var console = goog.debug.Console.console_;
|
||||
if (console) {
|
||||
switch (logRecord.getLevel()) {
|
||||
case goog.debug.Logger.Level.SHOUT:
|
||||
goog.debug.Console.logToConsole_(console, 'info', record);
|
||||
break;
|
||||
case goog.debug.Logger.Level.SEVERE:
|
||||
goog.debug.Console.logToConsole_(console, 'error', record);
|
||||
break;
|
||||
case goog.debug.Logger.Level.WARNING:
|
||||
goog.debug.Console.logToConsole_(console, 'warn', record);
|
||||
break;
|
||||
default:
|
||||
goog.debug.Console.logToConsole_(console, 'debug', record);
|
||||
break;
|
||||
}
|
||||
} else if (window.opera) {
|
||||
// window.opera.postError is considered an undefined property reference
|
||||
// by JSCompiler, so it has to be referenced using array notation instead.
|
||||
window.opera['postError'](record);
|
||||
} else {
|
||||
this.logBuffer_ += record;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Adds a logger name to be filtered.
|
||||
* @param {string} loggerName the logger name to add.
|
||||
*/
|
||||
goog.debug.Console.prototype.addFilter = function(loggerName) {
|
||||
this.filteredLoggers_[loggerName] = true;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Removes a logger name to be filtered.
|
||||
* @param {string} loggerName the logger name to remove.
|
||||
*/
|
||||
goog.debug.Console.prototype.removeFilter = function(loggerName) {
|
||||
delete this.filteredLoggers_[loggerName];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Global console logger instance
|
||||
* @type {goog.debug.Console}
|
||||
*/
|
||||
goog.debug.Console.instance = null;
|
||||
|
||||
|
||||
/**
|
||||
* The console to which to log. This is a property so it can be mocked out in
|
||||
* this unit test for goog.debug.Console.
|
||||
* @type {Object}
|
||||
* @private
|
||||
*/
|
||||
goog.debug.Console.console_ = window.console;
|
||||
|
||||
|
||||
/**
|
||||
* Sets the console to which to log.
|
||||
* @param {!Object} console The console to which to log.
|
||||
*/
|
||||
goog.debug.Console.setConsole = function(console) {
|
||||
goog.debug.Console.console_ = console;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Install the console and start capturing if "Debug=true" is in the page URL
|
||||
*/
|
||||
goog.debug.Console.autoInstall = function() {
|
||||
if (!goog.debug.Console.instance) {
|
||||
goog.debug.Console.instance = new goog.debug.Console();
|
||||
}
|
||||
|
||||
if (window.location.href.indexOf('Debug=true') != -1) {
|
||||
goog.debug.Console.instance.setCapturing(true);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Show an alert with all of the captured debug information.
|
||||
* Information is only captured if console is not available
|
||||
*/
|
||||
goog.debug.Console.show = function() {
|
||||
alert(goog.debug.Console.instance.logBuffer_);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Logs the record to the console using the given function. If the function is
|
||||
* not available on the console object, the log function is used instead.
|
||||
* @param {!Object} console The console object.
|
||||
* @param {string} fnName The name of the function to use.
|
||||
* @param {string} record The record to log.
|
||||
* @private
|
||||
*/
|
||||
goog.debug.Console.logToConsole_ = function(console, fnName, record) {
|
||||
if (console[fnName]) {
|
||||
console[fnName](record);
|
||||
} else {
|
||||
console.log(record);
|
||||
}
|
||||
};
|
||||
501
nicer-api-docs/closure-library/closure/goog/debug/debug.js
Normal file
501
nicer-api-docs/closure-library/closure/goog/debug/debug.js
Normal file
@@ -0,0 +1,501 @@
|
||||
// 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.string');
|
||||
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;
|
||||
}
|
||||
target.onerror = function(message, url, line) {
|
||||
if (oldErrorHandler) {
|
||||
oldErrorHandler(message, url, line);
|
||||
}
|
||||
logFunc({
|
||||
message: message,
|
||||
fileName: url,
|
||||
line: line
|
||||
});
|
||||
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 previous = new goog.structs.Set();
|
||||
var str = [];
|
||||
|
||||
var helper = function(obj, space) {
|
||||
var nestspace = space + ' ';
|
||||
|
||||
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 (previous.contains(obj)) {
|
||||
// TODO(user): This is a bug; it falsely detects non-loops as loops
|
||||
// when the reference tree contains two references to the same object.
|
||||
str.push('*** reference loop detected ***');
|
||||
} else {
|
||||
previous.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);
|
||||
}
|
||||
str.push('\n' + space + '}');
|
||||
}
|
||||
} else {
|
||||
str.push(obj);
|
||||
}
|
||||
} catch (e) {
|
||||
str.push('*** ' + e + ' ***');
|
||||
}
|
||||
};
|
||||
|
||||
helper(obj, '');
|
||||
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 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.
|
||||
*/
|
||||
goog.debug.exposeException = function(err, opt_fn) {
|
||||
/** @preserveTry */
|
||||
try {
|
||||
var e = goog.debug.normalizeErrorObject(err);
|
||||
|
||||
// Create the error message
|
||||
var error = 'Message: ' + goog.string.htmlEscape(e.message) +
|
||||
'\nUrl: <a href="view-source:' + e.fileName + '" target="_new">' +
|
||||
e.fileName + '</a>\nLine: ' + e.lineNumber + '\n\nBrowser stack:\n' +
|
||||
goog.string.htmlEscape(e.stack + '-> ') +
|
||||
'[end]\n\nJS stack traversal:\n' + goog.string.htmlEscape(
|
||||
goog.debug.getStacktrace(opt_fn) + '-> ');
|
||||
return error;
|
||||
} catch (e2) {
|
||||
return 'Exception trying to expose exception! You win, we lose. ' + e2;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* 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 = typeof err == 'string' ? Error(err) : err;
|
||||
if (!error.stack) {
|
||||
error.stack = goog.debug.getStacktrace(arguments.callee.caller);
|
||||
}
|
||||
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.
|
||||
*/
|
||||
goog.debug.getStacktraceSimple = function(opt_depth) {
|
||||
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;
|
||||
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
goog.debug.getStacktrace = function(opt_fn) {
|
||||
return goog.debug.getStacktraceHelper_(opt_fn || arguments.callee.caller, []);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Private helper for getStacktrace().
|
||||
* @param {Function} fn Function to start getting the trace from.
|
||||
* @param {Array} visited List of functions visited so far.
|
||||
* @return {string} Stack trace starting from function fn.
|
||||
* @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;
|
||||
for (var i = 0; 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]');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* 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_;
|
||||
615
nicer-api-docs/closure-library/closure/goog/debug/debugwindow.js
Normal file
615
nicer-api-docs/closure-library/closure/goog/debug/debugwindow.js
Normal file
@@ -0,0 +1,615 @@
|
||||
// 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.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}
|
||||
*/
|
||||
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_('<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_.formatRecord(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 {string} 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 {string} 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;
|
||||
|
||||
this.win.document.write(this.outputBuffer.join(''));
|
||||
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 (!this.showedBlockedAlert_) {
|
||||
// only show this once
|
||||
alert('Logger popup was blocked');
|
||||
this.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 {string} The style rule text, for inclusion in the initial HTML.
|
||||
*/
|
||||
goog.debug.DebugWindow.prototype.getStyleRules = function() {
|
||||
return '*{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 html = '<style>' + this.getStyleRules() + '</style>' +
|
||||
'<hr><div class="dbg-ev" style="text-align:center">' +
|
||||
this.welcomeMessage + '<br><small>Logger: ' +
|
||||
this.identifier + '</small></div><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);
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,444 @@
|
||||
// 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.cssom');
|
||||
goog.require('goog.dom.classes');
|
||||
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
|
||||
*/
|
||||
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;
|
||||
|
||||
/**
|
||||
* @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));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @type {Object}
|
||||
* @private
|
||||
*/
|
||||
goog.debug.DevCss.prototype.userAgentTokens_ = {};
|
||||
|
||||
|
||||
/**
|
||||
* 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('*');
|
||||
var matches = [];
|
||||
// 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.classes.has(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++) {
|
||||
if (!goog.dom.classes.has(el, classNameEntry.combinedClassName)) {
|
||||
goog.dom.classes.add(el, classNameEntry.combinedClassName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -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();
|
||||
})();
|
||||
141
nicer-api-docs/closure-library/closure/goog/debug/divconsole.js
Normal file
141
nicer-api-docs/closure-library/closure/goog/debug/divconsole.js
Normal file
@@ -0,0 +1,141 @@
|
||||
// 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.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) {
|
||||
var scroll = this.element_.scrollHeight - this.element_.scrollTop -
|
||||
this.element_.clientHeight <= 100;
|
||||
|
||||
var div = this.elementOwnerDocument_.createElement('div');
|
||||
div.className = 'logmsg';
|
||||
div.innerHTML = this.formatter_.formatRecord(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.Formatter} 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('div');
|
||||
div.className = 'logmsg logsep';
|
||||
this.element_.appendChild(div);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Clears the console.
|
||||
*/
|
||||
goog.debug.DivConsole.prototype.clear = function() {
|
||||
this.element_.innerHTML = '';
|
||||
};
|
||||
@@ -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 nicksantos@google.com (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--;
|
||||
};
|
||||
51
nicer-api-docs/closure-library/closure/goog/debug/error.js
Normal file
51
nicer-api-docs/closure-library/closure/goog/debug/error.js
Normal file
@@ -0,0 +1,51 @@
|
||||
// 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) {
|
||||
|
||||
// Ensure there is a stack trace.
|
||||
if (Error.captureStackTrace) {
|
||||
Error.captureStackTrace(this, goog.debug.Error);
|
||||
} else {
|
||||
this.stack = new Error().stack || '';
|
||||
}
|
||||
|
||||
if (opt_msg) {
|
||||
this.message = String(opt_msg);
|
||||
}
|
||||
};
|
||||
goog.inherits(goog.debug.Error, Error);
|
||||
|
||||
|
||||
/** @override */
|
||||
goog.debug.Error.prototype.name = 'CustomError';
|
||||
@@ -0,0 +1,363 @@
|
||||
// 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.asserts');
|
||||
goog.require('goog.debug');
|
||||
goog.require('goog.debug.EntryPointMonitor');
|
||||
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.base(this);
|
||||
|
||||
/**
|
||||
* 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(user): 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) {
|
||||
win[fnName] = this.protectEntryPoint(win[fnName]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Helper function for protecting setTimeout/setInterval.
|
||||
* @param {string} fnName The name of the function we're protecting. Must
|
||||
* be setTimeout or setInterval.
|
||||
* @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.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}
|
||||
*/
|
||||
goog.debug.ErrorHandler.ProtectedFunctionError = function(cause) {
|
||||
var message = goog.debug.ErrorHandler.ProtectedFunctionError.MESSAGE_PREFIX +
|
||||
(cause && cause.message ? String(cause.message) : String(cause));
|
||||
goog.base(this, 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: ';
|
||||
@@ -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}
|
||||
*/
|
||||
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; }
|
||||
};
|
||||
@@ -0,0 +1,376 @@
|
||||
// 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 Definition of the ErrorReporter class, which creates an error
|
||||
* handler that reports any errors raised to a URL.
|
||||
*
|
||||
*/
|
||||
|
||||
goog.provide('goog.debug.ErrorReporter');
|
||||
goog.provide('goog.debug.ErrorReporter.ExceptionEvent');
|
||||
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.debug');
|
||||
goog.require('goog.debug.ErrorHandler');
|
||||
goog.require('goog.debug.entryPointRegistry');
|
||||
goog.require('goog.events');
|
||||
goog.require('goog.events.Event');
|
||||
goog.require('goog.events.EventTarget');
|
||||
goog.require('goog.log');
|
||||
goog.require('goog.net.XhrIo');
|
||||
goog.require('goog.object');
|
||||
goog.require('goog.string');
|
||||
goog.require('goog.uri.utils');
|
||||
goog.require('goog.userAgent');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Constructs an error reporter. Internal Use Only. To install an error
|
||||
* reporter see the {@see #install} method below.
|
||||
*
|
||||
* @param {string} handlerUrl The URL to which all errors will be reported.
|
||||
* @param {function(!Error, !Object.<string, string>)=}
|
||||
* opt_contextProvider When a report is to be sent to the server,
|
||||
* this method will be called, and given an opportunity to modify the
|
||||
* context object before submission to the server.
|
||||
* @param {boolean=} opt_noAutoProtect Whether to automatically add handlers for
|
||||
* onerror and to protect entry points. If apps have other error reporting
|
||||
* facilities, it may make sense for them to set these up themselves and use
|
||||
* the ErrorReporter just for transmission of reports.
|
||||
* @constructor
|
||||
* @extends {goog.events.EventTarget}
|
||||
*/
|
||||
goog.debug.ErrorReporter = function(
|
||||
handlerUrl, opt_contextProvider, opt_noAutoProtect) {
|
||||
goog.base(this);
|
||||
|
||||
/**
|
||||
* Context provider, if one was provided.
|
||||
* @type {?function(!Error, !Object.<string, string>)}
|
||||
* @private
|
||||
*/
|
||||
this.contextProvider_ = opt_contextProvider || null;
|
||||
|
||||
/**
|
||||
* The string prefix of any optional context parameters logged with the error.
|
||||
* @private {string}
|
||||
*/
|
||||
this.contextPrefix_ = 'context.';
|
||||
|
||||
/**
|
||||
* The number of bytes after which the ErrorReporter truncates the POST body.
|
||||
* If null, the ErrorReporter won't truncate the body.
|
||||
* @private {?number}
|
||||
*/
|
||||
this.truncationLimit_ = null;
|
||||
|
||||
/**
|
||||
* XHR sender.
|
||||
* @type {function(string, string, string, (Object|goog.structs.Map)=)}
|
||||
* @private
|
||||
*/
|
||||
this.xhrSender_ = goog.debug.ErrorReporter.defaultXhrSender;
|
||||
|
||||
/**
|
||||
* The URL at which all errors caught by this handler will be logged.
|
||||
*
|
||||
* @type {string}
|
||||
* @private
|
||||
*/
|
||||
this.handlerUrl_ = handlerUrl;
|
||||
|
||||
if (!opt_noAutoProtect) {
|
||||
this.setup_();
|
||||
}
|
||||
};
|
||||
goog.inherits(goog.debug.ErrorReporter, goog.events.EventTarget);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Event broadcast when an exception is logged.
|
||||
* @param {Error} error The exception that was was reported.
|
||||
* @param {!Object.<string, string>} context The context values sent to the
|
||||
* server alongside this error.
|
||||
* @constructor
|
||||
* @extends {goog.events.Event}
|
||||
*/
|
||||
goog.debug.ErrorReporter.ExceptionEvent = function(error, context) {
|
||||
goog.events.Event.call(this, goog.debug.ErrorReporter.ExceptionEvent.TYPE);
|
||||
|
||||
/**
|
||||
* The error that was reported.
|
||||
* @type {Error}
|
||||
*/
|
||||
this.error = error;
|
||||
|
||||
/**
|
||||
* Context values sent to the server alongside this report.
|
||||
* @type {!Object.<string, string>}
|
||||
*/
|
||||
this.context = context;
|
||||
};
|
||||
goog.inherits(goog.debug.ErrorReporter.ExceptionEvent, goog.events.Event);
|
||||
|
||||
|
||||
/**
|
||||
* Event type for notifying of a logged exception.
|
||||
* @type {string}
|
||||
*/
|
||||
goog.debug.ErrorReporter.ExceptionEvent.TYPE =
|
||||
goog.events.getUniqueId('exception');
|
||||
|
||||
|
||||
/**
|
||||
* The internal error handler used to catch all errors.
|
||||
*
|
||||
* @type {goog.debug.ErrorHandler}
|
||||
* @private
|
||||
*/
|
||||
goog.debug.ErrorReporter.prototype.errorHandler_ = null;
|
||||
|
||||
|
||||
/**
|
||||
* Extra headers for the error-reporting XHR.
|
||||
* @type {Object|goog.structs.Map|undefined}
|
||||
* @private
|
||||
*/
|
||||
goog.debug.ErrorReporter.prototype.extraHeaders_;
|
||||
|
||||
|
||||
/**
|
||||
* Logging object.
|
||||
*
|
||||
* @type {goog.log.Logger}
|
||||
* @private
|
||||
*/
|
||||
goog.debug.ErrorReporter.logger_ =
|
||||
goog.log.getLogger('goog.debug.ErrorReporter');
|
||||
|
||||
|
||||
/**
|
||||
* Installs an error reporter to catch all JavaScript errors raised.
|
||||
*
|
||||
* @param {string} loggingUrl The URL to which the errors caught will be
|
||||
* reported.
|
||||
* @param {function(!Error, !Object.<string, string>)=}
|
||||
* opt_contextProvider When a report is to be sent to the server,
|
||||
* this method will be called, and given an opportunity to modify the
|
||||
* context object before submission to the server.
|
||||
* @param {boolean=} opt_noAutoProtect Whether to automatically add handlers for
|
||||
* onerror and to protect entry points. If apps have other error reporting
|
||||
* facilities, it may make sense for them to set these up themselves and use
|
||||
* the ErrorReporter just for transmission of reports.
|
||||
* @return {goog.debug.ErrorReporter} The error reporter.
|
||||
*/
|
||||
goog.debug.ErrorReporter.install = function(
|
||||
loggingUrl, opt_contextProvider, opt_noAutoProtect) {
|
||||
var instance = new goog.debug.ErrorReporter(
|
||||
loggingUrl, opt_contextProvider, opt_noAutoProtect);
|
||||
return instance;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Default implemntation of XHR sender interface.
|
||||
*
|
||||
* @param {string} uri URI to make request to.
|
||||
* @param {string} method Send method.
|
||||
* @param {string} content Post data.
|
||||
* @param {Object|goog.structs.Map=} opt_headers Map of headers to add to the
|
||||
* request.
|
||||
*/
|
||||
goog.debug.ErrorReporter.defaultXhrSender = function(uri, method, content,
|
||||
opt_headers) {
|
||||
goog.net.XhrIo.send(uri, null, method, content, opt_headers);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Installs exception protection for an entry point function in addition
|
||||
* to those that are protected by default.
|
||||
* Has no effect in IE because window.onerror is used for reporting
|
||||
* exceptions in that case.
|
||||
*
|
||||
* @param {Function} fn An entry point function to be protected.
|
||||
* @return {Function} A protected wrapper function that calls the entry point
|
||||
* function or null if the entry point could not be protected.
|
||||
*/
|
||||
goog.debug.ErrorReporter.prototype.protectAdditionalEntryPoint = function(fn) {
|
||||
if (this.errorHandler_) {
|
||||
return this.errorHandler_.protectEntryPoint(fn);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Add headers to the logging url.
|
||||
* @param {Object|goog.structs.Map} loggingHeaders Extra headers to send
|
||||
* to the logging URL.
|
||||
*/
|
||||
goog.debug.ErrorReporter.prototype.setLoggingHeaders =
|
||||
function(loggingHeaders) {
|
||||
this.extraHeaders_ = loggingHeaders;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Set the function used to send error reports to the server.
|
||||
* @param {function(string, string, string, (Object|goog.structs.Map)=)}
|
||||
* xhrSender If provided, this will be used to send a report to the
|
||||
* server instead of the default method. The function will be given the URI,
|
||||
* HTTP method request content, and (optionally) request headers to be
|
||||
* added.
|
||||
*/
|
||||
goog.debug.ErrorReporter.prototype.setXhrSender = function(xhrSender) {
|
||||
this.xhrSender_ = xhrSender;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets up the error reporter.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
goog.debug.ErrorReporter.prototype.setup_ = function() {
|
||||
if (goog.userAgent.IE) {
|
||||
// Use "onerror" because caught exceptions in IE don't provide line number.
|
||||
goog.debug.catchErrors(
|
||||
goog.bind(this.handleException, this), false, null);
|
||||
} else {
|
||||
// "onerror" doesn't work with FF2 or Chrome
|
||||
this.errorHandler_ = new goog.debug.ErrorHandler(
|
||||
goog.bind(this.handleException, this));
|
||||
|
||||
this.errorHandler_.protectWindowSetTimeout();
|
||||
this.errorHandler_.protectWindowSetInterval();
|
||||
goog.debug.entryPointRegistry.monitorAll(this.errorHandler_);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Handler for caught exceptions. Sends report to the LoggingServlet and
|
||||
* notifies any listeners.
|
||||
*
|
||||
* @param {Object} e The exception.
|
||||
* @param {!Object.<string, string>=} opt_context Context values to optionally
|
||||
* include in the error report.
|
||||
*/
|
||||
goog.debug.ErrorReporter.prototype.handleException = function(e,
|
||||
opt_context) {
|
||||
var error = /** @type {!Error} */ (goog.debug.normalizeErrorObject(e));
|
||||
|
||||
// Construct the context, possibly from the one provided in the argument, and
|
||||
// pass it to the context provider if there is one.
|
||||
var context = opt_context ? goog.object.clone(opt_context) : {};
|
||||
if (this.contextProvider_) {
|
||||
try {
|
||||
this.contextProvider_(error, context);
|
||||
} catch (err) {
|
||||
goog.log.error(goog.debug.ErrorReporter.logger_,
|
||||
'Context provider threw an exception: ' + err.message);
|
||||
}
|
||||
}
|
||||
// Truncate message to a reasonable length, since it will be sent in the URL.
|
||||
var message = error.message.substring(0, 2000);
|
||||
this.sendErrorReport(message, error.fileName, error.lineNumber, error.stack,
|
||||
context);
|
||||
|
||||
try {
|
||||
this.dispatchEvent(
|
||||
new goog.debug.ErrorReporter.ExceptionEvent(error, context));
|
||||
} catch (ex) {
|
||||
// Swallow exception to avoid infinite recursion.
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sends an error report to the logging URL. This will not consult the context
|
||||
* provider, the report will be sent exactly as specified.
|
||||
*
|
||||
* @param {string} message Error description.
|
||||
* @param {string} fileName URL of the JavaScript file with the error.
|
||||
* @param {number} line Line number of the error.
|
||||
* @param {string=} opt_trace Call stack trace of the error.
|
||||
* @param {!Object.<string, string>=} opt_context Context information to include
|
||||
* in the request.
|
||||
*/
|
||||
goog.debug.ErrorReporter.prototype.sendErrorReport =
|
||||
function(message, fileName, line, opt_trace, opt_context) {
|
||||
try {
|
||||
// Create the logging URL.
|
||||
var requestUrl = goog.uri.utils.appendParams(this.handlerUrl_,
|
||||
'script', fileName, 'error', message, 'line', line);
|
||||
var queryMap = {};
|
||||
queryMap['trace'] = opt_trace;
|
||||
|
||||
// Copy context into query data map
|
||||
if (opt_context) {
|
||||
for (var entry in opt_context) {
|
||||
queryMap[this.contextPrefix_ + entry] = opt_context[entry];
|
||||
}
|
||||
}
|
||||
|
||||
// Copy query data map into request.
|
||||
var queryData = goog.uri.utils.buildQueryDataFromMap(queryMap);
|
||||
|
||||
// Truncate if truncationLimit set.
|
||||
if (goog.isNumber(this.truncationLimit_)) {
|
||||
queryData = queryData.substring(0, this.truncationLimit_);
|
||||
}
|
||||
|
||||
// Send the request with the contents of the error.
|
||||
this.xhrSender_(requestUrl, 'POST', queryData, this.extraHeaders_);
|
||||
} catch (e) {
|
||||
var logMessage = goog.string.buildString(
|
||||
'Error occurred in sending an error report.\n\n',
|
||||
'script:', fileName, '\n',
|
||||
'line:', line, '\n',
|
||||
'error:', message, '\n',
|
||||
'trace:', opt_trace);
|
||||
goog.log.info(goog.debug.ErrorReporter.logger_, logMessage);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} prefix The prefix to appear prepended to all context
|
||||
* variables in the error report body.
|
||||
*/
|
||||
goog.debug.ErrorReporter.prototype.setContextPrefix = function(prefix) {
|
||||
this.contextPrefix_ = prefix;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {?number} limit Size in bytes to begin truncating POST body. Set to
|
||||
* null to prevent truncation. The limit must be >= 0.
|
||||
*/
|
||||
goog.debug.ErrorReporter.prototype.setTruncationLimit = function(limit) {
|
||||
goog.asserts.assert(!goog.isNumber(limit) || limit >= 0,
|
||||
'Body limit must be valid number >= 0 or null');
|
||||
this.truncationLimit_ = limit;
|
||||
};
|
||||
|
||||
|
||||
/** @override */
|
||||
goog.debug.ErrorReporter.prototype.disposeInternal = function() {
|
||||
goog.dispose(this.errorHandler_);
|
||||
goog.base(this, 'disposeInternal');
|
||||
};
|
||||
362
nicer-api-docs/closure-library/closure/goog/debug/fancywindow.js
Normal file
362
nicer-api-docs/closure-library/closure/goog/debug/fancywindow.js
Normal file
@@ -0,0 +1,362 @@
|
||||
// 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 FancyWindow 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.
|
||||
*
|
||||
* This is a pretty hacky implementation, aimed at making debugging of large
|
||||
* applications more manageable.
|
||||
*
|
||||
* @see ../demos/debug.html
|
||||
*/
|
||||
|
||||
|
||||
goog.provide('goog.debug.FancyWindow');
|
||||
|
||||
goog.require('goog.debug.DebugWindow');
|
||||
goog.require('goog.debug.LogManager');
|
||||
goog.require('goog.debug.Logger');
|
||||
goog.require('goog.dom.DomHelper');
|
||||
goog.require('goog.object');
|
||||
goog.require('goog.string');
|
||||
goog.require('goog.userAgent');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Provides a Fancy extension to the DebugWindow class. Allows filtering based
|
||||
* on loggers and levels.
|
||||
*
|
||||
* @param {string=} opt_identifier Idenitifier for this logging class.
|
||||
* @param {string=} opt_prefix Prefix pre-pended to messages.
|
||||
* @constructor
|
||||
* @extends {goog.debug.DebugWindow}
|
||||
*/
|
||||
goog.debug.FancyWindow = function(opt_identifier, opt_prefix) {
|
||||
this.readOptionsFromLocalStorage_();
|
||||
goog.base(this, opt_identifier, opt_prefix);
|
||||
};
|
||||
goog.inherits(goog.debug.FancyWindow, goog.debug.DebugWindow);
|
||||
|
||||
|
||||
/**
|
||||
* Constant indicating if we are able to use localStorage to persist filters
|
||||
* @type {boolean}
|
||||
*/
|
||||
goog.debug.FancyWindow.HAS_LOCAL_STORE = (function() {
|
||||
/** @preserveTry */
|
||||
try {
|
||||
return !!window['localStorage'].getItem;
|
||||
} catch (e) {}
|
||||
return false;
|
||||
})();
|
||||
|
||||
|
||||
/**
|
||||
* Constant defining the prefix to use when storing log levels
|
||||
* @type {string}
|
||||
*/
|
||||
goog.debug.FancyWindow.LOCAL_STORE_PREFIX = 'fancywindow.sel.';
|
||||
|
||||
|
||||
/** @override */
|
||||
goog.debug.FancyWindow.prototype.writeBufferToLog = function() {
|
||||
this.lastCall = goog.now();
|
||||
if (this.hasActiveWindow()) {
|
||||
var logel = this.dh_.getElement('log');
|
||||
|
||||
// Work out if scrolling is needed before we add the content
|
||||
var scroll =
|
||||
logel.scrollHeight - (logel.scrollTop + logel.offsetHeight) <= 100;
|
||||
|
||||
for (var i = 0; i < this.outputBuffer.length; i++) {
|
||||
var div = this.dh_.createDom('div', 'logmsg');
|
||||
div.innerHTML = this.outputBuffer[i];
|
||||
logel.appendChild(div);
|
||||
}
|
||||
this.outputBuffer.length = 0;
|
||||
this.resizeStuff_();
|
||||
|
||||
if (scroll) {
|
||||
logel.scrollTop = logel.scrollHeight;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/** @override */
|
||||
goog.debug.FancyWindow.prototype.writeInitialDocument = function() {
|
||||
if (!this.hasActiveWindow()) {
|
||||
return;
|
||||
}
|
||||
|
||||
var doc = this.win.document;
|
||||
doc.open();
|
||||
doc.write(this.getHtml_());
|
||||
doc.close();
|
||||
|
||||
(goog.userAgent.IE ? doc.body : this.win).onresize =
|
||||
goog.bind(this.resizeStuff_, this);
|
||||
|
||||
// Create a dom helper for the logging window
|
||||
this.dh_ = new goog.dom.DomHelper(doc);
|
||||
|
||||
// Don't use events system to reduce dependencies
|
||||
this.dh_.getElement('openbutton').onclick =
|
||||
goog.bind(this.openOptions_, this);
|
||||
this.dh_.getElement('closebutton').onclick =
|
||||
goog.bind(this.closeOptions_, this);
|
||||
this.dh_.getElement('clearbutton').onclick =
|
||||
goog.bind(this.clear, this);
|
||||
this.dh_.getElement('exitbutton').onclick =
|
||||
goog.bind(this.exit_, this);
|
||||
|
||||
this.writeSavedMessages();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Show the options menu.
|
||||
* @return {boolean} false.
|
||||
* @private
|
||||
*/
|
||||
goog.debug.FancyWindow.prototype.openOptions_ = function() {
|
||||
var el = this.dh_.getElement('optionsarea');
|
||||
el.innerHTML = '';
|
||||
|
||||
var loggers = goog.debug.FancyWindow.getLoggers_();
|
||||
var dh = this.dh_;
|
||||
for (var i = 0; i < loggers.length; i++) {
|
||||
var logger = goog.debug.Logger.getLogger(loggers[i]);
|
||||
var curlevel = logger.getLevel() ? logger.getLevel().name : 'INHERIT';
|
||||
var div = dh.createDom('div', {},
|
||||
this.getDropDown_('sel' + loggers[i], curlevel),
|
||||
dh.createDom('span', {}, loggers[i] || '(root)'));
|
||||
el.appendChild(div);
|
||||
}
|
||||
|
||||
this.dh_.getElement('options').style.display = 'block';
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Make a drop down for the log levels.
|
||||
* @param {string} id Logger id.
|
||||
* @param {string} selected What log level is currently selected.
|
||||
* @return {Element} The newly created 'select' DOM element.
|
||||
* @private
|
||||
*/
|
||||
goog.debug.FancyWindow.prototype.getDropDown_ = function(id, selected) {
|
||||
var dh = this.dh_;
|
||||
var sel = dh.createDom('select', {'id': id});
|
||||
var levels = goog.debug.Logger.Level.PREDEFINED_LEVELS;
|
||||
for (var i = 0; i < levels.length; i++) {
|
||||
var level = levels[i];
|
||||
var option = dh.createDom('option', {}, level.name);
|
||||
if (selected == level.name) {
|
||||
option.selected = true;
|
||||
}
|
||||
sel.appendChild(option);
|
||||
}
|
||||
sel.appendChild(dh.createDom('option',
|
||||
{'selected': selected == 'INHERIT'}, 'INHERIT'));
|
||||
return sel;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Close the options menu.
|
||||
* @return {boolean} The value false.
|
||||
* @private
|
||||
*/
|
||||
goog.debug.FancyWindow.prototype.closeOptions_ = function() {
|
||||
this.dh_.getElement('options').style.display = 'none';
|
||||
var loggers = goog.debug.FancyWindow.getLoggers_();
|
||||
var dh = this.dh_;
|
||||
for (var i = 0; i < loggers.length; i++) {
|
||||
var logger = goog.debug.Logger.getLogger(loggers[i]);
|
||||
var sel = dh.getElement('sel' + loggers[i]);
|
||||
var level = sel.options[sel.selectedIndex].text;
|
||||
if (level == 'INHERIT') {
|
||||
logger.setLevel(null);
|
||||
} else {
|
||||
logger.setLevel(goog.debug.Logger.Level.getPredefinedLevel(level));
|
||||
}
|
||||
}
|
||||
this.writeOptionsToLocalStorage_();
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Resize the lof elements
|
||||
* @private
|
||||
*/
|
||||
goog.debug.FancyWindow.prototype.resizeStuff_ = function() {
|
||||
var dh = this.dh_;
|
||||
var logel = dh.getElement('log');
|
||||
var headel = dh.getElement('head');
|
||||
logel.style.top = headel.offsetHeight + 'px';
|
||||
logel.style.height = (dh.getDocument().body.offsetHeight -
|
||||
headel.offsetHeight - (goog.userAgent.IE ? 4 : 0)) + 'px';
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Handles the user clicking the exit button, disabled the debug window and
|
||||
* closes the popup.
|
||||
* @param {Event} e Event object.
|
||||
* @private
|
||||
*/
|
||||
goog.debug.FancyWindow.prototype.exit_ = function(e) {
|
||||
this.setEnabled(false);
|
||||
if (this.win) {
|
||||
this.win.close();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/** @override */
|
||||
goog.debug.FancyWindow.prototype.getStyleRules = function() {
|
||||
return goog.base(this, 'getStyleRules') +
|
||||
'html,body{height:100%;width:100%;margin:0px;padding:0px;' +
|
||||
'background-color:#FFF;overflow:hidden}' +
|
||||
'*{}' +
|
||||
'.logmsg{border-bottom:1px solid #CCC;padding:2px;font:90% monospace}' +
|
||||
'#head{position:absolute;width:100%;font:x-small arial;' +
|
||||
'border-bottom:2px solid #999;background-color:#EEE;}' +
|
||||
'#head p{margin:0px 5px;}' +
|
||||
'#log{position:absolute;width:100%;background-color:#FFF;}' +
|
||||
'#options{position:absolute;right:0px;width:50%;height:100%;' +
|
||||
'border-left:1px solid #999;background-color:#DDD;display:none;' +
|
||||
'padding-left: 5px;font:normal small arial;overflow:auto;}' +
|
||||
'#openbutton,#closebutton{text-decoration:underline;color:#00F;cursor:' +
|
||||
'pointer;position:absolute;top:0px;right:5px;font:x-small arial;}' +
|
||||
'#clearbutton{text-decoration:underline;color:#00F;cursor:' +
|
||||
'pointer;position:absolute;top:0px;right:80px;font:x-small arial;}' +
|
||||
'#exitbutton{text-decoration:underline;color:#00F;cursor:' +
|
||||
'pointer;position:absolute;top:0px;right:50px;font:x-small arial;}' +
|
||||
'select{font:x-small arial;margin-right:10px;}' +
|
||||
'hr{border:0;height:5px;background-color:#8c8;color:#8c8;}';
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Return the default HTML for the debug window
|
||||
* @return {string} Html.
|
||||
* @private
|
||||
*/
|
||||
goog.debug.FancyWindow.prototype.getHtml_ = function() {
|
||||
return '' +
|
||||
'<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"' +
|
||||
'"http://www.w3.org/TR/html4/loose.dtd">' +
|
||||
'<html><head><title>Logging: ' + this.identifier + '</title>' +
|
||||
'<style>' + this.getStyleRules() + '</style>' +
|
||||
'</head><body>' +
|
||||
'<div id="log" style="overflow:auto"></div>' +
|
||||
'<div id="head">' +
|
||||
'<p><b>Logging: ' + this.identifier + '</b></p><p>' +
|
||||
this.welcomeMessage + '</p>' +
|
||||
'<span id="clearbutton">clear</span>' +
|
||||
'<span id="exitbutton">exit</span>' +
|
||||
'<span id="openbutton">options</span>' +
|
||||
'</div>' +
|
||||
'<div id="options">' +
|
||||
'<big><b>Options:</b></big>' +
|
||||
'<div id="optionsarea"></div>' +
|
||||
'<span id="closebutton">save and close</span>' +
|
||||
'</div>' +
|
||||
'</body></html>';
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Write logger levels to localStorage if possible.
|
||||
* @private
|
||||
*/
|
||||
goog.debug.FancyWindow.prototype.writeOptionsToLocalStorage_ = function() {
|
||||
if (!goog.debug.FancyWindow.HAS_LOCAL_STORE) {
|
||||
return;
|
||||
}
|
||||
var loggers = goog.debug.FancyWindow.getLoggers_();
|
||||
var storedKeys = goog.debug.FancyWindow.getStoredKeys_();
|
||||
for (var i = 0; i < loggers.length; i++) {
|
||||
var key = goog.debug.FancyWindow.LOCAL_STORE_PREFIX + loggers[i];
|
||||
var level = goog.debug.Logger.getLogger(loggers[i]).getLevel();
|
||||
if (key in storedKeys) {
|
||||
if (!level) {
|
||||
window.localStorage.removeItem(key);
|
||||
} else if (window.localStorage.getItem(key) != level.name) {
|
||||
window.localStorage.setItem(key, level.name);
|
||||
}
|
||||
} else if (level) {
|
||||
window.localStorage.setItem(key, level.name);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sync logger levels with any values stored in localStorage.
|
||||
* @private
|
||||
*/
|
||||
goog.debug.FancyWindow.prototype.readOptionsFromLocalStorage_ = function() {
|
||||
if (!goog.debug.FancyWindow.HAS_LOCAL_STORE) {
|
||||
return;
|
||||
}
|
||||
var storedKeys = goog.debug.FancyWindow.getStoredKeys_();
|
||||
for (var key in storedKeys) {
|
||||
var loggerName = key.replace(goog.debug.FancyWindow.LOCAL_STORE_PREFIX, '');
|
||||
var logger = goog.debug.Logger.getLogger(loggerName);
|
||||
var curLevel = logger.getLevel();
|
||||
var storedLevel = window.localStorage.getItem(key).toString();
|
||||
if (!curLevel || curLevel.toString() != storedLevel) {
|
||||
logger.setLevel(goog.debug.Logger.Level.getPredefinedLevel(storedLevel));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Helper function to create a list of locally stored keys. Used to avoid
|
||||
* expensive localStorage.getItem() calls.
|
||||
* @return {Object} List of keys.
|
||||
* @private
|
||||
*/
|
||||
goog.debug.FancyWindow.getStoredKeys_ = function() {
|
||||
var storedKeys = {};
|
||||
for (var i = 0, len = window.localStorage.length; i < len; i++) {
|
||||
var key = window.localStorage.key(i);
|
||||
if (key != null && goog.string.startsWith(
|
||||
key, goog.debug.FancyWindow.LOCAL_STORE_PREFIX)) {
|
||||
storedKeys[key] = true;
|
||||
}
|
||||
}
|
||||
return storedKeys;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Gets a sorted array of all the loggers registered
|
||||
* @return {Array} Array of logger idents, e.g. goog.net.XhrIo.
|
||||
* @private
|
||||
*/
|
||||
goog.debug.FancyWindow.getLoggers_ = function() {
|
||||
var loggers = goog.object.getKeys(goog.debug.LogManager.getLoggers());
|
||||
loggers.sort();
|
||||
return loggers;
|
||||
};
|
||||
316
nicer-api-docs/closure-library/closure/goog/debug/formatter.js
Normal file
316
nicer-api-docs/closure-library/closure/goog/debug/formatter.js
Normal file
@@ -0,0 +1,316 @@
|
||||
// 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 various formatters for logging. 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.Formatter');
|
||||
goog.provide('goog.debug.HtmlFormatter');
|
||||
goog.provide('goog.debug.TextFormatter');
|
||||
|
||||
goog.require('goog.debug.RelativeTimeProvider');
|
||||
goog.require('goog.string');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Base class for Formatters. A Formatter is used to format a LogRecord into
|
||||
* something that can be displayed to the user.
|
||||
*
|
||||
* @param {string=} opt_prefix The prefix to place before text records.
|
||||
* @constructor
|
||||
*/
|
||||
goog.debug.Formatter = function(opt_prefix) {
|
||||
this.prefix_ = opt_prefix || '';
|
||||
|
||||
/**
|
||||
* A provider that returns the relative start time.
|
||||
* @type {goog.debug.RelativeTimeProvider}
|
||||
* @private
|
||||
*/
|
||||
this.startTimeProvider_ =
|
||||
goog.debug.RelativeTimeProvider.getDefaultInstance();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Whether to show absolute time in the DebugWindow.
|
||||
* @type {boolean}
|
||||
*/
|
||||
goog.debug.Formatter.prototype.showAbsoluteTime = true;
|
||||
|
||||
|
||||
/**
|
||||
* Whether to show relative time in the DebugWindow.
|
||||
* @type {boolean}
|
||||
*/
|
||||
goog.debug.Formatter.prototype.showRelativeTime = true;
|
||||
|
||||
|
||||
/**
|
||||
* Whether to show the logger name in the DebugWindow.
|
||||
* @type {boolean}
|
||||
*/
|
||||
goog.debug.Formatter.prototype.showLoggerName = true;
|
||||
|
||||
|
||||
/**
|
||||
* Whether to show the logger exception text.
|
||||
* @type {boolean}
|
||||
*/
|
||||
goog.debug.Formatter.prototype.showExceptionText = false;
|
||||
|
||||
|
||||
/**
|
||||
* Whether to show the severity level.
|
||||
* @type {boolean}
|
||||
*/
|
||||
goog.debug.Formatter.prototype.showSeverityLevel = false;
|
||||
|
||||
|
||||
/**
|
||||
* Formats a record.
|
||||
* @param {goog.debug.LogRecord} logRecord the logRecord to format.
|
||||
* @return {string} The formatted string.
|
||||
*/
|
||||
goog.debug.Formatter.prototype.formatRecord = goog.abstractMethod;
|
||||
|
||||
|
||||
/**
|
||||
* Sets the start time provider. By default, this is the default instance
|
||||
* but can be changed.
|
||||
* @param {goog.debug.RelativeTimeProvider} provider The provider to use.
|
||||
*/
|
||||
goog.debug.Formatter.prototype.setStartTimeProvider = function(provider) {
|
||||
this.startTimeProvider_ = provider;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the start time provider. By default, this is the default instance
|
||||
* but can be changed.
|
||||
* @return {goog.debug.RelativeTimeProvider} The start time provider.
|
||||
*/
|
||||
goog.debug.Formatter.prototype.getStartTimeProvider = function() {
|
||||
return this.startTimeProvider_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Resets the start relative time.
|
||||
*/
|
||||
goog.debug.Formatter.prototype.resetRelativeTimeStart = function() {
|
||||
this.startTimeProvider_.reset();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns a string for the time/date of the LogRecord.
|
||||
* @param {goog.debug.LogRecord} logRecord The record to get a time stamp for.
|
||||
* @return {string} A string representation of the time/date of the LogRecord.
|
||||
* @private
|
||||
*/
|
||||
goog.debug.Formatter.getDateTimeStamp_ = function(logRecord) {
|
||||
var time = new Date(logRecord.getMillis());
|
||||
return goog.debug.Formatter.getTwoDigitString_((time.getFullYear() - 2000)) +
|
||||
goog.debug.Formatter.getTwoDigitString_((time.getMonth() + 1)) +
|
||||
goog.debug.Formatter.getTwoDigitString_(time.getDate()) + ' ' +
|
||||
goog.debug.Formatter.getTwoDigitString_(time.getHours()) + ':' +
|
||||
goog.debug.Formatter.getTwoDigitString_(time.getMinutes()) + ':' +
|
||||
goog.debug.Formatter.getTwoDigitString_(time.getSeconds()) + '.' +
|
||||
goog.debug.Formatter.getTwoDigitString_(
|
||||
Math.floor(time.getMilliseconds() / 10));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the number as a two-digit string, meaning it prepends a 0 if the
|
||||
* number if less than 10.
|
||||
* @param {number} n The number to format.
|
||||
* @return {string} A two-digit string representation of {@code n}.
|
||||
* @private
|
||||
*/
|
||||
goog.debug.Formatter.getTwoDigitString_ = function(n) {
|
||||
if (n < 10) {
|
||||
return '0' + n;
|
||||
}
|
||||
return String(n);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns a string for the number of seconds relative to the start time.
|
||||
* Prepads with spaces so that anything less than 1000 seconds takes up the
|
||||
* same number of characters for better formatting.
|
||||
* @param {goog.debug.LogRecord} logRecord The log to compare time to.
|
||||
* @param {number} relativeTimeStart The start time to compare to.
|
||||
* @return {string} The number of seconds of the LogRecord relative to the
|
||||
* start time.
|
||||
* @private
|
||||
*/
|
||||
goog.debug.Formatter.getRelativeTime_ = function(logRecord,
|
||||
relativeTimeStart) {
|
||||
var ms = logRecord.getMillis() - relativeTimeStart;
|
||||
var sec = ms / 1000;
|
||||
var str = sec.toFixed(3);
|
||||
|
||||
var spacesToPrepend = 0;
|
||||
if (sec < 1) {
|
||||
spacesToPrepend = 2;
|
||||
} else {
|
||||
while (sec < 100) {
|
||||
spacesToPrepend++;
|
||||
sec *= 10;
|
||||
}
|
||||
}
|
||||
while (spacesToPrepend-- > 0) {
|
||||
str = ' ' + str;
|
||||
}
|
||||
return str;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Formatter that returns formatted html. See formatRecord for the classes
|
||||
* it uses for various types of formatted output.
|
||||
*
|
||||
* @param {string=} opt_prefix The prefix to place before text records.
|
||||
* @constructor
|
||||
* @extends {goog.debug.Formatter}
|
||||
*/
|
||||
goog.debug.HtmlFormatter = function(opt_prefix) {
|
||||
goog.debug.Formatter.call(this, opt_prefix);
|
||||
};
|
||||
goog.inherits(goog.debug.HtmlFormatter, goog.debug.Formatter);
|
||||
|
||||
|
||||
/**
|
||||
* Whether to show the logger exception text
|
||||
* @type {boolean}
|
||||
* @override
|
||||
*/
|
||||
goog.debug.HtmlFormatter.prototype.showExceptionText = true;
|
||||
|
||||
|
||||
/**
|
||||
* Formats a record
|
||||
* @param {goog.debug.LogRecord} logRecord the logRecord to format.
|
||||
* @return {string} The formatted string as html.
|
||||
* @override
|
||||
*/
|
||||
goog.debug.HtmlFormatter.prototype.formatRecord = function(logRecord) {
|
||||
var className;
|
||||
switch (logRecord.getLevel().value) {
|
||||
case goog.debug.Logger.Level.SHOUT.value:
|
||||
className = 'dbg-sh';
|
||||
break;
|
||||
case goog.debug.Logger.Level.SEVERE.value:
|
||||
className = 'dbg-sev';
|
||||
break;
|
||||
case goog.debug.Logger.Level.WARNING.value:
|
||||
className = 'dbg-w';
|
||||
break;
|
||||
case goog.debug.Logger.Level.INFO.value:
|
||||
className = 'dbg-i';
|
||||
break;
|
||||
case goog.debug.Logger.Level.FINE.value:
|
||||
default:
|
||||
className = 'dbg-f';
|
||||
break;
|
||||
}
|
||||
|
||||
// Build message html
|
||||
var sb = [];
|
||||
sb.push(this.prefix_, ' ');
|
||||
if (this.showAbsoluteTime) {
|
||||
sb.push('[', goog.debug.Formatter.getDateTimeStamp_(logRecord), '] ');
|
||||
}
|
||||
if (this.showRelativeTime) {
|
||||
sb.push('[',
|
||||
goog.string.whitespaceEscape(
|
||||
goog.debug.Formatter.getRelativeTime_(logRecord,
|
||||
this.startTimeProvider_.get())),
|
||||
's] ');
|
||||
}
|
||||
|
||||
if (this.showLoggerName) {
|
||||
sb.push('[', goog.string.htmlEscape(logRecord.getLoggerName()), '] ');
|
||||
}
|
||||
if (this.showSeverityLevel) {
|
||||
sb.push('[', goog.string.htmlEscape(logRecord.getLevel().name), '] ');
|
||||
}
|
||||
sb.push('<span class="', className, '">',
|
||||
goog.string.newLineToBr(goog.string.whitespaceEscape(
|
||||
goog.string.htmlEscape(logRecord.getMessage()))));
|
||||
|
||||
if (this.showExceptionText && logRecord.getException()) {
|
||||
sb.push('<br>',
|
||||
goog.string.newLineToBr(goog.string.whitespaceEscape(
|
||||
logRecord.getExceptionText() || '')));
|
||||
}
|
||||
sb.push('</span><br>');
|
||||
|
||||
return sb.join('');
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Formatter that returns formatted plain text
|
||||
*
|
||||
* @param {string=} opt_prefix The prefix to place before text records.
|
||||
* @constructor
|
||||
* @extends {goog.debug.Formatter}
|
||||
*/
|
||||
goog.debug.TextFormatter = function(opt_prefix) {
|
||||
goog.debug.Formatter.call(this, opt_prefix);
|
||||
};
|
||||
goog.inherits(goog.debug.TextFormatter, goog.debug.Formatter);
|
||||
|
||||
|
||||
/**
|
||||
* Formats a record as text
|
||||
* @param {goog.debug.LogRecord} logRecord the logRecord to format.
|
||||
* @return {string} The formatted string.
|
||||
* @override
|
||||
*/
|
||||
goog.debug.TextFormatter.prototype.formatRecord = function(logRecord) {
|
||||
// Build message html
|
||||
var sb = [];
|
||||
sb.push(this.prefix_, ' ');
|
||||
if (this.showAbsoluteTime) {
|
||||
sb.push('[', goog.debug.Formatter.getDateTimeStamp_(logRecord), '] ');
|
||||
}
|
||||
if (this.showRelativeTime) {
|
||||
sb.push('[', goog.debug.Formatter.getRelativeTime_(logRecord,
|
||||
this.startTimeProvider_.get()), 's] ');
|
||||
}
|
||||
|
||||
if (this.showLoggerName) {
|
||||
sb.push('[', logRecord.getLoggerName(), '] ');
|
||||
}
|
||||
if (this.showSeverityLevel) {
|
||||
sb.push('[', logRecord.getLevel().name, '] ');
|
||||
}
|
||||
sb.push(logRecord.getMessage(), '\n');
|
||||
if (this.showExceptionText && logRecord.getException()) {
|
||||
sb.push(logRecord.getExceptionText(), '\n');
|
||||
}
|
||||
return sb.join('');
|
||||
};
|
||||
162
nicer-api-docs/closure-library/closure/goog/debug/fpsdisplay.js
Normal file
162
nicer-api-docs/closure-library/closure/goog/debug/fpsdisplay.js
Normal file
@@ -0,0 +1,162 @@
|
||||
// Copyright 2011 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 Displays frames per second (FPS) for the current window.
|
||||
* Only supported in browsers that support requestAnimationFrame.
|
||||
* See: https://developer.mozilla.org/en/DOM/window.requestAnimationFrame.
|
||||
*
|
||||
* @see ../demos/fpsdisplay.html
|
||||
*/
|
||||
|
||||
goog.provide('goog.debug.FpsDisplay');
|
||||
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.async.AnimationDelay');
|
||||
goog.require('goog.ui.Component');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Displays frames per seconds that the window this component is
|
||||
* rendered in is animating at.
|
||||
*
|
||||
* @param {goog.dom.DomHelper=} opt_domHelper An optional dom helper.
|
||||
* @constructor
|
||||
* @extends {goog.ui.Component}
|
||||
*/
|
||||
goog.debug.FpsDisplay = function(opt_domHelper) {
|
||||
goog.base(this, opt_domHelper);
|
||||
};
|
||||
goog.inherits(goog.debug.FpsDisplay, goog.ui.Component);
|
||||
|
||||
|
||||
/**
|
||||
* CSS class for the FPS display.
|
||||
*/
|
||||
goog.debug.FpsDisplay.CSS = goog.getCssName('goog-fps-display');
|
||||
|
||||
|
||||
/**
|
||||
* The number of samples per FPS report.
|
||||
*/
|
||||
goog.debug.FpsDisplay.SAMPLES = 10;
|
||||
|
||||
|
||||
/**
|
||||
* The current animation.
|
||||
* @type {goog.debug.FpsDisplay.FpsAnimation_}
|
||||
* @private
|
||||
*/
|
||||
goog.debug.FpsDisplay.prototype.animation_ = null;
|
||||
|
||||
|
||||
/** @override */
|
||||
goog.debug.FpsDisplay.prototype.createDom = function() {
|
||||
this.setElementInternal(
|
||||
this.getDomHelper().createDom('div', goog.debug.FpsDisplay.CSS));
|
||||
};
|
||||
|
||||
|
||||
/** @override */
|
||||
goog.debug.FpsDisplay.prototype.enterDocument = function() {
|
||||
goog.base(this, 'enterDocument');
|
||||
this.animation_ = new goog.debug.FpsDisplay.FpsAnimation_(this.getElement());
|
||||
this.delay_ = new goog.async.AnimationDelay(
|
||||
this.handleDelay_, this.getDomHelper().getWindow(), this);
|
||||
this.delay_.start();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {number} now The current time.
|
||||
* @private
|
||||
*/
|
||||
goog.debug.FpsDisplay.prototype.handleDelay_ = function(now) {
|
||||
if (this.isInDocument()) {
|
||||
this.animation_.onAnimationFrame(now);
|
||||
this.delay_.start();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/** @override */
|
||||
goog.debug.FpsDisplay.prototype.exitDocument = function() {
|
||||
goog.base(this, 'exitDocument');
|
||||
this.animation_ = null;
|
||||
goog.dispose(this.delay_);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} The average frames per second.
|
||||
*/
|
||||
goog.debug.FpsDisplay.prototype.getFps = function() {
|
||||
goog.asserts.assert(
|
||||
this.isInDocument(), 'Render the FPS display before querying FPS');
|
||||
return this.animation_.lastFps_;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @param {Element} elem An element to hold the FPS count.
|
||||
* @constructor
|
||||
* @private
|
||||
*/
|
||||
goog.debug.FpsDisplay.FpsAnimation_ = function(elem) {
|
||||
/**
|
||||
* An element to hold the current FPS rate.
|
||||
* @type {Element}
|
||||
* @private
|
||||
*/
|
||||
this.element_ = elem;
|
||||
|
||||
/**
|
||||
* The number of frames observed so far.
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
this.frameNumber_ = 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The last time which we reported FPS at.
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
goog.debug.FpsDisplay.FpsAnimation_.prototype.lastTime_ = 0;
|
||||
|
||||
|
||||
/**
|
||||
* The last average FPS.
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
goog.debug.FpsDisplay.FpsAnimation_.prototype.lastFps_ = -1;
|
||||
|
||||
|
||||
/**
|
||||
* @param {number} now The current time.
|
||||
*/
|
||||
goog.debug.FpsDisplay.FpsAnimation_.prototype.onAnimationFrame = function(now) {
|
||||
var SAMPLES = goog.debug.FpsDisplay.SAMPLES;
|
||||
if (this.frameNumber_ % SAMPLES == 0) {
|
||||
this.lastFps_ = Math.round((1000 * SAMPLES) / (now - this.lastTime_));
|
||||
this.element_.innerHTML = this.lastFps_;
|
||||
this.lastTime_ = now;
|
||||
}
|
||||
this.frameNumber_++;
|
||||
};
|
||||
@@ -0,0 +1,143 @@
|
||||
// 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 Definition of the GcDiagnostics class.
|
||||
*
|
||||
*/
|
||||
|
||||
goog.provide('goog.debug.GcDiagnostics');
|
||||
|
||||
goog.require('goog.debug.Trace');
|
||||
goog.require('goog.log');
|
||||
goog.require('goog.userAgent');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Class used for singleton goog.debug.GcDiagnostics. Used to hook into
|
||||
* the L2 ActiveX controller to profile garbage collection information in IE.
|
||||
* Can be used in combination with tracers (goog.debug.Trace), to provide object
|
||||
* allocation counts from within the tracers or used alone by invoking start and
|
||||
* stop.
|
||||
*
|
||||
* See http://go/l2binary for the install.
|
||||
* TODO(user): Move the L2 installer somewhere more general.
|
||||
* @constructor
|
||||
* @private
|
||||
*/
|
||||
goog.debug.GcDiagnostics_ = function() {};
|
||||
|
||||
|
||||
/**
|
||||
* Install the GcDiagnostics tool.
|
||||
*/
|
||||
goog.debug.GcDiagnostics_.prototype.install = function() {
|
||||
if (goog.userAgent.IE) {
|
||||
/** @preserveTry */
|
||||
try {
|
||||
var l2Helper = new ActiveXObject('L2.NativeHelper');
|
||||
|
||||
// If using tracers, use the higher precision timer provided by L2.
|
||||
if (goog.debug.Trace_) {
|
||||
goog.debug.Trace_.now = function() {
|
||||
return l2Helper['getMilliSeconds']();
|
||||
};
|
||||
}
|
||||
|
||||
if (l2Helper['gcTracer']) {
|
||||
l2Helper['gcTracer']['installGcTracing']();
|
||||
this.gcTracer_ = l2Helper['gcTracer'];
|
||||
if (goog.debug.Trace) {
|
||||
// If tracers are in use, register the gcTracer so that per tracer
|
||||
// allocations are recorded.
|
||||
goog.debug.Trace.setGcTracer(this.gcTracer_);
|
||||
}
|
||||
}
|
||||
goog.log.info(this.logger_, 'Installed L2 native helper');
|
||||
} catch (e) {
|
||||
goog.log.info(this.logger_, 'Failed to install L2 native helper: ' + e);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Logger for the gcDiagnotics
|
||||
* @type {goog.log.Logger}
|
||||
* @private
|
||||
*/
|
||||
goog.debug.GcDiagnostics_.prototype.logger_ =
|
||||
goog.log.getLogger('goog.debug.GcDiagnostics');
|
||||
|
||||
|
||||
/**
|
||||
* Starts recording garbage collection information. If a trace is already in
|
||||
* progress, it is ended.
|
||||
*/
|
||||
goog.debug.GcDiagnostics_.prototype.start = function() {
|
||||
if (this.gcTracer_) {
|
||||
if (this.gcTracer_['isTracing']()) {
|
||||
this.gcTracer_['endGcTracing']();
|
||||
}
|
||||
this.gcTracer_['startGcTracing']();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Stops recording garbage collection information. Logs details on the garbage
|
||||
* collections that occurred between start and stop. If tracers are in use,
|
||||
* adds comments where each GC occurs.
|
||||
*/
|
||||
goog.debug.GcDiagnostics_.prototype.stop = function() {
|
||||
if (this.gcTracer_ && this.gcTracer_['isTracing']()) {
|
||||
var gcTracer = this.gcTracer_;
|
||||
this.gcTracer_['endGcTracing']();
|
||||
|
||||
var numGCs = gcTracer['getNumTraces']();
|
||||
goog.log.info(this.logger_, '*********GC TRACE*********');
|
||||
goog.log.info(this.logger_, 'GC ran ' + numGCs + ' times.');
|
||||
var totalTime = 0;
|
||||
for (var i = 0; i < numGCs; i++) {
|
||||
var trace = gcTracer['getTrace'](i);
|
||||
|
||||
var msStart = trace['gcStartTime'];
|
||||
var msElapsed = trace['gcElapsedTime'];
|
||||
|
||||
var msRounded = Math.round(msElapsed * 10) / 10;
|
||||
var s = 'GC ' + i + ': ' + msRounded + ' ms, ' +
|
||||
'numVValAlloc=' + trace['numVValAlloc'] + ', ' +
|
||||
'numVarAlloc=' + trace['numVarAlloc'] + ', ' +
|
||||
'numBytesSysAlloc=' + trace['numBytesSysAlloc'];
|
||||
if (goog.debug.Trace) {
|
||||
goog.debug.Trace.addComment(s, null, msStart);
|
||||
}
|
||||
goog.log.info(this.logger_, s);
|
||||
totalTime += msElapsed;
|
||||
}
|
||||
if (goog.debug.Trace) {
|
||||
goog.debug.Trace.addComment('Total GC time was ' + totalTime + ' ms.');
|
||||
}
|
||||
goog.log.info(this.logger_, 'Total GC time was ' + totalTime + ' ms.');
|
||||
goog.log.info(this.logger_, '*********GC TRACE*********');
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Singleton GcDiagnostics object
|
||||
* @type {goog.debug.GcDiagnostics_}
|
||||
*/
|
||||
goog.debug.GcDiagnostics = new goog.debug.GcDiagnostics_();
|
||||
147
nicer-api-docs/closure-library/closure/goog/debug/logbuffer.js
Normal file
147
nicer-api-docs/closure-library/closure/goog/debug/logbuffer.js
Normal file
@@ -0,0 +1,147 @@
|
||||
// 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 buffer for log records. The purpose of this is to improve
|
||||
* logging performance by re-using old objects when the buffer becomes full and
|
||||
* to eliminate the need for each app to implement their own log buffer. The
|
||||
* disadvantage to doing this is that log handlers cannot maintain references to
|
||||
* log records and expect that they are not overwriten at a later point.
|
||||
*
|
||||
* @author agrieve@google.com (Andrew Grieve)
|
||||
*/
|
||||
|
||||
goog.provide('goog.debug.LogBuffer');
|
||||
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.debug.LogRecord');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Creates the log buffer.
|
||||
* @constructor
|
||||
*/
|
||||
goog.debug.LogBuffer = function() {
|
||||
goog.asserts.assert(goog.debug.LogBuffer.isBufferingEnabled(),
|
||||
'Cannot use goog.debug.LogBuffer without defining ' +
|
||||
'goog.debug.LogBuffer.CAPACITY.');
|
||||
this.clear();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* A static method that always returns the same instance of LogBuffer.
|
||||
* @return {!goog.debug.LogBuffer} The LogBuffer singleton instance.
|
||||
*/
|
||||
goog.debug.LogBuffer.getInstance = function() {
|
||||
if (!goog.debug.LogBuffer.instance_) {
|
||||
// This function is written with the return statement after the assignment
|
||||
// to avoid the jscompiler StripCode bug described in http://b/2608064.
|
||||
// After that bug is fixed this can be refactored.
|
||||
goog.debug.LogBuffer.instance_ = new goog.debug.LogBuffer();
|
||||
}
|
||||
return goog.debug.LogBuffer.instance_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @define {number} The number of log records to buffer. 0 means disable
|
||||
* buffering.
|
||||
*/
|
||||
goog.define('goog.debug.LogBuffer.CAPACITY', 0);
|
||||
|
||||
|
||||
/**
|
||||
* The array to store the records.
|
||||
* @type {!Array.<!goog.debug.LogRecord|undefined>}
|
||||
* @private
|
||||
*/
|
||||
goog.debug.LogBuffer.prototype.buffer_;
|
||||
|
||||
|
||||
/**
|
||||
* The index of the most recently added record or -1 if there are no records.
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
goog.debug.LogBuffer.prototype.curIndex_;
|
||||
|
||||
|
||||
/**
|
||||
* Whether the buffer is at capacity.
|
||||
* @type {boolean}
|
||||
* @private
|
||||
*/
|
||||
goog.debug.LogBuffer.prototype.isFull_;
|
||||
|
||||
|
||||
/**
|
||||
* Adds a log record to the buffer, possibly overwriting the oldest record.
|
||||
* @param {goog.debug.Logger.Level} level One of the level identifiers.
|
||||
* @param {string} msg The string message.
|
||||
* @param {string} loggerName The name of the source logger.
|
||||
* @return {!goog.debug.LogRecord} The log record.
|
||||
*/
|
||||
goog.debug.LogBuffer.prototype.addRecord = function(level, msg, loggerName) {
|
||||
var curIndex = (this.curIndex_ + 1) % goog.debug.LogBuffer.CAPACITY;
|
||||
this.curIndex_ = curIndex;
|
||||
if (this.isFull_) {
|
||||
var ret = this.buffer_[curIndex];
|
||||
ret.reset(level, msg, loggerName);
|
||||
return ret;
|
||||
}
|
||||
this.isFull_ = curIndex == goog.debug.LogBuffer.CAPACITY - 1;
|
||||
return this.buffer_[curIndex] =
|
||||
new goog.debug.LogRecord(level, msg, loggerName);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the log buffer is enabled.
|
||||
*/
|
||||
goog.debug.LogBuffer.isBufferingEnabled = function() {
|
||||
return goog.debug.LogBuffer.CAPACITY > 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Removes all buffered log records.
|
||||
*/
|
||||
goog.debug.LogBuffer.prototype.clear = function() {
|
||||
this.buffer_ = new Array(goog.debug.LogBuffer.CAPACITY);
|
||||
this.curIndex_ = -1;
|
||||
this.isFull_ = false;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Calls the given function for each buffered log record, starting with the
|
||||
* oldest one.
|
||||
* @param {function(!goog.debug.LogRecord)} func The function to call.
|
||||
*/
|
||||
goog.debug.LogBuffer.prototype.forEachRecord = function(func) {
|
||||
var buffer = this.buffer_;
|
||||
// Corner case: no records.
|
||||
if (!buffer[0]) {
|
||||
return;
|
||||
}
|
||||
var curIndex = this.curIndex_;
|
||||
var i = this.isFull_ ? curIndex : -1;
|
||||
do {
|
||||
i = (i + 1) % goog.debug.LogBuffer.CAPACITY;
|
||||
func(/** @type {!goog.debug.LogRecord} */ (buffer[i]));
|
||||
} while (i != curIndex);
|
||||
};
|
||||
|
||||
853
nicer-api-docs/closure-library/closure/goog/debug/logger.js
Normal file
853
nicer-api-docs/closure-library/closure/goog/debug/logger.js
Normal file
@@ -0,0 +1,853 @@
|
||||
// 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 Logger 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.
|
||||
*
|
||||
* @see ../demos/debug.html
|
||||
*/
|
||||
|
||||
goog.provide('goog.debug.LogManager');
|
||||
goog.provide('goog.debug.Logger');
|
||||
goog.provide('goog.debug.Logger.Level');
|
||||
|
||||
goog.require('goog.array');
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.debug');
|
||||
goog.require('goog.debug.LogBuffer');
|
||||
goog.require('goog.debug.LogRecord');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* The Logger is an object used for logging debug messages. Loggers are
|
||||
* normally named, using a hierarchical dot-separated namespace. Logger names
|
||||
* can be arbitrary strings, but they should normally be based on the package
|
||||
* name or class name of the logged component, such as goog.net.BrowserChannel.
|
||||
*
|
||||
* The Logger object is loosely based on the java class
|
||||
* java.util.logging.Logger. It supports different levels of filtering for
|
||||
* different loggers.
|
||||
*
|
||||
* The logger object should never be instantiated by application code. It
|
||||
* should always use the goog.debug.Logger.getLogger function.
|
||||
*
|
||||
* @constructor
|
||||
* @param {string} name The name of the Logger.
|
||||
*/
|
||||
goog.debug.Logger = function(name) {
|
||||
/**
|
||||
* Name of the Logger. Generally a dot-separated namespace
|
||||
* @type {string}
|
||||
* @private
|
||||
*/
|
||||
this.name_ = name;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Parent Logger.
|
||||
* @type {goog.debug.Logger}
|
||||
* @private
|
||||
*/
|
||||
goog.debug.Logger.prototype.parent_ = null;
|
||||
|
||||
|
||||
/**
|
||||
* Level that this logger only filters above. Null indicates it should
|
||||
* inherit from the parent.
|
||||
* @type {goog.debug.Logger.Level}
|
||||
* @private
|
||||
*/
|
||||
goog.debug.Logger.prototype.level_ = null;
|
||||
|
||||
|
||||
/**
|
||||
* Map of children loggers. The keys are the leaf names of the children and
|
||||
* the values are the child loggers.
|
||||
* @type {Object}
|
||||
* @private
|
||||
*/
|
||||
goog.debug.Logger.prototype.children_ = null;
|
||||
|
||||
|
||||
/**
|
||||
* Handlers that are listening to this logger.
|
||||
* @type {Array.<Function>}
|
||||
* @private
|
||||
*/
|
||||
goog.debug.Logger.prototype.handlers_ = null;
|
||||
|
||||
|
||||
/**
|
||||
* @define {boolean} Toggles whether loggers other than the root logger can have
|
||||
* log handlers attached to them and whether they can have their log level
|
||||
* set. Logging is a bit faster when this is set to false.
|
||||
*/
|
||||
goog.define('goog.debug.Logger.ENABLE_HIERARCHY', true);
|
||||
|
||||
|
||||
if (!goog.debug.Logger.ENABLE_HIERARCHY) {
|
||||
/**
|
||||
* @type {!Array.<Function>}
|
||||
* @private
|
||||
*/
|
||||
goog.debug.Logger.rootHandlers_ = [];
|
||||
|
||||
|
||||
/**
|
||||
* @type {goog.debug.Logger.Level}
|
||||
* @private
|
||||
*/
|
||||
goog.debug.Logger.rootLevel_;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* The Level class defines a set of standard logging levels that
|
||||
* can be used to control logging output. The logging Level objects
|
||||
* are ordered and are specified by ordered integers. Enabling logging
|
||||
* at a given level also enables logging at all higher levels.
|
||||
* <p>
|
||||
* Clients should normally use the predefined Level constants such
|
||||
* as Level.SEVERE.
|
||||
* <p>
|
||||
* The levels in descending order are:
|
||||
* <ul>
|
||||
* <li>SEVERE (highest value)
|
||||
* <li>WARNING
|
||||
* <li>INFO
|
||||
* <li>CONFIG
|
||||
* <li>FINE
|
||||
* <li>FINER
|
||||
* <li>FINEST (lowest value)
|
||||
* </ul>
|
||||
* In addition there is a level OFF that can be used to turn
|
||||
* off logging, and a level ALL that can be used to enable
|
||||
* logging of all messages.
|
||||
*
|
||||
* @param {string} name The name of the level.
|
||||
* @param {number} value The numeric value of the level.
|
||||
* @constructor
|
||||
*/
|
||||
goog.debug.Logger.Level = function(name, value) {
|
||||
/**
|
||||
* The name of the level
|
||||
* @type {string}
|
||||
*/
|
||||
this.name = name;
|
||||
|
||||
/**
|
||||
* The numeric value of the level
|
||||
* @type {number}
|
||||
*/
|
||||
this.value = value;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {string} String representation of the logger level.
|
||||
* @override
|
||||
*/
|
||||
goog.debug.Logger.Level.prototype.toString = function() {
|
||||
return this.name;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* OFF is a special level that can be used to turn off logging.
|
||||
* This level is initialized to <CODE>Infinity</CODE>.
|
||||
* @type {!goog.debug.Logger.Level}
|
||||
*/
|
||||
goog.debug.Logger.Level.OFF =
|
||||
new goog.debug.Logger.Level('OFF', Infinity);
|
||||
|
||||
|
||||
/**
|
||||
* SHOUT is a message level for extra debugging loudness.
|
||||
* This level is initialized to <CODE>1200</CODE>.
|
||||
* @type {!goog.debug.Logger.Level}
|
||||
*/
|
||||
goog.debug.Logger.Level.SHOUT = new goog.debug.Logger.Level('SHOUT', 1200);
|
||||
|
||||
|
||||
/**
|
||||
* SEVERE is a message level indicating a serious failure.
|
||||
* This level is initialized to <CODE>1000</CODE>.
|
||||
* @type {!goog.debug.Logger.Level}
|
||||
*/
|
||||
goog.debug.Logger.Level.SEVERE = new goog.debug.Logger.Level('SEVERE', 1000);
|
||||
|
||||
|
||||
/**
|
||||
* WARNING is a message level indicating a potential problem.
|
||||
* This level is initialized to <CODE>900</CODE>.
|
||||
* @type {!goog.debug.Logger.Level}
|
||||
*/
|
||||
goog.debug.Logger.Level.WARNING = new goog.debug.Logger.Level('WARNING', 900);
|
||||
|
||||
|
||||
/**
|
||||
* INFO is a message level for informational messages.
|
||||
* This level is initialized to <CODE>800</CODE>.
|
||||
* @type {!goog.debug.Logger.Level}
|
||||
*/
|
||||
goog.debug.Logger.Level.INFO = new goog.debug.Logger.Level('INFO', 800);
|
||||
|
||||
|
||||
/**
|
||||
* CONFIG is a message level for static configuration messages.
|
||||
* This level is initialized to <CODE>700</CODE>.
|
||||
* @type {!goog.debug.Logger.Level}
|
||||
*/
|
||||
goog.debug.Logger.Level.CONFIG = new goog.debug.Logger.Level('CONFIG', 700);
|
||||
|
||||
|
||||
/**
|
||||
* FINE is a message level providing tracing information.
|
||||
* This level is initialized to <CODE>500</CODE>.
|
||||
* @type {!goog.debug.Logger.Level}
|
||||
*/
|
||||
goog.debug.Logger.Level.FINE = new goog.debug.Logger.Level('FINE', 500);
|
||||
|
||||
|
||||
/**
|
||||
* FINER indicates a fairly detailed tracing message.
|
||||
* This level is initialized to <CODE>400</CODE>.
|
||||
* @type {!goog.debug.Logger.Level}
|
||||
*/
|
||||
goog.debug.Logger.Level.FINER = new goog.debug.Logger.Level('FINER', 400);
|
||||
|
||||
/**
|
||||
* FINEST indicates a highly detailed tracing message.
|
||||
* This level is initialized to <CODE>300</CODE>.
|
||||
* @type {!goog.debug.Logger.Level}
|
||||
*/
|
||||
|
||||
goog.debug.Logger.Level.FINEST = new goog.debug.Logger.Level('FINEST', 300);
|
||||
|
||||
|
||||
/**
|
||||
* ALL indicates that all messages should be logged.
|
||||
* This level is initialized to <CODE>0</CODE>.
|
||||
* @type {!goog.debug.Logger.Level}
|
||||
*/
|
||||
goog.debug.Logger.Level.ALL = new goog.debug.Logger.Level('ALL', 0);
|
||||
|
||||
|
||||
/**
|
||||
* The predefined levels.
|
||||
* @type {!Array.<!goog.debug.Logger.Level>}
|
||||
* @final
|
||||
*/
|
||||
goog.debug.Logger.Level.PREDEFINED_LEVELS = [
|
||||
goog.debug.Logger.Level.OFF,
|
||||
goog.debug.Logger.Level.SHOUT,
|
||||
goog.debug.Logger.Level.SEVERE,
|
||||
goog.debug.Logger.Level.WARNING,
|
||||
goog.debug.Logger.Level.INFO,
|
||||
goog.debug.Logger.Level.CONFIG,
|
||||
goog.debug.Logger.Level.FINE,
|
||||
goog.debug.Logger.Level.FINER,
|
||||
goog.debug.Logger.Level.FINEST,
|
||||
goog.debug.Logger.Level.ALL];
|
||||
|
||||
|
||||
/**
|
||||
* A lookup map used to find the level object based on the name or value of
|
||||
* the level object.
|
||||
* @type {Object}
|
||||
* @private
|
||||
*/
|
||||
goog.debug.Logger.Level.predefinedLevelsCache_ = null;
|
||||
|
||||
|
||||
/**
|
||||
* Creates the predefined levels cache and populates it.
|
||||
* @private
|
||||
*/
|
||||
goog.debug.Logger.Level.createPredefinedLevelsCache_ = function() {
|
||||
goog.debug.Logger.Level.predefinedLevelsCache_ = {};
|
||||
for (var i = 0, level; level = goog.debug.Logger.Level.PREDEFINED_LEVELS[i];
|
||||
i++) {
|
||||
goog.debug.Logger.Level.predefinedLevelsCache_[level.value] = level;
|
||||
goog.debug.Logger.Level.predefinedLevelsCache_[level.name] = level;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Gets the predefined level with the given name.
|
||||
* @param {string} name The name of the level.
|
||||
* @return {goog.debug.Logger.Level} The level, or null if none found.
|
||||
*/
|
||||
goog.debug.Logger.Level.getPredefinedLevel = function(name) {
|
||||
if (!goog.debug.Logger.Level.predefinedLevelsCache_) {
|
||||
goog.debug.Logger.Level.createPredefinedLevelsCache_();
|
||||
}
|
||||
|
||||
return goog.debug.Logger.Level.predefinedLevelsCache_[name] || null;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Gets the highest predefined level <= #value.
|
||||
* @param {number} value Level value.
|
||||
* @return {goog.debug.Logger.Level} The level, or null if none found.
|
||||
*/
|
||||
goog.debug.Logger.Level.getPredefinedLevelByValue = function(value) {
|
||||
if (!goog.debug.Logger.Level.predefinedLevelsCache_) {
|
||||
goog.debug.Logger.Level.createPredefinedLevelsCache_();
|
||||
}
|
||||
|
||||
if (value in goog.debug.Logger.Level.predefinedLevelsCache_) {
|
||||
return goog.debug.Logger.Level.predefinedLevelsCache_[value];
|
||||
}
|
||||
|
||||
for (var i = 0; i < goog.debug.Logger.Level.PREDEFINED_LEVELS.length; ++i) {
|
||||
var level = goog.debug.Logger.Level.PREDEFINED_LEVELS[i];
|
||||
if (level.value <= value) {
|
||||
return level;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Finds or creates a logger for a named subsystem. If a logger has already been
|
||||
* created with the given name it is returned. Otherwise a new logger is
|
||||
* created. If a new logger is created its log level will be configured based
|
||||
* on the LogManager configuration and it will configured to also send logging
|
||||
* output to its parent's handlers. It will be registered in the LogManager
|
||||
* global namespace.
|
||||
*
|
||||
* @param {string} name A name for the logger. This should be a dot-separated
|
||||
* name and should normally be based on the package name or class name of the
|
||||
* subsystem, such as goog.net.BrowserChannel.
|
||||
* @return {!goog.debug.Logger} The named logger.
|
||||
*/
|
||||
goog.debug.Logger.getLogger = function(name) {
|
||||
return goog.debug.LogManager.getLogger(name);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Logs a message to profiling tools, if available.
|
||||
* {@see http://code.google.com/webtoolkit/speedtracer/logging-api.html}
|
||||
* {@see http://msdn.microsoft.com/en-us/library/dd433074(VS.85).aspx}
|
||||
* @param {string} msg The message to log.
|
||||
*/
|
||||
goog.debug.Logger.logToProfilers = function(msg) {
|
||||
// Using goog.global, as loggers might be used in window-less contexts.
|
||||
if (goog.global['console']) {
|
||||
if (goog.global['console']['timeStamp']) {
|
||||
// Logs a message to Firebug, Web Inspector, SpeedTracer, etc.
|
||||
goog.global['console']['timeStamp'](msg);
|
||||
} else if (goog.global['console']['markTimeline']) {
|
||||
// TODO(user): markTimeline is deprecated. Drop this else clause entirely
|
||||
// after Chrome M14 hits stable.
|
||||
goog.global['console']['markTimeline'](msg);
|
||||
}
|
||||
}
|
||||
|
||||
if (goog.global['msWriteProfilerMark']) {
|
||||
// Logs a message to the Microsoft profiler
|
||||
goog.global['msWriteProfilerMark'](msg);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Gets the name of this logger.
|
||||
* @return {string} The name of this logger.
|
||||
*/
|
||||
goog.debug.Logger.prototype.getName = function() {
|
||||
return this.name_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Adds a handler to the logger. This doesn't use the event system because
|
||||
* we want to be able to add logging to the event system.
|
||||
* @param {Function} handler Handler function to add.
|
||||
*/
|
||||
goog.debug.Logger.prototype.addHandler = function(handler) {
|
||||
if (goog.debug.LOGGING_ENABLED) {
|
||||
if (goog.debug.Logger.ENABLE_HIERARCHY) {
|
||||
if (!this.handlers_) {
|
||||
this.handlers_ = [];
|
||||
}
|
||||
this.handlers_.push(handler);
|
||||
} else {
|
||||
goog.asserts.assert(!this.name_,
|
||||
'Cannot call addHandler on a non-root logger when ' +
|
||||
'goog.debug.Logger.ENABLE_HIERARCHY is false.');
|
||||
goog.debug.Logger.rootHandlers_.push(handler);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Removes a handler from the logger. This doesn't use the event system because
|
||||
* we want to be able to add logging to the event system.
|
||||
* @param {Function} handler Handler function to remove.
|
||||
* @return {boolean} Whether the handler was removed.
|
||||
*/
|
||||
goog.debug.Logger.prototype.removeHandler = function(handler) {
|
||||
if (goog.debug.LOGGING_ENABLED) {
|
||||
var handlers = goog.debug.Logger.ENABLE_HIERARCHY ? this.handlers_ :
|
||||
goog.debug.Logger.rootHandlers_;
|
||||
return !!handlers && goog.array.remove(handlers, handler);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the parent of this logger.
|
||||
* @return {goog.debug.Logger} The parent logger or null if this is the root.
|
||||
*/
|
||||
goog.debug.Logger.prototype.getParent = function() {
|
||||
return this.parent_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the children of this logger as a map of the child name to the logger.
|
||||
* @return {!Object} The map where the keys are the child leaf names and the
|
||||
* values are the Logger objects.
|
||||
*/
|
||||
goog.debug.Logger.prototype.getChildren = function() {
|
||||
if (!this.children_) {
|
||||
this.children_ = {};
|
||||
}
|
||||
return this.children_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Set the log level specifying which message levels will be logged by this
|
||||
* logger. Message levels lower than this value will be discarded.
|
||||
* The level value Level.OFF can be used to turn off logging. If the new level
|
||||
* is null, it means that this node should inherit its level from its nearest
|
||||
* ancestor with a specific (non-null) level value.
|
||||
*
|
||||
* @param {goog.debug.Logger.Level} level The new level.
|
||||
*/
|
||||
goog.debug.Logger.prototype.setLevel = function(level) {
|
||||
if (goog.debug.LOGGING_ENABLED) {
|
||||
if (goog.debug.Logger.ENABLE_HIERARCHY) {
|
||||
this.level_ = level;
|
||||
} else {
|
||||
goog.asserts.assert(!this.name_,
|
||||
'Cannot call setLevel() on a non-root logger when ' +
|
||||
'goog.debug.Logger.ENABLE_HIERARCHY is false.');
|
||||
goog.debug.Logger.rootLevel_ = level;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Gets the log level specifying which message levels will be logged by this
|
||||
* logger. Message levels lower than this value will be discarded.
|
||||
* The level value Level.OFF can be used to turn off logging. If the level
|
||||
* is null, it means that this node should inherit its level from its nearest
|
||||
* ancestor with a specific (non-null) level value.
|
||||
*
|
||||
* @return {goog.debug.Logger.Level} The level.
|
||||
*/
|
||||
goog.debug.Logger.prototype.getLevel = function() {
|
||||
return goog.debug.LOGGING_ENABLED ?
|
||||
this.level_ : goog.debug.Logger.Level.OFF;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the effective level of the logger based on its ancestors' levels.
|
||||
* @return {goog.debug.Logger.Level} The level.
|
||||
*/
|
||||
goog.debug.Logger.prototype.getEffectiveLevel = function() {
|
||||
if (!goog.debug.LOGGING_ENABLED) {
|
||||
return goog.debug.Logger.Level.OFF;
|
||||
}
|
||||
|
||||
if (!goog.debug.Logger.ENABLE_HIERARCHY) {
|
||||
return goog.debug.Logger.rootLevel_;
|
||||
}
|
||||
if (this.level_) {
|
||||
return this.level_;
|
||||
}
|
||||
if (this.parent_) {
|
||||
return this.parent_.getEffectiveLevel();
|
||||
}
|
||||
goog.asserts.fail('Root logger has no level set.');
|
||||
return null;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Checks if a message of the given level would actually be logged by this
|
||||
* logger. This check is based on the Loggers effective level, which may be
|
||||
* inherited from its parent.
|
||||
* @param {goog.debug.Logger.Level} level The level to check.
|
||||
* @return {boolean} Whether the message would be logged.
|
||||
*/
|
||||
goog.debug.Logger.prototype.isLoggable = function(level) {
|
||||
return goog.debug.LOGGING_ENABLED &&
|
||||
level.value >= this.getEffectiveLevel().value;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Logs a message. If the logger is currently enabled for the
|
||||
* given message level then the given message is forwarded to all the
|
||||
* registered output Handler objects.
|
||||
* @param {goog.debug.Logger.Level} level One of the level identifiers.
|
||||
* @param {string} msg The string message.
|
||||
* @param {Error|Object=} opt_exception An exception associated with the
|
||||
* message.
|
||||
*/
|
||||
goog.debug.Logger.prototype.log = function(level, msg, opt_exception) {
|
||||
// java caches the effective level, not sure it's necessary here
|
||||
if (goog.debug.LOGGING_ENABLED && this.isLoggable(level)) {
|
||||
this.doLogRecord_(this.getLogRecord(level, msg, opt_exception));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new log record and adds the exception (if present) to it.
|
||||
* @param {goog.debug.Logger.Level} level One of the level identifiers.
|
||||
* @param {string} msg The string message.
|
||||
* @param {Error|Object=} opt_exception An exception associated with the
|
||||
* message.
|
||||
* @return {!goog.debug.LogRecord} A log record.
|
||||
*/
|
||||
goog.debug.Logger.prototype.getLogRecord = function(level, msg, opt_exception) {
|
||||
if (goog.debug.LogBuffer.isBufferingEnabled()) {
|
||||
var logRecord =
|
||||
goog.debug.LogBuffer.getInstance().addRecord(level, msg, this.name_);
|
||||
} else {
|
||||
logRecord = new goog.debug.LogRecord(level, String(msg), this.name_);
|
||||
}
|
||||
if (opt_exception) {
|
||||
logRecord.setException(opt_exception);
|
||||
logRecord.setExceptionText(
|
||||
goog.debug.exposeException(opt_exception, arguments.callee.caller));
|
||||
}
|
||||
return logRecord;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Logs a message at the Logger.Level.SHOUT level.
|
||||
* If the logger is currently enabled for the given message level then the
|
||||
* given message is forwarded to all the registered output Handler objects.
|
||||
* @param {string} msg The string message.
|
||||
* @param {Error=} opt_exception An exception associated with the message.
|
||||
*/
|
||||
goog.debug.Logger.prototype.shout = function(msg, opt_exception) {
|
||||
if (goog.debug.LOGGING_ENABLED) {
|
||||
this.log(goog.debug.Logger.Level.SHOUT, msg, opt_exception);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Logs a message at the Logger.Level.SEVERE level.
|
||||
* If the logger is currently enabled for the given message level then the
|
||||
* given message is forwarded to all the registered output Handler objects.
|
||||
* @param {string} msg The string message.
|
||||
* @param {Error=} opt_exception An exception associated with the message.
|
||||
*/
|
||||
goog.debug.Logger.prototype.severe = function(msg, opt_exception) {
|
||||
if (goog.debug.LOGGING_ENABLED) {
|
||||
this.log(goog.debug.Logger.Level.SEVERE, msg, opt_exception);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Logs a message at the Logger.Level.WARNING level.
|
||||
* If the logger is currently enabled for the given message level then the
|
||||
* given message is forwarded to all the registered output Handler objects.
|
||||
* @param {string} msg The string message.
|
||||
* @param {Error=} opt_exception An exception associated with the message.
|
||||
*/
|
||||
goog.debug.Logger.prototype.warning = function(msg, opt_exception) {
|
||||
if (goog.debug.LOGGING_ENABLED) {
|
||||
this.log(goog.debug.Logger.Level.WARNING, msg, opt_exception);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Logs a message at the Logger.Level.INFO level.
|
||||
* If the logger is currently enabled for the given message level then the
|
||||
* given message is forwarded to all the registered output Handler objects.
|
||||
* @param {string} msg The string message.
|
||||
* @param {Error=} opt_exception An exception associated with the message.
|
||||
*/
|
||||
goog.debug.Logger.prototype.info = function(msg, opt_exception) {
|
||||
if (goog.debug.LOGGING_ENABLED) {
|
||||
this.log(goog.debug.Logger.Level.INFO, msg, opt_exception);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Logs a message at the Logger.Level.CONFIG level.
|
||||
* If the logger is currently enabled for the given message level then the
|
||||
* given message is forwarded to all the registered output Handler objects.
|
||||
* @param {string} msg The string message.
|
||||
* @param {Error=} opt_exception An exception associated with the message.
|
||||
*/
|
||||
goog.debug.Logger.prototype.config = function(msg, opt_exception) {
|
||||
if (goog.debug.LOGGING_ENABLED) {
|
||||
this.log(goog.debug.Logger.Level.CONFIG, msg, opt_exception);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Logs a message at the Logger.Level.FINE level.
|
||||
* If the logger is currently enabled for the given message level then the
|
||||
* given message is forwarded to all the registered output Handler objects.
|
||||
* @param {string} msg The string message.
|
||||
* @param {Error=} opt_exception An exception associated with the message.
|
||||
*/
|
||||
goog.debug.Logger.prototype.fine = function(msg, opt_exception) {
|
||||
if (goog.debug.LOGGING_ENABLED) {
|
||||
this.log(goog.debug.Logger.Level.FINE, msg, opt_exception);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Logs a message at the Logger.Level.FINER level.
|
||||
* If the logger is currently enabled for the given message level then the
|
||||
* given message is forwarded to all the registered output Handler objects.
|
||||
* @param {string} msg The string message.
|
||||
* @param {Error=} opt_exception An exception associated with the message.
|
||||
*/
|
||||
goog.debug.Logger.prototype.finer = function(msg, opt_exception) {
|
||||
if (goog.debug.LOGGING_ENABLED) {
|
||||
this.log(goog.debug.Logger.Level.FINER, msg, opt_exception);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Logs a message at the Logger.Level.FINEST level.
|
||||
* If the logger is currently enabled for the given message level then the
|
||||
* given message is forwarded to all the registered output Handler objects.
|
||||
* @param {string} msg The string message.
|
||||
* @param {Error=} opt_exception An exception associated with the message.
|
||||
*/
|
||||
goog.debug.Logger.prototype.finest = function(msg, opt_exception) {
|
||||
if (goog.debug.LOGGING_ENABLED) {
|
||||
this.log(goog.debug.Logger.Level.FINEST, msg, opt_exception);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Logs a LogRecord. If the logger is currently enabled for the
|
||||
* given message level then the given message is forwarded to all the
|
||||
* registered output Handler objects.
|
||||
* @param {goog.debug.LogRecord} logRecord A log record to log.
|
||||
*/
|
||||
goog.debug.Logger.prototype.logRecord = function(logRecord) {
|
||||
if (goog.debug.LOGGING_ENABLED && this.isLoggable(logRecord.getLevel())) {
|
||||
this.doLogRecord_(logRecord);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Logs a LogRecord.
|
||||
* @param {goog.debug.LogRecord} logRecord A log record to log.
|
||||
* @private
|
||||
*/
|
||||
goog.debug.Logger.prototype.doLogRecord_ = function(logRecord) {
|
||||
goog.debug.Logger.logToProfilers('log:' + logRecord.getMessage());
|
||||
if (goog.debug.Logger.ENABLE_HIERARCHY) {
|
||||
var target = this;
|
||||
while (target) {
|
||||
target.callPublish_(logRecord);
|
||||
target = target.getParent();
|
||||
}
|
||||
} else {
|
||||
for (var i = 0, handler; handler = goog.debug.Logger.rootHandlers_[i++]; ) {
|
||||
handler(logRecord);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Calls the handlers for publish.
|
||||
* @param {goog.debug.LogRecord} logRecord The log record to publish.
|
||||
* @private
|
||||
*/
|
||||
goog.debug.Logger.prototype.callPublish_ = function(logRecord) {
|
||||
if (this.handlers_) {
|
||||
for (var i = 0, handler; handler = this.handlers_[i]; i++) {
|
||||
handler(logRecord);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets the parent of this logger. This is used for setting up the logger tree.
|
||||
* @param {goog.debug.Logger} parent The parent logger.
|
||||
* @private
|
||||
*/
|
||||
goog.debug.Logger.prototype.setParent_ = function(parent) {
|
||||
this.parent_ = parent;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Adds a child to this logger. This is used for setting up the logger tree.
|
||||
* @param {string} name The leaf name of the child.
|
||||
* @param {goog.debug.Logger} logger The child logger.
|
||||
* @private
|
||||
*/
|
||||
goog.debug.Logger.prototype.addChild_ = function(name, logger) {
|
||||
this.getChildren()[name] = logger;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* There is a single global LogManager object that is used to maintain a set of
|
||||
* shared state about Loggers and log services. This is loosely based on the
|
||||
* java class java.util.logging.LogManager.
|
||||
*/
|
||||
goog.debug.LogManager = {};
|
||||
|
||||
|
||||
/**
|
||||
* Map of logger names to logger objects.
|
||||
*
|
||||
* @type {!Object}
|
||||
* @private
|
||||
*/
|
||||
goog.debug.LogManager.loggers_ = {};
|
||||
|
||||
|
||||
/**
|
||||
* The root logger which is the root of the logger tree.
|
||||
* @type {goog.debug.Logger}
|
||||
* @private
|
||||
*/
|
||||
goog.debug.LogManager.rootLogger_ = null;
|
||||
|
||||
|
||||
/**
|
||||
* Initializes the LogManager if not already initialized.
|
||||
*/
|
||||
goog.debug.LogManager.initialize = function() {
|
||||
if (!goog.debug.LogManager.rootLogger_) {
|
||||
goog.debug.LogManager.rootLogger_ = new goog.debug.Logger('');
|
||||
goog.debug.LogManager.loggers_[''] = goog.debug.LogManager.rootLogger_;
|
||||
goog.debug.LogManager.rootLogger_.setLevel(goog.debug.Logger.Level.CONFIG);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns all the loggers.
|
||||
* @return {!Object} Map of logger names to logger objects.
|
||||
*/
|
||||
goog.debug.LogManager.getLoggers = function() {
|
||||
return goog.debug.LogManager.loggers_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the root of the logger tree namespace, the logger with the empty
|
||||
* string as its name.
|
||||
*
|
||||
* @return {!goog.debug.Logger} The root logger.
|
||||
*/
|
||||
goog.debug.LogManager.getRoot = function() {
|
||||
goog.debug.LogManager.initialize();
|
||||
return /** @type {!goog.debug.Logger} */ (goog.debug.LogManager.rootLogger_);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Finds a named logger.
|
||||
*
|
||||
* @param {string} name A name for the logger. This should be a dot-separated
|
||||
* name and should normally be based on the package name or class name of the
|
||||
* subsystem, such as goog.net.BrowserChannel.
|
||||
* @return {!goog.debug.Logger} The named logger.
|
||||
*/
|
||||
goog.debug.LogManager.getLogger = function(name) {
|
||||
goog.debug.LogManager.initialize();
|
||||
var ret = goog.debug.LogManager.loggers_[name];
|
||||
return ret || goog.debug.LogManager.createLogger_(name);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a function that can be passed to goog.debug.catchErrors. The function
|
||||
* will log all reported errors using the given logger.
|
||||
* @param {goog.debug.Logger=} opt_logger The logger to log the errors to.
|
||||
* Defaults to the root logger.
|
||||
* @return {function(Object)} The created function.
|
||||
*/
|
||||
goog.debug.LogManager.createFunctionForCatchErrors = function(opt_logger) {
|
||||
return function(info) {
|
||||
var logger = opt_logger || goog.debug.LogManager.getRoot();
|
||||
logger.severe('Error: ' + info.message + ' (' + info.fileName +
|
||||
' @ Line: ' + info.line + ')');
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates the named logger. Will also create the parents of the named logger
|
||||
* if they don't yet exist.
|
||||
* @param {string} name The name of the logger.
|
||||
* @return {!goog.debug.Logger} The named logger.
|
||||
* @private
|
||||
*/
|
||||
goog.debug.LogManager.createLogger_ = function(name) {
|
||||
// find parent logger
|
||||
var logger = new goog.debug.Logger(name);
|
||||
if (goog.debug.Logger.ENABLE_HIERARCHY) {
|
||||
var lastDotIndex = name.lastIndexOf('.');
|
||||
var parentName = name.substr(0, lastDotIndex);
|
||||
var leafName = name.substr(lastDotIndex + 1);
|
||||
var parentLogger = goog.debug.LogManager.getLogger(parentName);
|
||||
|
||||
// tell the parent about the child and the child about the parent
|
||||
parentLogger.addChild_(leafName, logger);
|
||||
logger.setParent_(parentLogger);
|
||||
}
|
||||
|
||||
goog.debug.LogManager.loggers_[name] = logger;
|
||||
return logger;
|
||||
};
|
||||
271
nicer-api-docs/closure-library/closure/goog/debug/logrecord.js
Normal file
271
nicer-api-docs/closure-library/closure/goog/debug/logrecord.js
Normal file
@@ -0,0 +1,271 @@
|
||||
// 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 LogRecord 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.LogRecord');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* LogRecord objects are used to pass logging requests between
|
||||
* the logging framework and individual log Handlers.
|
||||
* @constructor
|
||||
* @param {goog.debug.Logger.Level} level One of the level identifiers.
|
||||
* @param {string} msg The string message.
|
||||
* @param {string} loggerName The name of the source logger.
|
||||
* @param {number=} opt_time Time this log record was created if other than now.
|
||||
* If 0, we use #goog.now.
|
||||
* @param {number=} opt_sequenceNumber Sequence number of this log record. This
|
||||
* should only be passed in when restoring a log record from persistence.
|
||||
*/
|
||||
goog.debug.LogRecord = function(level, msg, loggerName,
|
||||
opt_time, opt_sequenceNumber) {
|
||||
this.reset(level, msg, loggerName, opt_time, opt_sequenceNumber);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Time the LogRecord was created.
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
goog.debug.LogRecord.prototype.time_;
|
||||
|
||||
|
||||
/**
|
||||
* Level of the LogRecord
|
||||
* @type {goog.debug.Logger.Level}
|
||||
* @private
|
||||
*/
|
||||
goog.debug.LogRecord.prototype.level_;
|
||||
|
||||
|
||||
/**
|
||||
* Message associated with the record
|
||||
* @type {string}
|
||||
* @private
|
||||
*/
|
||||
goog.debug.LogRecord.prototype.msg_;
|
||||
|
||||
|
||||
/**
|
||||
* Name of the logger that created the record.
|
||||
* @type {string}
|
||||
* @private
|
||||
*/
|
||||
goog.debug.LogRecord.prototype.loggerName_;
|
||||
|
||||
|
||||
/**
|
||||
* Sequence number for the LogRecord. Each record has a unique sequence number
|
||||
* that is greater than all log records created before it.
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
goog.debug.LogRecord.prototype.sequenceNumber_ = 0;
|
||||
|
||||
|
||||
/**
|
||||
* Exception associated with the record
|
||||
* @type {Object}
|
||||
* @private
|
||||
*/
|
||||
goog.debug.LogRecord.prototype.exception_ = null;
|
||||
|
||||
|
||||
/**
|
||||
* Exception text associated with the record
|
||||
* @type {?string}
|
||||
* @private
|
||||
*/
|
||||
goog.debug.LogRecord.prototype.exceptionText_ = null;
|
||||
|
||||
|
||||
/**
|
||||
* @define {boolean} Whether to enable log sequence numbers.
|
||||
*/
|
||||
goog.define('goog.debug.LogRecord.ENABLE_SEQUENCE_NUMBERS', true);
|
||||
|
||||
|
||||
/**
|
||||
* A sequence counter for assigning increasing sequence numbers to LogRecord
|
||||
* objects.
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
goog.debug.LogRecord.nextSequenceNumber_ = 0;
|
||||
|
||||
|
||||
/**
|
||||
* Sets all fields of the log record.
|
||||
* @param {goog.debug.Logger.Level} level One of the level identifiers.
|
||||
* @param {string} msg The string message.
|
||||
* @param {string} loggerName The name of the source logger.
|
||||
* @param {number=} opt_time Time this log record was created if other than now.
|
||||
* If 0, we use #goog.now.
|
||||
* @param {number=} opt_sequenceNumber Sequence number of this log record. This
|
||||
* should only be passed in when restoring a log record from persistence.
|
||||
*/
|
||||
goog.debug.LogRecord.prototype.reset = function(level, msg, loggerName,
|
||||
opt_time, opt_sequenceNumber) {
|
||||
if (goog.debug.LogRecord.ENABLE_SEQUENCE_NUMBERS) {
|
||||
this.sequenceNumber_ = typeof opt_sequenceNumber == 'number' ?
|
||||
opt_sequenceNumber : goog.debug.LogRecord.nextSequenceNumber_++;
|
||||
}
|
||||
|
||||
this.time_ = opt_time || goog.now();
|
||||
this.level_ = level;
|
||||
this.msg_ = msg;
|
||||
this.loggerName_ = loggerName;
|
||||
delete this.exception_;
|
||||
delete this.exceptionText_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the source Logger's name.
|
||||
*
|
||||
* @return {string} source logger name (may be null).
|
||||
*/
|
||||
goog.debug.LogRecord.prototype.getLoggerName = function() {
|
||||
return this.loggerName_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the exception that is part of the log record.
|
||||
*
|
||||
* @return {Object} the exception.
|
||||
*/
|
||||
goog.debug.LogRecord.prototype.getException = function() {
|
||||
return this.exception_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Set the exception that is part of the log record.
|
||||
*
|
||||
* @param {Object} exception the exception.
|
||||
*/
|
||||
goog.debug.LogRecord.prototype.setException = function(exception) {
|
||||
this.exception_ = exception;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the exception text that is part of the log record.
|
||||
*
|
||||
* @return {?string} Exception text.
|
||||
*/
|
||||
goog.debug.LogRecord.prototype.getExceptionText = function() {
|
||||
return this.exceptionText_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Set the exception text that is part of the log record.
|
||||
*
|
||||
* @param {string} text The exception text.
|
||||
*/
|
||||
goog.debug.LogRecord.prototype.setExceptionText = function(text) {
|
||||
this.exceptionText_ = text;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the source Logger's name.
|
||||
*
|
||||
* @param {string} loggerName source logger name (may be null).
|
||||
*/
|
||||
goog.debug.LogRecord.prototype.setLoggerName = function(loggerName) {
|
||||
this.loggerName_ = loggerName;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the logging message level, for example Level.SEVERE.
|
||||
* @return {goog.debug.Logger.Level} the logging message level.
|
||||
*/
|
||||
goog.debug.LogRecord.prototype.getLevel = function() {
|
||||
return this.level_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Set the logging message level, for example Level.SEVERE.
|
||||
* @param {goog.debug.Logger.Level} level the logging message level.
|
||||
*/
|
||||
goog.debug.LogRecord.prototype.setLevel = function(level) {
|
||||
this.level_ = level;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the "raw" log message, before localization or formatting.
|
||||
*
|
||||
* @return {string} the raw message string.
|
||||
*/
|
||||
goog.debug.LogRecord.prototype.getMessage = function() {
|
||||
return this.msg_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Set the "raw" log message, before localization or formatting.
|
||||
*
|
||||
* @param {string} msg the raw message string.
|
||||
*/
|
||||
goog.debug.LogRecord.prototype.setMessage = function(msg) {
|
||||
this.msg_ = msg;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get event time in milliseconds since 1970.
|
||||
*
|
||||
* @return {number} event time in millis since 1970.
|
||||
*/
|
||||
goog.debug.LogRecord.prototype.getMillis = function() {
|
||||
return this.time_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Set event time in milliseconds since 1970.
|
||||
*
|
||||
* @param {number} time event time in millis since 1970.
|
||||
*/
|
||||
goog.debug.LogRecord.prototype.setMillis = function(time) {
|
||||
this.time_ = time;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the sequence number.
|
||||
* <p>
|
||||
* Sequence numbers are normally assigned in the LogRecord
|
||||
* constructor, which assigns unique sequence numbers to
|
||||
* each new LogRecord in increasing order.
|
||||
* @return {number} the sequence number.
|
||||
*/
|
||||
goog.debug.LogRecord.prototype.getSequenceNumber = function() {
|
||||
return this.sequenceNumber_;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
// Copyright 2011 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 Static methods for serializing and deserializing log
|
||||
* messages. These methods are deliberately kept separate from logrecord.js
|
||||
* and logger.js because they add dependencies on goog.json and goog.object.
|
||||
*
|
||||
*/
|
||||
|
||||
goog.provide('goog.debug.logRecordSerializer');
|
||||
|
||||
goog.require('goog.debug.LogRecord');
|
||||
goog.require('goog.debug.Logger.Level');
|
||||
goog.require('goog.json');
|
||||
goog.require('goog.object');
|
||||
|
||||
|
||||
/**
|
||||
* Enumeration of object keys used when serializing a log message.
|
||||
* @enum {string}
|
||||
* @private
|
||||
*/
|
||||
goog.debug.logRecordSerializer.Param_ = {
|
||||
TIME: 't',
|
||||
LEVEL_NAME: 'ln',
|
||||
LEVEL_VALUE: 'lv',
|
||||
MSG: 'm',
|
||||
LOGGER_NAME: 'n',
|
||||
SEQUENCE_NUMBER: 's',
|
||||
EXCEPTION: 'e',
|
||||
EXCEPTION_TEXT: 'et'
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Serializes a LogRecord to a JSON string. Note that any associated
|
||||
* exception is likely to be lost.
|
||||
* @param {goog.debug.LogRecord} record The record to serialize.
|
||||
* @return {string} Serialized JSON string of the log message.
|
||||
*/
|
||||
goog.debug.logRecordSerializer.serialize = function(record) {
|
||||
var param = goog.debug.logRecordSerializer.Param_;
|
||||
return goog.json.serialize(goog.object.create(
|
||||
param.TIME, record.getMillis(),
|
||||
param.LEVEL_NAME, record.getLevel().name,
|
||||
param.LEVEL_VALUE, record.getLevel().value,
|
||||
param.MSG, record.getMessage(),
|
||||
param.LOGGER_NAME, record.getLoggerName(),
|
||||
param.SEQUENCE_NUMBER, record.getSequenceNumber(),
|
||||
param.EXCEPTION, record.getException(),
|
||||
param.EXCEPTION_TEXT, record.getExceptionText()));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Deserializes a JSON-serialized LogRecord.
|
||||
* @param {string} s The JSON serialized record.
|
||||
* @return {!goog.debug.LogRecord} The deserialized record.
|
||||
*/
|
||||
goog.debug.logRecordSerializer.parse = function(s) {
|
||||
return goog.debug.logRecordSerializer.reconstitute_(goog.json.parse(s));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Deserializes a JSON-serialized LogRecord. Use this only if you're
|
||||
* naive enough to blindly trust any JSON formatted input that comes
|
||||
* your way.
|
||||
* @param {string} s The JSON serialized record.
|
||||
* @return {!goog.debug.LogRecord} The deserialized record.
|
||||
*/
|
||||
goog.debug.logRecordSerializer.unsafeParse = function(s) {
|
||||
return goog.debug.logRecordSerializer.reconstitute_(goog.json.unsafeParse(s));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Common reconsitution method for for parse and unsafeParse.
|
||||
* @param {Object} o The JSON object.
|
||||
* @return {!goog.debug.LogRecord} The reconstituted record.
|
||||
* @private
|
||||
*/
|
||||
goog.debug.logRecordSerializer.reconstitute_ = function(o) {
|
||||
var param = goog.debug.logRecordSerializer.Param_;
|
||||
var level = goog.debug.logRecordSerializer.getLevel_(
|
||||
o[param.LEVEL_NAME], o[param.LEVEL_VALUE]);
|
||||
|
||||
var ret = new goog.debug.LogRecord(level, o[param.MSG],
|
||||
o[param.LOGGER_NAME], o[param.TIME], o[param.SEQUENCE_NUMBER]);
|
||||
ret.setException(o[param.EXCEPTION]);
|
||||
ret.setExceptionText(o[param.EXCEPTION_TEXT]);
|
||||
return ret;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} name The name of the log level to return.
|
||||
* @param {number} value The numeric value of the log level to return.
|
||||
* @return {goog.debug.Logger.Level} Returns a goog.debug.Logger.Level with
|
||||
* the specified name and value. If the name and value match a predefined
|
||||
* log level, that instance will be returned, otherwise a new one will be
|
||||
* created.
|
||||
* @private
|
||||
*/
|
||||
goog.debug.logRecordSerializer.getLevel_ = function(name, value) {
|
||||
var level = goog.debug.Logger.Level.getPredefinedLevel(name);
|
||||
return level && level.value == value ?
|
||||
level : new goog.debug.Logger.Level(name, value);
|
||||
};
|
||||
178
nicer-api-docs/closure-library/closure/goog/debug/reflect.js
Normal file
178
nicer-api-docs/closure-library/closure/goog/debug/reflect.js
Normal file
@@ -0,0 +1,178 @@
|
||||
// Copyright 2011 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 JavaScript reflection tools. They should only be used for
|
||||
* debugging non-compiled code or tests, because there is no guarantee that
|
||||
* they work consistently in all browsers.
|
||||
*
|
||||
*/
|
||||
|
||||
goog.provide('goog.debug.reflect');
|
||||
|
||||
|
||||
/**
|
||||
* Maps the unique id of the known constructors to their full names.
|
||||
* Initialized lazily.
|
||||
* @type {Object.<number, string>}
|
||||
* @private
|
||||
*/
|
||||
goog.debug.reflect.typeMap_ = null;
|
||||
|
||||
|
||||
/**
|
||||
* List of all known constructors. Initialized lazily.
|
||||
* @type {Array.<!Function>}
|
||||
* @private
|
||||
*/
|
||||
goog.debug.reflect.constructors_ = null;
|
||||
|
||||
|
||||
/**
|
||||
* Copy of {@code Object.prototype.toString} to use if it is overridden later.
|
||||
* Although saving the original {@code toString} somewhat protects against
|
||||
* third-party libraries which touch {@code Object.prototype}, the actual goal
|
||||
* of this assignment is to allow overriding that method, thus more debug
|
||||
* information can be exposed about objects.
|
||||
* See {@link goog.debug.reflect.typeOf}.
|
||||
* @private
|
||||
*/
|
||||
goog.debug.reflect.toString_ = Object.prototype.toString;
|
||||
|
||||
|
||||
/**
|
||||
* Registers a type which will be recognized by goog.debug.reflect.typeOf.
|
||||
* @param {string} name Full name of the type.
|
||||
* @param {!Function} ctor The constructor.
|
||||
* @private
|
||||
*/
|
||||
goog.debug.reflect.registerType_ = function(name, ctor) {
|
||||
goog.debug.reflect.constructors_.push(ctor);
|
||||
goog.debug.reflect.typeMap_[goog.getUid(ctor)] = name;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Adds all known constructors to the type registry.
|
||||
* @private
|
||||
*/
|
||||
goog.debug.reflect.init_ = function() {
|
||||
if (goog.debug.reflect.typeMap_) {
|
||||
return;
|
||||
}
|
||||
|
||||
goog.debug.reflect.typeMap_ = {};
|
||||
goog.debug.reflect.constructors_ = [];
|
||||
var implicitNs = goog.getObjectByName('goog.implicitNamespaces_') || {};
|
||||
|
||||
for (var ns in implicitNs) {
|
||||
if (implicitNs.hasOwnProperty(ns)) {
|
||||
var nsObj = goog.getObjectByName(ns);
|
||||
for (var name in nsObj) {
|
||||
if (nsObj.hasOwnProperty(name) && goog.isFunction(nsObj[name])) {
|
||||
goog.debug.reflect.registerType_(ns + '.' + name, nsObj[name]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
goog.debug.reflect.registerType_('Array', Array);
|
||||
goog.debug.reflect.registerType_('Boolean', Boolean);
|
||||
goog.debug.reflect.registerType_('Date', Date);
|
||||
goog.debug.reflect.registerType_('Error', Error);
|
||||
goog.debug.reflect.registerType_('Function', Function);
|
||||
goog.debug.reflect.registerType_('Number', Number);
|
||||
goog.debug.reflect.registerType_('Object', Object);
|
||||
goog.debug.reflect.registerType_('String', String);
|
||||
|
||||
// The compiler gets upset if we alias regexp directly, because
|
||||
// then it can't optimize regexps as well. Just be sneaky about it,
|
||||
// because this is only for debugging.
|
||||
goog.debug.reflect.registerType_('RegExp', goog.global['RegExp']);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the name of a type of object.
|
||||
* @param {!Function} classConstructor A object constructor to get the name of.
|
||||
* @return {string|undefined} The string name of the class.
|
||||
*/
|
||||
goog.debug.reflect.className = function(classConstructor) {
|
||||
goog.debug.reflect.init_();
|
||||
if (goog.isDefAndNotNull(classConstructor)) {
|
||||
return goog.debug.reflect.typeMap_[goog.getUid(classConstructor)];
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Guesses the real type of the object, even if its {@code toString} method is
|
||||
* overridden. Gives exact result for all goog.provided classes in non-compiled
|
||||
* code, and some often used native classes in compiled code too. Not tested in
|
||||
* multi-frame environment.
|
||||
*
|
||||
* Example use case to get better type information in the Watch tab of FireBug:
|
||||
* <pre>
|
||||
* Object.prototype.toString = function() {
|
||||
* return goog.debug.reflect.typeOf(this);
|
||||
* };
|
||||
* </pre>
|
||||
*
|
||||
* @param {*} obj An arbitrary variable to get the type of.
|
||||
* @return {string} The namespaced type of the argument or 'Object' if didn't
|
||||
* manage to determine it. Warning: in IE7 ActiveX (including DOM) objects
|
||||
* don't expose their type to JavaScript. Their {@code constructor}
|
||||
* property is undefined and they are not even the instances of the
|
||||
* {@code Object} type. This method will recognize them as 'ActiveXObject'.
|
||||
*/
|
||||
goog.debug.reflect.typeOf = function(obj) {
|
||||
// Check primitive types.
|
||||
if (!obj || goog.isNumber(obj) || goog.isString(obj) || goog.isBoolean(obj)) {
|
||||
return goog.typeOf(obj);
|
||||
}
|
||||
|
||||
// Check if the type is present in the registry.
|
||||
goog.debug.reflect.init_();
|
||||
if (obj.constructor) {
|
||||
// Some DOM objects such as document don't have constructor in IE7.
|
||||
var type = goog.debug.reflect.typeMap_[goog.getUid(obj.constructor)];
|
||||
if (type) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
// In IE8 the internal 'class' property of ActiveXObjects is Object, but
|
||||
// String(obj) tells their real type.
|
||||
var isActiveXObject = goog.global.ActiveXObject &&
|
||||
obj instanceof ActiveXObject;
|
||||
var typeString = isActiveXObject ? String(obj) :
|
||||
goog.debug.reflect.toString_.call(/** @type {Object} */ (obj));
|
||||
var match = typeString.match(/^\[object (\w+)\]$/);
|
||||
if (match) {
|
||||
var name = match[1];
|
||||
var ctor = goog.global[name];
|
||||
try {
|
||||
if (obj instanceof ctor) {
|
||||
return name;
|
||||
}
|
||||
} catch (e) {
|
||||
// instanceof may fail if the guessed name is not a real type.
|
||||
}
|
||||
}
|
||||
|
||||
// Fall back to Object or ActiveXObject.
|
||||
return isActiveXObject ? 'ActiveXObject' : 'Object';
|
||||
};
|
||||
@@ -0,0 +1,83 @@
|
||||
// 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 Definition the goog.debug.RelativeTimeProvider class.
|
||||
*
|
||||
*/
|
||||
|
||||
goog.provide('goog.debug.RelativeTimeProvider');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A simple object to keep track of a timestamp considered the start of
|
||||
* something. The main use is for the logger system to maintain a start time
|
||||
* that is occasionally reset. For example, in Gmail, we reset this relative
|
||||
* time at the start of a user action so that timings are offset from the
|
||||
* beginning of the action. This class also provides a singleton as the default
|
||||
* behavior for most use cases is to share the same start time.
|
||||
*
|
||||
* @constructor
|
||||
*/
|
||||
goog.debug.RelativeTimeProvider = function() {
|
||||
/**
|
||||
* The start time.
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
this.relativeTimeStart_ = goog.now();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Default instance.
|
||||
* @type {goog.debug.RelativeTimeProvider}
|
||||
* @private
|
||||
*/
|
||||
goog.debug.RelativeTimeProvider.defaultInstance_ =
|
||||
new goog.debug.RelativeTimeProvider();
|
||||
|
||||
|
||||
/**
|
||||
* Sets the start time to the specified time.
|
||||
* @param {number} timeStamp The start time.
|
||||
*/
|
||||
goog.debug.RelativeTimeProvider.prototype.set = function(timeStamp) {
|
||||
this.relativeTimeStart_ = timeStamp;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Resets the start time to now.
|
||||
*/
|
||||
goog.debug.RelativeTimeProvider.prototype.reset = function() {
|
||||
this.set(goog.now());
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} The start time.
|
||||
*/
|
||||
goog.debug.RelativeTimeProvider.prototype.get = function() {
|
||||
return this.relativeTimeStart_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {goog.debug.RelativeTimeProvider} The default instance.
|
||||
*/
|
||||
goog.debug.RelativeTimeProvider.getDefaultInstance = function() {
|
||||
return goog.debug.RelativeTimeProvider.defaultInstance_;
|
||||
};
|
||||
724
nicer-api-docs/closure-library/closure/goog/debug/tracer.js
Normal file
724
nicer-api-docs/closure-library/closure/goog/debug/tracer.js
Normal file
@@ -0,0 +1,724 @@
|
||||
// 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 Tracer class and associated classes.
|
||||
*
|
||||
* @see ../demos/tracer.html
|
||||
*/
|
||||
|
||||
goog.provide('goog.debug.Trace');
|
||||
|
||||
goog.require('goog.array');
|
||||
goog.require('goog.iter');
|
||||
goog.require('goog.log');
|
||||
goog.require('goog.structs.Map');
|
||||
goog.require('goog.structs.SimplePool');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Class used for singleton goog.debug.Trace. Used for timing slow points in
|
||||
* the code. Based on the java Tracer class but optimized for javascript.
|
||||
* See com.google.common.tracing.Tracer.
|
||||
* @constructor
|
||||
* @private
|
||||
*/
|
||||
goog.debug.Trace_ = function() {
|
||||
|
||||
/**
|
||||
* Events in order.
|
||||
* @type {Array.<goog.debug.Trace_.Event_>}
|
||||
* @private
|
||||
*/
|
||||
this.events_ = [];
|
||||
|
||||
/**
|
||||
* Outstanding events that have started but haven't yet ended. The keys are
|
||||
* numeric ids and the values are goog.debug.Trace_.Event_ objects.
|
||||
* @type {goog.structs.Map}
|
||||
* @private
|
||||
*/
|
||||
this.outstandingEvents_ = new goog.structs.Map();
|
||||
|
||||
/**
|
||||
* Start time of the event trace
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
this.startTime_ = 0;
|
||||
|
||||
/**
|
||||
* Cummulative overhead of calls to startTracer
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
this.tracerOverheadStart_ = 0;
|
||||
|
||||
/**
|
||||
* Cummulative overhead of calls to endTracer
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
this.tracerOverheadEnd_ = 0;
|
||||
|
||||
/**
|
||||
* Cummulative overhead of calls to addComment
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
this.tracerOverheadComment_ = 0;
|
||||
|
||||
/**
|
||||
* Keeps stats on different types of tracers. The keys are strings and the
|
||||
* values are goog.debug.Stat
|
||||
* @type {goog.structs.Map}
|
||||
* @private
|
||||
*/
|
||||
this.stats_ = new goog.structs.Map();
|
||||
|
||||
/**
|
||||
* Total number of traces created in the trace.
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
this.tracerCount_ = 0;
|
||||
|
||||
/**
|
||||
* Total number of comments created in the trace.
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
this.commentCount_ = 0;
|
||||
|
||||
/**
|
||||
* Next id to use for the trace.
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
this.nextId_ = 1;
|
||||
|
||||
/**
|
||||
* A pool for goog.debug.Trace_.Event_ objects so we don't keep creating and
|
||||
* garbage collecting these (which is very expensive in IE6).
|
||||
* @type {goog.structs.SimplePool}
|
||||
* @private
|
||||
*/
|
||||
this.eventPool_ = new goog.structs.SimplePool(0, 4000);
|
||||
this.eventPool_.createObject = function() {
|
||||
return new goog.debug.Trace_.Event_();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* A pool for goog.debug.Trace_.Stat_ objects so we don't keep creating and
|
||||
* garbage collecting these (which is very expensive in IE6).
|
||||
* @type {goog.structs.SimplePool}
|
||||
* @private
|
||||
*/
|
||||
this.statPool_ = new goog.structs.SimplePool(0, 50);
|
||||
this.statPool_.createObject = function() {
|
||||
return new goog.debug.Trace_.Stat_();
|
||||
};
|
||||
|
||||
var that = this;
|
||||
this.idPool_ = new goog.structs.SimplePool(0, 2000);
|
||||
|
||||
// TODO(nicksantos): SimplePool is supposed to only return objects.
|
||||
// Reconcile this so that we don't have to cast to number below.
|
||||
this.idPool_.createObject = function() {
|
||||
return String(that.nextId_++);
|
||||
};
|
||||
this.idPool_.disposeObject = function(obj) {};
|
||||
|
||||
/**
|
||||
* Default threshold below which a tracer shouldn't be reported
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
this.defaultThreshold_ = 3;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Logger for the tracer
|
||||
* @type {goog.log.Logger}
|
||||
* @private
|
||||
*/
|
||||
goog.debug.Trace_.prototype.logger_ =
|
||||
goog.log.getLogger('goog.debug.Trace');
|
||||
|
||||
|
||||
/**
|
||||
* Maximum size of the trace before we discard events
|
||||
* @type {number}
|
||||
*/
|
||||
goog.debug.Trace_.prototype.MAX_TRACE_SIZE = 1000;
|
||||
|
||||
|
||||
/**
|
||||
* Event type supported by tracer
|
||||
* @enum {number}
|
||||
*/
|
||||
goog.debug.Trace_.EventType = {
|
||||
/**
|
||||
* Start event type
|
||||
*/
|
||||
START: 0,
|
||||
|
||||
/**
|
||||
* Stop event type
|
||||
*/
|
||||
STOP: 1,
|
||||
|
||||
/**
|
||||
* Comment event type
|
||||
*/
|
||||
COMMENT: 2
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Class to keep track of a stat of a single tracer type. Stores the count
|
||||
* and cumulative time.
|
||||
* @constructor
|
||||
* @private
|
||||
*/
|
||||
goog.debug.Trace_.Stat_ = function() {
|
||||
/**
|
||||
* Number of tracers
|
||||
* @type {number}
|
||||
*/
|
||||
this.count = 0;
|
||||
|
||||
/**
|
||||
* Cumulative time of traces
|
||||
* @type {number}
|
||||
*/
|
||||
this.time = 0;
|
||||
|
||||
/**
|
||||
* Total number of allocations for this tracer type
|
||||
* @type {number}
|
||||
*/
|
||||
this.varAlloc = 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @type {string|null|undefined}
|
||||
*/
|
||||
goog.debug.Trace_.Stat_.prototype.type;
|
||||
|
||||
|
||||
/**
|
||||
* @return {string} A string describing the tracer stat.
|
||||
* @override
|
||||
*/
|
||||
goog.debug.Trace_.Stat_.prototype.toString = function() {
|
||||
var sb = [];
|
||||
sb.push(this.type, ' ', this.count, ' (', Math.round(this.time * 10) / 10,
|
||||
' ms)');
|
||||
if (this.varAlloc) {
|
||||
sb.push(' [VarAlloc = ', this.varAlloc, ']');
|
||||
}
|
||||
return sb.join('');
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Private class used to encapsulate a single event, either the start or stop
|
||||
* of a tracer.
|
||||
* @constructor
|
||||
* @private
|
||||
*/
|
||||
goog.debug.Trace_.Event_ = function() {
|
||||
// the fields are different for different events - see usage in code
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @type {string|null|undefined}
|
||||
*/
|
||||
goog.debug.Trace_.Event_.prototype.type;
|
||||
|
||||
|
||||
/**
|
||||
* Returns a formatted string for the event.
|
||||
* @param {number} startTime The start time of the trace to generate relative
|
||||
* times.
|
||||
* @param {number} prevTime The completion time of the previous event or -1.
|
||||
* @param {string} indent Extra indent for the message
|
||||
* if there was no previous event.
|
||||
* @return {string} The formatted tracer string.
|
||||
*/
|
||||
goog.debug.Trace_.Event_.prototype.toTraceString = function(startTime, prevTime,
|
||||
indent) {
|
||||
var sb = [];
|
||||
|
||||
if (prevTime == -1) {
|
||||
sb.push(' ');
|
||||
} else {
|
||||
sb.push(goog.debug.Trace_.longToPaddedString_(this.eventTime - prevTime));
|
||||
}
|
||||
|
||||
sb.push(' ', goog.debug.Trace_.formatTime_(this.eventTime - startTime));
|
||||
if (this.eventType == goog.debug.Trace_.EventType.START) {
|
||||
sb.push(' Start ');
|
||||
} else if (this.eventType == goog.debug.Trace_.EventType.STOP) {
|
||||
sb.push(' Done ');
|
||||
var delta = this.stopTime - this.startTime;
|
||||
sb.push(goog.debug.Trace_.longToPaddedString_(delta), ' ms ');
|
||||
} else {
|
||||
sb.push(' Comment ');
|
||||
}
|
||||
|
||||
sb.push(indent, this);
|
||||
if (this.totalVarAlloc > 0) {
|
||||
sb.push('[VarAlloc ', this.totalVarAlloc, '] ');
|
||||
}
|
||||
return sb.join('');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {string} A string describing the tracer event.
|
||||
* @override
|
||||
*/
|
||||
goog.debug.Trace_.Event_.prototype.toString = function() {
|
||||
if (this.type == null) {
|
||||
return this.comment;
|
||||
} else {
|
||||
return '[' + this.type + '] ' + this.comment;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Add the ability to explicitly set the start time. This is useful for example
|
||||
* for measuring initial load time where you can set a variable as soon as the
|
||||
* main page of the app is loaded and then later call this function when the
|
||||
* Tracer code has been loaded.
|
||||
* @param {number} startTime The start time to set.
|
||||
*/
|
||||
goog.debug.Trace_.prototype.setStartTime = function(startTime) {
|
||||
this.startTime_ = startTime;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Initializes and resets the current trace
|
||||
* @param {number} defaultThreshold The default threshold below which the
|
||||
* tracer output will be supressed. Can be overridden on a per-Tracer basis.
|
||||
*/
|
||||
goog.debug.Trace_.prototype.initCurrentTrace = function(defaultThreshold) {
|
||||
this.reset(defaultThreshold);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Clears the current trace
|
||||
*/
|
||||
goog.debug.Trace_.prototype.clearCurrentTrace = function() {
|
||||
this.reset(0);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Resets the trace.
|
||||
* @param {number} defaultThreshold The default threshold below which the
|
||||
* tracer output will be supressed. Can be overridden on a per-Tracer basis.
|
||||
*/
|
||||
goog.debug.Trace_.prototype.reset = function(defaultThreshold) {
|
||||
this.defaultThreshold_ = defaultThreshold;
|
||||
|
||||
for (var i = 0; i < this.events_.length; i++) {
|
||||
var id = /** @type {Object} */ (this.eventPool_).id;
|
||||
if (id) {
|
||||
this.idPool_.releaseObject(id);
|
||||
}
|
||||
this.eventPool_.releaseObject(this.events_[i]);
|
||||
}
|
||||
|
||||
this.events_.length = 0;
|
||||
this.outstandingEvents_.clear();
|
||||
this.startTime_ = goog.debug.Trace_.now();
|
||||
this.tracerOverheadStart_ = 0;
|
||||
this.tracerOverheadEnd_ = 0;
|
||||
this.tracerOverheadComment_ = 0;
|
||||
this.tracerCount_ = 0;
|
||||
this.commentCount_ = 0;
|
||||
|
||||
var keys = this.stats_.getKeys();
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
var key = keys[i];
|
||||
var stat = this.stats_.get(key);
|
||||
stat.count = 0;
|
||||
stat.time = 0;
|
||||
stat.varAlloc = 0;
|
||||
this.statPool_.releaseObject(/** @type {Object} */ (stat));
|
||||
}
|
||||
this.stats_.clear();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Starts a tracer
|
||||
* @param {string} comment A comment used to identify the tracer. Does not
|
||||
* need to be unique.
|
||||
* @param {string=} opt_type Type used to identify the tracer. If a Trace is
|
||||
* given a type (the first argument to the constructor) and multiple Traces
|
||||
* are done on that type then a "TOTAL line will be produced showing the
|
||||
* total number of traces and the sum of the time
|
||||
* ("TOTAL Database 2 (37 ms)" in our example). These traces should be
|
||||
* mutually exclusive or else the sum won't make sense (the time will
|
||||
* be double counted if the second starts before the first ends).
|
||||
* @return {number} The identifier for the tracer that should be passed to the
|
||||
* the stopTracer method.
|
||||
*/
|
||||
goog.debug.Trace_.prototype.startTracer = function(comment, opt_type) {
|
||||
var tracerStartTime = goog.debug.Trace_.now();
|
||||
var varAlloc = this.getTotalVarAlloc();
|
||||
var outstandingEventCount = this.outstandingEvents_.getCount();
|
||||
if (this.events_.length + outstandingEventCount > this.MAX_TRACE_SIZE) {
|
||||
goog.log.warning(this.logger_,
|
||||
'Giant thread trace. Clearing to avoid memory leak.');
|
||||
// This is the more likely case. This usually means that we
|
||||
// either forgot to clear the trace or else we are performing a
|
||||
// very large number of events
|
||||
if (this.events_.length > this.MAX_TRACE_SIZE / 2) {
|
||||
for (var i = 0; i < this.events_.length; i++) {
|
||||
var event = this.events_[i];
|
||||
if (event.id) {
|
||||
this.idPool_.releaseObject(event.id);
|
||||
}
|
||||
this.eventPool_.releaseObject(event);
|
||||
}
|
||||
this.events_.length = 0;
|
||||
}
|
||||
|
||||
// This is less likely and probably indicates that a lot of traces
|
||||
// aren't being closed. We want to avoid unnecessarily clearing
|
||||
// this though in case the events do eventually finish.
|
||||
if (outstandingEventCount > this.MAX_TRACE_SIZE / 2) {
|
||||
this.outstandingEvents_.clear();
|
||||
}
|
||||
}
|
||||
|
||||
goog.debug.Logger.logToProfilers('Start : ' + comment);
|
||||
|
||||
var event = /** @type {goog.debug.Trace_.Event_} */ (
|
||||
this.eventPool_.getObject());
|
||||
event.totalVarAlloc = varAlloc;
|
||||
event.eventType = goog.debug.Trace_.EventType.START;
|
||||
event.id = Number(this.idPool_.getObject());
|
||||
event.comment = comment;
|
||||
event.type = opt_type;
|
||||
this.events_.push(event);
|
||||
this.outstandingEvents_.set(String(event.id), event);
|
||||
this.tracerCount_++;
|
||||
var now = goog.debug.Trace_.now();
|
||||
event.startTime = event.eventTime = now;
|
||||
this.tracerOverheadStart_ += now - tracerStartTime;
|
||||
return event.id;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Stops a tracer
|
||||
* @param {number|undefined|null} id The id of the tracer that is ending.
|
||||
* @param {number=} opt_silenceThreshold Threshold below which the tracer is
|
||||
* silenced.
|
||||
* @return {?number} The elapsed time for the tracer or null if the tracer
|
||||
* identitifer was not recognized.
|
||||
*/
|
||||
goog.debug.Trace_.prototype.stopTracer = function(id, opt_silenceThreshold) {
|
||||
// this used to call goog.isDef(opt_silenceThreshold) but that causes an
|
||||
// object allocation in IE for some reason (doh!). The following code doesn't
|
||||
// cause an allocation
|
||||
var now = goog.debug.Trace_.now();
|
||||
var silenceThreshold;
|
||||
if (opt_silenceThreshold === 0) {
|
||||
silenceThreshold = 0;
|
||||
} else if (opt_silenceThreshold) {
|
||||
silenceThreshold = opt_silenceThreshold;
|
||||
} else {
|
||||
silenceThreshold = this.defaultThreshold_;
|
||||
}
|
||||
|
||||
var startEvent = this.outstandingEvents_.get(String(id));
|
||||
if (startEvent == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
this.outstandingEvents_.remove(String(id));
|
||||
|
||||
var stopEvent;
|
||||
var elapsed = now - startEvent.startTime;
|
||||
if (elapsed < silenceThreshold) {
|
||||
var count = this.events_.length;
|
||||
for (var i = count - 1; i >= 0; i--) {
|
||||
var nextEvent = this.events_[i];
|
||||
if (nextEvent == startEvent) {
|
||||
this.events_.splice(i, 1);
|
||||
this.idPool_.releaseObject(startEvent.id);
|
||||
this.eventPool_.releaseObject(/** @type {Object} */ (startEvent));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
stopEvent = /** @type {goog.debug.Trace_.Event_} */ (
|
||||
this.eventPool_.getObject());
|
||||
stopEvent.eventType = goog.debug.Trace_.EventType.STOP;
|
||||
stopEvent.startTime = startEvent.startTime;
|
||||
stopEvent.comment = startEvent.comment;
|
||||
stopEvent.type = startEvent.type;
|
||||
stopEvent.stopTime = stopEvent.eventTime = now;
|
||||
|
||||
this.events_.push(stopEvent);
|
||||
}
|
||||
|
||||
var type = startEvent.type;
|
||||
var stat = null;
|
||||
if (type) {
|
||||
stat = this.getStat_(type);
|
||||
stat.count++;
|
||||
stat.time += elapsed;
|
||||
}
|
||||
if (stopEvent) {
|
||||
goog.debug.Logger.logToProfilers('Stop : ' + stopEvent.comment);
|
||||
|
||||
stopEvent.totalVarAlloc = this.getTotalVarAlloc();
|
||||
|
||||
if (stat) {
|
||||
stat.varAlloc += (stopEvent.totalVarAlloc - startEvent.totalVarAlloc);
|
||||
}
|
||||
}
|
||||
var tracerFinishTime = goog.debug.Trace_.now();
|
||||
this.tracerOverheadEnd_ += tracerFinishTime - now;
|
||||
return elapsed;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets the ActiveX object that can be used to get GC tracing in IE6.
|
||||
* @param {Object} gcTracer GCTracer ActiveX object.
|
||||
*/
|
||||
goog.debug.Trace_.prototype.setGcTracer = function(gcTracer) {
|
||||
this.gcTracer_ = gcTracer;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the total number of allocations since the GC stats were reset. Only
|
||||
* works in IE.
|
||||
* @return {number} The number of allocaitons or -1 if not supported.
|
||||
*/
|
||||
goog.debug.Trace_.prototype.getTotalVarAlloc = function() {
|
||||
var gcTracer = this.gcTracer_;
|
||||
// isTracing is defined on the ActiveX object.
|
||||
if (gcTracer && gcTracer['isTracing']()) {
|
||||
return gcTracer['totalVarAlloc'];
|
||||
}
|
||||
return -1;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Adds a comment to the trace. Makes it possible to see when a specific event
|
||||
* happened in relation to the traces.
|
||||
* @param {string} comment A comment that is inserted into the trace.
|
||||
* @param {?string=} opt_type Type used to identify the tracer. If a comment is
|
||||
* given a type and multiple comments are done on that type then a "TOTAL
|
||||
* line will be produced showing the total number of comments of that type.
|
||||
* @param {?number=} opt_timeStamp The timestamp to insert the comment. If not
|
||||
* specified, the current time wil be used.
|
||||
*/
|
||||
goog.debug.Trace_.prototype.addComment = function(comment, opt_type,
|
||||
opt_timeStamp) {
|
||||
var now = goog.debug.Trace_.now();
|
||||
var timeStamp = opt_timeStamp ? opt_timeStamp : now;
|
||||
|
||||
var eventComment = /** @type {goog.debug.Trace_.Event_} */ (
|
||||
this.eventPool_.getObject());
|
||||
eventComment.eventType = goog.debug.Trace_.EventType.COMMENT;
|
||||
eventComment.eventTime = timeStamp;
|
||||
eventComment.type = opt_type;
|
||||
eventComment.comment = comment;
|
||||
eventComment.totalVarAlloc = this.getTotalVarAlloc();
|
||||
this.commentCount_++;
|
||||
|
||||
if (opt_timeStamp) {
|
||||
var numEvents = this.events_.length;
|
||||
for (var i = 0; i < numEvents; i++) {
|
||||
var event = this.events_[i];
|
||||
var eventTime = event.eventTime;
|
||||
|
||||
if (eventTime > timeStamp) {
|
||||
goog.array.insertAt(this.events_, eventComment, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == numEvents) {
|
||||
this.events_.push(eventComment);
|
||||
}
|
||||
} else {
|
||||
this.events_.push(eventComment);
|
||||
}
|
||||
|
||||
var type = eventComment.type;
|
||||
if (type) {
|
||||
var stat = this.getStat_(type);
|
||||
stat.count++;
|
||||
}
|
||||
|
||||
this.tracerOverheadComment_ += goog.debug.Trace_.now() - now;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Gets a stat object for a particular type. The stat object is created if it
|
||||
* hasn't yet been.
|
||||
* @param {string} type The type of stat.
|
||||
* @return {goog.debug.Trace_.Stat_} The stat object.
|
||||
* @private
|
||||
*/
|
||||
goog.debug.Trace_.prototype.getStat_ = function(type) {
|
||||
var stat = this.stats_.get(type);
|
||||
if (!stat) {
|
||||
stat = /** @type {goog.debug.Trace_.Event_} */ (
|
||||
this.statPool_.getObject());
|
||||
stat.type = type;
|
||||
this.stats_.set(type, stat);
|
||||
}
|
||||
return /** @type {goog.debug.Trace_.Stat_} */(stat);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns a formatted string for the current trace
|
||||
* @return {string} A formatted string that shows the timings of the current
|
||||
* trace.
|
||||
*/
|
||||
goog.debug.Trace_.prototype.getFormattedTrace = function() {
|
||||
return this.toString();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns a formatted string that describes the thread trace.
|
||||
* @return {string} A formatted string.
|
||||
* @override
|
||||
*/
|
||||
goog.debug.Trace_.prototype.toString = function() {
|
||||
var sb = [];
|
||||
var etime = -1;
|
||||
var indent = [];
|
||||
for (var i = 0; i < this.events_.length; i++) {
|
||||
var e = this.events_[i];
|
||||
if (e.eventType == goog.debug.Trace_.EventType.STOP) {
|
||||
indent.pop();
|
||||
}
|
||||
sb.push(' ', e.toTraceString(this.startTime_, etime, indent.join('')));
|
||||
etime = e.eventTime;
|
||||
sb.push('\n');
|
||||
if (e.eventType == goog.debug.Trace_.EventType.START) {
|
||||
indent.push('| ');
|
||||
}
|
||||
}
|
||||
|
||||
if (this.outstandingEvents_.getCount() != 0) {
|
||||
var now = goog.debug.Trace_.now();
|
||||
|
||||
sb.push(' Unstopped timers:\n');
|
||||
goog.iter.forEach(this.outstandingEvents_, function(startEvent) {
|
||||
sb.push(' ', startEvent, ' (', now - startEvent.startTime,
|
||||
' ms, started at ',
|
||||
goog.debug.Trace_.formatTime_(startEvent.startTime),
|
||||
')\n');
|
||||
});
|
||||
}
|
||||
|
||||
var statKeys = this.stats_.getKeys();
|
||||
for (var i = 0; i < statKeys.length; i++) {
|
||||
var stat = this.stats_.get(statKeys[i]);
|
||||
if (stat.count > 1) {
|
||||
sb.push(' TOTAL ', stat, '\n');
|
||||
}
|
||||
}
|
||||
|
||||
sb.push('Total tracers created ', this.tracerCount_, '\n',
|
||||
'Total comments created ', this.commentCount_, '\n',
|
||||
'Overhead start: ', this.tracerOverheadStart_, ' ms\n',
|
||||
'Overhead end: ', this.tracerOverheadEnd_, ' ms\n',
|
||||
'Overhead comment: ', this.tracerOverheadComment_, ' ms\n');
|
||||
|
||||
return sb.join('');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Converts 'v' to a string and pads it with up to 3 spaces for
|
||||
* improved alignment. TODO there must be a better way
|
||||
* @param {number} v A number.
|
||||
* @return {string} A padded string.
|
||||
* @private
|
||||
*/
|
||||
goog.debug.Trace_.longToPaddedString_ = function(v) {
|
||||
v = Math.round(v);
|
||||
// todo (pupius) - there should be a generic string in goog.string for this
|
||||
var space = '';
|
||||
if (v < 1000) space = ' ';
|
||||
if (v < 100) space = ' ';
|
||||
if (v < 10) space = ' ';
|
||||
return space + v;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Return the sec.ms part of time (if time = "20:06:11.566", "11.566
|
||||
* @param {number} time The time in MS.
|
||||
* @return {string} A formatted string as sec.ms'.
|
||||
* @private
|
||||
*/
|
||||
goog.debug.Trace_.formatTime_ = function(time) {
|
||||
time = Math.round(time);
|
||||
var sec = (time / 1000) % 60;
|
||||
var ms = time % 1000;
|
||||
|
||||
// TODO their must be a nicer way to get zero padded integers
|
||||
return String(100 + sec).substring(1, 3) + '.' +
|
||||
String(1000 + ms).substring(1, 4);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the current time. Done through a wrapper function so it can be
|
||||
* overridden by application code. Gmail has an ActiveX extension that provides
|
||||
* higher precision timing info.
|
||||
* @return {number} The current time in milliseconds.
|
||||
*/
|
||||
goog.debug.Trace_.now = function() {
|
||||
return goog.now();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Singleton trace object
|
||||
* @type {goog.debug.Trace_}
|
||||
*/
|
||||
goog.debug.Trace = new goog.debug.Trace_();
|
||||
Reference in New Issue
Block a user