Pārlūkot izejas kodu

fix: safe-guard internal events

+ send the feedback earlier and save getReadyState immediately when running before documentElement appears
tophf 4 gadi atpakaļ
vecāks
revīzija
7bc3193837
2 mainītis faili ar 19 papildinājumiem un 17 dzēšanām
  1. 17 16
      src/injected/content/inject.js
  2. 2 1
      src/injected/utils/index.js

+ 17 - 16
src/injected/content/inject.js

@@ -77,8 +77,6 @@ export function injectPageSandbox() {
  * @param {boolean} isXml
  * @param {boolean} isXml
  */
  */
 export async function injectScripts(data, isXml) {
 export async function injectScripts(data, isXml) {
-  // eslint-disable-next-line prefer-rest-params
-  if (!elemByTag('*')) return onElement('*', injectScripts, ...arguments);
   const { hasMore, info } = data;
   const { hasMore, info } = data;
   pageInjectable = isXml ? false : null;
   pageInjectable = isXml ? false : null;
   realms = {
   realms = {
@@ -120,20 +118,23 @@ export async function injectScripts(data, isXml) {
   if (hasInvoker) {
   if (hasInvoker) {
     setupContentInvoker();
     setupContentInvoker();
   }
   }
-  injectAll('start');
-  const onBody = (pgLists.body[0] || contLists.body[0])
-    && onElement('body', injectAll, 'body');
-  // document-end, -idle
-  if (hasMore) {
-    data = await moreData;
-    if (data) await injectDelayedScripts(data, getReadyState, hasInvoker);
-  }
-  if (onBody) {
-    await onBody;
-  }
-  realms = null;
-  pgLists = null;
-  contLists = null;
+  // Using a callback to avoid a microtask tick when the root element exists or appears.
+  onElement('*', async () => {
+    injectAll('start');
+    const onBody = (pgLists.body[0] || contLists.body[0])
+      && onElement('body', injectAll, 'body');
+    // document-end, -idle
+    if (hasMore) {
+      data = await moreData;
+      if (data) await injectDelayedScripts(data, getReadyState, hasInvoker);
+    }
+    if (onBody) {
+      await onBody;
+    }
+    realms = null;
+    pgLists = null;
+    contLists = null;
+  });
 }
 }
 
 
 async function injectDelayedScripts({ info, scripts }, getReadyState, hasInvoker) {
 async function injectDelayedScripts({ info, scripts }, getReadyState, hasInvoker) {

+ 2 - 1
src/injected/utils/index.js

@@ -1,6 +1,7 @@
 export function bindEvents(srcId, destId, handle, cloneInto) {
 export function bindEvents(srcId, destId, handle, cloneInto) {
-  document::addEventListener(srcId, e => handle(e.detail));
+  const getDetail = describeProperty(CustomEvent.prototype, 'detail').get;
   const pageContext = cloneInto && document.defaultView;
   const pageContext = cloneInto && document.defaultView;
+  document::addEventListener(srcId, e => handle(e::getDetail()));
   return (cmd, params) => {
   return (cmd, params) => {
     const data = { cmd, data: params };
     const data = { cmd, data: params };
     const detail = cloneInto ? cloneInto(data, pageContext) : data;
     const detail = cloneInto ? cloneInto(data, pageContext) : data;