|
@@ -9,10 +9,9 @@ import { bindEvents, INJECT_PAGE, INJECT_CONTENT } from '../util';
|
|
|
|
|
|
// Make sure to call safe::methods() in code that may run after userscripts
|
|
|
|
|
|
-const queueMacrotask = cb => bridge.call('NextTask', 0, bridge, 0, cb);
|
|
|
-// Waiting for injection of content mode scripts that don't run on document-start
|
|
|
-let runningQueues;
|
|
|
-let waitingQueues;
|
|
|
+/** document-body scripts in content mode are inserted via executeScript at document-start
|
|
|
+ * in inert state, then wait for content bridge to call RunAt('body'). */
|
|
|
+let runAtBodyQueue;
|
|
|
|
|
|
export default function initialize(
|
|
|
webId,
|
|
@@ -20,18 +19,16 @@ export default function initialize(
|
|
|
invokeHost,
|
|
|
) {
|
|
|
let invokeGuest;
|
|
|
- if (process.env.HANDSHAKE_ID) {
|
|
|
- window::on(process.env.HANDSHAKE_ID + process.env.HANDSHAKE_ACK, e => {
|
|
|
+ if (PAGE_MODE_HANDSHAKE) {
|
|
|
+ window::on(PAGE_MODE_HANDSHAKE + '*', e => {
|
|
|
e = e::getDetail();
|
|
|
webId = e[0];
|
|
|
contentId = e[1];
|
|
|
}, { __proto__: null, once: true, capture: true });
|
|
|
- window::fire(new SafeCustomEvent(process.env.HANDSHAKE_ID));
|
|
|
+ window::fire(new SafeCustomEvent(PAGE_MODE_HANDSHAKE));
|
|
|
}
|
|
|
bridge.dataKey = contentId;
|
|
|
if (invokeHost) {
|
|
|
- runningQueues = [];
|
|
|
- waitingQueues = createNullObj();
|
|
|
bridge.mode = INJECT_CONTENT;
|
|
|
bridge.post = (cmd, data, context, node) => {
|
|
|
invokeHost({ cmd, data, node, dataKey: (context || bridge).dataKey }, INJECT_CONTENT);
|
|
@@ -43,7 +40,14 @@ export default function initialize(
|
|
|
global.chrome = undefined;
|
|
|
global.browser = undefined;
|
|
|
bridge.addHandlers({
|
|
|
- RunAt: doRunAt,
|
|
|
+ RunAt() {
|
|
|
+ // executeScript code may run after <body> appeared
|
|
|
+ if (runAtBodyQueue) {
|
|
|
+ for (const fn of runAtBodyQueue) fn();
|
|
|
+ }
|
|
|
+ // allowing the belated code to run immediately
|
|
|
+ runAtBodyQueue = false;
|
|
|
+ },
|
|
|
});
|
|
|
} else {
|
|
|
bridge.mode = INJECT_PAGE;
|
|
@@ -75,12 +79,9 @@ bridge.addHandlers({
|
|
|
assign(bridge, info);
|
|
|
}
|
|
|
if (items) {
|
|
|
- if (waitingQueues && runAt !== 'start') {
|
|
|
- waitingQueues[runAt] = [];
|
|
|
- }
|
|
|
items::forEach(createScriptData);
|
|
|
// FF bug workaround to enable processing of sourceURL in injected page scripts
|
|
|
- if (IS_FIREFOX && bridge.mode === INJECT_PAGE) {
|
|
|
+ if (IS_FIREFOX && PAGE_MODE_HANDSHAKE) {
|
|
|
bridge.post('InjectList', runAt);
|
|
|
}
|
|
|
}
|
|
@@ -109,7 +110,7 @@ function createScriptData(item) {
|
|
|
}
|
|
|
|
|
|
async function onCodeSet(item, fn) {
|
|
|
- const { dataKey, stage } = item;
|
|
|
+ const { dataKey } = item;
|
|
|
// deleting now to prevent interception via DOMNodeRemoved on el::remove()
|
|
|
delete window[dataKey];
|
|
|
if (process.env.DEBUG) {
|
|
@@ -121,40 +122,12 @@ async function onCodeSet(item, fn) {
|
|
|
(wrapper || global)::fn(gm, logging.error);
|
|
|
};
|
|
|
const el = document::getCurrentScript();
|
|
|
- const queue = waitingQueues?.[stage];
|
|
|
if (el) {
|
|
|
el::remove();
|
|
|
}
|
|
|
- if (queue) {
|
|
|
- if (stage === 'idle') safePush(queue, 1);
|
|
|
- safePush(queue, run);
|
|
|
+ if (!PAGE_MODE_HANDSHAKE && runAtBodyQueue !== false && item.runAt === 'body') {
|
|
|
+ safePush(runAtBodyQueue || (runAtBodyQueue = []), run);
|
|
|
} else {
|
|
|
run();
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
-async function doRunAt(name) {
|
|
|
- if (name) {
|
|
|
- safePush(runningQueues, waitingQueues[name]);
|
|
|
- if (runningQueues.length > 1) return;
|
|
|
- }
|
|
|
- for (let i = 0, queue; i < runningQueues.length; i += 1) {
|
|
|
- if ((queue = waitingQueues[i])) {
|
|
|
- for (let j = 0, fn; j < queue.length; j += 1) {
|
|
|
- fn = queue[j];
|
|
|
- if (fn) {
|
|
|
- queue[j] = null;
|
|
|
- if (fn === 1) {
|
|
|
- queueMacrotask(doRunAt);
|
|
|
- return;
|
|
|
- }
|
|
|
- await 0;
|
|
|
- fn();
|
|
|
- }
|
|
|
- }
|
|
|
- queue.length = 0;
|
|
|
- runningQueues[i] = null;
|
|
|
- }
|
|
|
- }
|
|
|
- runningQueues.length = 0;
|
|
|
-}
|