Separate offender analyze, parsing in the core, display in the front
This commit is contained in:
+527
-321
File diff suppressed because it is too large
Load Diff
+44
-58
@@ -31,70 +31,69 @@ var OffendersHelpers = function() {
|
||||
return result;
|
||||
};
|
||||
|
||||
this.domTreeToHTML = function(domTree) {
|
||||
|
||||
function recursiveHtmlBuilder(tree) {
|
||||
var html = '';
|
||||
var keys = Object.keys(tree);
|
||||
|
||||
keys.forEach(function(key) {
|
||||
if (isNaN(tree[key])) {
|
||||
html += '<div><span>' + key + '</span>' + recursiveHtmlBuilder(tree[key]) + '</div>';
|
||||
} else if (tree[key] > 1) {
|
||||
html += '<div><span>' + key + ' <span>(x' + tree[key] + ')</span></span></div>';
|
||||
} else {
|
||||
html += '<div><span>' + key + '</span></div>';
|
||||
}
|
||||
});
|
||||
|
||||
return html;
|
||||
}
|
||||
|
||||
return '<div class="domTree">' + recursiveHtmlBuilder(domTree) + '</div>';
|
||||
};
|
||||
|
||||
this.listOfDomPathsToHTML = function(domPaths) {
|
||||
var domArrays = domPaths.map(this.domPathToArray);
|
||||
var domTree = this.listOfDomArraysToTree(domArrays);
|
||||
return this.domTreeToHTML(domTree);
|
||||
};
|
||||
|
||||
this.domPathToButton = function(domPath) {
|
||||
this.domPathToDomElementObj = function(domPath) {
|
||||
var domArray = this.domPathToArray(domPath);
|
||||
var domTree = this.listOfDomPathsToHTML([domPath]);
|
||||
var domTree = this.listOfDomArraysToTree([this.domPathToArray(domPath)]);
|
||||
|
||||
if (domArray[0] === 'html') {
|
||||
return '<div class="offenderButton"><b>html</b></div>';
|
||||
return {
|
||||
type: 'html'
|
||||
};
|
||||
}
|
||||
if (domArray[0] === 'body') {
|
||||
if (domArray.length === 1) {
|
||||
return '<div class="offenderButton"><b>body</b></div>';
|
||||
return {
|
||||
type: 'body'
|
||||
};
|
||||
} else {
|
||||
return '<div class="offenderButton opens">DOM element <b>' + domArray[domArray.length - 1] + '</b>' + domTree + '</div>';
|
||||
return {
|
||||
type: 'domElement',
|
||||
element: domArray[domArray.length - 1],
|
||||
tree: domTree
|
||||
};
|
||||
}
|
||||
}
|
||||
if (domArray[0] === 'head') {
|
||||
return '<div class="offenderButton"><b>head</b></div>';
|
||||
return {
|
||||
type: 'head'
|
||||
};
|
||||
}
|
||||
if (domArray[0] === '#document') {
|
||||
return '<div class="offenderButton"><b>document</b></div>';
|
||||
return {
|
||||
type: 'document'
|
||||
};
|
||||
}
|
||||
if (domArray[0] === 'window') {
|
||||
return '<div class="offenderButton"><b>window</b></div>';
|
||||
return {
|
||||
type: 'window'
|
||||
};
|
||||
}
|
||||
if (domArray[0] === 'DocumentFragment') {
|
||||
if (domArray.length === 1) {
|
||||
return '<div class="offenderButton">Fragment</div>';
|
||||
return {
|
||||
type: 'fragment'
|
||||
};
|
||||
} else {
|
||||
return '<div class="offenderButton opens">Fragment element <b>' + domArray[domArray.length - 1] + '</b>' + domTree + '</div>';
|
||||
return {
|
||||
type: 'fragmentElement',
|
||||
element: domArray[domArray.length - 1],
|
||||
tree: domTree
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Not attached element, such as just created with document.createElement()
|
||||
if (domArray.length === 1) {
|
||||
return '<div class="offenderButton">Created element <b>' + domPath + '</b></div>';
|
||||
return {
|
||||
type: 'createdElement',
|
||||
element: domPath
|
||||
};
|
||||
} else {
|
||||
return '<div class="offenderButton opens">Created element <b>' + domArray[domArray.length - 1] + '</b>' + domTree + '</div>';
|
||||
return {
|
||||
type: 'createdElement',
|
||||
element: domArray[domArray.length - 1],
|
||||
tree: domTree
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
@@ -130,20 +129,6 @@ var OffendersHelpers = function() {
|
||||
}
|
||||
};
|
||||
|
||||
this.backtraceArrayToHtml = function(backtraceArray) {
|
||||
if (backtraceArray.length === 0) {
|
||||
return '<div class="offenderButton">no backtrace</div>';
|
||||
}
|
||||
|
||||
var html = '<div class="offenderButton opens">backtrace<div class="backtrace">';
|
||||
var that = this;
|
||||
backtraceArray.forEach(function(backtraceObj) {
|
||||
var functionName = (backtraceObj.functionName) ? backtraceObj.functionName + '() ' : '';
|
||||
html += '<div>' + functionName + that.urlToLink(backtraceObj.file) + ' line ' + backtraceObj.line + '</div>';
|
||||
});
|
||||
return html + '</div></div>';
|
||||
};
|
||||
|
||||
|
||||
this.sortVarsLikeChromeDevTools = function(vars) {
|
||||
return vars.sort(function(a, b) {
|
||||
@@ -157,7 +142,7 @@ var OffendersHelpers = function() {
|
||||
};
|
||||
|
||||
this.cssOffenderPattern = function(offender) {
|
||||
var parts = /^(.*) @ (\d+):(\d+)$/.exec(offender);
|
||||
var parts = /^(.*) (?:<([^ \(]*)>|\[inline CSS\]) @ (\d+):(\d+)$/.exec(offender);
|
||||
|
||||
if (!parts) {
|
||||
return {
|
||||
@@ -165,9 +150,10 @@ var OffendersHelpers = function() {
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
offender: parts[1],
|
||||
line: parseInt(parts[2], 10),
|
||||
character: parseInt(parts[3], 10)
|
||||
css: parts[1],
|
||||
file: parts[2] || null,
|
||||
line: parseInt(parts[3], 10),
|
||||
column: parseInt(parts[4], 10)
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
+50
-38
@@ -26,52 +26,64 @@ var RulesChecker = function() {
|
||||
policy: extend({}, policy) // Clone object policy instead of reference
|
||||
};
|
||||
|
||||
var offenders = [];
|
||||
|
||||
// Take DOMqueriesAvoidable's offenders from DOMqueriesDuplicated, for example.
|
||||
if (policy.takeOffendersFrom) {
|
||||
|
||||
var fromList = policy.takeOffendersFrom;
|
||||
|
||||
// takeOffendersFrom option can be a string or an array of strings.
|
||||
if (typeof fromList === 'string') {
|
||||
fromList = [fromList];
|
||||
}
|
||||
|
||||
fromList.forEach(function(from) {
|
||||
if (data.toolsResults[policy.tool] &&
|
||||
data.toolsResults[policy.tool].offenders &&
|
||||
data.toolsResults[policy.tool].offenders[from]) {
|
||||
offenders = offenders.concat(data.toolsResults[policy.tool].offenders[from]);
|
||||
// Deal with offenders
|
||||
if (policy.hasOffenders) {
|
||||
|
||||
var offenders = [];
|
||||
|
||||
// Take DOMqueriesAvoidable's offenders from DOMqueriesDuplicated, for example.
|
||||
if (policy.takeOffendersFrom) {
|
||||
|
||||
var fromList = policy.takeOffendersFrom;
|
||||
|
||||
// takeOffendersFrom option can be a string or an array of strings.
|
||||
if (typeof fromList === 'string') {
|
||||
fromList = [fromList];
|
||||
}
|
||||
});
|
||||
|
||||
fromList.forEach(function(from) {
|
||||
if (data.toolsResults[policy.tool] &&
|
||||
data.toolsResults[policy.tool].offenders &&
|
||||
data.toolsResults[policy.tool].offenders[from]) {
|
||||
offenders = offenders.concat(data.toolsResults[policy.tool].offenders[from]);
|
||||
}
|
||||
});
|
||||
|
||||
data.toolsResults[policy.tool].offenders[metricName] = offenders;
|
||||
data.toolsResults[policy.tool].offenders[metricName] = offenders;
|
||||
|
||||
} else if (data.toolsResults[policy.tool] &&
|
||||
data.toolsResults[policy.tool].offenders &&
|
||||
data.toolsResults[policy.tool].offenders[metricName]) {
|
||||
offenders = data.toolsResults[policy.tool].offenders[metricName];
|
||||
}
|
||||
|
||||
// It is possible to declare a transformation function for the offenders.
|
||||
// The function should take an array of strings as single parameter and return a string.
|
||||
if (policy.offendersTransformFn) {
|
||||
rule.offendersCount = offenders.length;
|
||||
|
||||
try {
|
||||
offenders = policy.offendersTransformFn(offenders);
|
||||
} catch(err) {
|
||||
debug('Error while transforming offenders for %s', metricName);
|
||||
debug(err);
|
||||
} else if (data.toolsResults[policy.tool] &&
|
||||
data.toolsResults[policy.tool].offenders &&
|
||||
data.toolsResults[policy.tool].offenders[metricName]) {
|
||||
offenders = data.toolsResults[policy.tool].offenders[metricName];
|
||||
}
|
||||
|
||||
var offendersObj = {};
|
||||
|
||||
delete rule.policy.offendersTransformFn;
|
||||
// It is possible to declare a transformation function for the offenders.
|
||||
// The function should take an array of strings as single parameter and return a string.
|
||||
if (policy.offendersTransformFn) {
|
||||
|
||||
try {
|
||||
offendersObj = policy.offendersTransformFn(offenders);
|
||||
} catch(err) {
|
||||
debug('Error while transforming offenders for %s', metricName);
|
||||
debug(err);
|
||||
}
|
||||
|
||||
delete rule.policy.offendersTransformFn;
|
||||
|
||||
} else {
|
||||
|
||||
offendersObj = {
|
||||
count: offenders.length,
|
||||
list: offenders
|
||||
};
|
||||
}
|
||||
|
||||
rule.offendersObj = offendersObj;
|
||||
}
|
||||
|
||||
if (offenders && offenders.length > 0) {
|
||||
rule.offenders = offenders;
|
||||
}
|
||||
|
||||
rule.bad = rule.value > policy.isOkThreshold;
|
||||
rule.abnormal = policy.isAbnormalThreshold && rule.value >= policy.isAbnormalThreshold;
|
||||
|
||||
@@ -40,7 +40,8 @@ var PhantomasWrapper = function() {
|
||||
'eventListeners', // overridden
|
||||
'filmStrip', // not needed
|
||||
'har', // not needed for the moment
|
||||
'javaScriptBottlenecks', // needs to be launched after custom module scopeYLT,
|
||||
'javaScriptBottlenecks', // needs to be launched after custom module scopeYLT
|
||||
'jQuery', // overridden
|
||||
'jserrors', // overridden
|
||||
'pageSource', // not needed
|
||||
'screenshot', // not needed for the moment
|
||||
|
||||
Reference in New Issue
Block a user