diff --git a/Gruntfile.js b/Gruntfile.js index 9525960..581e6c1 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -66,7 +66,9 @@ module.exports = function(grunt) { 'app/nodeControllers/*.js', 'app/public/scripts/*.js', 'phantomas_custom/**/*.js', - 'test/**/*.js', + 'test/api/*.js', + 'test/core/*.js', + 'test/fixtures/*.js', 'front/src/js/**/*.js' ] }, diff --git a/front/src/css/rule.css b/front/src/css/rule.css index 2a2dce0..9a07fc4 100644 --- a/front/src/css/rule.css +++ b/front/src/css/rule.css @@ -109,6 +109,7 @@ border-bottom-left-radius: 0.4em; border-bottom-right-radius: 0.4em; border-top: 1px solid #999; + z-index: 2; } .offenders .offenderButton .domTree { text-align: left; @@ -125,13 +126,13 @@ white-space: nowrap; padding: 0.5em; } -.offenders .offenderButton.opens.mouseOver { +.offenders .offenderButton.opens:hover { border-bottom-left-radius: 0; border-bottom-right-radius: 0; background: #ffe0cc; z-index: 2; } -.offenders .offenderButton.opens.mouseOver > div { +.offenders .offenderButton.opens:hover > div { display: block; } .offendersHtml { diff --git a/front/src/css/timeline.css b/front/src/css/timeline.css index 9c3a0cd..ab00a13 100644 --- a/front/src/css/timeline.css +++ b/front/src/css/timeline.css @@ -143,20 +143,6 @@ border: 1px dotted #aaa; text-align: left; } -.slowRequestsLimit { - width: 3em; - font-size: 1em; - text-align: right; - border: 1px solid #aaa; -} -input.textFilter { - box-shadow: none; - font-size: 1em; - padding: 0 0.2em; - border: 1px solid #aaa; - border-radius: none; - width: 15em; -} .table { display: table; width: 100%; @@ -226,6 +212,9 @@ input.textFilter { .table .child span:hover { background: #EBD8E2; } +.table .child span:hover div { + display: inline-block; +} .table .child span:hover .childArgs { display: block; position: absolute; @@ -259,6 +248,7 @@ input.textFilter { width: 0.8em; } .detailsOverlay { + display: none; position: absolute; right: 3em; top: -3em; @@ -268,13 +258,16 @@ input.textFilter { background: #fff; border: 2px solid #f1c40f; border-radius: 0.5em; - z-index: 1; + z-index: 2; } @media screen and (max-width: 1024px) { .detailsOverlay { width: 25em; } } +.showDetails .detailsOverlay { + display: block; +} .detailsOverlay .closeBtn { position: absolute; top: 0.5em; diff --git a/front/src/js/app.js b/front/src/js/app.js index 8a601df..a17c4f7 100644 --- a/front/src/js/app.js +++ b/front/src/js/app.js @@ -13,7 +13,6 @@ var yltApp = angular.module('YellowLabTools', [ 'apiService', 'menuService', 'gradeDirective', - 'jsChildrenDirective', 'offendersDirectives' ]); diff --git a/front/src/js/controllers/timelineCtrl.js b/front/src/js/controllers/timelineCtrl.js index 4351ae6..9105831 100644 --- a/front/src/js/controllers/timelineCtrl.js +++ b/front/src/js/controllers/timelineCtrl.js @@ -52,7 +52,7 @@ timelineCtrl.controller('TimelineCtrl', ['$scope', '$rootScope', '$routeParams', var lastEvent = originalExecutions[originalExecutions.length - 1]; $scope.endTime = lastEvent.data.timestamp + (lastEvent.data.time || 0); - // Filter and calculate the search index + // Filter $scope.executionTree = []; originalExecutions.forEach(function(node) { @@ -66,9 +66,6 @@ timelineCtrl.controller('TimelineCtrl', ['$scope', '$rootScope', '$routeParams', } } - // 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; - $scope.executionTree.push(node); }); } @@ -114,38 +111,6 @@ timelineCtrl.controller('TimelineCtrl', ['$scope', '$rootScope', '$routeParams', $scope.profilerData = $scope.executionTree; } - - function parseBacktrace(str) { - if (!str) { - return null; - } - - var out = []; - var splited = str.split(' / '); - splited.forEach(function(trace) { - 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.changeScript = function() { initExecutionTree(); initTimeline(); @@ -170,22 +135,6 @@ timelineCtrl.controller('TimelineCtrl', ['$scope', '$rootScope', '$routeParams', return lineIndex; }; - $scope.onNodeDetailsClick = function(node) { - var isOpen = node.showDetails; - if (!isOpen) { - // Close all other nodes - $scope.executionTree.forEach(function(currentNode) { - currentNode.showDetails = false; - }); - - // Parse the backtrace - if (!node.parsedBacktrace) { - node.parsedBacktrace = parseBacktrace(node.data.backtrace); - } - - } - node.showDetails = !isOpen; - }; $scope.backToDashboard = function() { $location.path('/result/' + $scope.runId); diff --git a/front/src/js/directives/jsChildrenDirective.js b/front/src/js/directives/jsChildrenDirective.js deleted file mode 100644 index ca7372f..0000000 --- a/front/src/js/directives/jsChildrenDirective.js +++ /dev/null @@ -1,44 +0,0 @@ -var jsChildrenDirective = angular.module('jsChildrenDirective', []); - -jsChildrenDirective.directive('jsChildren', function() { - - return { - restrict: 'E', - scope: { - node: '=node' - }, - template: '
', - replace: true, - link: function(scope, element, attrs) { - - function recursiveHtmlBuilder(node) { - var html = ''; - - if (node.children) { - node.children.forEach(function(child) { - - var childArgs = ''; - if (child.data.callDetails && child.data.callDetails.arguments && child.data.callDetails.arguments.length > 0) { - childArgs = child.data.callDetails.arguments.join(' : '); - if (childArgs.length > 100) { - childArgs = childArgs.substr(0, 98) + '...'; - } - } - - html += 'Useless function call, as the jQuery object is empty.
'; + } else if (node.data.type === 'jQuery - bind' && node.data.callDetails.context.length > 5) { + html += 'The .bind() method attaches the event listener to each jQuery element one by one. Using the .on() method is preferable if available (from v1.7).
'; + } + + if (node.data.resultsNumber === 0) { + html += 'The query returned 0 results. Could it be unused or dead code?
'; + } else if (node.data.resultsNumber > 0) { + html += 'The query returned ' + node.data.resultsNumber + ' ' + (node.data.resultsNumber > 1 ? 'results' : 'result') + '.
'; + } + + if (node.data.backtrace) { + html += 'Useless function call, as the jQuery object is empty.
-- The .bind() method attaches the event listener to each jQuery element one by one. Using the .on() method is preferable if available (from v1.7). -
-First one is: {{node.data.callDetails.context.firstElementPath}}
-- The query returned 0 results. Could it be unused or dead code? -
- -| t |