Skip to content

Refactor canvas elements: registry-driven controls#7621

Open
hatton wants to merge 36 commits intomasterfrom
BL-15770RefactorCanvas
Open

Refactor canvas elements: registry-driven controls#7621
hatton wants to merge 36 commits intomasterfrom
BL-15770RefactorCanvas

Conversation

@hatton
Copy link
Member

@hatton hatton commented Jan 26, 2026

CanvasElementManager had grown too large and UI affordances (context menu + mini toolbar) were being assembled imperatively, which made ordering/section dividers hard to reason about and encouraged cross-bundle imports.

This change introduces a declarative canvas element registry that drives which buttons and menus are available per element type.

It also makes context menu/mini-toolbar composition deterministic: fixed section ordering, exactly one divider/spacer between non-empty sections, and Duplicate/Delete always last.

To reduce runtime import-cycle risk across the edit view + toolbox bundles, DOM selectors/constants move to a dependency-light module (canvasElementConstants) while canvasElementUtils is narrowed to a cross-frame bridge (getCanvasElementManager) with type-only imports.

CanvasElementManager is partially decomposed into focused helper modules (Geometry/Positioning/Alternates) plus public-function wrappers, and related call sites were updated. Misc hardening: safer MUI Menu anchoring, avoid non-null assertions, fix closest() selector typo, and remove duplicate pxToNumber helper.

Follow-ups in this series:

  • Make mini-toolbar + menu more declarative and consistent
    • Make toolbarButtons the sole source of truth for the mini-toolbar (including explicit spacers) and normalize spacer runs.

    • Share menu + toolbar definitions via a single command registry to keep icons/tooltips/click behavior in sync.

    • Replace “Set Up Hyperlink” with the “Set Destination” command in this context, and do not show either on simple image elements.


This change is Reviewable


Open with Devin

devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

CanvasElementManager had grown too large and UI affordances (context menu + mini toolbar) were being assembled imperatively, which made ordering/section dividers hard to reason about and encouraged cross-bundle imports.

This change introduces a declarative canvas element registry that drives which buttons and menus are available per element type.

It also makes context menu/mini-toolbar composition deterministic: fixed section ordering, exactly one divider/spacer between non-empty sections, and Duplicate/Delete always last.

To reduce runtime import-cycle risk across the edit view + toolbox bundles, DOM selectors/constants move to a dependency-light module (canvasElementConstants) while canvasElementUtils is narrowed to a cross-frame bridge (getCanvasElementManager) with type-only imports.

CanvasElementManager is partially decomposed into focused helper modules (Geometry/Positioning/Alternates) plus public-function wrappers, and related call sites were updated. Misc hardening: safer MUI Menu anchoring, avoid non-null assertions, fix closest() selector typo, and remove duplicate pxToNumber helper.

Follow-ups in this series:

- Make mini-toolbar + menu more declarative and consistent
  - Make `toolbarButtons` the sole source of truth for the mini-toolbar (including explicit spacers) and normalize spacer runs.
  - Share menu + toolbar definitions via a single command registry to keep icons/tooltips/click behavior in sync.

  - Replace “Set Up Hyperlink” with the “Set Destination” command in this context, and do not show either on simple image elements.
@hatton hatton force-pushed the BL-15770RefactorCanvas branch from c0fc612 to e95f491 Compare February 11, 2026 21:51
- Delegate addCanvasElement* to CanvasElementFactories (toolbox drop + templates)\n- Move paste-image flow to CanvasElementClipboard\n- Move duplication + audio file copy helper to CanvasElementDuplication\n- Keep CanvasElementManager as orchestrator; behavior validated with live toolbox→page drag/drop\n- Track checkpoints + line count in REFACTOR_PLAN.md
- Switch CanvasToolControls to import CanvasElementManager/ITextColorInfo as types only\n- Move ITextColorInfo to dependency-light CanvasElementSharedTypes and re-export from CanvasElementManager\n- Update CanvasElementFactories to use shared ITextColorInfo type\n- Mark Phase B4 complete in REFACTOR_PLAN.md
Extract resize/crop/side-handle/move-crop drag logic into CanvasElementHandleDragInteractions and wire CanvasElementManager/SelectionUi to delegate to it.

This keeps CanvasElementManager focused on orchestration and reduces its size.
Move language-alternate behaviors into CanvasElementAlternates and extract draggable/target ordering+cleanup into CanvasElementDraggableIntegration.

CanvasElementManager now delegates to these modules and continues to expose compatibility wrappers for existing callers/tests.
Extract origami splitter drag + comic editing suspend/resume logic into CanvasElementEditingSuspension and delegate from CanvasElementManager.
Extract bloom-canvas size-change child adjustment logic into CanvasElementCanvasResizeAdjustments and delegate from CanvasElementManager.
Backport selected master-side fixes into the refactored canvasElementManager structure while preserving refactor boundaries.
BL-15247, BL-15657, BL-15695, BL-15719, BL-15752, BL-15754, BL-15757, BL-15791, BL-15831

Includes motion-tool guard behavior, splitter interaction suppression, canvas-tool activation flow updates, background image sizing/race fixes, expand-to-fill enablement logic, missing-image metadata handling, and image-fit attribute propagation.

Also exposes requestPageContent delay helpers through editable page exports and adds editablePageUtils helper used by split-pane and manager code.
# Conflicts:
#	src/BloomBrowserUI/bookEdit/js/CanvasElementManager.ts
#	src/BloomBrowserUI/bookEdit/js/bloomEditing.ts
#	src/BloomBrowserUI/bookEdit/js/canvasElementManager/CanvasElementContextControls.tsx
#	src/BloomBrowserUI/bookEdit/js/editablePageUtils.ts
#	src/BloomBrowserUI/bookEdit/toolbox/canvas/canvasElementUtils.ts
#	src/BloomBrowserUI/lib/split-pane/split-pane.ts
devin-ai-integration[bot]

This comment was marked as resolved.

@hatton hatton marked this pull request as ready for review February 13, 2026 23:22
Copilot AI review requested due to automatic review settings February 13, 2026 23:22

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

Copy link

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 new potential issue.

View 28 additional findings in Devin Review.

Open in Devin Review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

Comments