Change: a better way to defer page script injection, switch to inline script (#766)

* Revert "Revert defer page script injection (#758)"

This reverts commit 7d52326eb7.

* Add: store style count in sessionStorage

* Change: use localStorage instead of sessionStorage

* Update web-ext

* Fix: page script doesn't work in XML

* Fix: promise never returns if the script is rejected

* Change: disable page script preload

* Drop: stylusStyleCount
This commit is contained in:
eight 2019-09-09 12:45:08 +08:00 committed by narcolepticinsomniac
parent a7445011a9
commit 34dfd83056
2 changed files with 21 additions and 8 deletions

View File

@ -88,10 +88,9 @@ const APPLY = (() => {
// Since it's easy to spoof the browser version in pre-Quantum FF we're checking // Since it's easy to spoof the browser version in pre-Quantum FF we're checking
// for getPreventDefault which got removed in FF59 https://bugzil.la/691151 // for getPreventDefault which got removed in FF59 https://bugzil.la/691151
const EVENT_NAME = chrome.runtime.id; const EVENT_NAME = chrome.runtime.id;
const usePageScript = CHROME || IS_OWN_PAGE || Event.prototype.getPreventDefault ? let ready;
Promise.resolve(false) : injectPageScript();
return (el, content, disabled) => return (el, content, disabled) =>
usePageScript.then(ok => { checkPageScript().then(ok => {
if (!ok) { if (!ok) {
el.textContent = content; el.textContent = content;
// https://github.com/openstyles/stylus/issues/693 // https://github.com/openstyles/stylus/issues/693
@ -107,6 +106,14 @@ const APPLY = (() => {
} }
}); });
function checkPageScript() {
if (!ready) {
ready = CHROME || IS_OWN_PAGE || Event.prototype.getPreventDefault ?
Promise.resolve(false) : injectPageScript();
}
return ready;
}
function injectPageScript() { function injectPageScript() {
const scriptContent = EVENT_NAME => { const scriptContent = EVENT_NAME => {
document.currentScript.remove(); document.currentScript.remove();
@ -132,6 +139,8 @@ const APPLY = (() => {
}})); }}));
function checkStyleApplied() { function checkStyleApplied() {
// FIXME: this is not reliable
// https://bugzilla.mozilla.org/show_bug.cgi?id=1579345
const style = document.createElement('style'); const style = document.createElement('style');
style.textContent = ':root{--stylus-applied:1}'; style.textContent = ':root{--stylus-applied:1}';
document.documentElement.appendChild(style); document.documentElement.appendChild(style);
@ -142,14 +151,18 @@ const APPLY = (() => {
} }
}; };
const code = `(${scriptContent})(${JSON.stringify(EVENT_NAME)})`; const code = `(${scriptContent})(${JSON.stringify(EVENT_NAME)})`;
const src = `data:application/javascript;base64,${btoa(code)}`; // make sure it works in XML
const script = document.createElement('script'); const script = document.createElementNS('http://www.w3.org/1999/xhtml', 'script');
const {resolve, promise} = deferred(); const {resolve, promise} = deferred();
script.src = src; // use inline script because using src is too slow
// https://github.com/openstyles/stylus/pull/766
script.text = code;
script.onerror = resolveFalse; script.onerror = resolveFalse;
window.addEventListener('error', resolveFalse); window.addEventListener('error', resolveFalse);
window.addEventListener(EVENT_NAME, handleInit); window.addEventListener(EVENT_NAME, handleInit);
document.documentElement.appendChild(script); (document.head || document.documentElement).appendChild(script);
// injection failed if handleInit is not called.
resolveFalse();
return promise.then(result => { return promise.then(result => {
script.remove(); script.remove();
window.removeEventListener(EVENT_NAME, handleInit); window.removeEventListener(EVENT_NAME, handleInit);

View File

@ -21,7 +21,7 @@
"stylus-lang-bundle": "^0.54.5", "stylus-lang-bundle": "^0.54.5",
"updates": "^8.2.1", "updates": "^8.2.1",
"usercss-meta": "^0.9.0", "usercss-meta": "^0.9.0",
"web-ext": "^3.1.0", "web-ext": "^3.1.1",
"webext-tx-fix": "^0.3.2", "webext-tx-fix": "^0.3.2",
"zipjs-browserify": "^1.0.1" "zipjs-browserify": "^1.0.1"
}, },