Skip to content

Commit 8e7cfb4

Browse files
committed
Full x-load checks Chromium support.
1 parent 4241ea7 commit 8e7cfb4

File tree

1 file changed

+48
-4
lines changed

1 file changed

+48
-4
lines changed

src/content/eventsHook.main.js

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,61 @@ if (location.protocol == "file:") {
2424
const {exportFunction, patchWindow} = Worlds.main;
2525

2626
function modifyWindow(scope, {port, xray}) {
27-
const {window} = xray;
27+
const { window } = xray;
28+
const { Proxy, document } = window;
29+
30+
const { Reflect } = globalThis;
2831

29-
const { Proxy } = window;
3032
const { addEventListener } = window.EventTarget.prototype;
33+
const nodeProps = {};
34+
for (const prop of ["ownerDocument", "parentNode", "nextSibling"]) {
35+
nodeProps[prop] = xray.getSafeDescriptor(Node.prototype, prop, "get").get;
36+
}
37+
for (const method of ["insertBefore", "removeChild"]) {
38+
nodeProps[method] = Node.prototype[method];
39+
}
40+
const adoptNode = document.adoptNode;
41+
const getDocumentElement = xray.getSafeDescriptor(Document.prototype, "documentElement", "get").get;
3142

3243
const watchList = new WeakSet();
3344

45+
const NO_ARGS = [];
46+
const call = (func, obj, ...args) => Reflect.apply(func, obj, args || NO_ARGS);
47+
3448
const watch = watching => {
3549
if (!watchList.has(watching)) {
36-
port.postMessage({watching});
37-
watchList.add(watching);
50+
const ownerDocument = call(nodeProps.ownerDocument, watching);
51+
const crossDoc = ownerDocument != document;
52+
const parentNode = call(nodeProps.parentNode, watching);
53+
54+
if (!crossDoc && parentNode) {
55+
// Nothing to do: eventHook.js' MutationObserver should kick in
56+
return;
57+
}
58+
59+
if (xray.enabled) {
60+
port.postMessage({watching});
61+
watchList.add(watching);
62+
return;
63+
}
64+
65+
// Chromium cannot marshall DOM nodes in port.postMessage():
66+
// following hack triggers eventHook.js' mutation observer instead.
67+
68+
const nextSibling = call(nodeProps.nextSibling, watching);
69+
if (crossDoc) {
70+
call(adoptNode, document, watching);
71+
}
72+
const documentElement = call(getDocumentElement, document);
73+
call(nodeProps.insertBefore, documentElement, watching, null);
74+
call(nodeProps.removeChild, documentElement, watching);
75+
if (crossDoc) {
76+
// put the node back at its place in its document
77+
call(adoptNode, ownerDocument, watching);
78+
if (parentNode) {
79+
call(nodeProps.insertBefore, ownerDocument, watching, nextSibling);
80+
}
81+
}
3882
}
3983
}
4084

0 commit comments

Comments
 (0)