|
@@ -19,16 +19,52 @@ timelineCtrl.controller('TimelineCtrl', ['$scope', '$rootScope', '$routeParams',
|
|
|
}
|
|
|
|
|
|
function render() {
|
|
|
+ initScriptFiltering();
|
|
|
initExecutionTree();
|
|
|
initTimeline();
|
|
|
$timeout(initProfiler, 100);
|
|
|
}
|
|
|
|
|
|
+ function initScriptFiltering() {
|
|
|
+ var offenders = $scope.result.rules.jsCount.offendersObj.list;
|
|
|
+ $scope.scripts = [];
|
|
|
+
|
|
|
+ offenders.forEach(function(script) {
|
|
|
+ var filePath = script.file;
|
|
|
+
|
|
|
+ if (filePath.length > 100) {
|
|
|
+ filePath = filePath.substr(0, 98) + '...';
|
|
|
+ }
|
|
|
+
|
|
|
+ var scriptObj = {
|
|
|
+ fullPath: script.file,
|
|
|
+ shortPath: filePath
|
|
|
+ };
|
|
|
+
|
|
|
+ $scope.scripts.push(scriptObj);
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
function initExecutionTree() {
|
|
|
var originalExecutions = $scope.result.javascriptExecutionTree.children || [];
|
|
|
- $scope.executionTree = [];
|
|
|
+
|
|
|
+ // Detect the last event of all (before filtering) and read time
|
|
|
+ var lastEvent = originalExecutions[originalExecutions.length - 1];
|
|
|
+ $scope.endTime = lastEvent.data.timestamp + (lastEvent.data.time || 0);
|
|
|
|
|
|
+ // Filter and calculate the search index
|
|
|
+ $scope.executionTree = [];
|
|
|
originalExecutions.forEach(function(node) {
|
|
|
+
|
|
|
+ // Filter by script (if enabled)
|
|
|
+ if ($scope.selectedScript) {
|
|
|
+ if (node.data.backtrace && node.data.backtrace.indexOf($scope.selectedScript.fullPath + ':') === -1) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (node.data.type === "jQuery loaded" || node.data.type === "jQuery version change") {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
// Prepare a faster angular search by creating a kind of search index
|
|
|
node.searchIndex = (node.data.callDetails) ? [node.data.type].concat(node.data.callDetails.arguments).join('°°') : node.data.type;
|
|
@@ -41,8 +77,6 @@ timelineCtrl.controller('TimelineCtrl', ['$scope', '$rootScope', '$routeParams',
|
|
|
|
|
|
// Split the timeline into 200 intervals
|
|
|
var numberOfIntervals = 199;
|
|
|
- var lastEvent = $scope.executionTree[$scope.executionTree.length - 1];
|
|
|
- $scope.endTime = lastEvent.data.timestamp + (lastEvent.data.time || 0);
|
|
|
$scope.timelineIntervalDuration = $scope.endTime / numberOfIntervals;
|
|
|
|
|
|
// Pre-fill array of as many elements as there are milleseconds
|
|
@@ -89,25 +123,33 @@ timelineCtrl.controller('TimelineCtrl', ['$scope', '$rootScope', '$routeParams',
|
|
|
var out = [];
|
|
|
var splited = str.split(' / ');
|
|
|
splited.forEach(function(trace) {
|
|
|
- var result = /^(\S*)\s?\(?(https?:\/\/\S+):(\d+)\)?$/g.exec(trace);
|
|
|
- if (result && result[2].length > 0) {
|
|
|
- var filePath = result[2];
|
|
|
- var chunks = filePath.split('/');
|
|
|
- var fileName = chunks[chunks.length - 1];
|
|
|
-
|
|
|
- out.push({
|
|
|
- fnName: result[1],
|
|
|
- fileName: fileName,
|
|
|
- filePath: filePath,
|
|
|
- line: result[3]
|
|
|
- });
|
|
|
+ var fnName = null, fileAndLine;
|
|
|
+
|
|
|
+ var withFnResult = /^([^\s\(]+) \((.+:\d+)\)$/.exec(trace);
|
|
|
+ if (withFnResult === null) {
|
|
|
+ fileAndLine = trace;
|
|
|
+ } else {
|
|
|
+ fnName = withFnResult[1];
|
|
|
+ fileAndLine = withFnResult[2];
|
|
|
}
|
|
|
+
|
|
|
+ var fileAndLineSplit = /^(.*):(\d+)$/.exec(fileAndLine);
|
|
|
+ var filePath = fileAndLineSplit[1];
|
|
|
+ var line = fileAndLineSplit[2];
|
|
|
+
|
|
|
+ out.push({
|
|
|
+ fnName: fnName,
|
|
|
+ filePath: filePath,
|
|
|
+ line: line
|
|
|
+ });
|
|
|
});
|
|
|
return out;
|
|
|
}
|
|
|
|
|
|
- $scope.filter = function(textFilter, scriptName) {
|
|
|
-
|
|
|
+ $scope.changeScript = function() {
|
|
|
+ initExecutionTree();
|
|
|
+ initTimeline();
|
|
|
+ initProfiler();
|
|
|
};
|
|
|
|
|
|
$scope.onNodeDetailsClick = function(node) {
|