Skip to content

Commit

Permalink
Allow to display warnings in the browser
Browse files Browse the repository at this point in the history
Inspired by postcss-messages. Then why not use that plugin? Well, look at the
diff of index.js:

    -    console.log(warningLog);
    +    if (!('console' in options && !options.console)) {
    +      console.log(warningLog);
    +    }
    +
    +    if (options.browser) {
    +      result.root.append(formatBrowser(warningLog));
    +    }

The only difference is how to display the warnings! There's no need to duplicate
the rest of features between the two plugins.

This fixes postcss/postcss-browser-reporter#8, postcss/postcss-browser-reporter#9 and
postcss/postcss-browser-reporter#10.

As opposed to postcss-messages, this implementation:

- Inserts the messages at `head::before` instead of `html::before`. While
  `html::before` is unlikely to conflict with other styles, `head::before` is
  even less so! In fact, it should be _extremely_ unlikely to conflict.

- Does not allow to change the selector. Because of the above point there's no
  need to.

- Does not use `::after` if `::before` was already used in the CSS. Again,
  because of the first point there is no need to.

- Does not allow to change the styling. There's no way to change the styling
  when logging to the console either. Also, @ai said:

  > BTW, options is a lack in UX. You should better think more about default
  > options and styles, rather than add options for every case.

  postcss/postcss-browser-reporter#3 (comment)

- Uses simpler styling. KISS. It is still similar to postcss-messages.
  • Loading branch information
lydell committed May 29, 2015
1 parent 52a4e23 commit 64b8b78
Show file tree
Hide file tree
Showing 14 changed files with 137 additions and 38 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
node_modules
*.log
tmp
/test/compiled.css
15 changes: 12 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
# postcss-log-warnings [![Build Status](https://travis-ci.org/davidtheclark/postcss-log-warnings.svg?branch=master)](https://travis-ci.org/davidtheclark/postcss-log-warnings)

Log PostCSS warnings in the console.
Log PostCSS warnings in the console and in the browser.

## Purpose

