oasis-editor 0.0.76 → 0.0.78

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,209 @@
1
+ import { EditorPosition, EditorState } from '../../core/model.js';
2
+ import { EditorLogger } from '../../utils/logger.js';
3
+ import { createEditorCommandsController } from '../../app/controllers/EditorCommandsController.js';
4
+ import { createEditorDocumentRuntime } from './createEditorDocumentRuntime.js';
5
+
6
+ type DocRuntime = ReturnType<typeof createEditorDocumentRuntime>;
7
+ type CommandsController = ReturnType<typeof createEditorCommandsController>;
8
+ export interface EditorInteractionRuntimeDeps {
9
+ state: EditorState;
10
+ logger: EditorLogger;
11
+ isReadOnly: () => boolean;
12
+ applyState: (next: EditorState) => void;
13
+ cloneState: (state: EditorState) => EditorState;
14
+ focusInput: () => void;
15
+ focusInputAfterPointerSelection: () => void;
16
+ surfaceRef: () => HTMLDivElement | undefined;
17
+ viewportRef: () => HTMLDivElement | undefined;
18
+ zoomFactor: () => number;
19
+ insertImageFromFile: DocRuntime["docIO"]["insertImageFromFile"];
20
+ getForcePlainTextPaste: () => boolean;
21
+ setForcePlainTextPaste: (value: boolean) => void;
22
+ /** Back-edge to the command runtime (phase C); read lazily at command time. */
23
+ getCommandsController: () => CommandsController;
24
+ applyTransactionalState: DocRuntime["applyTransactionalState"];
25
+ clearPreferredColumn: DocRuntime["clearPreferredColumn"];
26
+ resetTransactionGrouping: DocRuntime["resetTransactionGrouping"];
27
+ updateHistoryState: DocRuntime["updateHistoryState"];
28
+ caretBox: DocRuntime["caretBox"];
29
+ preferredColumnX: DocRuntime["preferredColumnX"];
30
+ setPreferredColumnX: DocRuntime["setPreferredColumnX"];
31
+ measuredBlockHeights: DocRuntime["measuredBlockHeights"];
32
+ measuredParagraphLayouts: DocRuntime["measuredParagraphLayouts"];
33
+ }
34
+ /**
35
+ * Phase B of the editor runtime: selection queries, the hit resolver, find &
36
+ * replace, the table/image/text-box operations, the style controller and the
37
+ * interaction-wiring cluster (gesture / input / clipboard / navigation). Runs
38
+ * synchronously after the document runtime, preserving the original creation
39
+ * order. The only forward cross-phase edge — style controller -> commands — is
40
+ * read lazily via getCommandsController. Extracted from `OasisEditorApp` (S1).
41
+ */
42
+ export declare function createEditorInteractionRuntime(deps: EditorInteractionRuntimeDeps): {
43
+ selectedImageRun: () => import('../../core/commands/selectedObjectRun.js').SelectedObjectRun | null;
44
+ selectedTextBoxRun: () => import('../../core/commands/selectedObjectRun.js').SelectedObjectRun | null;
45
+ layoutOptionsOverlay: import('../editorUiTypes.js').LayoutOptionsOverlay;
46
+ fr: import('../../app/controllers/useEditorFindReplace.js').UseEditorFindReplaceResult;
47
+ resolveSurfaceHitAtPoint: (clientX: number, clientY: number, context?: {
48
+ forDrag?: boolean;
49
+ pierce?: boolean;
50
+ }) => import('../canvas/CanvasHitTestService.js').SurfaceHit | null;
51
+ resolvePositionAtSurfacePoint: (clientX: number, clientY: number) => EditorPosition | null;
52
+ tableOps: {
53
+ resolveTableCellRangeSelection: (current: EditorState) => EditorState["selection"] | null;
54
+ resolveHorizontalTableCellRange: (current: EditorState) => import('../../app/controllers/tableOpsSelectionRanges.js').HorizontalTableCellRange | null;
55
+ resolveVerticalTableCellRange: (current: EditorState) => import('../../app/controllers/tableOpsSelectionRanges.js').VerticalTableCellRange | null;
56
+ canMergeSelectedTableCells: (current: EditorState) => boolean;
57
+ canSplitSelectedTableCell: (current: EditorState) => boolean;
58
+ canMergeSelectedTableRows: (current: EditorState) => boolean;
59
+ canMergeSelectedTable: (current: EditorState) => boolean;
60
+ canSplitSelectedTableCellVertically: (current: EditorState) => boolean;
61
+ canSplitSelectedTable: (current: EditorState) => boolean;
62
+ canEditSelectedTableRow: (current: EditorState) => boolean;
63
+ canEditSelectedTableColumn: (current: EditorState) => boolean;
64
+ mergeSelectedTableCells: (current: EditorState) => EditorState;
65
+ mergeSelectedTableRows: (current: EditorState) => EditorState;
66
+ mergeSelectedTable: (current: EditorState) => EditorState;
67
+ splitSelectedTableCellVertically: (current: EditorState) => EditorState;
68
+ splitSelectedTableCell: (current: EditorState) => EditorState;
69
+ splitSelectedTable: (current: EditorState) => EditorState;
70
+ insertSelectedTableRow: (current: EditorState, direction: -1 | 1) => EditorState;
71
+ deleteSelectedTableRow: (current: EditorState) => EditorState;
72
+ insertSelectedTableColumn: (current: EditorState, direction: -1 | 1) => EditorState;
73
+ deleteSelectedTableColumn: (current: EditorState) => EditorState;
74
+ getRowVisualWidth: (row: import('../../core/model.js').EditorTableRowNode) => number;
75
+ getTableVisualWidth: (table: import('../../core/model.js').EditorTableNode) => number;
76
+ findCellAtVisualColumn: (row: import('../../core/model.js').EditorTableRowNode, visualColumn: number) => import('../../core/model.js').EditorTableCellNode | null;
77
+ findFirstNavigableParagraphInTable: (table: import('../../core/model.js').EditorTableNode) => import('../../core/model.js').EditorParagraphNode | null;
78
+ updateBlocksInCurrentSection: (current: EditorState, blocks: import('../../core/model.js').EditorBlockNode[], zone?: import('../../core/model.js').EditorEditingZone) => EditorState;
79
+ resolveAdjacentTableCellPosition: (document: import('../../core/model.js').EditorDocument, paragraphId: string, delta: -1 | 1) => EditorPosition | null;
80
+ applyTableAwareParagraphEdit: (current: EditorState, edit: (tempState: EditorState) => EditorState) => EditorState;
81
+ withExpandedTableCellSelection: (current: EditorState) => EditorState;
82
+ applySelectionAwareTextCommand: (command: (current: EditorState) => EditorState) => void;
83
+ applySelectionAwareParagraphCommand: (command: (current: EditorState) => EditorState) => void;
84
+ insertTableCommand: (rows: number, cols: number) => void;
85
+ };
86
+ imageOps: {
87
+ dragging: import('solid-js').Accessor<boolean>;
88
+ draggedImageInfo: import('solid-js').Accessor<import('../../app/controllers/useEditorImageOperations.js').ActiveImageDrag | null>;
89
+ mousePos: import('solid-js').Accessor<{
90
+ x: number;
91
+ y: number;
92
+ }>;
93
+ dropTargetPos: import('solid-js').Accessor<EditorPosition | null>;
94
+ getSelectedImageInfo: (current: EditorState) => {
95
+ paragraph: import('../../core/model.js').EditorParagraphNode;
96
+ run: import('../../core/model.js').EditorTextRun;
97
+ startOffset: number;
98
+ width: number;
99
+ height: number;
100
+ src: string;
101
+ } | null;
102
+ startImageDrag: (paragraphId: string, paragraphOffset: number, event: MouseEvent, pointerBounds?: import('../../app/controllers/useEditorImageOperations.js').ImagePointerBounds) => void;
103
+ stopImageDrag: () => void;
104
+ stopImageResize: () => void;
105
+ stopImageRotate: () => void;
106
+ handleImageMouseDown: (paragraphId: string, paragraphOffset: number, event: MouseEvent & {
107
+ currentTarget: HTMLElement;
108
+ }) => void;
109
+ handleImageResizeHandleMouseDown: (paragraphId: string, paragraphOffset: number, direction: import('../resizeGeometry.js').ResizeHandleDirection, event: MouseEvent & {
110
+ currentTarget: HTMLElement;
111
+ }) => void;
112
+ handleImageRotateHandleMouseDown: (paragraphId: string, paragraphOffset: number, event: MouseEvent & {
113
+ currentTarget: HTMLElement;
114
+ }) => void;
115
+ };
116
+ textBoxOps: {
117
+ handleTextBoxResizeHandleMouseDown: (paragraphId: string, paragraphOffset: number, direction: import('../resizeGeometry.js').ResizeHandleDirection, event: MouseEvent & {
118
+ currentTarget: HTMLElement;
119
+ }) => void;
120
+ handleTextBoxRotateHandleMouseDown: (paragraphId: string, paragraphOffset: number, event: MouseEvent & {
121
+ currentTarget: HTMLElement;
122
+ }) => void;
123
+ stopTextBoxResize: () => void;
124
+ stopTextBoxRotate: () => void;
125
+ };
126
+ styleController: {
127
+ pendingCaretTextStyle: import('solid-js').Accessor<import('../../core/model.js').EditorTextStyle | undefined>;
128
+ clearPendingCaretTextStyle: () => void;
129
+ toolbarStyleState: () => import('../toolbarStyleState.js').ToolbarStyleState;
130
+ applyToolbarValueStyleCommand: <K extends "link" | "underlineStyle" | "textEffect" | "fontFamily" | "fontSize" | "color" | "highlight" | "shading" | "language">(key: K, value: import('../../core/model.js').EditorTextStyle[K] | null) => void;
131
+ applyToolbarBooleanStyleCommand: (key: import('../toolbarStyleState.js').BooleanStyleKey) => void;
132
+ };
133
+ onEditorMouseDown: (event: MouseEvent) => void;
134
+ tableResize: import('../../app/controllers/useEditorTableResize.js').TableResizeOps;
135
+ tableDrag: {
136
+ dragging: import('solid-js').Accessor<boolean>;
137
+ draggedTableInfo: import('solid-js').Accessor<{
138
+ tableId: string;
139
+ width: number;
140
+ height: number;
141
+ offsetX: number;
142
+ offsetY: number;
143
+ } | null>;
144
+ mousePos: import('solid-js').Accessor<{
145
+ x: number;
146
+ y: number;
147
+ }>;
148
+ dropTargetPos: import('solid-js').Accessor<EditorPosition | null>;
149
+ handleMouseDown: (tableId: string, event: MouseEvent) => void;
150
+ };
151
+ revisionController: {
152
+ hoveredRevision: import('solid-js').Accessor<import('../editorUiTypes.js').RevisionBox | null>;
153
+ handleRevisionMouseEnter: (revisionId: string, event: MouseEvent) => void;
154
+ handleRevisionMouseLeave: () => void;
155
+ };
156
+ textDrag: {
157
+ dragging: import('solid-js').Accessor<boolean>;
158
+ dropTargetPos: import('solid-js').Accessor<EditorPosition | null>;
159
+ copyMode: import('solid-js').Accessor<boolean>;
160
+ pointerPos: import('solid-js').Accessor<{
161
+ x: number;
162
+ y: number;
163
+ } | null>;
164
+ caretViewport: import('solid-js').Accessor<{
165
+ left: number;
166
+ top: number;
167
+ height: number;
168
+ } | null>;
169
+ tryStartTextDrag: (event: MouseEvent, hit: import('../canvas/CanvasHitTestService.js').SurfaceHit | null) => boolean;
170
+ stopDrag: () => void;
171
+ };
172
+ surfaceEventsWithTextDrag: {
173
+ handleSurfaceMouseDown: (event: MouseEvent) => void;
174
+ handleSurfaceClick: (event: MouseEvent) => void;
175
+ handleSurfaceDblClick: (event: MouseEvent) => void;
176
+ handleParagraphMouseDown: (_paragraphId: string, event: MouseEvent & {
177
+ currentTarget: HTMLParagraphElement;
178
+ }) => void;
179
+ stopDragging: () => void;
180
+ };
181
+ textInput: {
182
+ handleTextInput: (event: InputEvent & {
183
+ currentTarget: HTMLTextAreaElement;
184
+ }) => void;
185
+ handleCompositionStart: () => void;
186
+ handleCompositionEnd: (event: CompositionEvent & {
187
+ currentTarget: HTMLTextAreaElement;
188
+ }) => void;
189
+ composing: import('solid-js').Accessor<boolean>;
190
+ };
191
+ navigation: {
192
+ moveSelectionToParagraphBoundary: (boundary: "start" | "end", extend: boolean) => boolean;
193
+ moveSelectionToDocumentBoundary: (boundary: "start" | "end", extend: boolean) => boolean;
194
+ moveSelectionByWord: (direction: "left" | "right", extend: boolean) => boolean;
195
+ moveVerticalByBlock: (direction: -1 | 1) => boolean;
196
+ moveVerticalSelection: (direction: -1 | 1, extend: boolean) => boolean;
197
+ };
198
+ handleCopy: (event: ClipboardEvent & {
199
+ currentTarget: HTMLTextAreaElement;
200
+ }) => void;
201
+ handleCut: (event: ClipboardEvent & {
202
+ currentTarget: HTMLTextAreaElement;
203
+ }) => void;
204
+ handlePaste: (event: ClipboardEvent & {
205
+ currentTarget: HTMLTextAreaElement;
206
+ }) => void;
207
+ handleDrop: (event: DragEvent) => void;
208
+ };
209
+ export {};
@@ -0,0 +1,51 @@
1
+ import { EditorState } from '../../core/model.js';
2
+ import { SelectedImageRun } from '../../core/commands/image.js';
3
+ import { EditorLogger } from '../../utils/logger.js';
4
+ import { EditorTransactionPort } from '../../app/controllers/controllerPorts.js';
5
+ import { EditorKeyboardDeps } from '../../app/controllers/EditorKeyboardDeps.js';
6
+ import { createEditorTableOperations } from '../../app/controllers/useEditorTableOperations.js';
7
+ import { createEditorNavigation } from '../../app/controllers/useEditorNavigation.js';
8
+ import { createEditorHistoryActions } from '../../app/controllers/useEditorHistoryActions.js';
9
+ import { useEditorRuntimeBootstrap } from './useEditorRuntimeBootstrap.js';
10
+
11
+ type EditorTableOperations = ReturnType<typeof createEditorTableOperations>;
12
+ type EditorNavigation = ReturnType<typeof createEditorNavigation>;
13
+ type EditorHistoryActions = ReturnType<typeof createEditorHistoryActions>;
14
+ type RuntimeEditorAccessor = ReturnType<typeof useEditorRuntimeBootstrap>["runtimeEditor"];
15
+ export interface EditorKeyboardBindingDeps {
16
+ state: () => EditorState;
17
+ isReadOnly: () => boolean;
18
+ logger: EditorLogger;
19
+ focusInput: () => void;
20
+ clearPreferredColumn: () => void;
21
+ resetTransactionGrouping: () => void;
22
+ applyState: (next: EditorState) => void;
23
+ applyTransactionalState: EditorTransactionPort["applyTransactionalState"];
24
+ setForcePlainTextPaste: (value: boolean) => void;
25
+ selectedImageRun: () => SelectedImageRun | null;
26
+ commandsController: EditorKeyboardDeps["commandsController"];
27
+ tableOps: EditorTableOperations;
28
+ navigation: EditorNavigation;
29
+ historyActions: EditorHistoryActions;
30
+ styleController: {
31
+ clearPendingCaretTextStyle: () => void;
32
+ };
33
+ findReplace: {
34
+ isOpen: () => boolean;
35
+ setIsOpen: (open: boolean) => void;
36
+ };
37
+ runtimeEditor: RuntimeEditorAccessor;
38
+ }
39
+ /**
40
+ * Assembles the keyboard controller dependency bag from the editor's cohesive
41
+ * collaborators (transaction, navigation, history, table, find/replace, command
42
+ * runtime) and wraps the raw handler with caret-style reset, structured logging
43
+ * and the input-to-layout perf mark. Extracted from `OasisEditorApp` so the
44
+ * composition root no longer hand-wires 26 keyboard callbacks inline (S1).
45
+ */
46
+ export declare function createEditorKeyboardBinding(deps: EditorKeyboardBindingDeps): {
47
+ handleKeyDown: (event: KeyboardEvent & {
48
+ currentTarget: HTMLTextAreaElement;
49
+ }) => void;
50
+ };
51
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oasis-editor",
3
- "version": "0.0.76",
3
+ "version": "0.0.78",
4
4
  "type": "module",
5
5
  "repository": {
6
6
  "type": "git",