Inline text editor invisible (0x0) for path/line shapes (callout, cloud, cylinder, parallelogram, cross) #211

Closed
opened 2026-05-21 12:05:28 +00:00 by AhmedHanafy725 · 1 comment
Member

Inline text editor is invisible (0x0) for path/line-based shapes

Summary

Double-clicking a shape to type text works for most shapes, but for several shape types the inline text editor renders with zero size, so you cannot see what you are typing. The text is actually captured and saved (it shows after you click away), but during editing the editor is invisible. The callout shape is the most obvious case.

Affected shapes

  • callout (Konva.Path)
  • cloud (Konva.Path)
  • cylinder (Konva.Path)
  • parallelogram (Konva.Line)
  • cross (Konva.Line)

Working shapes: rectangle, rounded rectangle (Konva.Rect), circle, ellipse (Konva.Ellipse), diamond, triangle, pentagon, hexagon (Konva.RegularPolygon), star (Konva.Star).

Root cause

The inline editor (editMarkdownText in static/web/js/whiteboard/objects.js) sizes its <textarea> from the shape's .bg node inside computeGeom(). For type === 'shape' it runs:

if (bg && bg.width && bg.className !== 'Ellipse') { sw = bg.width(); sh = bg.height(); }
else if (bg && bg.radiusX) { sw = bg.radiusX() * 2; sh = bg.radiusY() * 2; }
else if (bg && bg.radius)  { sw = bg.radius() * 2; sh = sw; }
else { sw = 120; sh = 80; }

bg.width is a method, so it is always truthy and the first branch is taken for every non-Ellipse shape. For Konva.Path (callout, cloud, cylinder) and Konva.Line (parallelogram, cross), there is no width/height attribute, so bg.width() and bg.height() return 0. The textarea is therefore laid out at 0 x 0 and is effectively invisible.

These shapes already store their real dimensions on the bg node as _nominalWidth / _nominalHeight, and the rest of the codebase reads those values (e.g. objects.js:956, objects.js:1030, objects.js:1500). computeGeom() is the one place that does not.

Expected behavior

Double-clicking any shape opens a correctly sized, visible inline editor that overlays the shape body, for all 14 shape types.

Proposed fix

In computeGeom() (the type === 'shape' branch), resolve the editor size robustly for every shape node type:

  • Prefer bg._nominalWidth / bg._nominalHeight when present (Path/Line shapes).
  • Use radiusX()*2 / radiusY()*2 for Ellipse.
  • Use radius()*2 for RegularPolygon and outerRadius()*2 for Star.
  • Use width() / height() only when greater than zero (Rect).
  • Fall back to 120x80 otherwise.
  • Multiply by the bg node's scaleX() / scaleY() so non-uniform polygons/stars (which are built around min(w,h) and stretched via scale) get the right box.

Acceptance criteria

  • Double-clicking a callout shows a visible editor sized to the shape; typed text is visible live.
  • Same verified for cloud, cylinder, parallelogram, and cross.
  • No regression for rectangle, rounded rectangle, circle, ellipse, diamond, triangle, pentagon, hexagon, star.
  • The editor stays anchored and correctly sized when the board is zoomed and panned.
## Inline text editor is invisible (0x0) for path/line-based shapes ### Summary Double-clicking a shape to type text works for most shapes, but for several shape types the inline text editor renders with zero size, so you cannot see what you are typing. The text is actually captured and saved (it shows after you click away), but during editing the editor is invisible. The callout shape is the most obvious case. ### Affected shapes - callout (Konva.Path) - cloud (Konva.Path) - cylinder (Konva.Path) - parallelogram (Konva.Line) - cross (Konva.Line) Working shapes: rectangle, rounded rectangle (Konva.Rect), circle, ellipse (Konva.Ellipse), diamond, triangle, pentagon, hexagon (Konva.RegularPolygon), star (Konva.Star). ### Root cause The inline editor (`editMarkdownText` in `static/web/js/whiteboard/objects.js`) sizes its `<textarea>` from the shape's `.bg` node inside `computeGeom()`. For `type === 'shape'` it runs: ```js if (bg && bg.width && bg.className !== 'Ellipse') { sw = bg.width(); sh = bg.height(); } else if (bg && bg.radiusX) { sw = bg.radiusX() * 2; sh = bg.radiusY() * 2; } else if (bg && bg.radius) { sw = bg.radius() * 2; sh = sw; } else { sw = 120; sh = 80; } ``` `bg.width` is a method, so it is always truthy and the first branch is taken for every non-Ellipse shape. For `Konva.Path` (callout, cloud, cylinder) and `Konva.Line` (parallelogram, cross), there is no `width`/`height` attribute, so `bg.width()` and `bg.height()` return `0`. The textarea is therefore laid out at `0 x 0` and is effectively invisible. These shapes already store their real dimensions on the bg node as `_nominalWidth` / `_nominalHeight`, and the rest of the codebase reads those values (e.g. objects.js:956, objects.js:1030, objects.js:1500). `computeGeom()` is the one place that does not. ### Expected behavior Double-clicking any shape opens a correctly sized, visible inline editor that overlays the shape body, for all 14 shape types. ### Proposed fix In `computeGeom()` (the `type === 'shape'` branch), resolve the editor size robustly for every shape node type: - Prefer `bg._nominalWidth` / `bg._nominalHeight` when present (Path/Line shapes). - Use `radiusX()*2` / `radiusY()*2` for Ellipse. - Use `radius()*2` for RegularPolygon and `outerRadius()*2` for Star. - Use `width()` / `height()` only when greater than zero (Rect). - Fall back to 120x80 otherwise. - Multiply by the bg node's `scaleX()` / `scaleY()` so non-uniform polygons/stars (which are built around `min(w,h)` and stretched via scale) get the right box. ### Acceptance criteria - [ ] Double-clicking a callout shows a visible editor sized to the shape; typed text is visible live. - [ ] Same verified for cloud, cylinder, parallelogram, and cross. - [ ] No regression for rectangle, rounded rectangle, circle, ellipse, diamond, triangle, pentagon, hexagon, star. - [ ] The editor stays anchored and correctly sized when the board is zoomed and panned.
Author
Member

