diff --git a/lib/tools/phantomas/custom_modules/core/scopeYLT/scopeYLT.js b/lib/tools/phantomas/custom_modules/core/scopeYLT/scopeYLT.js index 9ed515a..c7478bb 100644 --- a/lib/tools/phantomas/custom_modules/core/scopeYLT/scopeYLT.js +++ b/lib/tools/phantomas/custom_modules/core/scopeYLT/scopeYLT.js @@ -7,7 +7,7 @@ */ /* global document: true, window: true */ -exports.version = '0.1'; +exports.version = '0.2'; exports.module = function(phantomas) { 'use strict'; @@ -62,7 +62,7 @@ exports.module = function(phantomas) { // After if (enabled && callbackAfter) { - callbackAfter.call(this, result); + callbackAfter.call(this, result, arguments); } } diff --git a/lib/tools/phantomas/custom_modules/modules/domQYLT/domQYLT.js b/lib/tools/phantomas/custom_modules/modules/domQYLT/domQYLT.js index 78260d2..81985f4 100644 --- a/lib/tools/phantomas/custom_modules/modules/domQYLT/domQYLT.js +++ b/lib/tools/phantomas/custom_modules/modules/domQYLT/domQYLT.js @@ -3,12 +3,13 @@ */ /* global Element: true, Document: true, Node: true, window: true */ -exports.version = '0.9.a'; +exports.version = '0.10.a'; exports.module = function(phantomas) { 'use strict'; phantomas.setMetric('DOMqueries'); // @desc number of all DOM queries @offenders + phantomas.setMetric('DOMqueriesWithoutResults'); // @desc number of DOM queries that retutned nothing @offenders phantomas.setMetric('DOMqueriesById'); // @desc number of document.getElementById calls phantomas.setMetric('DOMqueriesByClassName'); // @desc number of document.getElementsByClassName calls phantomas.setMetric('DOMqueriesByTagName'); // @desc number of document.getElementsByTagName calls @@ -21,14 +22,13 @@ exports.module = function(phantomas) { phantomas.once('init', function() { phantomas.evaluate(function() { (function(phantomas) { - function querySpy(type, query, fnName, context) { - phantomas.emit('domQuery', type, query, fnName, context); // @desc DOM query has been made + function querySpy(type, query, fnName, context, hasNoResults) { + phantomas.emit('domQuery', type, query, fnName, context, hasNoResults); // @desc DOM query has been made } phantomas.spy(Document.prototype, 'getElementById', function(id) { phantomas.incrMetric('DOMqueriesById'); phantomas.addOffender('DOMqueriesById', '#%s (in %s)', id, '#document'); - querySpy('id', '#' + id, 'getElementById', '#document'); phantomas.enterContext({ type: 'getElementById', @@ -41,9 +41,13 @@ exports.module = function(phantomas) { backtrace: phantomas.getBacktrace() }); - }, function(result) { + }, function(result, args) { + var id = args[0]; + + querySpy('id', '#' + id, 'getElementById', '#document', (result === null)); + var moreData = { - resultsNumber : result ? 1 : 0 + resultsNumber : (result === null) ? 0 : 1 }; phantomas.leaveContext(moreData); }); @@ -56,7 +60,6 @@ exports.module = function(phantomas) { phantomas.incrMetric('DOMqueriesByClassName'); phantomas.addOffender('DOMqueriesByClassName', '.%s (in %s)', className, context); - querySpy('class', '.' + className, 'getElementsByClassName', context); phantomas.enterContext({ type: 'getElementsByClassName', @@ -70,7 +73,14 @@ exports.module = function(phantomas) { }); } - function selectorClassNameAfter(result) { + function selectorClassNameAfter(result, args) { + /*jshint validthis: true */ + + var className = args[0]; + var context = phantomas.getDOMPath(this); + + querySpy('class', '.' + className, 'getElementsByClassName', context, (result.length === 0)); + var moreData = { resultsNumber : (result && result.length > 0) ? result.length : 0 }; @@ -88,7 +98,6 @@ exports.module = function(phantomas) { phantomas.incrMetric('DOMqueriesByTagName'); phantomas.addOffender('DOMqueriesByTagName', '%s (in %s)', tagName, context); - querySpy('tag name', tagName.toLowerCase(), 'getElementsByTagName', context); phantomas.enterContext({ type: 'getElementsByTagName', @@ -102,7 +111,14 @@ exports.module = function(phantomas) { }); } - function selectorTagNameSpyAfter(result) { + function selectorTagNameSpyAfter(result, args) { + /*jshint validthis: true */ + + var tagName = args[0]; + var context = phantomas.getDOMPath(this); + + querySpy('tag name', tagName.toLowerCase(), 'getElementsByTagName', context, (result.length === 0)); + var moreData = { resultsNumber : (result && result.length > 0) ? result.length : 0 }; @@ -112,11 +128,11 @@ exports.module = function(phantomas) { phantomas.spy(Document.prototype, 'getElementsByTagName', selectorTagNameSpyBefore, selectorTagNameSpyAfter); phantomas.spy(Element.prototype, 'getElementsByTagName', selectorTagNameSpyBefore, selectorTagNameSpyAfter); + // selector queries function selectorQuerySpy(selector, context) { phantomas.incrMetric('DOMqueriesByQuerySelectorAll'); phantomas.addOffender('DOMqueriesByQuerySelectorAll', '%s (in %s)', selector, context); - querySpy('selector', selector, 'querySelectorAll', context); } function selectorQuerySpyBefore(selector) { @@ -137,7 +153,14 @@ exports.module = function(phantomas) { }); } - function selectorQuerySpyAfter(result) { + function selectorQuerySpyAfter(result, args) { + /*jshint validthis: true */ + + var selector = args[0]; + var context = phantomas.getDOMPath(this); + + querySpy('selector', selector, 'querySelectorAll', context, (!result || result.length === 0)); + var moreData = { resultsNumber : result ? 1 : 0 }; @@ -162,7 +185,14 @@ exports.module = function(phantomas) { }); } - function selectorAllQuerySpryAfter(result) { + function selectorAllQuerySpryAfter(result, args) { + /*jshint validthis: true */ + + var selector = args[0]; + var context = phantomas.getDOMPath(this); + + querySpy('selector', selector, 'querySelectorAll', context, (!result || result.length === 0)); + var moreData = { resultsNumber : (result && result.length > 0) ? result.length : 0 }; @@ -244,6 +274,19 @@ exports.module = function(phantomas) { }); }); + // report DOM queries that return no results (issue #420) + phantomas.on('domQuery', function(type, query, fnName, context, hasNoResults) { + // ignore DOM queries within DOM fragments (used internally by jQuery) + if (context.indexOf('body') !== 0 && context.indexOf('#document') !== 0) { + return; + } + + if (hasNoResults === true) { + phantomas.incrMetric('DOMqueriesWithoutResults'); + phantomas.addOffender('DOMqueriesWithoutResults', '%s (in %s) using %s', query, context, fnName); + } + }); + // count DOM queries by either ID, tag name, class name and selector query // @see https://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-document-doctype var Collection = require('../../../../../../node_modules/phantomas/lib/collection'),