|
@@ -7,16 +7,17 @@
|
|
|
/* global document: true, window: true */
|
|
|
/* jshint -W030 */
|
|
|
|
|
|
-exports.version = '0.2.a';
|
|
|
+exports.version = '1.0.a';
|
|
|
|
|
|
exports.module = function(phantomas) {
|
|
|
'use strict';
|
|
|
|
|
|
phantomas.setMetric('jQueryVersion', ''); // @desc version of jQuery framework (if loaded) [string]
|
|
|
+ phantomas.setMetric('jQueryVersionsLoaded'); // @desc number of loaded jQuery "instances" (even in the same version)
|
|
|
phantomas.setMetric('jQueryOnDOMReadyFunctions'); // @desc number of functions bound to onDOMReady event
|
|
|
+ phantomas.setMetric('jQueryWindowOnLoadFunctions'); // @desc number of functions bound to windowOnLoad event
|
|
|
phantomas.setMetric('jQuerySizzleCalls'); // @desc number of calls to Sizzle (including those that will be resolved using querySelectorAll)
|
|
|
- phantomas.setMetric('jQuerySizzleCallsDuplicated'); // @desc number of calls on the same Sizzle request
|
|
|
- phantomas.setMetric('jQueryDifferentVersions'); //@desc number of different jQuery versions loaded on the page (not counting iframes)
|
|
|
+ //phantomas.setMetric('jQueryEventTriggers'); // @desc number of jQuery event triggers
|
|
|
|
|
|
var jQueryFunctions = [
|
|
|
// DOM manipulations
|
|
@@ -110,30 +111,28 @@ exports.module = function(phantomas) {
|
|
|
phantomas.evaluate(function(jQueryFunctions) {
|
|
|
(function(phantomas) {
|
|
|
var jQuery;
|
|
|
+ var oldJQuery;
|
|
|
|
|
|
- // TODO: create a helper - phantomas.spyGlobalVar() ?
|
|
|
- window.__defineSetter__('jQuery', function(val) {
|
|
|
+ phantomas.spyGlobalVar('jQuery', function(jQuery) {
|
|
|
var version;
|
|
|
- var jQueryFn;
|
|
|
- var oldJQuery = jQuery;
|
|
|
|
|
|
- if (!val || !val.fn) {
|
|
|
+ if (!jQuery || !jQuery.fn) {
|
|
|
phantomas.log('jQuery: unable to detect version!');
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- version = val.fn.jquery;
|
|
|
- jQuery = val;
|
|
|
- jQueryFn = val.fn;
|
|
|
- // Older jQuery (v?.?) compatibility
|
|
|
- if (!jQueryFn) {
|
|
|
- jQueryFn = jQuery;
|
|
|
+ // Tag the current version of jQuery to avoid multiple reports of jQuery being loaded
|
|
|
+ // when it's actually only restored via $.noConflict(true) - see comments in #435
|
|
|
+ if (jQuery.__phantomas === true) {
|
|
|
+ phantomas.log('jQuery: this instance has already been seen by phantomas');
|
|
|
+ return;
|
|
|
}
|
|
|
+ jQuery.__phantomas = true;
|
|
|
|
|
|
- phantomas.log('jQuery: loaded v' + version);
|
|
|
- phantomas.setMetric('jQueryVersion', version);
|
|
|
+ // report the version of jQuery
|
|
|
+ version = jQuery.fn.jquery;
|
|
|
phantomas.emit('jQueryLoaded', version);
|
|
|
-
|
|
|
+
|
|
|
phantomas.pushContext({
|
|
|
type: (oldJQuery) ? 'jQuery version change' : 'jQuery loaded',
|
|
|
callDetails: {
|
|
@@ -141,11 +140,13 @@ exports.module = function(phantomas) {
|
|
|
},
|
|
|
backtrace: phantomas.getBacktrace()
|
|
|
});
|
|
|
+ oldJQuery = version;
|
|
|
|
|
|
// jQuery.ready.promise
|
|
|
// works for jQuery 1.8.0+ (released Aug 09 2012)
|
|
|
- phantomas.spy(val.ready, 'promise', function(func) {
|
|
|
+ phantomas.spy(jQuery.ready, 'promise', function(func) {
|
|
|
phantomas.incrMetric('jQueryOnDOMReadyFunctions');
|
|
|
+ phantomas.addOffender('jQueryOnDOMReadyFunctions', phantomas.getCaller(3));
|
|
|
|
|
|
phantomas.pushContext({
|
|
|
type: 'jQuery - onDOMReady',
|
|
@@ -160,9 +161,9 @@ exports.module = function(phantomas) {
|
|
|
|
|
|
// Sizzle calls - jQuery.find
|
|
|
// works for jQuery 1.3+ (released Jan 13 2009)
|
|
|
- phantomas.spy(val, 'find', function(selector, context) {
|
|
|
+ phantomas.spy(jQuery, 'find', function(selector, context) {
|
|
|
phantomas.incrMetric('jQuerySizzleCalls');
|
|
|
- phantomas.emit('onSizzleCall', selector + ' (context: ' + (phantomas.getDOMPath(context) || 'unknown') + ')');
|
|
|
+ phantomas.addOffender('jQuerySizzleCalls', '%s (in %s)', selector, (phantomas.getDOMPath(context) || 'unknown'));
|
|
|
|
|
|
phantomas.enterContext({
|
|
|
type: 'jQuery - find',
|
|
@@ -183,12 +184,39 @@ exports.module = function(phantomas) {
|
|
|
phantomas.leaveContext(moreData);
|
|
|
}) || phantomas.log('jQuery: can not measure jQuerySizzleCalls (jQuery used on the page is too old)!');
|
|
|
|
|
|
+ /*if (!jQuery.event) {
|
|
|
+ phantomas.spy(jQuery.event, 'trigger', function(ev, data, elem) {
|
|
|
+ var path = phantomas.getDOMPath(elem),
|
|
|
+ type = ev.type || ev;
|
|
|
+
|
|
|
+ phantomas.log('Event: triggered "%s" on "%s"', type, path);
|
|
|
+
|
|
|
+ phantomas.incrMetric('jQueryEventTriggers');
|
|
|
+ phantomas.addOffender('jQueryEventTriggers', '"%s" on "%s"', type, path);
|
|
|
+ });
|
|
|
+ }*/
|
|
|
+
|
|
|
+ // jQuery events bound to window' onLoad event (#451)
|
|
|
+ phantomas.spy(jQuery.fn, 'on', function(eventName, func) {
|
|
|
+ if ((eventName === 'load') && (this[0] === window)) {
|
|
|
+ phantomas.incrMetric('jQueryWindowOnLoadFunctions');
|
|
|
+ phantomas.addOffender('jQueryWindowOnLoadFunctions', phantomas.getCaller(2));
|
|
|
+
|
|
|
+ phantomas.pushContext({
|
|
|
+ type: 'jQuery - windowOnLoad',
|
|
|
+ callDetails: {
|
|
|
+ arguments: [func]
|
|
|
+ },
|
|
|
+ backtrace: phantomas.getBacktrace()
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
|
|
|
// Add spys on many jQuery functions
|
|
|
jQueryFunctions.forEach(function(functionName) {
|
|
|
var capitalizedName = functionName.substring(0,1).toUpperCase() + functionName.substring(1);
|
|
|
|
|
|
- phantomas.spy(jQueryFn, functionName, function(args) {
|
|
|
+ phantomas.spy(jQuery.fn, functionName, function(args) {
|
|
|
|
|
|
// Clean args
|
|
|
args = [].slice.call(arguments);
|
|
@@ -263,42 +291,28 @@ exports.module = function(phantomas) {
|
|
|
phantomas.leaveContext();
|
|
|
}) || phantomas.log('jQuery: can not track jQuery - ' + capitalizedName + ' (this version of jQuery doesn\'t support it)');
|
|
|
});
|
|
|
-
|
|
|
-
|
|
|
- });
|
|
|
-
|
|
|
- window.__defineGetter__('jQuery', function() {
|
|
|
- return jQuery;
|
|
|
});
|
|
|
})(window.__phantomas);
|
|
|
}, jQueryFunctions);
|
|
|
});
|
|
|
|
|
|
|
|
|
- // count Sizzle calls to detect duplicated queries
|
|
|
- var Collection = require('../../util/collection'),
|
|
|
- sizzleCalls = new Collection(),
|
|
|
- jQueryLoading = new Collection();
|
|
|
-
|
|
|
- phantomas.on('onSizzleCall', function(request) {
|
|
|
- sizzleCalls.push(request);
|
|
|
+ // store the last resource that was received
|
|
|
+ // try to report where given jQuery version was loaded from
|
|
|
+ phantomas.on('recv', function(entry) {
|
|
|
+ if (entry.isJS) {
|
|
|
+ lastUrl = entry.url;
|
|
|
+ }
|
|
|
});
|
|
|
|
|
|
phantomas.on('jQueryLoaded', function(version) {
|
|
|
- jQueryLoading.push(version);
|
|
|
- });
|
|
|
+ phantomas.log('jQuery: loaded v' + version);
|
|
|
+ phantomas.setMetric('jQueryVersion', version);
|
|
|
+
|
|
|
+ // report multiple jQuery "instances" (issue #435)
|
|
|
+ phantomas.incrMetric('jQueryVersionsLoaded');
|
|
|
+ phantomas.addOffender('jQueryVersionsLoaded', 'v%s', version);
|
|
|
|
|
|
- phantomas.on('report', function() {
|
|
|
- sizzleCalls.sort().forEach(function(id, cnt) {
|
|
|
- if (cnt > 1) {
|
|
|
- phantomas.incrMetric('jQuerySizzleCallsDuplicated');
|
|
|
- phantomas.addOffender('jQuerySizzleCallsDuplicated', '%s: %d', id, cnt);
|
|
|
- }
|
|
|
- });
|
|
|
-
|
|
|
- jQueryLoading.forEach(function(version) {
|
|
|
- phantomas.incrMetric('jQueryDifferentVersions');
|
|
|
- phantomas.addOffender('jQueryDifferentVersions', '%s', version);
|
|
|
- });
|
|
|
+ phantomas.log('jQuery: v%s (probably loaded from <%s>)', version, lastUrl);
|
|
|
});
|
|
|
};
|