123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266 |
- var app = angular.module('Results', []);
- app.controller('ResultsCtrl', function ($scope) {
- // Grab results from nodeJS served page
- $scope.phantomasResults = window._phantomas_results;
- $scope.phantomasMetadata = window._phantomas_metadata.metrics;
- $scope.view = 'summary';
- if ($scope.phantomasResults.metrics && $scope.phantomasResults.offenders && $scope.phantomasResults.offenders.javascriptExecutionTree) {
- // Get the execution tree from the offenders
- $scope.javascript = JSON.parse($scope.phantomasResults.offenders.javascriptExecutionTree);
- initSummaryView();
- initExecutionView();
- initMetricsView();
- }
- $scope.setView = function(viewName) {
- $scope.view = viewName;
- };
- $scope.onNodeDetailsClick = function(node) {
- var isOpen = node.data.showDetails;
- if (!isOpen) {
- // Close all other nodes
- $scope.javascript.children.forEach(function(currentNode) {
- currentNode.data.showDetails = false;
- });
- // Parse the backtrace
- if (!node.data.parsedBacktrace) {
- node.data.parsedBacktrace = parseBacktrace(node.data.backtrace);
- }
- }
- node.data.showDetails = !isOpen;
- };
- function initSummaryView() {
- // Read the main elements of the tree and sum the total time
- $scope.totalJSTime = 0;
- treeRunner($scope.javascript, function(node) {
- if (node.data.time) {
- $scope.totalJSTime += node.data.time;
- }
-
- if (node.data.type !== 'main') {
- // Don't check the children
- return false;
- }
- });
- // Read all the duplicated queries and calculate a more appropriated score
- $scope.duplicatedQueriesCountAll = 0;
- if ($scope.phantomasResults.offenders.DOMqueriesDuplicated) {
- var regex = /^{.*}: *(\d+) queries$/;
- $scope.phantomasResults.offenders.DOMqueriesDuplicated.forEach(function(query) {
- var regexResult = regex.exec(query);
- if (regexResult) {
- $scope.duplicatedQueriesCountAll += parseInt(regexResult[1], 10) - 1;
- }
- });
- }
- $scope.notations = {
- domComplexity: 'A',
- domManipulations: 'A',
- duplicatedDomQueries: 'A',
- eventsBound: 'A',
- badPractices: 'A',
- scripts: 'A',
- jQueryLoading: 'A'
- };
- var domComplexityScore = $scope.phantomasResults.metrics.DOMelementsCount +
- Math.pow($scope.phantomasResults.metrics.DOMelementMaxDepth, 2) +
- $scope.phantomasResults.metrics.iframesCount * 50;
- if (domComplexityScore > 1000) {
- $scope.notations.domComplexity = 'B';
- }
- if (domComplexityScore > 1500) {
- $scope.notations.domComplexity = 'C';
- }
- if (domComplexityScore > 2000) {
- $scope.notations.domComplexity = 'D';
- }
- if (domComplexityScore > 3000) {
- $scope.notations.domComplexity = 'E';
- }
- if (domComplexityScore > 4000) {
- $scope.notations.domComplexity = 'F';
- }
- var domManipulationsScore = $scope.phantomasResults.metrics.DOMinserts +
- $scope.phantomasResults.metrics.DOMqueries * 0.5 +
- $scope.totalJSTime;
- if (domManipulationsScore > 100) {
- $scope.notations.domManipulations = 'B';
- }
- if (domManipulationsScore > 200) {
- $scope.notations.domManipulations = 'C';
- }
- if (domManipulationsScore > 300) {
- $scope.notations.domManipulations = 'D';
- }
- if (domManipulationsScore > 500) {
- $scope.notations.domManipulations = 'E';
- }
- if (domManipulationsScore > 800) {
- $scope.notations.domManipulations = 'F';
- }
- var duplicatedDomQueries = $scope.duplicatedQueriesCountAll;
- if (duplicatedDomQueries > 10) {
- $scope.notations.duplicatedDomQueries = 'B';
- }
- if (duplicatedDomQueries > 50) {
- $scope.notations.duplicatedDomQueries = 'C';
- }
- if (duplicatedDomQueries > 100) {
- $scope.notations.duplicatedDomQueries = 'D';
- }
- if (duplicatedDomQueries > 200) {
- $scope.notations.duplicatedDomQueries = 'E';
- }
- if (duplicatedDomQueries > 500) {
- $scope.notations.duplicatedDomQueries = 'F';
- }
- var eventsBoundScore = $scope.phantomasResults.metrics.eventsBound;
- if (eventsBoundScore > 50) {
- $scope.notations.eventsBound = 'B';
- }
- if (eventsBoundScore > 100) {
- $scope.notations.eventsBound = 'C';
- }
- if (eventsBoundScore > 200) {
- $scope.notations.eventsBound = 'D';
- }
- if (eventsBoundScore > 500) {
- $scope.notations.eventsBound = 'E';
- }
- if (eventsBoundScore > 1000) {
- $scope.notations.eventsBound = 'F';
- }
- var badPracticesScore = $scope.phantomasResults.metrics.documentWriteCalls * 3 +
- $scope.phantomasResults.metrics.evalCalls * 3 +
- $scope.phantomasResults.metrics.jsErrors * 10 +
- $scope.phantomasResults.metrics.consoleMessages;
- if (badPracticesScore > 5) {
- $scope.notations.badPractices = 'B';
- }
- if (badPracticesScore > 10) {
- $scope.notations.badPractices = 'C';
- }
- if (badPracticesScore > 15) {
- $scope.notations.badPractices = 'D';
- }
- if (badPracticesScore > 25) {
- $scope.notations.badPractices = 'E';
- }
- if (badPracticesScore > 40) {
- $scope.notations.badPractices = 'F';
- }
- var scriptsScore = $scope.phantomasResults.metrics.jsCount;
- if (scriptsScore > 4) {
- $scope.notations.scripts = 'B';
- }
- if (scriptsScore > 8) {
- $scope.notations.scripts = 'C';
- }
- if (scriptsScore > 12) {
- $scope.notations.scripts = 'D';
- }
- if (scriptsScore > 16) {
- $scope.notations.scripts = 'E';
- }
- if (scriptsScore > 20) {
- $scope.notations.scripts = 'F';
- }
- $scope.notations.jQueryLoading = 'NA';
- if ($scope.phantomasResults.metrics.jQueryDifferentVersions > 1) {
- $scope.notations.jQueryLoading = 'F';
- } else if ($scope.phantomasResults.metrics.jQueryVersion) {
- if ($scope.phantomasResults.metrics.jQueryVersion.indexOf('1.10.') === 0 ||
- $scope.phantomasResults.metrics.jQueryVersion.indexOf('1.11.') === 0 ||
- $scope.phantomasResults.metrics.jQueryVersion.indexOf('1.12.') === 0 ||
- $scope.phantomasResults.metrics.jQueryVersion.indexOf('2.0.') === 0 ||
- $scope.phantomasResults.metrics.jQueryVersion.indexOf('2.1.') === 0 ||
- $scope.phantomasResults.metrics.jQueryVersion.indexOf('2.2.') === 0) {
- $scope.notations.jQueryLoading = 'A';
- } else if ($scope.phantomasResults.metrics.jQueryVersion.indexOf('1.8.') === 0 ||
- $scope.phantomasResults.metrics.jQueryVersion.indexOf('1.9.') === 0) {
- $scope.notations.jQueryLoading = 'B';
- } else if ($scope.phantomasResults.metrics.jQueryVersion.indexOf('1.6.') === 0 ||
- $scope.phantomasResults.metrics.jQueryVersion.indexOf('1.7.') === 0) {
- $scope.notations.jQueryLoading = 'C';
- } else if ($scope.phantomasResults.metrics.jQueryVersion.indexOf('1.4.') === 0 ||
- $scope.phantomasResults.metrics.jQueryVersion.indexOf('1.5.') === 0) {
- $scope.notations.jQueryLoading = 'D';
- } else if ($scope.phantomasResults.metrics.jQueryVersion.indexOf('1.2.') === 0 ||
- $scope.phantomasResults.metrics.jQueryVersion.indexOf('1.3.') === 0) {
- $scope.notations.jQueryLoading = 'E';
- }
- }
- }
- function initExecutionView() {
- $scope.slowRequestsOn = false;
- $scope.slowRequestsLimit = 5;
- }
- function initMetricsView() {
- // Get the Phantomas modules from metadata
- $scope.metricsModule = {};
- for (var metricName in $scope.phantomasMetadata) {
- var metric = $scope.phantomasMetadata[metricName];
- if (!$scope.metricsModule[metric.module]) {
- $scope.metricsModule[metric.module] = {};
- }
- $scope.metricsModule[metric.module][metricName] = metric;
- }
- }
- function parseBacktrace(str) {
- if (!str) {
- return null;
- }
- 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]
- });
- }
- });
- return out;
- }
- // Goes on every node of the tree and calls the function fn. If fn returns false on a node, its children won't be checked.
- function treeRunner(node, fn) {
- if (fn(node) !== false && node.children) {
- node.children.forEach(function(child) {
- treeRunner(child, fn);
- });
- }
- }
- });
|