/* 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