From f9b0f6d613a535a9562cbf41ad507b8c0081abfb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20M=C3=A9tais?= Date: Tue, 18 Nov 2014 22:29:07 +0100 Subject: [PATCH 01/17] Remove Beta status on HP --- app/node_views/index.html | 1 - 1 file changed, 1 deletion(-) diff --git a/app/node_views/index.html b/app/node_views/index.html index 5cd772b..3cf1054 100644 --- a/app/node_views/index.html +++ b/app/node_views/index.html @@ -13,7 +13,6 @@ -

(This is a BETA, your feedback is more than welcome)

+
+
F
+
CSS errors
+
+
+
+
CSS files with syntax errors
+
+ {{phantomasResults.metrics.cssParsingErrors}} + +
+
+
+ +

Yellow Lab Tools failed to parse a CSS file. I doubt the problem comes from the css parser.

+

+ Check directly on W3C CSS Validator: +

+
+
+
+
+
+
{{notations.cssComplexity}}
CSS complexity
@@ -339,20 +367,6 @@
Bad CSS
-
-
CSS syntax error
-
- {{phantomasResults.metrics.cssParsingErrors}} - -
-
-
- -

Yellow Lab Tools failed to parse a CSS file. I doubt the problem comes from the css parser.

-

Maybe a CSS validator can help you.

-
-
-
Uses of @import
diff --git a/app/public/scripts/resultsCtrl.js b/app/public/scripts/resultsCtrl.js index 0325b0e..8cc9542 100644 --- a/app/public/scripts/resultsCtrl.js +++ b/app/public/scripts/resultsCtrl.js @@ -64,6 +64,19 @@ app.controller('ResultsCtrl', function ($scope) { } }); + // If there are some CSS parsing errors, prepare the W3C CSS Validator direct URLs + if ($scope.phantomasResults.offenders.cssParsingErrors) { + $scope.cssW3cDirectUrls = []; + $scope.phantomasResults.offenders.cssParsingErrors.forEach(function(errorString, index) { + var stylesheet = errorString.split(' ')[0]; + var w3cUrl = 'http://jigsaw.w3.org/css-validator/validator?profile=css3&usermedium=all&warning=no&vextwarning=true&lang=en&uri=' + encodeURIComponent(stylesheet); + $scope.cssW3cDirectUrls.push({ + url: stylesheet, + w3c: w3cUrl + }); + }); + } + // Grab the notes $scope.notations = { domComplexity: getDomComplexityScore(), @@ -283,9 +296,7 @@ app.controller('ResultsCtrl', function ($scope) { } function getBadCssScore() { - if ($scope.phantomasResults.metrics.cssParsingErrors) { - return 'F'; - } else if (!$scope.phantomasResults.metrics.cssRules) { + if (!$scope.phantomasResults.metrics.cssRules) { return 'NA'; } From 5b2bf8956aa58fac812add796390da503e823ff2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20M=C3=A9tais?= Date: Thu, 20 Nov 2014 11:19:18 +0100 Subject: [PATCH 06/17] #2 Give a A grade if no syntax error --- app/node_views/results.html | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/app/node_views/results.html b/app/node_views/results.html index e017095..e6b414a 100644 --- a/app/node_views/results.html +++ b/app/node_views/results.html @@ -277,10 +277,12 @@
-
-
F
-
CSS errors
-
+
+
F
+
F
+
CSS syntax errors
+
+
CSS files with syntax errors
@@ -289,8 +291,8 @@
-
- +
+

Yellow Lab Tools failed to parse a CSS file. I doubt the problem comes from the css parser.

Check directly on W3C CSS Validator: From 041904f4c67c8cb579b22c9b03e99c5583f3d4a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20M=C3=A9tais?= Date: Thu, 20 Nov 2014 11:34:21 +0100 Subject: [PATCH 07/17] Wording improved --- app/node_views/results.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/node_views/results.html b/app/node_views/results.html index e6b414a..9109b2c 100644 --- a/app/node_views/results.html +++ b/app/node_views/results.html @@ -295,7 +295,7 @@

Yellow Lab Tools failed to parse a CSS file. I doubt the problem comes from the css parser.

