From 8b1dc4c43d87ba096c0ac2f790ed5e54387f1d04 Mon Sep 17 00:00:00 2001 From: "Julien Carion (juca)" Date: Mon, 3 Jul 2023 10:57:04 +0200 Subject: [PATCH] [FIX] devtools: fix/imp env display This commit first fixes how object prototype are detected so that it won't stop as soon as the constructor name of the object is "Object". This allows displaying every single prototype encountered and closes https://github.com/odoo/owl/issues/1467. This commit also improves how the env of a component is displayed by expanding its chain of prototypes by default while keeping its keys lit as long as it is their first occurence in the chain. --- .../object_tree_element.js | 2 +- .../devtools/src/devtools_app/store/store.js | 36 ++++++++++++++++--- .../page_scripts/owl_devtools_global_hook.js | 25 +++++++------ 3 files changed, 47 insertions(+), 16 deletions(-) diff --git a/tools/devtools/src/devtools_app/devtools_window/components_tab/details_window/object_tree_element/object_tree_element.js b/tools/devtools/src/devtools_app/devtools_window/components_tab/details_window/object_tree_element/object_tree_element.js index f659e45d..c50072ab 100644 --- a/tools/devtools/src/devtools_app/devtools_window/components_tab/details_window/object_tree_element/object_tree_element.js +++ b/tools/devtools/src/devtools_app/devtools_window/components_tab/details_window/object_tree_element/object_tree_element.js @@ -47,7 +47,7 @@ export class ObjectTreeElement extends Component { classFor(object) { // Prototype items will be dyed down to appear less important - if (object.path.some((item) => item?.type === "prototype")) { + if (object.path.some((item) => item?.type === "prototype") && !object.keepLit) { return "attenuate"; } // Same for subscription items which are not present in the keys while the keys will be bold diff --git a/tools/devtools/src/devtools_app/store/store.js b/tools/devtools/src/devtools_app/store/store.js index cca8597c..70705728 100644 --- a/tools/devtools/src/devtools_app/store/store.js +++ b/tools/devtools/src/devtools_app/store/store.js @@ -102,7 +102,7 @@ export const store = reactive({ if (IS_FIREFOX) { await evalInWindow("window.$0 = $0;", this.activeFrame); } - const [apps, component] = await evalFunctionInWindow( + const [apps, details] = await evalFunctionInWindow( "getComponentsTree", fromOld && this.activeComponent ? [this.activeComponent.path, this.apps, this.activeComponent] @@ -113,7 +113,8 @@ export const store = reactive({ if (!fromOld && this.settings.expandByDefault) { this.apps.forEach((tree) => expandNodes(tree, true)); } - this.activeComponent = component; + keepEnvLit(details); + this.activeComponent = details; }, // Select a component by retrieving its details from the page based on its path @@ -150,9 +151,11 @@ export const store = reactive({ [component.path], this.activeFrame ); - this.activeComponent = details; - if (!this.activeComponent) { + if (!details) { await this.loadComponentsTree(false); + } else { + keepEnvLit(details); + this.activeComponent = details; } if (this.page !== "ComponentsTab") { this.switchTab("ComponentsTab"); @@ -887,6 +890,31 @@ function expandNodes(node, blacklist = false) { } } +// This function transforms the env part of the details such that all env keys are not +// greyed out in the UI at their first occurence +function keepEnvLit(details) { + let alreadyMet = new Set(); + for (let i = 0; i < details.env.children.length; i++) { + if (i < details.env.children.length - 1) { + alreadyMet.add(details.env.children[i].name); + } else { + let lastElement = details.env.children[i]; + while (lastElement.children.at(-1).name === "[[Prototype]]") { + for (const [index, child] of lastElement.children.entries()) { + if (index < lastElement.children.length - 1) { + if (!alreadyMet.has(child.name)) { + child.keepLit = true; + alreadyMet.add(child.name); + } + } else { + lastElement = child; + } + } + } + } + } +} + // Fold the node given in entry and all of its children function foldNodes(node) { node.toggled = false; diff --git a/tools/devtools/src/page_scripts/owl_devtools_global_hook.js b/tools/devtools/src/page_scripts/owl_devtools_global_hook.js index 995185e0..e126ed09 100644 --- a/tools/devtools/src/page_scripts/owl_devtools_global_hook.js +++ b/tools/devtools/src/page_scripts/owl_devtools_global_hook.js @@ -748,6 +748,9 @@ child.contentType = "object"; child.content = this.serializer.serializeItem(Object.getPrototypeOf(parentObj), true); child.hasChildren = true; + if (!oldTree && type === "env") { + child.toggled = true; + } break; case "set entries": case "map entries": @@ -890,7 +893,7 @@ const children = []; depth = depth + 1; let obj = this.getObjectProperty(path); - let oldBranch = this.getObjectInOldTree(oldTree, path, objType); + let oldBranch = oldTree && this.getObjectInOldTree(oldTree, path, objType); if (!obj) { return []; } @@ -905,7 +908,7 @@ depth, objType, path, - oldBranch.children[0], + oldBranch?.children[0], oldTree ); children.push(mapKey); @@ -915,7 +918,7 @@ depth, objType, path, - oldBranch.children[1], + oldBranch?.children[1], oldTree ); children.push(mapValue); @@ -926,7 +929,7 @@ depth, objType, path, - oldBranch.children[0], + oldBranch?.children[0], oldTree ); children.push(setValue); @@ -947,7 +950,7 @@ depth, objType, path, - oldBranch.children[index], + oldBranch?.children[index], oldTree ); if (child) { @@ -962,7 +965,7 @@ depth, objType, path, - oldBranch.children[index], + oldBranch?.children[index], oldTree ); if (child) { @@ -979,7 +982,7 @@ depth, objType, path, - oldBranch.children[index], + oldBranch?.children[index], oldTree ); if (entries) { @@ -993,7 +996,7 @@ depth, objType, path, - oldBranch.children[index], + oldBranch?.children[index], oldTree ); if (child) { @@ -1028,7 +1031,7 @@ depth, objType, path, - oldBranch.children[index], + oldBranch?.children[index], oldTree ); if (child) children.push(child); @@ -1061,14 +1064,14 @@ }); proto = Object.getPrototypeOf(proto); } - if (!(obj.constructor.name === "Object")) { + if (obj.__proto__) { prototype = this.serializeObjectChild( obj, { type: "prototype", childIndex: children.length }, depth, objType, path, - oldBranch.children.at(-1), + oldBranch?.children.at(-1), oldTree ); children.push(prototype);