Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .eslintrc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ env:
es2017: true
node: true
browser: true
parserOptions:
ecmaVersion: 2020
extends:
- 'eslint:recommended'
- 'plugin:node/recommended'
Expand All @@ -15,3 +17,4 @@ rules:
- allowEmptyCatch: true
no-prototype-builtins: 'off'
"node/no-extraneous-require": 'off'
"node/no-unsupported-features/es-syntax": 'error'
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
strategy:
fail-fast: false
matrix:
node-version: [12.x, 14.x, 15.x, 16.x]
node-version: [14.x, 15.x, 16.x]

steps:
- uses: actions/checkout@v2
Expand Down
155 changes: 77 additions & 78 deletions modules/analyzeCss/analyzeCss.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ module.exports = function (phantomas) {
return f + str.substr(1);
}

function analyzeCss(css, context, callback) {
async function analyzeCss(css, context) {
/**
// force JSON output format
options.push('--json');
Expand All @@ -94,90 +94,89 @@ module.exports = function (phantomas) {

// https://www.npmjs.com/package/analyze-css#commonjs-module
var options = {};

new analyzer(css, options, function (err, results) {
var offenderSrc = context || "[inline CSS]";

if (err !== null) {
phantomas.log("analyzeCss: sub-process failed! - %s", err);

// report failed CSS parsing (issue #494(
var offender = offenderSrc;
if (err.message) {
// Error object returned
if (err.message.indexOf("Unable to parse JSON string") > 0) {
offender += " (analyzeCss output error)";
}
} else {
// Error string returned (stderror)
if (
err.indexOf("CSS parsing failed") > 0 ||
err.indexOf("is an invalid expression") > 0
) {
offender += " (" + err.trim() + ")";
} else if (err.indexOf("Empty CSS was provided") > 0) {
offender += " (Empty CSS was provided)";
}
let results;

try {
results = await analyzer(css, options);
} catch (err) {
phantomas.log("analyzeCss: sub-process failed! - %s", err);

// report failed CSS parsing (issue #494(
var offender = offenderSrc;
if (err.message) {
// Error object returned
if (err.message.indexOf("Unable to parse JSON string") > 0) {
offender += " (analyzeCss output error)";
}
} else {
// Error string returned (stderror)
if (
err.indexOf("CSS parsing failed") > 0 ||
err.indexOf("is an invalid expression") > 0
) {
offender += " (" + err.trim() + ")";
} else if (err.indexOf("Empty CSS was provided") > 0) {
offender += " (Empty CSS was provided)";
}
}

phantomas.incrMetric("cssParsingErrors");
phantomas.addOffender("cssParsingErrors", offender);
phantomas.incrMetric("cssParsingErrors");
phantomas.addOffender("cssParsingErrors", offender);
return;
}

callback();
return;
}
var offenderSrc = context || "[inline CSS]";

phantomas.log(
"Got results for %s from %s",
offenderSrc,
results.generator
);
phantomas.log("Got results for %s from %s", offenderSrc, results.generator);

var metrics = results.metrics || {},
offenders = results.offenders || {};
const metrics = results.metrics,
offenders = results.offenders;

Object.keys(metrics).forEach(function (metric) {
var metricPrefixed = "css" + ucfirst(metric);
Object.keys(metrics).forEach((metric) => {
var metricPrefixed = "css" + ucfirst(metric);

if (/Avg$/.test(metricPrefixed)) {
// update the average value (see #641)
phantomas.addToAvgMetric(metricPrefixed, metrics[metric]);
} else {
// increase metrics
phantomas.incrMetric(metricPrefixed, metrics[metric]);
}
if (/Avg$/.test(metricPrefixed)) {
// update the average value (see #641)
phantomas.addToAvgMetric(metricPrefixed, metrics[metric]);
} else {
// increase metrics
phantomas.incrMetric(metricPrefixed, metrics[metric]);
}

// and add offenders
if (typeof offenders[metric] !== "undefined") {
offenders[metric].forEach(function (msg) {
// and add offenders
if (typeof offenders[metric] !== "undefined") {
offenders[metric].forEach((offender) => {
phantomas.addOffender(metricPrefixed, {
url: offenderSrc,
value: {
message: offender.message,
position: {
...offender.position,
source: offender.source || "undefined",
}, // cast to object
},
});
});
}
// add more offenders (#578)
else {
switch (metricPrefixed) {
case "cssLength":
case "cssRules":
case "cssSelectors":
case "cssDeclarations":
case "cssNotMinified":
case "cssSelectorLengthAvg":
case "cssSpecificityIdAvg":
case "cssSpecificityClassAvg":
case "cssSpecificityTagAvg":
phantomas.addOffender(metricPrefixed, {
url: offenderSrc,
value: msg,
value: metrics[metric],
});
});
break;
}
// add more offenders (#578)
else {
switch (metricPrefixed) {
case "cssLength":
case "cssRules":
case "cssSelectors":
case "cssDeclarations":
case "cssNotMinified":
case "cssSelectorLengthAvg":
case "cssSpecificityIdAvg":
case "cssSpecificityClassAvg":
case "cssSpecificityTagAvg":
phantomas.addOffender(metricPrefixed, {
url: offenderSrc,
value: metrics[metric],
});
break;
}
}
});

callback();
}
});
}

Expand All @@ -195,23 +194,23 @@ module.exports = function (phantomas) {

// ok, now let's analyze the collect CSS
phantomas.on("beforeClose", () => {
var promises = [];
const promises = [];

stylesheets.forEach((entry) => {
promises.push(
new Promise(async (resolve) => {
var css = entry.inline;
let css = entry.inline;
phantomas.log("Analyzing %s", entry.url || "inline CSS");

if (entry.content) {
css = await entry.content();
}

if (css) {
analyzeCss(css, entry.url, resolve);
} else {
resolve();
await analyzeCss(css, entry.url);
}

resolve();
})
);
});
Expand Down
24 changes: 12 additions & 12 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@
],
"license": "BSD-2-Clause",
"engines": {
"node": ">=12.0"
"node": ">=14.0"
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

☝🏻

},
"dependencies": {
"analyze-css": "^1.0.0",
"analyze-css": "^2.0.0",
"ansicolors": "~0.3.2",
"ansistyles": "~0.1.0",
"ascii-table": "0.0.9",
Expand Down
25 changes: 18 additions & 7 deletions test/integration-spec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -164,8 +164,8 @@
cssDuplicatedSelectors: 1
cssParsingErrors: 1
cssInlineStyles: 3
cssLength: 200
cssRules: 4
cssLength: 208
cssRules: 6
cssImportants: 1
DOMqueries: 0
offenders:
Expand All @@ -174,9 +174,9 @@
url: "[inline CSS]",
value:
{
message: "missing '{'",
message: "Unmatched selector: = red; } bar",
position:
{ end: { column: 2, line: 3 }, start: { column: 2, line: 3 } },
{"end": {"column": 43, "line": 2}, "source": "undefined", "start": {"column": 14, "line": 2} },
},
}
cssInlineStyles:
Expand All @@ -189,9 +189,20 @@
options:
"analyze-css": true
metrics:
cssParsingErrors: 3
cssLength: 39
cssRules: 1
cssParsingErrors: 1
cssLength: 91
cssRules: 3
offenders:
cssParsingErrors:
- {
url: "http://127.0.0.1:8888/static/broken.css",
value:
{
message: "Unmatched selector: = red; } bar",
position:
{"end": {"column": 41, "line": 1}, "source": "undefined", "start": {"column": 12, "line": 1} },
},
}

- url: "/dom-operations.html"
options:
Expand Down
2 changes: 1 addition & 1 deletion test/webroot/inline-css.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
}
</style>
<style>
this will not parse correctly as CSS (and should be reported)
foo { color= red; } bar { color: blue; } baz {}} boo { display: none}
</style>
<style type="junk">do not complain about this</style>
<h1>foo</h1>
Expand Down
4 changes: 1 addition & 3 deletions test/webroot/static/broken.css
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
broken {
foo;
}
foo { color= red; } bar { color: blue; } baz {}} boo { display: none}