From bb78ebb7722676f733a3f5e78c466c071ab944e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20B=C3=BCnemann?= Date: Wed, 20 Mar 2019 12:19:12 +0100 Subject: [PATCH] fix: CSP inline style violations, closes #905 (#906) Content Security Policy prevents the usage of inline styles on DOM elements, unless the insecure 'unsafe-inline' rule is used. This can be worked around by setting styles through the JS DOM API. --- src/backend/highlighter.js | 17 ++++++++--- src/backend/toast.js | 58 ++++++++++++++++++++------------------ 2 files changed, 44 insertions(+), 31 deletions(-) diff --git a/src/backend/highlighter.js b/src/backend/highlighter.js index 2813849901..ad7dd11f30 100644 --- a/src/backend/highlighter.js +++ b/src/backend/highlighter.js @@ -44,10 +44,19 @@ export function highlight (instance) { init() if (rect) { - let content = '' + const content = [] let name = instance.fnContext ? getComponentName(instance.fnOptions) : getInstanceName(instance) if (SharedData.classifyComponents) name = classify(name) - if (name) content = `<${name}>` + if (name) { + const pre = document.createElement('span') + pre.style.opacity = '0.6' + pre.innerText = '<' + const text = document.createTextNode(name) + const post = document.createElement('span') + post.style.opacity = '0.6' + post.innerText = '>' + content.push(pre, text, post) + } showOverlay(rect, content) } } @@ -148,7 +157,7 @@ function getTextRect (node) { * @param {Rect} */ -function showOverlay ({ width = 0, height = 0, top = 0, left = 0 }, content = '') { +function showOverlay ({ width = 0, height = 0, top = 0, left = 0 }, content = []) { if (!isBrowser) return overlay.style.width = ~~width + 'px' @@ -156,7 +165,7 @@ function showOverlay ({ width = 0, height = 0, top = 0, left = 0 }, content = '' overlay.style.top = ~~top + 'px' overlay.style.left = ~~left + 'px' - overlayContent.innerHTML = content + content.forEach(child => overlayContent.appendChild(child)) document.body.appendChild(overlay) } diff --git a/src/backend/toast.js b/src/backend/toast.js index 6976a60357..42082df805 100644 --- a/src/backend/toast.js +++ b/src/backend/toast.js @@ -18,33 +18,37 @@ export function installToast (target) { if (!toastEl) { toastEl = document.createElement('div') toastEl.addEventListener('click', removeToast) - toastEl.innerHTML = ` -
-
-
-
-
- ` + + const vueDevtoolsToast = document.createElement('div') + vueDevtoolsToast.id = 'vue-devtools-toast' + vueDevtoolsToast.style.position = 'fixed' + vueDevtoolsToast.style.bottom = '6px' + vueDevtoolsToast.style.left = '0' + vueDevtoolsToast.style.right = '0' + vueDevtoolsToast.style.height = '0' + vueDevtoolsToast.style.display = 'flex' + vueDevtoolsToast.style.alignItems = 'flex-end' + vueDevtoolsToast.style.justifyContent = 'center' + vueDevtoolsToast.style.zIndex = '999999999999999999999' + vueDevtoolsToast.style.fontFamily = 'Menlo, Consolas, monospace' + vueDevtoolsToast.style.fontSize = '14px' + + const vueWrapper = document.createElement('div') + vueWrapper.className = 'vue-wrapper' + vueWrapper.style.padding = '6px 12px' + vueWrapper.style.background = color + vueWrapper.style.color = 'white' + vueWrapper.style.borderRadius = '3px' + vueWrapper.style.flex = 'auto 0 1' + vueWrapper.style.boxShadow = '0 3px 10px rgba(0, 0, 0, 0.2)' + vueWrapper.style.cursor = 'pointer' + + const vueContent = document.createElement('div') + vueContent.className = 'vue-content' + + vueWrapper.appendChild(vueContent) + vueDevtoolsToast.appendChild(vueWrapper) + toastEl.appendChild(vueDevtoolsToast) document.body.appendChild(toastEl) } else { toastEl.querySelector('.vue-wrapper').style.background = color