Skip to content

Commit

Permalink
feat: improve styles for overlay (#4576)
Browse files Browse the repository at this point in the history
  • Loading branch information
malcolm-kee committed Sep 26, 2022
1 parent d440baf commit 791fb85
Show file tree
Hide file tree
Showing 5 changed files with 2,446 additions and 761 deletions.
84 changes: 39 additions & 45 deletions client-src/overlay.js
Expand Up @@ -3,6 +3,15 @@

import ansiHTML from "ansi-html-community";
import { encode } from "html-entities";
import {
containerStyle,
dismissButtonStyle,
headerStyle,
iframeStyle,
msgStyles,
msgTextStyle,
msgTypeStyle,
} from "./overlay/styles.js";

const colors = {
reset: ["transparent", "transparent"],
Expand All @@ -28,6 +37,17 @@ let overlayTrustedTypesPolicy;

ansiHTML.setColors(colors);

/**
*
* @param {HTMLElement} element
* @param {CSSStyleDeclaration} style
*/
function applyStyle(element, style) {
Object.keys(style).forEach((prop) => {
element.style[prop] = style[prop];
});
}

/**
* @param {string | null} trustedTypesPolicyName
*/
Expand All @@ -45,64 +65,35 @@ function createContainer(trustedTypesPolicyName) {
iframeContainerElement = document.createElement("iframe");
iframeContainerElement.id = "webpack-dev-server-client-overlay";
iframeContainerElement.src = "about:blank";
iframeContainerElement.style.position = "fixed";
iframeContainerElement.style.left = 0;
iframeContainerElement.style.top = 0;
iframeContainerElement.style.right = 0;
iframeContainerElement.style.bottom = 0;
iframeContainerElement.style.width = "100vw";
iframeContainerElement.style.height = "100vh";
iframeContainerElement.style.border = "none";
iframeContainerElement.style.zIndex = 9999999999;
applyStyle(iframeContainerElement, iframeStyle);
iframeContainerElement.onload = () => {
containerElement =
/** @type {Document} */
(
/** @type {HTMLIFrameElement} */
(iframeContainerElement).contentDocument
).createElement("div");

containerElement.id = "webpack-dev-server-client-overlay-div";
containerElement.style.position = "fixed";
containerElement.style.boxSizing = "border-box";
containerElement.style.left = 0;
containerElement.style.top = 0;
containerElement.style.right = 0;
containerElement.style.bottom = 0;
containerElement.style.width = "100vw";
containerElement.style.height = "100vh";
containerElement.style.backgroundColor = "rgba(0, 0, 0, 0.85)";
containerElement.style.color = "#E8E8E8";
containerElement.style.fontFamily = "Menlo, Consolas, monospace";
containerElement.style.fontSize = "large";
containerElement.style.padding = "2rem";
containerElement.style.lineHeight = "1.2";
containerElement.style.whiteSpace = "pre-wrap";
containerElement.style.overflow = "auto";

const headerElement = document.createElement("span");
applyStyle(containerElement, containerStyle);

const headerElement = document.createElement("div");

headerElement.innerText = "Compiled with problems:";
applyStyle(headerElement, headerStyle);

const closeButtonElement = document.createElement("button");

closeButtonElement.innerText = "X";
closeButtonElement.style.background = "transparent";
closeButtonElement.style.border = "none";
closeButtonElement.style.fontSize = "20px";
closeButtonElement.style.fontWeight = "bold";
closeButtonElement.style.color = "white";
closeButtonElement.style.cursor = "pointer";
closeButtonElement.style.cssFloat = "right";
// @ts-ignore
closeButtonElement.style.styleFloat = "right";
applyStyle(closeButtonElement, dismissButtonStyle);

closeButtonElement.innerText = "×";
closeButtonElement.ariaLabel = "Dismiss";
closeButtonElement.addEventListener("click", () => {
hide();
});

containerElement.appendChild(headerElement);
containerElement.appendChild(closeButtonElement);
containerElement.appendChild(document.createElement("br"));
containerElement.appendChild(document.createElement("br"));

/** @type {Document} */
(
Expand Down Expand Up @@ -200,26 +191,29 @@ function show(type, messages, trustedTypesPolicyName) {
ensureOverlayExists(() => {
messages.forEach((message) => {
const entryElement = document.createElement("div");
const typeElement = document.createElement("span");
const msgStyle = type === "warning" ? msgStyles.warning : msgStyles.error;
applyStyle(entryElement, {
...msgStyle,
padding: "1rem 1rem 1.5rem 1rem",
});

const typeElement = document.createElement("div");
const { header, body } = formatProblem(type, message);

typeElement.innerText = header;
typeElement.style.color = `#${colors.red}`;
applyStyle(typeElement, msgTypeStyle);

// Make it look similar to our terminal.
const text = ansiHTML(encode(body));
const messageTextNode = document.createElement("div");
applyStyle(messageTextNode, msgTextStyle);

messageTextNode.innerHTML = overlayTrustedTypesPolicy
? overlayTrustedTypesPolicy.createHTML(text)
: text;

entryElement.appendChild(typeElement);
entryElement.appendChild(document.createElement("br"));
entryElement.appendChild(document.createElement("br"));
entryElement.appendChild(messageTextNode);
entryElement.appendChild(document.createElement("br"));
entryElement.appendChild(document.createElement("br"));

/** @type {HTMLDivElement} */
(containerElement).appendChild(entryElement);
Expand Down
89 changes: 89 additions & 0 deletions client-src/overlay/styles.js
@@ -0,0 +1,89 @@
// styles are inspired by `react-error-overlay`

const msgStyles = {
error: {
backgroundColor: "rgba(206, 17, 38, 0.1)",
color: "#fccfcf",
},
warning: {
backgroundColor: "rgba(251, 245, 180, 0.1)",
color: "#fbf5b4",
},
};

const iframeStyle = {
position: "fixed",
top: 0,
left: 0,
right: 0,
bottom: 0,
width: "100vw",
height: "100vh",
border: "none",
"z-index": 9999999999,
};

const containerStyle = {
position: "fixed",
boxSizing: "border-box",
left: 0,
top: 0,
right: 0,
bottom: 0,
width: "100vw",
height: "100vh",
fontSize: "large",
padding: "2rem 2rem 4rem 2rem",
lineHeight: "1.2",
whiteSpace: "pre-wrap",
overflow: "auto",
backgroundColor: "rgba(0, 0, 0, 0.9)",
color: "white",
};

const headerStyle = {
color: "#e83b46",
fontSize: "2em",
whiteSpace: "pre-wrap",
fontFamily: "sans-serif",
margin: "0 2rem 2rem 0",
flex: "0 0 auto",
maxHeight: "50%",
overflow: "auto",
};

const dismissButtonStyle = {
color: "#ffffff",
lineHeight: "1rem",
fontSize: "1.5rem",
padding: "1rem",
cursor: "pointer",
position: "absolute",
right: 0,
top: 0,
backgroundColor: "transparent",
border: "none",
};

const msgTypeStyle = {
color: "#e83b46",
fontSize: "1.2em",
marginBottom: "1rem",
fontFamily: "sans-serif",
};

const msgTextStyle = {
lineHeight: "1.5",
fontSize: "1rem",
fontFamily: "Menlo, Consolas, monospace",
};

export {
msgStyles,
iframeStyle,
containerStyle,
headerStyle,
dismissButtonStyle,
msgTypeStyle,
msgTextStyle,
};
12 changes: 6 additions & 6 deletions test/e2e/__snapshots__/multi-compiler.test.js.snap.webpack5
Expand Up @@ -51,13 +51,13 @@ Array [
"[HMR] Cannot apply update. Need to do a full reload!",
"[HMR] Error: Aborted because ./browser.js is not accepted
Update propagation: ./browser.js
at applyHandler (http://127.0.0.1:8103/browser.js:1034:31)
at http://127.0.0.1:8103/browser.js:733:21
at applyHandler (http://127.0.0.1:8103/browser.js:1045:31)
at http://127.0.0.1:8103/browser.js:744:21
at Array.map (<anonymous>)
at internalApply (http://127.0.0.1:8103/browser.js:732:54)
at http://127.0.0.1:8103/browser.js:702:26
at waitForBlockingPromises (http://127.0.0.1:8103/browser.js:656:48)
at http://127.0.0.1:8103/browser.js:700:24",
at internalApply (http://127.0.0.1:8103/browser.js:743:54)
at http://127.0.0.1:8103/browser.js:713:26
at waitForBlockingPromises (http://127.0.0.1:8103/browser.js:667:48)
at http://127.0.0.1:8103/browser.js:711:24",
"[webpack-dev-server] Server started: Hot Module Replacement enabled, Live Reloading disabled, Progress disabled, Overlay enabled.",
"[HMR] Waiting for update signal from WDS...",
"Hello from the browser",
Expand Down

0 comments on commit 791fb85

Please sign in to comment.