- Check directly on W3C CSS Validator: + Direct links to the W3C CSS Validator for the following stylesheets:

  • {{stylesheet.url}} From b0b6e71d2ef5ea99b4bb07d8e318e8b841ce354c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20M=C3=A9tais?= Date: Thu, 20 Nov 2014 13:02:49 +0100 Subject: [PATCH 08/17] Fix grade error --- app/node_views/results.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/node_views/results.html b/app/node_views/results.html index 9109b2c..b6fab8d 100644 --- a/app/node_views/results.html +++ b/app/node_views/results.html @@ -278,7 +278,7 @@
-
F
+
A
F
CSS syntax errors
From 2a2d99191d88ed1943a9fabce2d49d6e14ac7dd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20M=C3=A9tais?= Date: Thu, 20 Nov 2014 14:41:46 +0100 Subject: [PATCH 09/17] Another warning --- app/node_views/results.html | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/app/node_views/results.html b/app/node_views/results.html index b6fab8d..6cab6db 100644 --- a/app/node_views/results.html +++ b/app/node_views/results.html @@ -295,7 +295,7 @@

Yellow Lab Tools failed to parse a CSS file. I doubt the problem comes from the css parser.

- Direct links to the W3C CSS Validator for the following stylesheets: + Direct links to the W3C CSS Validator for the following stylesheet(s):

