Spaces:
Runtime error
Runtime error
/* eslint-env browser */ | |
const removeElement = el => el && el.parentNode && el.parentNode.removeChild(el) | |
const ErrorOverlay = () => { | |
let errors = [] | |
let compileError = null | |
const errorsTitle = 'Failed to init component' | |
const compileErrorTitle = 'Failed to compile' | |
const style = { | |
section: ` | |
position: fixed; | |
top: 0; | |
bottom: 0; | |
left: 0; | |
right: 0; | |
padding: 32px; | |
background: rgba(0, 0, 0, .85); | |
font-family: Menlo, Consolas, monospace; | |
font-size: large; | |
color: rgb(232, 232, 232); | |
overflow: auto; | |
z-index: 2147483647; | |
`, | |
h1: ` | |
margin-top: 0; | |
color: #E36049; | |
font-size: large; | |
font-weight: normal; | |
`, | |
h2: ` | |
margin: 32px 0 0; | |
font-size: large; | |
font-weight: normal; | |
`, | |
pre: ``, | |
} | |
const createOverlay = () => { | |
const h1 = document.createElement('h1') | |
h1.style = style.h1 | |
const section = document.createElement('section') | |
section.appendChild(h1) | |
section.style = style.section | |
const body = document.createElement('div') | |
section.appendChild(body) | |
return { h1, el: section, body } | |
} | |
const setTitle = title => { | |
overlay.h1.textContent = title | |
} | |
const show = () => { | |
const { el } = overlay | |
if (!el.parentNode) { | |
const target = document.body | |
target.appendChild(overlay.el) | |
} | |
} | |
const hide = () => { | |
const { el } = overlay | |
if (el.parentNode) { | |
overlay.el.remove() | |
} | |
} | |
const update = () => { | |
if (compileError) { | |
overlay.body.innerHTML = '' | |
setTitle(compileErrorTitle) | |
const errorEl = renderError(compileError) | |
overlay.body.appendChild(errorEl) | |
show() | |
} else if (errors.length > 0) { | |
overlay.body.innerHTML = '' | |
setTitle(errorsTitle) | |
errors.forEach(({ title, message }) => { | |
const errorEl = renderError(message, title) | |
overlay.body.appendChild(errorEl) | |
}) | |
show() | |
} else { | |
hide() | |
} | |
} | |
const renderError = (message, title) => { | |
const div = document.createElement('div') | |
if (title) { | |
const h2 = document.createElement('h2') | |
h2.textContent = title | |
h2.style = style.h2 | |
div.appendChild(h2) | |
} | |
const pre = document.createElement('pre') | |
pre.textContent = message | |
div.appendChild(pre) | |
return div | |
} | |
const addError = (error, title) => { | |
const message = (error && error.stack) || error | |
errors.push({ title, message }) | |
update() | |
} | |
const clearErrors = () => { | |
errors.forEach(({ element }) => { | |
removeElement(element) | |
}) | |
errors = [] | |
update() | |
} | |
const setCompileError = message => { | |
compileError = message | |
update() | |
} | |
const overlay = createOverlay() | |
return { | |
addError, | |
clearErrors, | |
setCompileError, | |
} | |
} | |
export default ErrorOverlay | |