|
@@ -13,16 +13,24 @@ var jsExecutionTransformer = function() {
|
|
|
var metrics = {
|
|
|
DOMaccesses: 0,
|
|
|
DOMaccessesOnScroll: 0,
|
|
|
- queriesWithoutResults: 0,
|
|
|
- jQueryCalls: 0,
|
|
|
- jQueryCallsOnEmptyObject: 0,
|
|
|
- jQueryNotDelegatedEvent: 0
|
|
|
+ queriesWithoutResults: 0
|
|
|
};
|
|
|
|
|
|
var offenders = {
|
|
|
|
|
|
};
|
|
|
|
|
|
+ var hasjQuery = (data.toolsResults.phantomas.metrics.jQueryVersionsLoaded > 0);
|
|
|
+ if (hasjQuery) {
|
|
|
+ metrics.jQueryCalls = 0;
|
|
|
+ metrics.jQueryFunctionsUsed = 0;
|
|
|
+ metrics.jQueryCallsOnEmptyObject = 0;
|
|
|
+ metrics.jQueryNotDelegatedEvents = 0;
|
|
|
+
|
|
|
+ offenders.jQueryFunctionsUsed = [];
|
|
|
+ offenders.jQueryNotDelegatedEvents = [];
|
|
|
+ }
|
|
|
+
|
|
|
try {
|
|
|
|
|
|
debug('Starting JS execution transformation');
|
|
@@ -31,11 +39,17 @@ var jsExecutionTransformer = function() {
|
|
|
if (javascriptExecutionTree.children) {
|
|
|
javascriptExecutionTree.children.forEach(function(node) {
|
|
|
|
|
|
- var contextLenght = (node.data.callDetails && node.data.callDetails.context) ? node.data.callDetails.context.length : null;
|
|
|
-
|
|
|
- if ((node.data.type === 'jQuery - bind' || node.data.type === 'jQuery - on') && contextLenght > 3) {
|
|
|
- metrics.jQueryNotDelegatedEvent += contextLenght - 1;
|
|
|
+ var contextLength = (node.data.callDetails && node.data.callDetails.context) ? node.data.callDetails.context.length : null;
|
|
|
+
|
|
|
+ if (isABindWithoutEventDelegation(node, contextLength)) {
|
|
|
+ metrics.jQueryNotDelegatedEvents += contextLength;
|
|
|
+ offenders.jQueryNotDelegatedEvents.push({
|
|
|
+ functionName: node.data.type.substring(9),
|
|
|
+ contextLength: contextLength,
|
|
|
+ backtrace: offendersHelpers.backtraceToArray(node.data.backtrace)
|
|
|
+ });
|
|
|
node.warning = true;
|
|
|
+ node.eventNotDelegated = true;
|
|
|
}
|
|
|
|
|
|
if (node.data.resultsNumber === 0) {
|
|
@@ -43,7 +57,7 @@ var jsExecutionTransformer = function() {
|
|
|
node.warning = true;
|
|
|
}
|
|
|
|
|
|
- if (contextLenght === 0) {
|
|
|
+ if (contextLength === 0) {
|
|
|
metrics.jQueryCallsOnEmptyObject ++;
|
|
|
node.warning = true;
|
|
|
}
|
|
@@ -87,9 +101,7 @@ var jsExecutionTransformer = function() {
|
|
|
});
|
|
|
|
|
|
// Count the number of different jQuery functions called
|
|
|
- if (data.toolsResults.phantomas.metrics.jQueryVersionsLoaded) {
|
|
|
- metrics.jQueryFunctionsUsed = 0;
|
|
|
- offenders.jQueryFunctionsUsed = [];
|
|
|
+ if (hasjQuery) {
|
|
|
|
|
|
jQueryFunctionsCollection.sort().forEach(function(fnName, cnt) {
|
|
|
if (fnName === 'jQuery - find') {
|
|
@@ -181,6 +193,30 @@ var jsExecutionTransformer = function() {
|
|
|
|
|
|
return count;
|
|
|
}
|
|
|
+
|
|
|
+ function isPureString(str) {
|
|
|
+ return typeof str === 'string' && str[0] !== '{' && str !== '(function)' && str !== '[Object]' && str !== '[Array]' && str !== 'true' && str !== 'false' && str !== 'undefined' && str !== 'unknown' && str !== 'null';
|
|
|
+ }
|
|
|
+
|
|
|
+ function isABindWithoutEventDelegation(node, contextLength) {
|
|
|
+ // Count only on larger bindings
|
|
|
+ if (contextLength <= 3) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (node.data.type === 'jQuery - on' && node.data.callDetails.arguments[1] && !isPureString(node.data.callDetails.arguments[1])) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (node.data.type.indexOf('jQuery - ') === 0 && node.children && node.children.length === 1) {
|
|
|
+ var child = node.children[0];
|
|
|
+ if (child.data.type === 'jQuery - on' && child.data.callDetails.arguments[1] && !isPureString(child.data.callDetails.arguments[1])) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return false;
|
|
|
+ }
|
|
|
};
|
|
|
|
|
|
module.exports = new jsExecutionTransformer();
|