Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: tweak style for overlay #4576

Merged
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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