Extract editor selection lifecycle from App.vue#90
Conversation
Moves the Android editor selection machinery into a createEditorSelectionLifecycle factory in features/editor: DOM range capture/restore kept in sync with Muya's selection model (including the collapsed-restore, edge-collapse, and clear helpers), the selection-toolbar command sequencing for copy/cut/paste/select-all with its native-clipboard and execCommand paths, ActionMode dismissal with caret restoration, the selection-menu suppression bridge, and the native selection-tap listener lifecycle used to dismiss the toolbar. Muya internals and the toolbar UI are untouched. App injects the editor and element getters, screen/readiness refs, the input-diagnostics snapshot, and the logger, and destructures the same function names, so editor init/teardown, the toolbar bindings, and the link/image insert flows are textually unchanged. The insert-flow state (pendingInlineInsertRange) and the diagnostics installers stay in App — they belong to the insert and debugging features that consume selection capture, not to the lifecycle itself. Adds happy-dom as a root dev dependency so the new module tests can exercise real Range/Selection behavior; the Muya package already tests with the same environment.
a290f8a to
d9cf9dc
Compare
|
Review finding addressed before merge: the tap-handler test claimed toolbar-hit coverage but No production code changed. Re-verified: module tests 12/12, full unit suite 308/308, ESLint, vue-tsc green. Amended into the single commit ( |
Summary
Fifth PR of the semantic-decomposition series: moves the Android editor selection machinery out of
App.vueinto acreateEditorSelectionLifecyclefactory infeatures/editor. Behavior-preserving; Muya internals and the selection-toolbar UI are untouched, per the TODO.Boundary
The factory owns:
execCommandpath with its clipboard fallback, post-command caret placement, and the native select-all preference that keeps Chromium's touch handles alive.Deliberately kept in App:
pendingInlineInsertRangeand the link/image insert flows (they consume selection capture but belong to the insert feature), the selection/input diagnostics installers (debugging facilities tied to editor init), andcanPasteSelection(a UI availability prop). Platform bridges (lib/androidSelection) and the DOM helpers (editorInlineInsert,caretRangeAtPoint) are imported directly by the module; App-owned state comes in as refs/getters. App destructures the same seven function names, so editor init/teardown, the template bindings (@run-selection-command,@dismiss-selection), and the toolbar/insert flows are textually unchanged.Testing
selectionLifecycle.test.ts(11 tests, happy-dom, mocked platform bridge): capture round-trip, expanded-range restore syncing the Muya model, web-path copy with ActionMode dismissal and caret collapse, native-bridge cut, empty-payload skip, paste sequencing, native-vs-Muya select-all preference, suppression failure tolerance, tap-listener idempotence/cleanup, and the tap handler's dismissal and screen guards.happy-domis added as a root dev dependency for real Range/Selection behavior — the Muya package already tests with the same environment.mobile-selection-toolbar.spec.ts(real-clipboard copy/cut/paste/select-all plus the placeholder-selection guard) andmobile-editor-toolbar.spec.ts(link/image insert flows that ride on selection capture/restore).