From 1c3c325d6d0bdc2285abc7530d015122fc67d3b1 Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Wed, 4 Nov 2026 10:00:51 +0100 Subject: [PATCH] :bug: Keep Inspect from crashing on a shape whose parent is missing In a damaged file a shape may point to a parent that does not exist. The Inspect tab computes the position relative to the parent, so inspecting such a shape replaced the workspace with the internal error page. Inspect leaves the position out and logs a warning instead. --- .../src/app/util/code_gen/style_css_values.cljs | 15 ++++++++++++++- .../frontend_tests/ui/inspect_geometry_test.cljs | 14 ++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/frontend/src/app/util/code_gen/style_css_values.cljs b/frontend/src/app/util/code_gen/style_css_values.cljs index 4052adba14..e35ef02c44 100644 --- a/frontend/src/app/util/code_gen/style_css_values.cljs +++ b/frontend/src/app/util/code_gen/style_css_values.cljs @@ -12,6 +12,7 @@ [app.common.files.helpers :as cfh] [app.common.geom.matrix :as gmt] [app.common.geom.shapes :as gsh] + [app.common.logging :as log] [app.common.types.shape.layout :as ctl] [app.main.ui.formats :as fmt] [app.util.code-gen.common :as cgc] @@ -24,12 +25,24 @@ :gradient fill-color-gradient :image fill-image}) +(defn- missing-parent? + "True when the parent of `shape` is not in `objects`, which happens in a + damaged file; the position, relative to the parent, cannot be computed." + [objects shape] + (let [missing? (not (contains? objects (:parent-id shape)))] + (when missing? + (log/wrn :hint "shape parent not found" + :shape-id (dm/str (:id shape)) + :parent-id (dm/str (:parent-id shape)))) + missing?)) + (defn get-shape-position [shape objects coord] (when (and (not (cfh/root-frame? shape)) (or (not (ctl/any-layout-immediate-child? objects shape)) - (ctl/position-absolute? shape))) + (ctl/position-absolute? shape)) + (not (missing-parent? objects shape))) (let [parent (get objects (:parent-id shape)) diff --git a/frontend/test/frontend_tests/ui/inspect_geometry_test.cljs b/frontend/test/frontend_tests/ui/inspect_geometry_test.cljs index 3b9c5879d2..5fc4285da9 100644 --- a/frontend/test/frontend_tests/ui/inspect_geometry_test.cljs +++ b/frontend/test/frontend_tests/ui/inspect_geometry_test.cljs @@ -112,3 +112,17 @@ (let [markup (render-panel panel shapes)] (t/is (str/includes? markup "Border width")) (t/is (str/includes? markup "3px"))))))) + +;; Scenario: the selected shape points to a parent missing from the page, as +;; in a damaged file or while a rejected save is on screen. Proves: the +;; geometry panels and the code view show the size and leave out the +;; position, which needs the parent, instead of crashing the workspace. +(t/deftest geometry-without-a-parent-leaves-out-the-position + (let [orphan (assoc (shape :rect per-side-stroke) :parent-id (uuid/next) :frame-id (uuid/next))] + (doseq [panel [geometry/geometry-panel* styles-geometry/geometry-panel*]] + (let [markup (render-panel panel [orphan])] + (t/is (str/includes? markup "120px")) + (t/is (not (str/includes? markup "Left"))))) + (let [code (css/get-shape-properties-css {(:id orphan) orphan} orphan css/shape-css-properties)] + (t/is (str/includes? code "width: 120px;")) + (t/is (not (str/includes? code "left:"))))))