+
+
( couldn't be parsed)
+
+
+
@@ -534,6 +539,11 @@
+
+
( couldn't be parsed)
+
+
+
From 4e64af0f10f53f0dfbf730f36f62ce0ddc85a86c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20M=C3=A9tais?= Date: Thu, 20 Nov 2014 14:53:50 +0100 Subject: [PATCH 10/17] Add quotes to User-Agent when console.logging the phantomas command line --- app/lib/phantomasWrapper.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/lib/phantomasWrapper.js b/app/lib/phantomasWrapper.js index cadb516..39a099c 100644 --- a/app/lib/phantomasWrapper.js +++ b/app/lib/phantomasWrapper.js @@ -50,7 +50,13 @@ var PhantomasWrapper = function() { console.log('If you want to reproduce the phantomas task only, copy the following command line:'); var optionsString = ''; for (var opt in options) { - optionsString += ' ' + '--' + opt + '=' + options[opt]; + + var value = options[opt]; + if ((typeof value === 'string' || value instanceof String) && value.indexOf(' ') >= 0) { + value = '"' + value + '"'; + } + + optionsString += ' ' + '--' + opt + '=' + value; } console.log('node node_modules/phantomas/bin/phantomas.js --url=' + task.url + optionsString + ' --verbose'); From a9fb0b3b082c63c4f4f933a17efd889e77be5428 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20M=C3=A9tais?= Date: Thu, 20 Nov 2014 15:03:46 +0100 Subject: [PATCH 11/17] Fix test, google added a redirection --- test/server/phantomasWrapperTest.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/server/phantomasWrapperTest.js b/test/server/phantomasWrapperTest.js index b585210..4710774 100644 --- a/test/server/phantomasWrapperTest.js +++ b/test/server/phantomasWrapperTest.js @@ -8,7 +8,7 @@ describe('phantomasWrapper', function() { }); it('should execute', function(done) { - var url = 'http://www.google.fr/'; + var url = 'http://example.com/'; this.timeout(20000); phantomasWrapper.execute({ From 362dc9bbcc8016a3787a606e84a8e7de041685ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20M=C3=A9tais?= Date: Thu, 20 Nov 2014 15:23:19 +0100 Subject: [PATCH 12/17] Wait until all CSS files are analyzed --- app/lib/phantomasWrapper.js | 1 + .../analyzeStyleYLT/analyzeStyleYLT.js | 137 ++++++++++++++++++ 2 files changed, 138 insertions(+) create mode 100644 phantomas_custom/modules/analyzeStyleYLT/analyzeStyleYLT.js diff --git a/app/lib/phantomasWrapper.js b/app/lib/phantomasWrapper.js index 39a099c..3b71204 100644 --- a/app/lib/phantomasWrapper.js +++ b/app/lib/phantomasWrapper.js @@ -28,6 +28,7 @@ var PhantomasWrapper = function() { reporter: 'json:pretty', 'analyze-css': true, 'skip-modules': [ + 'analyzeCss', // overriden 'blockDomains', // not needed 'domComplexity', // overriden 'domMutations', // not compatible with webkit diff --git a/phantomas_custom/modules/analyzeStyleYLT/analyzeStyleYLT.js b/phantomas_custom/modules/analyzeStyleYLT/analyzeStyleYLT.js new file mode 100644 index 0000000..4f6a960 --- /dev/null +++ b/phantomas_custom/modules/analyzeStyleYLT/analyzeStyleYLT.js @@ -0,0 +1,137 @@ +/** + * Adds CSS related metrics using analyze-css NPM module + * + * @see https://github.com/macbre/analyze-css + * + * Run phantomas with --analyze-css option to use this module + * + * setMetric('cssBase64Length') @desc total length of base64-encoded data in CSS source (will warn about base64-encoded data bigger than 4 kB) @optional @offenders + * setMetric('cssRedundantBodySelectors') @desc number of redundant body selectors (e.g. body .foo, section body h2, but not body > h1) @optional @offenders + * setMetric('redundantChildNodesSelectors') @desc number of redundant child nodes selectors @optional @offenders + * setMetric('cssComments') @desc number of comments in CSS source @optional @offenders + * setMetric('cssCommentsLength') @desc length of comments content in CSS source @optional + * setMetric('cssComplexSelectors') @desc number of complex selectors (consisting of more than three expressions, e.g. header ul li .foo) @optional @offenders + * setMetric('cssComplexSelectorsByAttribute') @desc [number] number of selectors with complex matching by attribute (e.g. [class$="foo"]) @optional @offenders + * setMetric('cssDuplicatedSelectors') @desc number of CSS selectors defined more than once in CSS source @optional @offenders + * setMetric('cssDuplicatedProperties') @desc number of CSS property definitions duplicated within a selector @optional @offenders + * setMetric('cssEmptyRules') @desc number of rules with no properties (e.g. .foo { }) @optional @offenders + * setMetric('cssExpressions') @desc number of rules with CSS expressions (e.g. expression( document.body.clientWidth > 600 ? "600px" : "auto" )) @optional @offenders + * setMetric('cssOldIEFixes') @desc number of fixes for old versions of Internet Explorer (e.g. * html .foo {} and .foo { *zoom: 1 }) @optional @offenders + * setMetric('cssImports') @desc number of @import rules @optional @offenders + * setMetric('cssImportants') @desc number of properties with value forced by !important @optional @offenders + * setMetric('cssMediaQueries') @desc number of media queries (e.g. @media screen and (min-width: 1370px)) @optional @offenders + * setMetric('cssOldPropertyPrefixes') @desc number of properties with no longer needed vendor prefix, powered by data provided by autoprefixer (e.g. --moz-border-radius) @optional @offenders + * setMetric('cssQualifiedSelectors') @desc number of qualified selectors (e.g. header#nav, .foo#bar, h1.title) @optional @offenders + * setMetric('cssSpecificityIdAvg') @desc average specificity for ID @optional + * setMetric('cssSpecificityIdTotal') @desc total specificity for ID @optional + * setMetric('cssSpecificityClassAvg') @desc average specificity for class, pseudo-class or attribute @optional + * setMetric('cssSpecificityClassTotal') @desc total specificity for class, pseudo-class or attribute @optional + * setMetric('cssSpecificityTagAvg') @desc average specificity for element @optional + * setMetric('cssSpecificityTagTotal') @desc total specificity for element @optional + * setMetric('cssSelectorsByAttribute') @desc number of selectors by attribute (e.g. .foo[value=bar]) @optional + * setMetric('cssSelectorsByClass') @desc number of selectors by class @optional + * setMetric('cssSelectorsById') @desc number of selectors by ID @optional + * setMetric('cssSelectorsByPseudo') @desc number of pseudo-selectors (e,g. :hover) @optional + * setMetric('cssSelectorsByTag') @desc number of selectors by tag name @optional + * setMetric('cssUniversalSelectors') @desc number of selectors trying to match every element (e.g. .foo > *) @optional @offenders + * setMetric('cssLength') @desc length of CSS source (in bytes) @optional + * setMetric('cssRules') @desc number of rules (e.g. .foo, .bar { color: red } is counted as one rule) @optional + * setMetric('cssSelectors') @desc number of selectors (e.g. .foo, .bar { color: red } is counted as two selectors - .foo and .bar) @optional + * setMetric('cssDeclarations') @desc number of declarations (e.g. .foo, .bar { color: red } is counted as one declaration - color: red) @optional + */ +'use strict'; + +exports.version = '0.3.a'; + +exports.module = function(phantomas) { + if (!phantomas.getParam('analyze-css')) { + phantomas.log('To enable CSS in-depth metrics please run phantomas with --analyze-css option'); + return; + } + + function ucfirst(str) { + // http://kevin.vanzonneveld.net + // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) + // + bugfixed by: Onno Marsman + // + improved by: Brett Zamir (http://brett-zamir.me) + // * example 1: ucfirst('kevin van zonneveld'); + // * returns 1: 'Kevin van zonneveld' + str += ''; + var f = str.charAt(0).toUpperCase(); + return f + str.substr(1); + } + + var isWindows = (require('system').os.name === 'windows'), + binary = isWindows ? 'analyze-css.cmd' : 'analyze-css'; + + phantomas.setMetric('cssParsingErrors'); // @desc number of CSS files (or embeded CSS) that failed to be parse by analyze-css @optional + + var runningScripts = 0; + + phantomas.on('recv', function(entry, res) { + if (entry.isCSS) { + phantomas.log('CSS: analyzing <%s>...', entry.url); + + // run analyze-css "binary" installed by npm + phantomas.runScript('node_modules/.bin/' + binary, ['--url', entry.url, '--json'], function(err, results) { + runningScripts --; + + if (err !== null) { + phantomas.log('analyzeCss: sub-process failed!'); + + // report failed CSS parsing (issue #494( + var offender = entry.url; + if (err.indexOf('CSS parsing failed') > 0) { + offender += ' (' + err.trim() + ')'; + } + + phantomas.incrMetric('cssParsingErrors'); + phantomas.addOffender('cssParsingErrors', offender); + return; + } + + phantomas.log('analyzeCss: using ' + results.generator); + + var metrics = results.metrics || {}, + offenders = results.offenders || {}; + + Object.keys(metrics).forEach(function(metric) { + var metricPrefixed = 'css' + ucfirst(metric); + + // increase metrics + phantomas.incrMetric(metricPrefixed, metrics[metric]); + + // and add offenders + if (typeof offenders[metric] !== 'undefined') { + offenders[metric].forEach(function(msg) { + phantomas.addOffender(metricPrefixed, msg); + }); + } + }); + }); + + runningScripts ++; + } + }); + + phantomas.reportQueuePush(function(done) { + phantomas.on('loadFinished', function() { + var intervalId, + pollFn; + + phantomas.log('analyze-css: making sure all processes are finished'); + + pollFn = function() { + if (runningScripts === 0) { + clearInterval(intervalId); + done(); + } else { + phantomas.log('analyze-css: waiting for %d processes to finish', runningScripts); + } + }; + + intervalId = setInterval(pollFn, 200); + pollFn(); + }); + }); +}; From ec081776070e8c77375cb69b620179b3d1e830cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20M=C3=A9tais?= Date: Thu, 20 Nov 2014 15:39:19 +0100 Subject: [PATCH 13/17] jsHint complaining --- phantomas_custom/modules/analyzeStyleYLT/analyzeStyleYLT.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/phantomas_custom/modules/analyzeStyleYLT/analyzeStyleYLT.js b/phantomas_custom/modules/analyzeStyleYLT/analyzeStyleYLT.js index 4f6a960..1c5f04e 100644 --- a/phantomas_custom/modules/analyzeStyleYLT/analyzeStyleYLT.js +++ b/phantomas_custom/modules/analyzeStyleYLT/analyzeStyleYLT.js @@ -39,11 +39,12 @@ * setMetric('cssSelectors') @desc number of selectors (e.g. .foo, .bar { color: red } is counted as two selectors - .foo and .bar) @optional * setMetric('cssDeclarations') @desc number of declarations (e.g. .foo, .bar { color: red } is counted as one declaration - color: red) @optional */ -'use strict'; exports.version = '0.3.a'; exports.module = function(phantomas) { + 'use strict'; + if (!phantomas.getParam('analyze-css')) { phantomas.log('To enable CSS in-depth metrics please run phantomas with --analyze-css option'); return; From e3d96de203542f00735cec900b0f792b1ee63fd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20M=C3=A9tais?= Date: Thu, 20 Nov 2014 16:54:11 +0100 Subject: [PATCH 14/17] Add articles links to the home page --- app/node_views/index.html | 7 +++++++ app/public/styles/index.css | 8 ++++++++ app/public/styles/less/index.less | 9 +++++++++ 3 files changed, 24 insertions(+) diff --git a/app/node_views/index.html b/app/node_views/index.html index f5f2b4a..6c0b603 100644 --- a/app/node_views/index.html +++ b/app/node_views/index.html @@ -15,6 +15,13 @@ +
+

If you want to learn more...

+ What is Yellow Lab Tools? +
+ How to deeply analyze your JavaScript? +
+ diff --git a/app/public/styles/index.css b/app/public/styles/index.css index a555cef..87521c5 100644 --- a/app/public/styles/index.css +++ b/app/public/styles/index.css @@ -10,6 +10,14 @@ background: #e74c3c; color: #fff; } +.readings { + margin-top: 5em; + font-size: 0.8em; +} +.readings a { + color: inherit; + line-height: 1.7em; +} input[type=submit], input.url { padding: 0 0.5em; diff --git a/app/public/styles/less/index.less b/app/public/styles/less/index.less index ff487ad..bc40851 100644 --- a/app/public/styles/less/index.less +++ b/app/public/styles/less/index.less @@ -13,6 +13,15 @@ color: #fff; } +.readings { + margin-top: 5em; + font-size: 0.8em; + & a { + color: inherit; + line-height: 1.7em; + } +} + input[type=submit], input.url { padding: 0 0.5em; margin: 0.5em; From 7af3bc519acd897381c1b3a4f379dd4bffaf688f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20M=C3=A9tais?= Date: Thu, 20 Nov 2014 17:54:41 +0100 Subject: [PATCH 15/17] Fix JSON cyclic problem --- phantomas_custom/modules/jQYLT/jQYLT.js | 24 +----------------------- 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/phantomas_custom/modules/jQYLT/jQYLT.js b/phantomas_custom/modules/jQYLT/jQYLT.js index 149fce0..e33e1b6 100644 --- a/phantomas_custom/modules/jQYLT/jQYLT.js +++ b/phantomas_custom/modules/jQYLT/jQYLT.js @@ -62,6 +62,7 @@ exports.module = function(phantomas) { 'delegate', 'undelegate', 'one', + 'bind', 'unbind', // more events @@ -182,29 +183,6 @@ exports.module = function(phantomas) { phantomas.leaveContext(moreData); }) || phantomas.log('jQuery: can not measure jQuerySizzleCalls (jQuery used on the page is too old)!'); - - // $().bind - jQuery.bind - // works for jQuery v?.? - phantomas.spy(jQueryFn, 'bind', function(eventTypes, func) { - - phantomas.enterContext({ - type: 'jQuery - bind', - callDetails: { - context: { - length: this.length, - firstElementPath: phantomas.getDOMPath(this[0]), - selector: this.selector - }, - arguments: [eventTypes, func] - }, - backtrace: phantomas.getBacktrace() - }); - - }, function(result) { - phantomas.leaveContext(); - }) || phantomas.log('jQuery: can not measure jQueryBindCalls (jQuery used on the page is too old)!'); - - // Add spys on many jQuery functions jQueryFunctions.forEach(function(functionName) { From 13787708e914f9bb33a0a629c53ed30548d637c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20M=C3=A9tais?= Date: Thu, 20 Nov 2014 18:07:50 +0100 Subject: [PATCH 16/17] Add version number to the home page --- app/node_controllers/indexController.js | 3 ++- app/node_views/index.html | 3 ++- app/public/styles/index.css | 3 +++ app/public/styles/less/index.less | 4 ++++ server.js | 3 ++- 5 files changed, 13 insertions(+), 3 deletions(-) diff --git a/app/node_controllers/indexController.js b/app/node_controllers/indexController.js index b5c488c..88d1913 100644 --- a/app/node_controllers/indexController.js +++ b/app/node_controllers/indexController.js @@ -6,7 +6,7 @@ var async = require('async'); var fs = require ('fs'); var strReplace = require('../lib/strReplace'); -var indexController = function(req, res, googleAnalyticsId) { +var indexController = function(req, res, googleAnalyticsId, version) { 'use strict'; async.parallel({ @@ -18,6 +18,7 @@ var indexController = function(req, res, googleAnalyticsId) { }, function(err, results) { var html = results.htmlTemplate; html = strReplace(html, '%%GA_ID%%', googleAnalyticsId); + html = strReplace(html, '%%VERSION%%', version); res.setHeader('Content-Type', 'text/html'); res.send(html); diff --git a/app/node_views/index.html b/app/node_views/index.html index 6c0b603..f1a4c18 100644 --- a/app/node_views/index.html +++ b/app/node_views/index.html @@ -19,11 +19,12 @@

If you want to learn more...

What is Yellow Lab Tools?
- How to deeply analyze your JavaScript? + Learn how to deeply analyze your JavaScript