Fix implemented and verified

Change

crates/hero_whiteboard_admin/static/web/js/whiteboard/objects.jseditMarkdownText -> computeGeom(), the type === 'shape' branch.

The branch previously sized the editor textarea via bg.width()/height(), which return 0 for Konva.Path (callout, cloud, cylinder) and Konva.Line (parallelogram, cross) nodes, producing a 0x0 (invisible) editor. It now resolves the box per node type:

  • _nominalWidth/_nominalHeight for Path/Line shapes (the value the rest of the code already uses).
  • radiusX()*2/radiusY()*2 for Ellipse.
  • outerRadius()*2 for Star, radius()*2 for RegularPolygon.
  • width()/height() only when greater than zero (Rect).
  • 120x80 fallback.
  • Multiplied by the bg node's scaleX()/scaleY(), so non-uniform polygons/stars (built around min(w,h) and stretched via scale) get the correct box.

Verification

Rust workspace lib tests (no regression):

cargo test --workspace --lib  ->  ok. 0 failed

Geometry logic test — replicates the old vs new shape-sizing branch against a mock bg node for every shape type (stage scale 1):

PASS  callout (Path 200x120)        -> NEW 200x120   OLD 0x0
PASS  cloud (Path 180x120)          -> NEW 180x120   OLD 0x0
PASS  cylinder (Path 140x160)       -> NEW 140x160   OLD 0x0
PASS  parallelogram (Line 200x100)  -> NEW 200x100   OLD 0x0
PASS  cross (Line 120x120)          -> NEW 120x120   OLD 0x0
PASS  rectangle (Rect 160x90)       -> NEW 160x90    OLD 160x90
PASS  circle/ellipse (rx80 ry80)    -> NEW 160x160   OLD 160x160
PASS  diamond non-square            -> NEW 200x120   OLD 80x80
PASS  star non-square               -> NEW 180x140   OLD 100x100
ALL PASS

The old logic returned 0x0 for the five path/line shapes (the reported invisible editor) and the wrong box for non-uniform diamond/star; the new logic returns the correct box for all 14 shape types with no change to rectangle/ellipse.

Deployed to the local environment (release build, installed, service restarted); the served objects.js now contains the fix.

## Fix implemented and verified ### Change `crates/hero_whiteboard_admin/static/web/js/whiteboard/objects.js` — `editMarkdownText` -> `computeGeom()`, the `type === 'shape'` branch. The branch previously sized the editor textarea via `bg.width()/height()`, which return 0 for `Konva.Path` (callout, cloud, cylinder) and `Konva.Line` (parallelogram, cross) nodes, producing a 0x0 (invisible) editor. It now resolves the box per node type: - `_nominalWidth`/`_nominalHeight` for Path/Line shapes (the value the rest of the code already uses). - `radiusX()*2`/`radiusY()*2` for Ellipse. - `outerRadius()*2` for Star, `radius()*2` for RegularPolygon. - `width()`/`height()` only when greater than zero (Rect). - 120x80 fallback. - Multiplied by the bg node's `scaleX()`/`scaleY()`, so non-uniform polygons/stars (built around `min(w,h)` and stretched via scale) get the correct box. ### Verification Rust workspace lib tests (no regression): ``` cargo test --workspace --lib -> ok. 0 failed ``` Geometry logic test — replicates the old vs new shape-sizing branch against a mock bg node for every shape type (stage scale 1): ``` PASS callout (Path 200x120) -> NEW 200x120 OLD 0x0 PASS cloud (Path 180x120) -> NEW 180x120 OLD 0x0 PASS cylinder (Path 140x160) -> NEW 140x160 OLD 0x0 PASS parallelogram (Line 200x100) -> NEW 200x100 OLD 0x0 PASS cross (Line 120x120) -> NEW 120x120 OLD 0x0 PASS rectangle (Rect 160x90) -> NEW 160x90 OLD 160x90 PASS circle/ellipse (rx80 ry80) -> NEW 160x160 OLD 160x160 PASS diamond non-square -> NEW 200x120 OLD 80x80 PASS star non-square -> NEW 180x140 OLD 100x100 ALL PASS ``` The old logic returned 0x0 for the five path/line shapes (the reported invisible editor) and the wrong box for non-uniform diamond/star; the new logic returns the correct box for all 14 shape types with no change to rectangle/ellipse. Deployed to the local environment (release build, installed, service restarted); the served `objects.js` now contains the fix.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
lhumina_code/hero_whiteboard#211
No description provided.