function injectPageSandbox(data) {
  pageInjectable = false;
  const VAULT_WRITER = data[kSessionId] + 'VW';
  const VAULT_WRITER_ACK = VAULT_WRITER + '*';
  const vaultId = safeGetUniqId();
  const handshakeId = safeGetUniqId();
  const contentId = safeGetUniqId();
  const webId = safeGetUniqId();
  nonce = data.nonce;
  if (IS_FIREFOX) {
    // In FF, content scripts running in a same-origin frame cannot directly call parent's functions
    window::on(VAULT_WRITER, evt => {
      evt::stopImmediatePropagation();
      if (!frameEventWnd) {
        // setupVaultId's first event is the frame's contentWindow
        frameEventWnd = evt::getRelatedTarget();
      } else {
        // setupVaultId's second event is the vaultId
        frameEventWnd::fire(new SafeCustomEvent(VAULT_WRITER_ACK, {
          __proto__: null,
          detail: tellBridgeToWriteVault(evt::getDetail(), frameEventWnd),
        }));
        frameEventWnd = null;
      }
    }, true);
  } else {
    setOwnProp(global, VAULT_WRITER, tellBridgeToWriteVault, false);
  }
  if (useOpener(opener) || useOpener(window !== top && parent)) {
    startHandshake();
  } else {
    /* Sites can do window.open(sameOriginUrl,'iframeNameOrNewWindowName').opener=null, spoof JS
     * environment and easily hack into our communication channel before our content scripts run.
     * Content scripts will see `document.opener = null`, not the original opener, so we have
     * to use an iframe to extract the safe globals. Detection via document.referrer won't work
     * is it can be emptied by the opener page, too. */
    inject({ code: `parent["${vaultId}"] = [this, 0]`/* DANGER! See addVaultExports */ }, () => {
      if (!IS_FIREFOX || addVaultExports(window.wrappedJSObject[vaultId])) {
        startHandshake();
      }
    });
  }
  return pageInjectable;

  function useOpener(opener) {
    let ok;
    try {
      ok = opener && describeProperty(opener.location, 'href').get;
    } catch (e) {
      // Old Chrome throws in sandboxed frames, TODO: remove `try` when minimum_chrome_version >= 86
    }
    if (ok) {
      ok = false;
      // TODO: Use a single PointerEvent with `pointerType: vaultId` when strict_min_version >= 59
      if (IS_FIREFOX) {
        const setOk = evt => { ok = evt::getDetail(); };
        window::on(VAULT_WRITER_ACK, setOk, true);
        try {
          opener::fire(new SafeMouseEvent(VAULT_WRITER, { relatedTarget: window }));
          opener::fire(new SafeCustomEvent(VAULT_WRITER, { detail: vaultId }));
        } catch (e) { /* FF quirk or bug: opener may reject our fire */ }
        window::off(VAULT_WRITER_ACK, setOk, true);
      } else {
        ok = opener[VAULT_WRITER];
        ok = ok && ok(vaultId, window);
      }
    }
    return ok;
  }
  /** A page can read our script's textContent in a same-origin iframe via DOMNodeRemoved event.
   * Directly preventing it would require redefining ~20 DOM methods in the parent.
   * Instead, we'll send the ids via a temporary handshakeId event, to which the web-bridge
   * will listen only during its initial phase using vault-protected DOM methods.
   * TODO: simplify this when strict_min_version >= 63 (attachShadow in FF) */
  function startHandshake() {
    /* With `once` the listener is removed before DOMNodeInserted is dispatched by appendChild,
     * otherwise a same-origin parent page could use it to spoof the handshake. */
    window::on(handshakeId, handshaker, { capture: true, once: true });
    inject({
      code: `(${VMInitInjection}(${IS_FIREFOX},'${handshakeId}','${vaultId}'))()`
        + `\n//# sourceURL=${VM_UUID}sandbox/injected-web.js`,
    });
    // Clean up in case CSP prevented the script from running
    window::off(handshakeId, handshaker, true);
  }
  function handshaker(evt) {
    pageInjectable = true;
    evt::stopImmediatePropagation();
    bindEvents(contentId, webId, bridge);
    fireBridgeEvent(`${handshakeId}*`, [webId, contentId]);
  }
}
FF bug workaround to enable processing of sourceURL in injected page scripts