update YUI to 2.8.0r4

This commit is contained in:
Graham Knop 2009-09-21 12:54:44 -05:00
parent 27f474ec64
commit 2d28e0c0ba
2007 changed files with 344487 additions and 210070 deletions

View file

@ -1,8 +1,8 @@
/*
Copyright (c) 2008, Yahoo! Inc. All rights reserved.
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 2.6.0
version: 2.8.0r4
*/
YAHOO.namespace("tool");
@ -19,33 +19,39 @@ YAHOO.namespace("tool");
* @class Profiler
* @static
*/
YAHOO.tool.Profiler = {
YAHOO.tool.Profiler = function(){
//-------------------------------------------------------------------------
// Private Properties
// Private Variables and Functions
//-------------------------------------------------------------------------
/**
* Container object on which to put the original unprofiled methods.
* @type Object
* @private
* @static
* @property _container
*/
_container : new Object(),
/**
* Call information for functions.
* @type Object
* @private
* @static
* @property _report
*/
_report : new Object(),
//-------------------------------------------------------------------------
// Private Methods
//-------------------------------------------------------------------------
var container = {}, //Container object on which to put the original unprofiled methods.
report = {}, //Profiling information for functions
stopwatches = {}, //Additional stopwatch information
WATCH_STARTED = 0,
WATCH_STOPPED = 1,
WATCH_PAUSED = 2,
lang = YAHOO.lang;
/**
* Creates a report object with the given name.
* @param {String} name The name to store for the report object.
* @return {Void}
* @method createReport
* @private
*/
function createReport(name){
report[name] = {
calls: 0,
max: 0,
min: 0,
avg: 0,
points: []
};
}
/**
* Called when a method ends execution. Marks the start and end time of the
@ -55,13 +61,19 @@ YAHOO.tool.Profiler = {
* @param {int} duration The number of milliseconds it took the function to
* execute.
* @return {Void}
* @method saveDataPoint
* @private
* @static
*/
_saveData : function (name /*:String*/, duration /*:int*/){
function saveDataPoint(name, duration){
//get the function data
var functionData /*:Object*/ = this._report[name];
var functionData /*:Object*/ = report[name];
//just in case clear() was called
if (!functionData){
functionData = createReport(name);
}
//increment the calls
functionData.calls++;
@ -78,303 +90,468 @@ YAHOO.tool.Profiler = {
functionData.max = duration;
}
},
}
//-------------------------------------------------------------------------
// Reporting Methods
//-------------------------------------------------------------------------
// Singleton Object
//-------------------------------------------------------------------------
/**
* Returns the average amount of time (in milliseconds) that the function
* with the given name takes to execute.
* @param {String} name The name of the function whose data should be returned.
* If an object type method, it should be 'constructor.prototype.methodName';
* a normal object method would just be 'object.methodName'.
* @return {float} The average time it takes the function to execute.
* @static
*/
getAverage : function (name /*:String*/) /*:float*/ {
return this._report[name].avg;
},
/**
* Returns the number of times that the given function has been called.
* @param {String} name The name of the function whose data should be returned.
* @return {int} The number of times the function was called.
* @static
*/
getCallCount : function (name /*:String*/) /*:int*/ {
return this._report[name].calls;
},
return {
/**
* Returns the maximum amount of time (in milliseconds) that the function
* with the given name takes to execute.
* @param {String} name The name of the function whose data should be returned.
* If an object type method, it should be 'constructor.prototype.methodName';
* a normal object method would just be 'object.methodName'.
* @return {float} The maximum time it takes the function to execute.
*/
getMax : function (name /*:String*/) /*:int*/ {
return this._report[name].max;
},
/**
* Returns the minimum amount of time (in milliseconds) that the function
* with the given name takes to execute.
* @param {String} name The name of the function whose data should be returned.
* If an object type method, it should be 'constructor.prototype.methodName';
* a normal object method would just be 'object.methodName'.
* @return {float} The minimum time it takes the function to execute.
*/
getMin : function (name /*:String*/) /*:int*/ {
return this._report[name].min;
},
/**
* Returns an object containing profiling data for a single function.
* The object has an entry for min, max, avg, calls, and points).
* @return {Object} An object containing profile data for a given function.
* @static
*/
getFunctionReport : function (name /*:String*/) /*:Object*/ {
return this._report[name];
},
/**
* Returns an object containing profiling data for all of the functions
* that were profiled. The object has an entry for each function and
* returns all information (min, max, average, calls, etc.) for each
* function.
* @return {Object} An object containing all profile data.
* @static
*/
getFullReport : function (filter /*:Function*/) /*:Object*/ {
filter = filter || function(){return true;};
if (YAHOO.lang.isFunction(filter)) {
var report = {};
for (var name in this._report){
if (filter(this._report[name])){
report[name] = this._report[name];
}
//-------------------------------------------------------------------------
// Utility Methods
//-------------------------------------------------------------------------
/**
* Removes all report data from the profiler.
* @param {String} name (Optional) The name of the report to clear. If
* omitted, then all report data is cleared.
* @return {Void}
* @method clear
* @static
*/
clear: function(name){
if (lang.isString(name)){
delete report[name];
delete stopwatches[name];
} else {
report = {};
stopwatches = {};
}
return report;
}
},
},
//-------------------------------------------------------------------------
// Profiling Methods
//-------------------------------------------------------------------------
/**
* Returns the uninstrumented version of a function/object.
* @param {String} name The name of the function/object to retrieve.
* @return {Function|Object} The uninstrumented version of a function/object.
* @method getOriginal
* @static
*/
getOriginal: function(name){
return container[name];
},
/**
* Sets up a constructor for profiling, including all properties and methods on the prototype.
* @param {string} name The fully-qualified name of the function including namespace information.
* @param {Object} owner (Optional) The object that owns the function (namespace or containing object).
* @return {Void}
* @static
*/
registerConstructor : function (name /*:String*/, owner /*:Object*/) /*:Void*/ {
this.registerFunction(name, owner, true);
},
/**
* Sets up a function for profiling. It essentially overwrites the function with one
* that has instrumentation data. This method also creates an entry for the function
* in the profile report. The original function is stored on the _container object.
* @param {String} name The full name of the function including namespacing. This
* is the name of the function that is stored in the report.
* @param {Object} owner (Optional) The object that owns the function. If the function
* isn't global then this argument is required. This could be the namespace that
* the function belongs to, such as YAHOO.util.Dom, or the object on which it's
* a method.
* @return {Void}
* @method registerFunction
*/
registerFunction : function(name /*:String*/, owner /*:Object*/, registerPrototype /*:Boolean*/) /*:Void*/{
/**
* Instruments a method to have profiling calls.
* @param {String} name The name of the report for the function.
* @param {Function} method The function to instrument.
* @return {Function} An instrumented version of the function.
* @method instrument
* @static
*/
instrument: function(name, method){
//create instrumented version of function
var newMethod = function () {
//figure out the function name without namespacing
var funcName /*:String*/ = (name.indexOf(".") > -1 ? name.substring(name.lastIndexOf(".")+1) : name);
if (!YAHOO.lang.isObject(owner)){
owner = eval(name.substring(0, name.lastIndexOf(".")));
}
//get the method and prototype
var method /*:Function*/ = owner[funcName];
var prototype /*:Object*/ = method.prototype;
//see if the method has already been registered
if (YAHOO.lang.isFunction(method) && !method.__yuiProfiled){
//create a new slot for the original method
this._container[name] = method;
//replace the function with the profiling one
owner[funcName] = function () {
var start = new Date();
var retval = method.apply(this, arguments);
var stop = new Date();
var start = new Date(),
retval = method.apply(this, arguments),
stop = new Date();
YAHOO.tool.Profiler._saveData(name, stop-start);
saveDataPoint(name, stop-start);
return retval;
};
//copy the function properties over
YAHOO.lang.augmentObject(owner[funcName], method);
owner[funcName].__yuiProfiled = true;
owner[funcName].prototype = prototype;
this._container[name].__yuiOwner = owner;
this._container[name].__yuiFuncName = funcName;
//register prototype if necessary
if (registerPrototype) {
this.registerObject(name + ".prototype", prototype);
}
//store function information
this._report[name] = {
calls: 0,
max: 0,
min: 0,
avg: 0,
points: []
};
}
return method;
},
/**
* Sets up an object for profiling. It takes the object and looks for functions.
* When a function is found, registerMethod() is called on it. If set to recrusive
* mode, it will also setup objects found inside of this object for profiling,
* using the same methodology.
* @param {String} name The name of the object to profile (shows up in report).
* @param {Object} owner (Optional) The object represented by the name.
* @param {Boolean} recurse (Optional) Determines if subobject methods are also profiled.
* @return {Void}
* @static
*/
registerObject : function (name /*:String*/, object /*:Object*/, recurse /*:Boolean*/) /*:Void*/{
//get the object
object = (YAHOO.lang.isObject(object) ? object : eval(name));
//save the object
this._container[name] = object;
for (var prop in object) {
if (typeof object[prop] == "function"){
if (prop != "constructor" && prop != "superclass"){ //don't do constructor or superclass, it's recursive
this.registerFunction(name + "." + prop, object);
}
} else if (typeof object[prop] == "object" && recurse){
this.registerObject(name + "." + prop, object[prop], recurse);
}
}
},
/**
* Removes a constructor function from profiling. Reverses the registerConstructor() method.
* @param {String} name The full name of the function including namespacing. This
* is the name of the function that is stored in the report.
* @return {Void}
* @method unregisterFunction
*/
unregisterConstructor : function(name /*:String*/) /*:Void*/{
//see if the method has been registered
if (YAHOO.lang.isFunction(this._container[name])){
//get original data
//var owner /*:Object*/ = this._container[name].__yuiOwner;
//var funcName /*:String*/ = this._container[name].__yuiFuncName;
//delete this._container[name].__yuiOwner;
//delete this._container[name].__yuiFuncName;
//replace instrumented function
//owner[funcName] = this._container[name];
//delete this._container[name];
this.unregisterFunction(name, true);
}
};
},
/**
* Removes function from profiling. Reverses the registerFunction() method.
* @param {String} name The full name of the function including namespacing. This
* is the name of the function that is stored in the report.
* @return {Void}
* @method unregisterFunction
*/
unregisterFunction : function(name /*:String*/, unregisterPrototype /*:Boolean*/) /*:Void*/{
//copy the function properties over
lang.augmentObject(newMethod, method);
//see if the method has been registered
if (YAHOO.lang.isFunction(this._container[name])){
//assign prototype and flag as being profiled
newMethod.__yuiProfiled = true;
newMethod.prototype = method.prototype;
//store original method
container[name] = method;
container[name].__yuiFuncName = name;
//create the report
createReport(name);
//return the new method
return newMethod;
},
//check to see if you should unregister the prototype
if (unregisterPrototype){
this.unregisterObject(name + ".prototype", this._container[name].prototype);
}
//-------------------------------------------------------------------------
// Stopwatch Methods
//-------------------------------------------------------------------------
/**
* Pauses profiling information for a given name.
* @param {String} name The name of the data point.
* @return {Void}
* @method pause
* @static
*/
pause: function(name){
var now = new Date(),
stopwatch = stopwatches[name];
//get original data
var owner /*:Object*/ = this._container[name].__yuiOwner;
var funcName /*:String*/ = this._container[name].__yuiFuncName;
delete this._container[name].__yuiOwner;
delete this._container[name].__yuiFuncName;
if (stopwatch && stopwatch.state == WATCH_STARTED){
stopwatch.total += (now - stopwatch.start);
stopwatch.start = 0;
stopwatch.state = WATCH_PAUSED;
}
},
/**
* Start profiling information for a given name. The name cannot be the name
* of a registered function or object. This is used to start timing for a
* particular block of code rather than instrumenting the entire function.
* @param {String} name The name of the data point.
* @return {Void}
* @method start
* @static
*/
start: function(name){
if(container[name]){
throw new Error("Cannot use '" + name + "' for profiling through start(), name is already in use.");
} else {
//replace instrumented function
owner[funcName] = this._container[name];
//create report if necessary
if (!report[name]){
createReport(name);
}
//create stopwatch object if necessary
if (!stopwatches[name]){
stopwatches[name] = {
state: WATCH_STOPPED,
start: 0,
total: 0
};
}
if (stopwatches[name].state == WATCH_STOPPED){
stopwatches[name].state = WATCH_STARTED;
stopwatches[name].start = new Date();
}
}
},
/**
* Stops profiling information for a given name.
* @param {String} name The name of the data point.
* @return {Void}
* @method stop
* @static
*/
stop: function(name){
var now = new Date(),
stopwatch = stopwatches[name];
if (stopwatch){
if (stopwatch.state == WATCH_STARTED){
saveDataPoint(name, stopwatch.total + (now - stopwatch.start));
} else if (stopwatch.state == WATCH_PAUSED){
saveDataPoint(name, stopwatch.total);
}
//reset stopwatch information
stopwatch.start = 0;
stopwatch.total = 0;
stopwatch.state = WATCH_STOPPED;
}
},
//-------------------------------------------------------------------------
// Reporting Methods
//-------------------------------------------------------------------------
/**
* Returns the average amount of time (in milliseconds) that the function
* with the given name takes to execute.
* @param {String} name The name of the function whose data should be returned.
* If an object type method, it should be 'constructor.prototype.methodName';
* a normal object method would just be 'object.methodName'.
* @return {float} The average time it takes the function to execute.
* @method getAverage
* @static
*/
getAverage : function (name /*:String*/) /*:float*/ {
return report[name].avg;
},
/**
* Returns the number of times that the given function has been called.
* @param {String} name The name of the function whose data should be returned.
* @return {int} The number of times the function was called.
* @method getCallCount
* @static
*/
getCallCount : function (name /*:String*/) /*:int*/ {
return report[name].calls;
},
/**
* Returns the maximum amount of time (in milliseconds) that the function
* with the given name takes to execute.
* @param {String} name The name of the function whose data should be returned.
* If an object type method, it should be 'constructor.prototype.methodName';
* a normal object method would just be 'object.methodName'.
* @return {float} The maximum time it takes the function to execute.
* @method getMax
* @static
*/
getMax : function (name /*:String*/) /*:int*/ {
return report[name].max;
},
/**
* Returns the minimum amount of time (in milliseconds) that the function
* with the given name takes to execute.
* @param {String} name The name of the function whose data should be returned.
* If an object type method, it should be 'constructor.prototype.methodName';
* a normal object method would just be 'object.methodName'.
* @return {float} The minimum time it takes the function to execute.
* @method getMin
* @static
*/
getMin : function (name /*:String*/) /*:int*/ {
return report[name].min;
},
/**
* Returns an object containing profiling data for a single function.
* The object has an entry for min, max, avg, calls, and points).
* @return {Object} An object containing profile data for a given function.
* @method getFunctionReport
* @static
* @deprecated Use getReport() instead.
*/
getFunctionReport : function (name /*:String*/) /*:Object*/ {
return report[name];
},
/**
* Returns an object containing profiling data for a single function.
* The object has an entry for min, max, avg, calls, and points).
* @return {Object} An object containing profile data for a given function.
* @method getReport
* @static
*/
getReport : function (name /*:String*/) /*:Object*/ {
return report[name];
},
/**
* Returns an object containing profiling data for all of the functions
* that were profiled. The object has an entry for each function and
* returns all information (min, max, average, calls, etc.) for each
* function.
* @return {Object} An object containing all profile data.
* @static
*/
getFullReport : function (filter /*:Function*/) /*:Object*/ {
filter = filter || function(){return true;};
if (lang.isFunction(filter)) {
var fullReport = {};
for (var name in report){
if (filter(report[name])){
fullReport[name] = report[name];
}
}
return fullReport;
}
},
//-------------------------------------------------------------------------
// Profiling Methods
//-------------------------------------------------------------------------
/**
* Sets up a constructor for profiling, including all properties and methods on the prototype.
* @param {string} name The fully-qualified name of the function including namespace information.
* @param {Object} owner (Optional) The object that owns the function (namespace or containing object).
* @return {Void}
* @method registerConstructor
* @static
*/
registerConstructor : function (name /*:String*/, owner /*:Object*/) /*:Void*/ {
this.registerFunction(name, owner, true);
},
/**
* Sets up a function for profiling. It essentially overwrites the function with one
* that has instrumentation data. This method also creates an entry for the function
* in the profile report. The original function is stored on the container object.
* @param {String} name The full name of the function including namespacing. This
* is the name of the function that is stored in the report.
* @param {Object} owner (Optional) The object that owns the function. If the function
* isn't global then this argument is required. This could be the namespace that
* the function belongs to, such as YAHOO.util.Dom, or the object on which it's
* a method.
* @param {Boolean} registerPrototype (Optional) Indicates that the prototype should
* also be instrumented. Setting to true has the same effect as calling
* registerConstructor().
* @return {Void}
* @method registerFunction
* @static
*/
registerFunction : function(name /*:String*/, owner /*:Object*/, registerPrototype /*:Boolean*/) /*:Void*/{
//figure out the function name without namespacing
var funcName = (name.indexOf(".") > -1 ?
name.substring(name.lastIndexOf(".")+1) : name),
method,
prototype;
//if owner isn't an object, try to find it from the name
if (!lang.isObject(owner)){
owner = eval(name.substring(0, name.lastIndexOf(".")));
}
//delete supporting information
delete this._container[name];
delete this._report[name];
}
//get the method and prototype
method = owner[funcName];
prototype = method.prototype;
//see if the method has already been registered
if (lang.isFunction(method) && !method.__yuiProfiled){
//replace the function with the profiling one
owner[funcName] = this.instrument(name, method);
/*
* Store original function information. We store the actual
* function as well as the owner and the name used to identify
* the function so it can be restored later.
*/
container[name].__yuiOwner = owner;
container[name].__yuiFuncName = funcName; //overwrite with less-specific name
//register prototype if necessary
if (registerPrototype) {
this.registerObject(name + ".prototype", prototype);
}
},
/**
* Unregisters an object for profiling. It takes the object and looks for functions.
* When a function is found, unregisterMethod() is called on it. If set to recrusive
* mode, it will also unregister objects found inside of this object,
* using the same methodology.
* @param {String} name The name of the object to unregister.
* @param {Boolean} recurse (Optional) Determines if subobject methods should also be
* unregistered.
* @return {Void}
* @static
*/
unregisterObject : function (name /*:String*/, recurse /*:Boolean*/) /*:Void*/{
//get the object
if (YAHOO.lang.isObject(this._container[name])){
var object = this._container[name];
}
},
/**
* Sets up an object for profiling. It takes the object and looks for functions.
* When a function is found, registerMethod() is called on it. If set to recrusive
* mode, it will also setup objects found inside of this object for profiling,
* using the same methodology.
* @param {String} name The name of the object to profile (shows up in report).
* @param {Object} owner (Optional) The object represented by the name.
* @param {Boolean} recurse (Optional) Determines if subobject methods are also profiled.
* @return {Void}
* @method registerObject
* @static
*/
registerObject : function (name /*:String*/, object /*:Object*/, recurse /*:Boolean*/) /*:Void*/{
//get the object
object = (lang.isObject(object) ? object : eval(name));
//save the object
container[name] = object;
for (var prop in object) {
if (typeof object[prop] == "function"){
this.unregisterFunction(name + "." + prop);
if (prop != "constructor" && prop != "superclass"){ //don't do constructor or superclass, it's recursive
this.registerFunction(name + "." + prop, object);
}
} else if (typeof object[prop] == "object" && recurse){
this.unregisterObject(name + "." + prop, recurse);
this.registerObject(name + "." + prop, object[prop], recurse);
}
}
},
/**
* Removes a constructor function from profiling. Reverses the registerConstructor() method.
* @param {String} name The full name of the function including namespacing. This
* is the name of the function that is stored in the report.
* @return {Void}
* @method unregisterFunction
* @static
*/
unregisterConstructor : function(name /*:String*/) /*:Void*/{
//see if the method has been registered
if (lang.isFunction(container[name])){
this.unregisterFunction(name, true);
}
},
/**
* Removes function from profiling. Reverses the registerFunction() method.
* @param {String} name The full name of the function including namespacing. This
* is the name of the function that is stored in the report.
* @return {Void}
* @method unregisterFunction
* @static
*/
unregisterFunction : function(name /*:String*/, unregisterPrototype /*:Boolean*/) /*:Void*/{
//see if the method has been registered
if (lang.isFunction(container[name])){
delete this._container[name];
//check to see if you should unregister the prototype
if (unregisterPrototype){
this.unregisterObject(name + ".prototype", container[name].prototype);
}
//get original data
var owner /*:Object*/ = container[name].__yuiOwner,
funcName /*:String*/ = container[name].__yuiFuncName;
//delete extra information
delete container[name].__yuiOwner;
delete container[name].__yuiFuncName;
//replace instrumented function
owner[funcName] = container[name];
//delete supporting information
delete container[name];
}
},
/**
* Unregisters an object for profiling. It takes the object and looks for functions.
* When a function is found, unregisterMethod() is called on it. If set to recrusive
* mode, it will also unregister objects found inside of this object,
* using the same methodology.
* @param {String} name The name of the object to unregister.
* @param {Boolean} recurse (Optional) Determines if subobject methods should also be
* unregistered.
* @return {Void}
* @method unregisterObject
* @static
*/
unregisterObject : function (name /*:String*/, recurse /*:Boolean*/) /*:Void*/{
//get the object
if (lang.isObject(container[name])){
var object = container[name];
for (var prop in object) {
if (typeof object[prop] == "function"){
this.unregisterFunction(name + "." + prop);
} else if (typeof object[prop] == "object" && recurse){
this.unregisterObject(name + "." + prop, recurse);
}
}
delete container[name];
}
}
}
};
YAHOO.register("profiler", YAHOO.tool.Profiler, {version: "2.6.0", build: "1321"});
};
}();
YAHOO.register("profiler", YAHOO.tool.Profiler, {version: "2.8.0r4", build: "2449"});