Merge pull request #54 from gmetais/scriptfilter

Introduce a script selector to filter the timeline and the profiler.
This commit is contained in:
Gaël Métais
2015-02-27 10:04:00 +01:00
4 changed files with 98 additions and 17 deletions
+14
View File
@@ -2,6 +2,19 @@
.execution {
text-align: center;
}
.selectScript {
padding-bottom: 2em;
font-size: 0.9em;
}
.selectScript select {
max-width: 30em;
}
.selectScript.empty {
font-size: 0.8em;
}
.selectScript.empty select {
width: 10em;
}
.timeline {
margin: 2em 0 5em;
}
@@ -173,6 +186,7 @@ input.textFilter {
}
.table > div > .index {
color: #bbb;
word-break: normal;
}
.table > div > .type {
white-space: nowrap;
+58 -16
View File
@@ -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];
var fnName = null, fileAndLine;
out.push({
fnName: result[1],
fileName: fileName,
filePath: filePath,
line: result[3]
});
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) {
+18
View File
@@ -14,6 +14,23 @@
text-align: center;
}
.selectScript {
padding-bottom: 2em;
font-size: 0.9em;
select {
max-width: 30em;
}
&.empty {
font-size: 0.8em;
select {
width: 10em;
}
}
}
.timeline {
margin: 2em 0 5em;
}
@@ -191,6 +208,7 @@ input.textFilter {
.table > div > .index {
color: #bbb;
word-break: normal;
}
.table > div > .type {
+8 -1
View File
@@ -1,5 +1,12 @@
<div ng-include="'views/resultSubHeader.html'"></div>
<div class="execution board">
<div class="selectScript" ng-class="{empty:!selectedScript}">
Filter timeline and profiler by script:
<select ng-model="selectedScript" ng-options="script.shortPath for script in scripts" ng-change="changeScript()">
<option value="">All (no filter)</option>
</select>
</div>
<h2>Javascript Timeline</h2>
<p>This graph gives a quick view of when the Javascript interactions with the DOM occur during the loading of the page.</p>
@@ -130,7 +137,7 @@
<div class="table">
<div ng-repeat="trace in node.parsedBacktrace track by $index">
<div>{{trace.fnName || '(anonymous)'}}</div>
<div class="trace"><a href="{{trace.filePath}}" title="{{trace.filePath}}" target="_blank">{{trace.fileName || 'HTML'}}</a>:{{trace.line}}</div>
<div class="trace"><url-link url="trace.filePath" max-length="40"></url-link>:{{trace.line}}</div>
</div>
<div ng-if="node.parsedBacktrace.length == 0 && node.data.type != 'script loaded'">
<div>can't find any backtrace :/</div>