Fix: detect style CSP (#573)

This commit is contained in:
eight 2018-11-22 01:09:48 +08:00 committed by Rob Garrison
parent 25fb5acabe
commit 05ec2fb1c7

View File

@ -86,30 +86,57 @@ const APPLY = (() => {
function injectPageScript() { function injectPageScript() {
const scriptContent = EVENT_NAME => { const scriptContent = EVENT_NAME => {
document.currentScript.remove(); document.currentScript.remove();
window.addEventListener(EVENT_NAME, function handler(e) { const available = checkStyleApplied();
const {method, id, content} = e.detail; if (available) {
if (method === 'setStyleContent') { window.addEventListener(EVENT_NAME, function handler(e) {
const el = document.getElementById(id); const {method, id, content} = e.detail;
if (!el) { if (method === 'setStyleContent') {
return; const el = document.getElementById(id);
if (!el) {
return;
}
const disabled = el.disabled;
el.textContent = content;
el.disabled = disabled;
} else if (method === 'orphan') {
window.removeEventListener(EVENT_NAME, handler);
} }
const disabled = el.disabled; }, true);
el.textContent = content; }
el.disabled = disabled; window.dispatchEvent(new CustomEvent(EVENT_NAME, {detail: {
} else if (method === 'orphan') { method: 'init',
window.removeEventListener(EVENT_NAME, handler); available
} }}));
}, true);
function checkStyleApplied() {
const style = document.createElement('style');
style.textContent = ':root{--stylus-applied:1}';
document.documentElement.appendChild(style);
const applied = getComputedStyle(document.documentElement)
.getPropertyValue('--stylus-applied');
style.remove();
return Boolean(applied);
}
}; };
const code = `(${scriptContent})(${JSON.stringify(EVENT_NAME)})`; const code = `(${scriptContent})(${JSON.stringify(EVENT_NAME)})`;
const src = `data:application/javascript;base64,${btoa(code)}`; const src = `data:application/javascript;base64,${btoa(code)}`;
const script = document.createElement('script'); const script = document.createElement('script');
const {resolve, promise} = deferred(); const {resolve, promise} = deferred();
script.src = src; script.src = src;
script.onload = () => resolve(true);
script.onerror = () => resolve(false); script.onerror = () => resolve(false);
window.addEventListener(EVENT_NAME, handleInit);
document.documentElement.appendChild(script); document.documentElement.appendChild(script);
return promise; return promise.then(result => {
script.remove();
window.removeEventListener(EVENT_NAME, handleInit);
return result;
});
function handleInit(e) {
if (e.detail.method === 'init') {
resolve(e.detail.available);
}
}
} }
} }