Skip to content
Open
Show file tree
Hide file tree
Changes from 4 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
1 change: 0 additions & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ workflows:
tags:
only: /.*/


commands:
setup:
steps:
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,8 @@ Configuration options can be passed to the client by adding querystring paramete
* **dynamicPublicPath** - Set to `true` to use webpack `publicPath` as prefix of `path`. (We can set `__webpack_public_path__` dynamically at runtime in the entry point, see note of [output.publicPath](https://webpack.js.org/configuration/output/#output-publicpath))
* **autoConnect** - Set to `false` to use to prevent a connection being automatically opened from the client to the webpack back-end - ideal if you need to modify the options using the `setOptionsAndConnect` function
* **ansiColors** - An object to customize the client overlay colors as mentioned in the [ansi-html-community](https://github.com/mahdyar/ansi-html-community#set-colors) package.
* **overlayStyles** - An object to let you override or add new inline styles to the client overlay div.
* **overlayStyleMode** - Set to `'inline'` to use inline styling (default), or `'headless'` for custom or [CSP](https://webpack.js.org/guides/csp/) compatible styling (You can import `webpack-hot-middleware/client-overlay.css` to enable the default styles; make sure a proper loader have been configured for the CSS files).
* **overlayStyles** - An object to let you override or add new inline styles to the client overlay div. Requires `overlayStyleMode` to be `'inline'`.
* **overlayWarnings** - Set to `true` to enable client overlay on warnings in addition to errors.
* **statsOptions** - An object to customize stats options.

Expand Down
36 changes: 36 additions & 0 deletions client-overlay.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
.webpack-hot-middleware-clientOverlay {
background: rgba(0, 0, 0, 0.85);
color: #e8e8e8;
line-height: 1.6;
white-space: pre;
font-family: Menlo, Consolas, monospace;
font-size: 13px;
position: fixed;
z-index: 9999;
padding: 10px;
left: 0;
right: 0;
top: 0;
bottom: 0;
overflow: auto;
dir: ltr;
text-align: left;
}

.webpack-hot-middleware-clientOverlay__problem-group {
margin-bottom: 26px;
}

.webpack-hot-middleware-clientOverlay__problem {
color: #000000;
padding: 3px 6px;
border-radius: 4px;
}

.webpack-hot-middleware-clientOverlay__problem--error {
background-color: #ff3348;
}

.webpack-hot-middleware-clientOverlay__problem--warning {
background-color: #ffd30e;
}
50 changes: 36 additions & 14 deletions client-overlay.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

var clientOverlay = document.createElement('div');
clientOverlay.id = 'webpack-hot-middleware-clientOverlay';
clientOverlay.classList.add('webpack-hot-middleware-clientOverlay');

var styles = {
background: 'rgba(0,0,0,0.85)',
color: '#e8e8e8',
Expand Down Expand Up @@ -37,13 +39,16 @@ var colors = {

var htmlEntities = require('html-entities');

function showProblems(type, lines) {
function showProblems(type, lines, options) {
clientOverlay.innerHTML = '';
lines.forEach(function (msg) {
msg = ansiHTML(htmlEntities.encode(msg));
var div = document.createElement('div');
div.style.marginBottom = '26px';
div.innerHTML = problemType(type) + ' in ' + msg;
div.classList.add('webpack-hot-middleware-clientOverlay__problem-group');
if (options.overlayStyleMode === 'inline') {
div.style.marginBottom = '26px';
}
div.innerHTML = problemType(type, options) + ' in ' + msg;
clientOverlay.appendChild(div);
});
if (document.body) {
Expand All @@ -57,17 +62,32 @@ function clear() {
}
}

function problemType(type) {
function problemType(type, options) {
var problemTypeSingularNames = {
errors: 'error',
warnings: 'warning',
};
var typeName = problemTypeSingularNames[type] || 'error';
var className = 'webpack-hot-middleware-clientOverlay__problem--' + typeName;
var problemColors = {
errors: colors.red,
warnings: colors.yellow,
};
var color = problemColors[type] || colors.red;
var styleAttributeFragment = '';
if (options.overlayStyleMode === 'inline') {
var color = problemColors[type] || colors.red;
styleAttributeFragment =
' style="background-color:#' +
color +
'; color:#000000; padding:3px 6px; border-radius: 4px;"';
}
return (
'<span style="background-color:#' +
color +
'; color:#000000; padding:3px 6px; border-radius: 4px;">' +
type.slice(0, -1).toUpperCase() +
'<span class="webpack-hot-middleware-clientOverlay__problem ' +
className +
'"' +
styleAttributeFragment +
'>' +
typeName.toUpperCase() +
'</span>'
);
}
Expand All @@ -80,12 +100,14 @@ module.exports = function (options) {
ansiHTML.setColors(colors);
}

for (var style in options.overlayStyles) {
styles[style] = options.overlayStyles[style];
}
if (options.overlayStyleMode === 'inline') {
for (var style in options.overlayStyles) {
styles[style] = options.overlayStyles[style];
}

for (var key in styles) {
clientOverlay.style[key] = styles[key];
for (var key in styles) {
clientOverlay.style[key] = styles[key];
}
}

return {
Expand Down
23 changes: 18 additions & 5 deletions client.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ var options = {
overlayStyles: {},
overlayWarnings: false,
ansiColors: {},
overlayStyleMode: 'inline', // 'headless', 'inline'
};
if (__resourceQuery) {
var params = Array.from(new URLSearchParams(__resourceQuery.slice(1)));
Expand Down Expand Up @@ -74,6 +75,21 @@ function setOverrides(overrides) {
if (overrides.overlayWarnings) {
options.overlayWarnings = overrides.overlayWarnings == 'true';
}
if (overrides.overlayStyleMode) {
if (
overrides.overlayStyleMode === 'inline' ||
overrides.overlayStyleMode === 'headless'
) {
options.overlayStyleMode = overrides.overlayStyleMode;
} else {
console.warn(
'Unsupported `overlayStyleMode` value. Expected one of `inline`, or `headless`.' +
'Falling back to the default mode: `' +
options.overlayStyleMode +
'`.'
);
}
}
}

function EventSourceWrapper() {
Expand Down Expand Up @@ -167,10 +183,7 @@ function createReporter() {

var overlay;
if (typeof document !== 'undefined' && options.overlay) {
overlay = require('./client-overlay')({
ansiColors: options.ansiColors,
overlayStyles: options.overlayStyles,
});
overlay = require('./client-overlay')(options);
}

var styles = {
Expand Down Expand Up @@ -218,7 +231,7 @@ function createReporter() {
}
if (overlay) {
if (options.overlayWarnings || type === 'errors') {
overlay.showProblems(type, obj[type]);
overlay.showProblems(type, obj[type], options);
return false;
}
overlay.clear();
Expand Down
24 changes: 15 additions & 9 deletions example/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,25 @@ var time = document.getElementById('time');

var timer = setInterval(updateClock, 1000);

var isInlineStylingAllowed =
app.dataset.overlayStyleMode == null ||
app.dataset.overlayStyleMode === 'inline';

function updateClock() {
time.innerHTML = new Date().toString();
}

// Edit these styles to see them take effect immediately
app.style.display = 'table-cell';
app.style.width = '400px';
app.style.height = '400px';
app.style.border = '3px solid #339';
app.style.background = '#99d';
app.style.color = '#333';
app.style.textAlign = 'center';
app.style.verticalAlign = 'middle';
if (isInlineStylingAllowed) {
// Edit these styles to see them take effect immediately
app.style.display = 'table-cell';
app.style.width = '400px';
app.style.height = '400px';
app.style.border = '3px solid #339';
app.style.background = '#99d';
app.style.color = '#333';
app.style.textAlign = 'center';
app.style.verticalAlign = 'middle';
}

// Uncomment one of the following lines to see error handling
// require('unknown-module')
Expand Down
5 changes: 5 additions & 0 deletions example/csp.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
console.log('Testing CSP...');

if (module.hot) {
module.hot.accept();
}
5 changes: 5 additions & 0 deletions example/headless-styling.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
console.log('Testing headless styling...');

if (module.hot) {
module.hot.accept();
}
20 changes: 20 additions & 0 deletions example/index-csp.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Webpack Hot Middleware CSP Example</title>
</head>
<body>
<div id="app" data-overlay-style-mode="headless">
<p id="time">Date</p>
<input
type="text"
size="40"
placeholder="Type something in here to prove state isn't lost"
/>
</div>
<script src="/client.js"></script>
<script src="/csp.js"></script>
</body>
</html>
39 changes: 39 additions & 0 deletions example/index-headless-styling.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Webpack Hot Middleware Headless Styling Example</title>
<style>
.webpack-hot-middleware-clientOverlay__problem-group {
margin-bottom: 26px;
}

.webpack-hot-middleware-clientOverlay__problem {
color: #ffffff;
padding: 3px 6px;
border-radius: 4px;
}

.webpack-hot-middleware-clientOverlay__problem--error {
background-color: #000000;
}

.webpack-hot-middleware-clientOverlay__problem--warning {
background-color: #000000;
}
</style>
</head>
<body>
<div id="app" data-overlay-style-mode="headless">
<p id="time">Date</p>
<input
type="text"
size="40"
placeholder="Type something in here to prove state isn't lost"
/>
</div>
<script src="/client.js"></script>
<script src="/headless-styling.js"></script>
</body>
</html>
Loading