As of PostCSS 4.1, a single PostCSS process can accumulate warnings from all of the plugins it uses.
Presumably, plugin authors want you to see those warnings.
So this plugin exists to read the accumulated warnings (or warnings from only the plugins you've specified), format them for human legibility, and print them to the console.
So this plugin exists to read the accumulated warnings (or warnings from only the plugins you've specified), format them for human legibility, and print them to the console, display them in the browser or both.

## Example Output

![Example](example.png?raw=true)
![Console example](example-console.png?raw=true)
![Browser example](example-browser.png?raw=true)

## Installation

Expand Down Expand Up @@ -42,6 +43,14 @@ gulp.task('css', function() {

### Options

- **console** (boolean, default = `true`)

Whether or not to log to the console.

- **browser** (boolean, default = `false`)

Whether or not to display warnings in the browser. (This works by injecting `head::before { content: '{warnings}' }` (and some nice styling of it) into the CSS.)

- **keepWarnings** (boolean, default = `false`)

If true, the plugin will *not* clear the warnings after it logs them (by default, it will clear them). Other plugins will then have access to these warnings and might re-print them.
Expand Down
Binary file added example-browser.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added example-console.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed example.png
Binary file not shown.
9 changes: 8 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
var postcss = require('postcss');
var chalk = require('chalk');
var processResult = require('./lib/processResult');
var formatBrowser = require('./lib/formatBrowser');

module.exports = postcss.plugin('postcss-log-warnings', function(options) {
options = options || {};
Expand All @@ -12,7 +13,13 @@ module.exports = postcss.plugin('postcss-log-warnings', function(options) {

if (!warningLog) return;

console.log(warningLog);
if (!('console' in options && !options.console)) {
console.log(warningLog);
}

if (options.browser) {
result.root.append(formatBrowser(warningLog));
}

if (options.throwError) {
throw new Error(chalk.red.bold('\n** postcss-log-warnings: warnings were found **'));
Expand Down
29 changes: 29 additions & 0 deletions lib/formatBrowser.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
'use strict';

var fs = require('fs');
var chalk = require('chalk');

var style = fs.readFileSync(require.resolve('./style.css')).toString();

module.exports = function(warningLog) {
var output = escapeCssStringContents(chalk.stripColor(warningLog.trim()));
return style.replace('$OUTPUT', output);
};

function escapeCssStringContents(stringContents) {
return stringContents.split('').map(function(ch) {
switch (ch) {
case '\\':
return '\\\\';
case '\n':
case '\r':
return '\\A ';
case '\'':
return '\\\'';
case '"':
return '\\"';
default:
return ch;
}
}).join('');
}
29 changes: 29 additions & 0 deletions lib/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
head {
display: block;
}

head::before, head::after {
position: fixed;
top: 0;
z-index: 2147483647; /* Maximum value browsers accept. */
min-height: 3em;
font: 14px/1.2 monospace;
color: white;
}

head::before {
content: '$OUTPUT';
left: 0;
right: 0;
padding: 1em;
padding-left: 5em; /* Add room for the warning sign. */
background: #DF4F5E;
white-space: pre;
}

head::after {
content: '\26A0'; /* Warning sign. */
left: 0.25em;
font-size: 5em;
line-height: 1;
}
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
"scripts": {
"lint": "eslint .",
"test": "npm run lint && tape test",
"visual": "node test/visual.js"
"visual": "node test/visual.js console",
"visual-browser": "node test/visual.js browser"
},
"repository": {
"type": "git",
Expand All @@ -25,6 +26,7 @@
"devDependencies": {
"eslint": "0.20.0",
"lodash": "3.8.0",
"postcss-bem-linter": "0.3.0",
"tape": "4.0.0"
},
"dependencies": {
Expand Down
12 changes: 4 additions & 8 deletions test/forVisual.css
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
body {
/** @define HamSandwich */
.Ham.Sandwich {
color: pink;
}

div {
color: orange;
background: blue;
}

p {
color: yellow;
:root a {
font-weight: bold;
}
27 changes: 27 additions & 0 deletions test/formatBrowser.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
'use strict';

var test = require('tape');
var formatBrowser = require('../lib/formatBrowser');
var chalk = require('chalk');

var input = [
'',
'|',
'||',
'" |"',
'\' |\'',
'\r',
chalk.red('foo'),
''
].join('\n').replace(/\|/g, '\\');

var escaped = '|||A |||||A |" |||"|A |\' |||\'|A |A |A foo'.replace(/\|/g, '\\');

test('formatBrowser with really tricky input', function(t) {
t.ok(
formatBrowser(input).indexOf('content: \'' + escaped + '\'') !== -1,
'includes escaped content'
);

t.end();
});
1 change: 1 addition & 0 deletions test/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
'use strict';

require('./processResult');
require('./formatBrowser');
5 changes: 5 additions & 0 deletions test/visual.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<!doctype html>
<meta charset=utf-8>
<title>visual warnings test</title>
<link rel=stylesheet href=compiled.css>
<p style="margin-top:300px">There's your visual confirmation that it works.</p>
43 changes: 18 additions & 25 deletions test/visual.js
Original file line number Diff line number Diff line change
@@ -1,37 +1,30 @@
'use strict';

var postcss = require('postcss');
var bemLinter = require('postcss-bem-linter');
var logWarnings = require('..');
var fs = require('fs');

var rejectColors = postcss.plugin('reject-colors', function() {
return function(css, result) {
css.eachDecl(function(decl) {
if (decl.prop === 'color') {
result.warn('no colors allowed', { node: decl });
}
});
};
});

var rejectBackgrounds = postcss.plugin('reject-backgrounds', function() {
return function(css, result) {
css.eachDecl(function(decl) {
if (decl.prop === 'background') {
result.warn('no backgrounds allowed', { node: decl });
}
});
};
});
var display = process.argv[2] || 'console';

fs.readFile('test/forVisual.css', { encoding: 'utf8' }, function(err, data) {
if (err) throw err;
fs.readFile('test/forVisual.css', { encoding: 'utf8' }, function(readErr, data) {
if (readErr) throw readErr;
postcss()
.use(rejectColors())
.use(rejectBackgrounds())
.use(logWarnings({ throwError: true }))
.use(bemLinter())
.use(logWarnings({
console: display === 'console',
browser: display === 'browser',
throwError: display === 'console'
}))
.process(data, { from: 'test/forVisual.css' })
.then(function() {
.then(function(result) {
fs.writeFile('test/compiled.css', result.css, function(writeErr) {
if (writeErr) throw writeErr;
console.log('Now open test/visual.html in a browser!');
});
})
.catch(function(ourErr) {
console.log(ourErr);
console.log('There\'s your visual confirmation that it works.');
});
});

0 comments on commit 64b8b78

Please sign in to comment.