mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
[FIX] devtools: Fix app methods patching
This commit fixes how the apps methods are patched by decoupling the patching of the destroy method from the rest because we need to have a valid reference to a component node to do so (the root node in this case). The previous behavior was to only patch methods when an app with a root node is added but this was not working when the app has no root node initially and gets one dynamically. There is now a listener to patch the destroy method as soon as a root node is set on any of the apps if it is not already the case.
This commit is contained in:
committed by
Géry Debongnie
parent
cae32c5bd4
commit
c049022798
@@ -47,10 +47,8 @@
|
|||||||
});
|
});
|
||||||
iFrameObserver.observe(document.body, { subtree: true, childList: true });
|
iFrameObserver.observe(document.body, { subtree: true, childList: true });
|
||||||
this.appsPatched = false;
|
this.appsPatched = false;
|
||||||
|
this.destroyPatched = false;
|
||||||
this.patchAppsSetMethods();
|
this.patchAppsSetMethods();
|
||||||
setTimeout(() => {
|
|
||||||
this.patchAppMethods();
|
|
||||||
}, 200);
|
|
||||||
this.recordEvents = false;
|
this.recordEvents = false;
|
||||||
this.traceRenderings = false;
|
this.traceRenderings = false;
|
||||||
this.traceSubscriptions = false;
|
this.traceSubscriptions = false;
|
||||||
@@ -177,6 +175,26 @@
|
|||||||
const self = this;
|
const self = this;
|
||||||
this.apps.add = function () {
|
this.apps.add = function () {
|
||||||
originalAdd.call(this, ...arguments);
|
originalAdd.call(this, ...arguments);
|
||||||
|
if (!self.destroyPatched) {
|
||||||
|
const newApp = arguments[0];
|
||||||
|
// It is not a given that apps have a root node at creation so we need to wait
|
||||||
|
if (newApp.root) {
|
||||||
|
self.patchDestroyMethod(newApp.root);
|
||||||
|
} else {
|
||||||
|
let root = null;
|
||||||
|
Object.defineProperty(newApp, "root", {
|
||||||
|
get() {
|
||||||
|
return root;
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
root = value;
|
||||||
|
if (!self.destroyPatched) {
|
||||||
|
self.patchDestroyMethod(root);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
self.patchAppMethods();
|
self.patchAppMethods();
|
||||||
window.top.postMessage({
|
window.top.postMessage({
|
||||||
source: "owl-devtools",
|
source: "owl-devtools",
|
||||||
@@ -192,18 +210,40 @@
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
patchDestroyMethod(root) {
|
||||||
|
if (!this.destroyPatched) {
|
||||||
|
// Signals when a component is destroyed
|
||||||
|
const originalDestroy = root.constructor.prototype._destroy;
|
||||||
|
const self = this;
|
||||||
|
root.constructor.prototype._destroy = function () {
|
||||||
|
if (self.recordEvents) {
|
||||||
|
const path = self.getComponentPath(this);
|
||||||
|
const event = {
|
||||||
|
type: "destroy",
|
||||||
|
component: this.name,
|
||||||
|
key: this.parentKey,
|
||||||
|
path: path,
|
||||||
|
time: 0,
|
||||||
|
id: self.eventId++,
|
||||||
|
};
|
||||||
|
self.eventsBatch.push(event);
|
||||||
|
const before = performance.now();
|
||||||
|
originalDestroy.call(this, ...arguments);
|
||||||
|
event.time = performance.now() - before;
|
||||||
|
} else {
|
||||||
|
originalDestroy.call(this, ...arguments);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
this.destroyPatched = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Modify methods of each app so that it triggers messages on each flush and component render
|
// Modify methods of each app so that it triggers messages on each flush and component render
|
||||||
patchAppMethods() {
|
patchAppMethods() {
|
||||||
if (this.appsPatched) {
|
if (this.appsPatched) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let app;
|
let app = this.apps.values().next().value;
|
||||||
for (const appItem of this.apps) {
|
|
||||||
if (appItem.root) {
|
|
||||||
app = appItem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// We don't want to bother patching the apps methods if none have components inside
|
|
||||||
if (!app) {
|
if (!app) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -337,27 +377,6 @@
|
|||||||
self.eventsBatch = [];
|
self.eventsBatch = [];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
// Signals when a component is destroyed
|
|
||||||
const originalDestroy = app.root.constructor.prototype._destroy;
|
|
||||||
app.root.constructor.prototype._destroy = function () {
|
|
||||||
if (self.recordEvents) {
|
|
||||||
const path = self.getComponentPath(this);
|
|
||||||
const event = {
|
|
||||||
type: "destroy",
|
|
||||||
component: this.name,
|
|
||||||
key: this.parentKey,
|
|
||||||
path: path,
|
|
||||||
time: 0,
|
|
||||||
id: self.eventId++,
|
|
||||||
};
|
|
||||||
self.eventsBatch.push(event);
|
|
||||||
const before = performance.now();
|
|
||||||
originalDestroy.call(this, ...arguments);
|
|
||||||
event.time = performance.now() - before;
|
|
||||||
} else {
|
|
||||||
originalDestroy.call(this, ...arguments);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
this.appsPatched = true;
|
this.appsPatched = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user