From 61c09a5b49da9627b973596f88ef830aca4d39d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20M=C3=A9tais?= Date: Mon, 26 Jan 2015 15:10:26 +0100 Subject: [PATCH] Revert custom dev and implement jQueryVersionsLoaded --- front/src/views/rule.html | 2 +- lib/metadata/policies.js | 4 +- lib/metadata/scoreProfileGeneric.json | 2 +- .../custom_modules/modules/jQYLT/jQYLT.js | 108 ++++++++++-------- 4 files changed, 65 insertions(+), 51 deletions(-) diff --git a/front/src/views/rule.html b/front/src/views/rule.html index 28e3c31..ab7d250 100644 --- a/front/src/views/rule.html +++ b/front/src/views/rule.html @@ -128,7 +128,7 @@ () -
+
{{offender}}
diff --git a/lib/metadata/policies.js b/lib/metadata/policies.js index 00e667b..ac11d83 100644 --- a/lib/metadata/policies.js +++ b/lib/metadata/policies.js @@ -273,7 +273,7 @@ var policies = { "message": "

Current latest versions of jQuery are 1.11 (with support for old IE versions) and 2.1 (without).

Each new version of jQuery optimizes performances. Do not keep an old version of jQuery. Updating can sometimes break a few things, but it is generally quite easy to fix them up. So don't hesitate.

", "hasOffenders": false, "scoreFn": function(data) { - var differentVersions = data.toolsResults.phantomas.metrics.jQueryDifferentVersions; + var differentVersions = data.toolsResults.phantomas.metrics.jQueryVersionsLoaded; if (differentVersions === 0 || differentVersions > 1 || !data.toolsResults.phantomas.metrics.jQueryVersion) { // Not applicable @@ -322,7 +322,7 @@ var policies = { } } }, - "jQueryDifferentVersions": { + "jQueryVersionsLoaded": { "tool": "phantomas", "label": "Several versions loaded", "message": "

jQuery is a heavy library. You should never load jQuery more than once on the same page.

", diff --git a/lib/metadata/scoreProfileGeneric.json b/lib/metadata/scoreProfileGeneric.json index 48a81bb..8a3b2d3 100644 --- a/lib/metadata/scoreProfileGeneric.json +++ b/lib/metadata/scoreProfileGeneric.json @@ -32,7 +32,7 @@ "label": "jQuery version", "policies": { "jQueryVersion": 5, - "jQueryDifferentVersions": 0.1 + "jQueryVersionsLoaded": 0.1 } }, "cssSyntaxError": { diff --git a/lib/tools/phantomas/custom_modules/modules/jQYLT/jQYLT.js b/lib/tools/phantomas/custom_modules/modules/jQYLT/jQYLT.js index d76db71..c4a962d 100644 --- a/lib/tools/phantomas/custom_modules/modules/jQYLT/jQYLT.js +++ b/lib/tools/phantomas/custom_modules/modules/jQYLT/jQYLT.js @@ -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); - phantomas.on('report', function() { - sizzleCalls.sort().forEach(function(id, cnt) { - if (cnt > 1) { - phantomas.incrMetric('jQuerySizzleCallsDuplicated'); - phantomas.addOffender('jQuerySizzleCallsDuplicated', '%s: %d', id, cnt); - } - }); + // report multiple jQuery "instances" (issue #435) + phantomas.incrMetric('jQueryVersionsLoaded'); + phantomas.addOffender('jQueryVersionsLoaded', 'v%s', version); - jQueryLoading.forEach(function(version) { - phantomas.incrMetric('jQueryDifferentVersions'); - phantomas.addOffender('jQueryDifferentVersions', '%s', version); - }); + phantomas.log('jQuery: v%s (probably loaded from <%s>)', version, lastUrl); }); };