@openeditor/react-native-prose-editor 0.0.6 → 0.0.8
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.
- package/android/build.gradle +35 -0
- package/android/src/main/java/com/apollohg/editor/CaretGeometry.kt +2 -2
- package/android/src/main/java/com/apollohg/editor/EditorEditText.kt +138 -597
- package/android/src/main/java/com/apollohg/editor/EditorInputConnection.kt +13 -3
- package/android/src/main/java/com/apollohg/editor/InputSnapshotSupport.kt +6 -0
- package/android/src/main/java/com/apollohg/editor/NativeBlockEditorSurface.kt +1086 -0
- package/android/src/main/java/com/apollohg/editor/NativeEditorExpoView.kt +1 -1
- package/android/src/main/java/com/apollohg/editor/NativeEditorModule.kt +26 -50
- package/android/src/main/java/com/apollohg/editor/NativeImageLoader.kt +89 -0
- package/android/src/main/java/com/apollohg/editor/RemoteSelectionOverlayView.kt +31 -66
- package/android/src/main/java/com/apollohg/editor/RichTextEditorView.kt +98 -33
- package/dist/EditorToolbar.d.ts +1 -1
- package/dist/EditorToolbar.js +19 -0
- package/dist/NativeEditorBridge.d.ts +62 -35
- package/dist/NativeEditorBridge.js +122 -79
- package/dist/NativeProseViewer.d.ts +13 -34
- package/dist/NativeProseViewer.js +40 -465
- package/dist/NativeRichTextEditor.d.ts +10 -1
- package/dist/NativeRichTextEditor.js +72 -34
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -1
- package/dist/schemas.d.ts +11 -0
- package/dist/schemas.js +149 -0
- package/dist/useNativeEditor.d.ts +3 -3
- package/dist/useNativeEditor.js +3 -3
- package/ios/EditorCore.xcframework/ios-arm64/libeditor_core.a +0 -0
- package/ios/EditorCore.xcframework/ios-arm64_x86_64-simulator/libeditor_core.a +0 -0
- package/ios/Generated_editor_core.swift +97 -2
- package/ios/NativeBlockEditorSurface.swift +1393 -0
- package/ios/NativeEditorExpoView.swift +3 -3
- package/ios/NativeEditorModule.swift +30 -45
- package/ios/NativeInputSupport.swift +396 -0
- package/ios/PositionBridge.swift +4 -4
- package/ios/RichTextEditorView.swift +333 -786
- package/ios/editor_coreFFI/editor_coreFFI.h +147 -70
- package/package.json +1 -1
- package/rust/android/arm64-v8a/libeditor_core.so +0 -0
- package/rust/android/armeabi-v7a/libeditor_core.so +0 -0
- package/rust/android/x86_64/libeditor_core.so +0 -0
- package/rust/bindings/kotlin/uniffi/editor_core/editor_core.kt +2087 -1399
- package/android/src/androidTest/AndroidManifest.xml +0 -8
- package/android/src/androidTest/java/com/apollohg/editor/MeasureHeightInstrumentedTest.kt +0 -53
- package/android/src/androidTest/java/com/apollohg/editor/NativeDeviceCollaborationInitialSyncTest.kt +0 -241
- package/android/src/androidTest/java/com/apollohg/editor/NativeDeviceImeRegressionTest.kt +0 -338
- package/android/src/androidTest/java/com/apollohg/editor/NativeDeviceOutsideTapTest.kt +0 -789
- package/android/src/androidTest/java/com/apollohg/editor/NativeDevicePerformanceTest.kt +0 -350
- package/android/src/androidTest/java/com/apollohg/editor/NativeEditorOutsideTapActivity.kt +0 -5
- package/android/src/main/java/com/apollohg/editor/NativeProseViewerExpoView.kt +0 -315
- package/android/src/main/java/com/apollohg/editor/RenderBridge.kt +0 -2172
- package/android/src/sharedTest/java/com/apollohg/editor/NativePerformanceSupport.kt +0 -482
- package/android/src/test/java/com/apollohg/editor/CaretGeometryTest.kt +0 -137
- package/android/src/test/java/com/apollohg/editor/EditorEditTextHardwareKeyTest.kt +0 -321
- package/android/src/test/java/com/apollohg/editor/EditorInputConnectionTest.kt +0 -4202
- package/android/src/test/java/com/apollohg/editor/NativeEditorExpoViewTest.kt +0 -2581
- package/android/src/test/java/com/apollohg/editor/NativeEditorModuleTest.kt +0 -27
- package/android/src/test/java/com/apollohg/editor/NativePerformanceTest.kt +0 -197
- package/android/src/test/java/com/apollohg/editor/NativeProseViewerExpoViewTest.kt +0 -84
- package/android/src/test/java/com/apollohg/editor/NativeToolbarTest.kt +0 -544
- package/android/src/test/java/com/apollohg/editor/PositionBridgeTest.kt +0 -461
- package/android/src/test/java/com/apollohg/editor/RenderBridgeTest.kt +0 -2054
- package/android/src/test/java/com/apollohg/editor/RichTextEditorViewTest.kt +0 -1367
- package/ios/EditorLayoutManager.swift +0 -774
- package/ios/NativeProseViewerExpoView.swift +0 -276
- package/ios/RenderBridge.swift +0 -1708
- package/ios/Tests/NativePerformanceTests.swift +0 -687
- package/ios/Tests/PositionBridgeTests.swift +0 -706
- package/ios/Tests/RenderBridgeTests.swift +0 -2236
- package/ios/Tests/RichTextEditorViewTests.swift +0 -6548
|
@@ -439,41 +439,34 @@ function isCurrentNativeEditorEvent(event, bridge) {
|
|
|
439
439
|
return true;
|
|
440
440
|
return event.editorId === 0 || bridge?.editorId === event.editorId;
|
|
441
441
|
}
|
|
442
|
-
function computeRenderedTextLength(
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
el.type === 'opaqueInlineAtom' ||
|
|
459
|
-
el.type === 'opaqueBlockAtom') {
|
|
460
|
-
if (el.type === 'opaqueInlineAtom' || el.type === 'opaqueBlockAtom') {
|
|
461
|
-
const visibleText = el.nodeType === 'mention' ? (el.label ?? '?') : `[${el.label ?? '?'}]`;
|
|
462
|
-
len += unicodeScalarCount(visibleText);
|
|
463
|
-
}
|
|
464
|
-
else {
|
|
465
|
-
// U+FFFC placeholder / hard break
|
|
466
|
-
len += 1;
|
|
467
|
-
}
|
|
468
|
-
}
|
|
469
|
-
else if (el.type === 'blockEnd') {
|
|
470
|
-
blockCount++;
|
|
442
|
+
function computeRenderedTextLength(tree) {
|
|
443
|
+
const blockLengths = [];
|
|
444
|
+
collectTextSurfaceBlockLengths(tree.root, blockLengths);
|
|
445
|
+
if (blockLengths.length === 0)
|
|
446
|
+
return 0;
|
|
447
|
+
return blockLengths.reduce((sum, value) => sum + value, 0) + blockLengths.length - 1;
|
|
448
|
+
}
|
|
449
|
+
function collectTextSurfaceBlockLengths(node, output) {
|
|
450
|
+
if (node.kind === 'text') {
|
|
451
|
+
return unicodeScalarCount(node.text ?? '');
|
|
452
|
+
}
|
|
453
|
+
if (node.kind === 'inlineAtom' || node.kind === 'blockAtom') {
|
|
454
|
+
if (node.nodeType === 'mention')
|
|
455
|
+
return unicodeScalarCount(node.label ?? '?');
|
|
456
|
+
if (node.kind === 'inlineAtom' && node.nodeType !== 'hardBreak' && node.nodeType !== 'hard_break') {
|
|
457
|
+
return unicodeScalarCount(`[${node.label ?? '?'}]`);
|
|
471
458
|
}
|
|
459
|
+
return 1;
|
|
472
460
|
}
|
|
473
|
-
|
|
474
|
-
if (
|
|
475
|
-
|
|
476
|
-
|
|
461
|
+
const childLength = (node.children ?? []).reduce((sum, child) => sum + collectTextSurfaceBlockLengths(child, output), 0);
|
|
462
|
+
if (node.kind === 'textBlock' ||
|
|
463
|
+
node.kind === 'listItem' ||
|
|
464
|
+
node.kind === 'block' ||
|
|
465
|
+
node.kind === 'tableCell') {
|
|
466
|
+
output.push(childLength);
|
|
467
|
+
return 0;
|
|
468
|
+
}
|
|
469
|
+
return childLength;
|
|
477
470
|
}
|
|
478
471
|
function serializeRemoteSelections(remoteSelections) {
|
|
479
472
|
if (!remoteSelections || remoteSelections.length === 0) {
|
|
@@ -725,7 +718,7 @@ exports.NativeRichTextEditor = (0, react_1.forwardRef)(function NativeRichTextEd
|
|
|
725
718
|
setActiveState(update.activeState);
|
|
726
719
|
setHistoryState(update.historyState);
|
|
727
720
|
selectionRef.current = update.selection;
|
|
728
|
-
renderedTextLengthRef.current = computeRenderedTextLength(update.
|
|
721
|
+
renderedTextLengthRef.current = computeRenderedTextLength(update.renderTree);
|
|
729
722
|
if (typeof update.documentVersion === 'number') {
|
|
730
723
|
const previousDocumentVersion = documentVersionRef.current;
|
|
731
724
|
documentVersionRef.current = update.documentVersion;
|
|
@@ -2222,6 +2215,27 @@ exports.NativeRichTextEditor = (0, react_1.forwardRef)(function NativeRichTextEd
|
|
|
2222
2215
|
insertImage(src, attrs) {
|
|
2223
2216
|
insertImage(src, attrs);
|
|
2224
2217
|
},
|
|
2218
|
+
insertColumns(options) {
|
|
2219
|
+
runAndApply(() => bridgeRef.current?.insertContentJson((0, schemas_1.buildColumnsFragmentJson)(options)) ?? null);
|
|
2220
|
+
},
|
|
2221
|
+
insertTable(options) {
|
|
2222
|
+
runAndApply(() => bridgeRef.current?.insertContentJson((0, schemas_1.buildTableFragmentJson)(options)) ?? null);
|
|
2223
|
+
},
|
|
2224
|
+
insertTableRow(after = true) {
|
|
2225
|
+
runAndApply(() => bridgeRef.current?.insertTableRow(after) ?? null);
|
|
2226
|
+
},
|
|
2227
|
+
deleteTableRow() {
|
|
2228
|
+
runAndApply(() => bridgeRef.current?.deleteTableRow() ?? null);
|
|
2229
|
+
},
|
|
2230
|
+
insertTableColumn(after = true) {
|
|
2231
|
+
runAndApply(() => bridgeRef.current?.insertTableColumn(after) ?? null);
|
|
2232
|
+
},
|
|
2233
|
+
deleteTableColumn() {
|
|
2234
|
+
runAndApply(() => bridgeRef.current?.deleteTableColumn() ?? null);
|
|
2235
|
+
},
|
|
2236
|
+
moveTableCell(forward = true) {
|
|
2237
|
+
runAndApply(() => bridgeRef.current?.moveTableCell(forward) ?? null);
|
|
2238
|
+
},
|
|
2225
2239
|
insertText(text) {
|
|
2226
2240
|
runAndApply(() => bridgeRef.current?.replaceSelectionText(text) ?? null);
|
|
2227
2241
|
},
|
|
@@ -2520,6 +2534,30 @@ exports.NativeRichTextEditor = (0, react_1.forwardRef)(function NativeRichTextEd
|
|
|
2520
2534
|
case 'outdentList':
|
|
2521
2535
|
runAndApply(() => bridgeRef.current?.outdentListItem() ?? null);
|
|
2522
2536
|
break;
|
|
2537
|
+
case 'insertTableRowBefore':
|
|
2538
|
+
runAndApply(() => bridgeRef.current?.insertTableRow(false) ?? null);
|
|
2539
|
+
break;
|
|
2540
|
+
case 'insertTableRowAfter':
|
|
2541
|
+
runAndApply(() => bridgeRef.current?.insertTableRow(true) ?? null);
|
|
2542
|
+
break;
|
|
2543
|
+
case 'deleteTableRow':
|
|
2544
|
+
runAndApply(() => bridgeRef.current?.deleteTableRow() ?? null);
|
|
2545
|
+
break;
|
|
2546
|
+
case 'insertTableColumnBefore':
|
|
2547
|
+
runAndApply(() => bridgeRef.current?.insertTableColumn(false) ?? null);
|
|
2548
|
+
break;
|
|
2549
|
+
case 'insertTableColumnAfter':
|
|
2550
|
+
runAndApply(() => bridgeRef.current?.insertTableColumn(true) ?? null);
|
|
2551
|
+
break;
|
|
2552
|
+
case 'deleteTableColumn':
|
|
2553
|
+
runAndApply(() => bridgeRef.current?.deleteTableColumn() ?? null);
|
|
2554
|
+
break;
|
|
2555
|
+
case 'moveToNextTableCell':
|
|
2556
|
+
runAndApply(() => bridgeRef.current?.moveTableCell(true) ?? null);
|
|
2557
|
+
break;
|
|
2558
|
+
case 'moveToPreviousTableCell':
|
|
2559
|
+
runAndApply(() => bridgeRef.current?.moveTableCell(false) ?? null);
|
|
2560
|
+
break;
|
|
2523
2561
|
case 'undo':
|
|
2524
2562
|
runAndApply(() => bridgeRef.current?.undo() ?? null);
|
|
2525
2563
|
break;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
export { NativeRichTextEditor, type NativeRichTextEditorProps, type NativeRichTextEditorRef, type NativeRichTextEditorCaretRect, type NativeRichTextEditorHeightBehavior, type NativeRichTextEditorToolbarPlacement, type NativeRichTextEditorValueJSONUpdateMode, type NativeRichTextEditorAutoCapitalize, type NativeRichTextEditorKeyboardType, type RemoteSelectionDecoration, type LinkRequestContext, type ImageRequestContext, } from './NativeRichTextEditor';
|
|
2
|
-
export { NativeProseViewer, type NativeProseViewerProps,
|
|
2
|
+
export { NativeProseViewer, type NativeProseViewerProps, } from './NativeProseViewer';
|
|
3
3
|
export { EditorToolbar, DEFAULT_EDITOR_TOOLBAR_ITEMS, type EditorToolbarProps, type EditorToolbarItem, type EditorToolbarLeafItem, type EditorToolbarGroupChildItem, type EditorToolbarGroupItem, type EditorToolbarGroupPresentation, type EditorToolbarIcon, type EditorToolbarDefaultIconId, type EditorToolbarSFSymbolIcon, type EditorToolbarMaterialIcon, type EditorToolbarCommand, type EditorToolbarHeadingLevel, type EditorToolbarListType, } from './EditorToolbar';
|
|
4
4
|
export type { EditorContentInsets, EditorTheme, EditorTextStyle, EditorLinkTheme, EditorHeadingTheme, EditorListTheme, EditorHorizontalRuleTheme, EditorMentionTheme, EditorToolbarTheme, EditorToolbarAppearance, EditorFontStyle, EditorFontWeight, } from './EditorTheme';
|
|
5
5
|
export { MENTION_NODE_NAME, mentionNodeSpec, withMentionsSchema, buildMentionFragmentJson, type EditorAddons, type MentionsAddonConfig, type MentionSuggestion, type MentionQueryChangeEvent, type MentionSelectionAttrsEvent, type MentionThemeResolveEvent, type MentionSelectEvent, type EditorAddonEvent, } from './addons';
|
|
6
|
-
export { tiptapSchema, prosemirrorSchema, IMAGE_NODE_NAME, imageNodeSpec, withImagesSchema, buildImageFragmentJson, type SchemaDefinition, type NodeSpec, type MarkSpec, type AttrSpec, type ImageNodeAttributes, } from './schemas';
|
|
6
|
+
export { tiptapSchema, prosemirrorSchema, IMAGE_NODE_NAME, imageNodeSpec, withImagesSchema, buildImageFragmentJson, buildTableFragmentJson, type SchemaDefinition, type NodeSpec, type MarkSpec, type AttrSpec, type ImageNodeAttributes, type TableFragmentOptions, } from './schemas';
|
|
7
7
|
export { createYjsCollaborationController, useYjsCollaboration, type YjsCollaborationOptions, type YjsCollaborationState, type YjsTransportStatus, type LocalAwarenessState, type LocalAwarenessUser, type UseYjsCollaborationResult, type YjsCollaborationController, } from './YjsCollaboration';
|
|
8
8
|
export type { Selection, ActiveState, HistoryState, EditorUpdate, DocumentJSON, CollaborationPeer, EncodedCollaborationStateInput, } from './NativeEditorBridge';
|
|
9
9
|
export { encodeCollaborationStateBase64, decodeCollaborationStateBase64, } from './NativeEditorBridge';
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.clearHeightCache = exports.decodeCollaborationStateBase64 = exports.encodeCollaborationStateBase64 = exports.useYjsCollaboration = exports.createYjsCollaborationController = exports.buildImageFragmentJson = exports.withImagesSchema = exports.imageNodeSpec = exports.IMAGE_NODE_NAME = exports.prosemirrorSchema = exports.tiptapSchema = exports.buildMentionFragmentJson = exports.withMentionsSchema = exports.mentionNodeSpec = exports.MENTION_NODE_NAME = exports.DEFAULT_EDITOR_TOOLBAR_ITEMS = exports.EditorToolbar = exports.NativeProseViewer = exports.NativeRichTextEditor = void 0;
|
|
3
|
+
exports.clearHeightCache = exports.decodeCollaborationStateBase64 = exports.encodeCollaborationStateBase64 = exports.useYjsCollaboration = exports.createYjsCollaborationController = exports.buildTableFragmentJson = exports.buildImageFragmentJson = exports.withImagesSchema = exports.imageNodeSpec = exports.IMAGE_NODE_NAME = exports.prosemirrorSchema = exports.tiptapSchema = exports.buildMentionFragmentJson = exports.withMentionsSchema = exports.mentionNodeSpec = exports.MENTION_NODE_NAME = exports.DEFAULT_EDITOR_TOOLBAR_ITEMS = exports.EditorToolbar = exports.NativeProseViewer = exports.NativeRichTextEditor = void 0;
|
|
4
4
|
var NativeRichTextEditor_1 = require("./NativeRichTextEditor");
|
|
5
5
|
Object.defineProperty(exports, "NativeRichTextEditor", { enumerable: true, get: function () { return NativeRichTextEditor_1.NativeRichTextEditor; } });
|
|
6
6
|
var NativeProseViewer_1 = require("./NativeProseViewer");
|
|
@@ -20,6 +20,7 @@ Object.defineProperty(exports, "IMAGE_NODE_NAME", { enumerable: true, get: funct
|
|
|
20
20
|
Object.defineProperty(exports, "imageNodeSpec", { enumerable: true, get: function () { return schemas_1.imageNodeSpec; } });
|
|
21
21
|
Object.defineProperty(exports, "withImagesSchema", { enumerable: true, get: function () { return schemas_1.withImagesSchema; } });
|
|
22
22
|
Object.defineProperty(exports, "buildImageFragmentJson", { enumerable: true, get: function () { return schemas_1.buildImageFragmentJson; } });
|
|
23
|
+
Object.defineProperty(exports, "buildTableFragmentJson", { enumerable: true, get: function () { return schemas_1.buildTableFragmentJson; } });
|
|
23
24
|
var YjsCollaboration_1 = require("./YjsCollaboration");
|
|
24
25
|
Object.defineProperty(exports, "createYjsCollaborationController", { enumerable: true, get: function () { return YjsCollaboration_1.createYjsCollaborationController; } });
|
|
25
26
|
Object.defineProperty(exports, "useYjsCollaboration", { enumerable: true, get: function () { return YjsCollaboration_1.useYjsCollaboration; } });
|
package/dist/schemas.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ export interface NodeSpec {
|
|
|
8
8
|
group?: string;
|
|
9
9
|
attrs?: Record<string, AttrSpec>;
|
|
10
10
|
role: string;
|
|
11
|
+
layoutRole?: 'columns' | 'column' | 'table' | 'tableRow' | 'tableCell' | 'tableHeader';
|
|
11
12
|
htmlTag?: string;
|
|
12
13
|
isVoid?: boolean;
|
|
13
14
|
}
|
|
@@ -31,6 +32,16 @@ export declare const IMAGE_NODE_NAME = "image";
|
|
|
31
32
|
export declare function imageNodeSpec(name?: string): NodeSpec;
|
|
32
33
|
export declare function withImagesSchema(schema: SchemaDefinition): SchemaDefinition;
|
|
33
34
|
export declare function buildImageFragmentJson(attrs: ImageNodeAttributes): DocumentJSON;
|
|
35
|
+
export interface TableFragmentOptions {
|
|
36
|
+
rows?: number;
|
|
37
|
+
cols?: number;
|
|
38
|
+
withHeaderRow?: boolean;
|
|
39
|
+
}
|
|
40
|
+
export declare function buildTableFragmentJson({ rows, cols, withHeaderRow, }?: TableFragmentOptions): DocumentJSON;
|
|
41
|
+
export interface ColumnsFragmentOptions {
|
|
42
|
+
count?: number;
|
|
43
|
+
}
|
|
44
|
+
export declare function buildColumnsFragmentJson({ count, }?: ColumnsFragmentOptions): DocumentJSON;
|
|
34
45
|
export declare const tiptapSchema: SchemaDefinition;
|
|
35
46
|
export declare function defaultEmptyDocument(schema?: SchemaDefinition): DocumentJSON;
|
|
36
47
|
export declare function normalizeDocumentJson(doc: DocumentJSON, schema?: SchemaDefinition): DocumentJSON;
|
package/dist/schemas.js
CHANGED
|
@@ -4,6 +4,8 @@ exports.prosemirrorSchema = exports.tiptapSchema = exports.IMAGE_NODE_NAME = voi
|
|
|
4
4
|
exports.imageNodeSpec = imageNodeSpec;
|
|
5
5
|
exports.withImagesSchema = withImagesSchema;
|
|
6
6
|
exports.buildImageFragmentJson = buildImageFragmentJson;
|
|
7
|
+
exports.buildTableFragmentJson = buildTableFragmentJson;
|
|
8
|
+
exports.buildColumnsFragmentJson = buildColumnsFragmentJson;
|
|
7
9
|
exports.defaultEmptyDocument = defaultEmptyDocument;
|
|
8
10
|
exports.normalizeDocumentJson = normalizeDocumentJson;
|
|
9
11
|
exports.IMAGE_NODE_NAME = 'image';
|
|
@@ -55,6 +57,45 @@ function buildImageFragmentJson(attrs) {
|
|
|
55
57
|
],
|
|
56
58
|
};
|
|
57
59
|
}
|
|
60
|
+
function buildTableFragmentJson({ rows = 3, cols = 3, withHeaderRow = true, } = {}) {
|
|
61
|
+
const rowCount = Math.max(1, Math.floor(rows));
|
|
62
|
+
const colCount = Math.max(1, Math.floor(cols));
|
|
63
|
+
return {
|
|
64
|
+
type: 'doc',
|
|
65
|
+
content: [
|
|
66
|
+
{
|
|
67
|
+
type: 'table',
|
|
68
|
+
content: Array.from({ length: rowCount }, (_, rowIndex) => ({
|
|
69
|
+
type: 'tableRow',
|
|
70
|
+
content: Array.from({ length: colCount }, () => ({
|
|
71
|
+
type: withHeaderRow && rowIndex === 0 ? 'tableHeader' : 'tableCell',
|
|
72
|
+
content: [{ type: 'paragraph' }],
|
|
73
|
+
})),
|
|
74
|
+
})),
|
|
75
|
+
},
|
|
76
|
+
],
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
function buildColumnsFragmentJson({ count = 2, } = {}) {
|
|
80
|
+
const columnCount = Math.min(Math.max(1, Math.floor(count)), 4);
|
|
81
|
+
return {
|
|
82
|
+
type: 'doc',
|
|
83
|
+
content: [
|
|
84
|
+
{
|
|
85
|
+
type: 'columns',
|
|
86
|
+
content: Array.from({ length: columnCount }, (_, index) => ({
|
|
87
|
+
type: 'column',
|
|
88
|
+
content: [
|
|
89
|
+
{
|
|
90
|
+
type: 'paragraph',
|
|
91
|
+
content: [{ type: 'text', text: `Column ${index + 1}` }],
|
|
92
|
+
},
|
|
93
|
+
],
|
|
94
|
+
})),
|
|
95
|
+
},
|
|
96
|
+
],
|
|
97
|
+
};
|
|
98
|
+
}
|
|
58
99
|
const MARKS = [
|
|
59
100
|
{ name: 'bold' },
|
|
60
101
|
{ name: 'italic' },
|
|
@@ -122,6 +163,60 @@ exports.tiptapSchema = {
|
|
|
122
163
|
isVoid: true,
|
|
123
164
|
},
|
|
124
165
|
imageNodeSpec(),
|
|
166
|
+
{
|
|
167
|
+
name: 'columns',
|
|
168
|
+
content: 'column+',
|
|
169
|
+
group: 'block',
|
|
170
|
+
role: 'block',
|
|
171
|
+
layoutRole: 'columns',
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
name: 'column',
|
|
175
|
+
content: 'block+',
|
|
176
|
+
role: 'block',
|
|
177
|
+
layoutRole: 'column',
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
name: 'table',
|
|
181
|
+
content: 'tableRow+',
|
|
182
|
+
group: 'block',
|
|
183
|
+
role: 'block',
|
|
184
|
+
layoutRole: 'table',
|
|
185
|
+
htmlTag: 'table',
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
name: 'tableRow',
|
|
189
|
+
content: '(tableCell | tableHeader)+',
|
|
190
|
+
role: 'block',
|
|
191
|
+
layoutRole: 'tableRow',
|
|
192
|
+
htmlTag: 'tr',
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
name: 'tableCell',
|
|
196
|
+
content: 'block+',
|
|
197
|
+
role: 'block',
|
|
198
|
+
layoutRole: 'tableCell',
|
|
199
|
+
attrs: {
|
|
200
|
+
colspan: { default: 1 },
|
|
201
|
+
rowspan: { default: 1 },
|
|
202
|
+
colwidth: { default: null },
|
|
203
|
+
align: { default: null },
|
|
204
|
+
},
|
|
205
|
+
htmlTag: 'td',
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
name: 'tableHeader',
|
|
209
|
+
content: 'block+',
|
|
210
|
+
role: 'block',
|
|
211
|
+
layoutRole: 'tableHeader',
|
|
212
|
+
attrs: {
|
|
213
|
+
colspan: { default: 1 },
|
|
214
|
+
rowspan: { default: 1 },
|
|
215
|
+
colwidth: { default: null },
|
|
216
|
+
align: { default: null },
|
|
217
|
+
},
|
|
218
|
+
htmlTag: 'th',
|
|
219
|
+
},
|
|
125
220
|
{
|
|
126
221
|
name: 'text',
|
|
127
222
|
content: '',
|
|
@@ -252,6 +347,60 @@ exports.prosemirrorSchema = {
|
|
|
252
347
|
isVoid: true,
|
|
253
348
|
},
|
|
254
349
|
imageNodeSpec('image'),
|
|
350
|
+
{
|
|
351
|
+
name: 'columns',
|
|
352
|
+
content: 'column+',
|
|
353
|
+
group: 'block',
|
|
354
|
+
role: 'block',
|
|
355
|
+
layoutRole: 'columns',
|
|
356
|
+
},
|
|
357
|
+
{
|
|
358
|
+
name: 'column',
|
|
359
|
+
content: 'block+',
|
|
360
|
+
role: 'block',
|
|
361
|
+
layoutRole: 'column',
|
|
362
|
+
},
|
|
363
|
+
{
|
|
364
|
+
name: 'table',
|
|
365
|
+
content: 'table_row+',
|
|
366
|
+
group: 'block',
|
|
367
|
+
role: 'block',
|
|
368
|
+
layoutRole: 'table',
|
|
369
|
+
htmlTag: 'table',
|
|
370
|
+
},
|
|
371
|
+
{
|
|
372
|
+
name: 'table_row',
|
|
373
|
+
content: '(table_cell | table_header)+',
|
|
374
|
+
role: 'block',
|
|
375
|
+
layoutRole: 'tableRow',
|
|
376
|
+
htmlTag: 'tr',
|
|
377
|
+
},
|
|
378
|
+
{
|
|
379
|
+
name: 'table_cell',
|
|
380
|
+
content: 'block+',
|
|
381
|
+
role: 'block',
|
|
382
|
+
layoutRole: 'tableCell',
|
|
383
|
+
attrs: {
|
|
384
|
+
colspan: { default: 1 },
|
|
385
|
+
rowspan: { default: 1 },
|
|
386
|
+
colwidth: { default: null },
|
|
387
|
+
align: { default: null },
|
|
388
|
+
},
|
|
389
|
+
htmlTag: 'td',
|
|
390
|
+
},
|
|
391
|
+
{
|
|
392
|
+
name: 'table_header',
|
|
393
|
+
content: 'block+',
|
|
394
|
+
role: 'block',
|
|
395
|
+
layoutRole: 'tableHeader',
|
|
396
|
+
attrs: {
|
|
397
|
+
colspan: { default: 1 },
|
|
398
|
+
rowspan: { default: 1 },
|
|
399
|
+
colwidth: { default: null },
|
|
400
|
+
align: { default: null },
|
|
401
|
+
},
|
|
402
|
+
htmlTag: 'th',
|
|
403
|
+
},
|
|
255
404
|
{
|
|
256
405
|
name: 'text',
|
|
257
406
|
content: '',
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { NativeEditorBridge, type ActiveState, type HistoryState, type
|
|
1
|
+
import { NativeEditorBridge, type ActiveState, type HistoryState, type RenderTree, type Selection } from './NativeEditorBridge';
|
|
2
2
|
export interface UseNativeEditorOptions {
|
|
3
3
|
/** Maximum character length. Omit for no limit. */
|
|
4
4
|
maxLength?: number;
|
|
@@ -20,8 +20,8 @@ export interface UseNativeEditorReturn {
|
|
|
20
20
|
activeState: ActiveState;
|
|
21
21
|
/** Current undo/redo availability. */
|
|
22
22
|
historyState: HistoryState;
|
|
23
|
-
/** Current render
|
|
24
|
-
|
|
23
|
+
/** Current structural render tree. */
|
|
24
|
+
renderTree: RenderTree | null;
|
|
25
25
|
/** Toggle a mark (e.g. 'bold', 'italic', 'underline'). */
|
|
26
26
|
toggleMark: (markType: string) => void;
|
|
27
27
|
/** Undo the last operation. */
|
package/dist/useNativeEditor.js
CHANGED
|
@@ -24,11 +24,11 @@ function useNativeEditor(options = {}) {
|
|
|
24
24
|
const [selection, setSelection] = (0, react_1.useState)(DEFAULT_SELECTION);
|
|
25
25
|
const [activeState, setActiveState] = (0, react_1.useState)(DEFAULT_ACTIVE_STATE);
|
|
26
26
|
const [historyState, setHistoryState] = (0, react_1.useState)(DEFAULT_HISTORY_STATE);
|
|
27
|
-
const [
|
|
27
|
+
const [renderTree, setRenderTree] = (0, react_1.useState)(null);
|
|
28
28
|
const syncStateFromUpdate = (0, react_1.useCallback)((update) => {
|
|
29
29
|
if (!update)
|
|
30
30
|
return;
|
|
31
|
-
|
|
31
|
+
setRenderTree(update.renderTree);
|
|
32
32
|
setSelection(update.selection);
|
|
33
33
|
setActiveState(update.activeState);
|
|
34
34
|
setHistoryState(update.historyState);
|
|
@@ -111,7 +111,7 @@ function useNativeEditor(options = {}) {
|
|
|
111
111
|
selection,
|
|
112
112
|
activeState,
|
|
113
113
|
historyState,
|
|
114
|
-
|
|
114
|
+
renderTree,
|
|
115
115
|
toggleMark,
|
|
116
116
|
undo,
|
|
117
117
|
redo,
|
|
Binary file
|
|
Binary file
|
|
@@ -730,6 +730,26 @@ public func editorDeleteScalarRange(id: UInt64, scalarFrom: UInt32, scalarTo: UI
|
|
|
730
730
|
)
|
|
731
731
|
})
|
|
732
732
|
}
|
|
733
|
+
/**
|
|
734
|
+
* Delete the current table column.
|
|
735
|
+
*/
|
|
736
|
+
public func editorDeleteTableColumn(id: UInt64) -> String {
|
|
737
|
+
return try! FfiConverterString.lift(try! rustCall() {
|
|
738
|
+
uniffi_editor_core_fn_func_editor_delete_table_column(
|
|
739
|
+
FfiConverterUInt64.lower(id),$0
|
|
740
|
+
)
|
|
741
|
+
})
|
|
742
|
+
}
|
|
743
|
+
/**
|
|
744
|
+
* Delete the current table row.
|
|
745
|
+
*/
|
|
746
|
+
public func editorDeleteTableRow(id: UInt64) -> String {
|
|
747
|
+
return try! FfiConverterString.lift(try! rustCall() {
|
|
748
|
+
uniffi_editor_core_fn_func_editor_delete_table_row(
|
|
749
|
+
FfiConverterUInt64.lower(id),$0
|
|
750
|
+
)
|
|
751
|
+
})
|
|
752
|
+
}
|
|
733
753
|
/**
|
|
734
754
|
* Destroy an editor instance, freeing its resources.
|
|
735
755
|
*/
|
|
@@ -893,6 +913,28 @@ public func editorInsertNodeAtSelectionScalar(id: UInt64, scalarAnchor: UInt32,
|
|
|
893
913
|
)
|
|
894
914
|
})
|
|
895
915
|
}
|
|
916
|
+
/**
|
|
917
|
+
* Insert a table column before or after the current column.
|
|
918
|
+
*/
|
|
919
|
+
public func editorInsertTableColumn(id: UInt64, after: Bool) -> String {
|
|
920
|
+
return try! FfiConverterString.lift(try! rustCall() {
|
|
921
|
+
uniffi_editor_core_fn_func_editor_insert_table_column(
|
|
922
|
+
FfiConverterUInt64.lower(id),
|
|
923
|
+
FfiConverterBool.lower(after),$0
|
|
924
|
+
)
|
|
925
|
+
})
|
|
926
|
+
}
|
|
927
|
+
/**
|
|
928
|
+
* Insert a table row before or after the current row.
|
|
929
|
+
*/
|
|
930
|
+
public func editorInsertTableRow(id: UInt64, after: Bool) -> String {
|
|
931
|
+
return try! FfiConverterString.lift(try! rustCall() {
|
|
932
|
+
uniffi_editor_core_fn_func_editor_insert_table_row(
|
|
933
|
+
FfiConverterUInt64.lower(id),
|
|
934
|
+
FfiConverterBool.lower(after),$0
|
|
935
|
+
)
|
|
936
|
+
})
|
|
937
|
+
}
|
|
896
938
|
/**
|
|
897
939
|
* Insert text at a position. Returns an update JSON string.
|
|
898
940
|
*/
|
|
@@ -917,6 +959,17 @@ public func editorInsertTextScalar(id: UInt64, scalarPos: UInt32, text: String)
|
|
|
917
959
|
)
|
|
918
960
|
})
|
|
919
961
|
}
|
|
962
|
+
/**
|
|
963
|
+
* Move the selection to the next or previous table cell.
|
|
964
|
+
*/
|
|
965
|
+
public func editorMoveTableCell(id: UInt64, forward: Bool) -> String {
|
|
966
|
+
return try! FfiConverterString.lift(try! rustCall() {
|
|
967
|
+
uniffi_editor_core_fn_func_editor_move_table_cell(
|
|
968
|
+
FfiConverterUInt64.lower(id),
|
|
969
|
+
FfiConverterBool.lower(forward),$0
|
|
970
|
+
)
|
|
971
|
+
})
|
|
972
|
+
}
|
|
920
973
|
/**
|
|
921
974
|
* Outdent the current list item to the parent list level. Returns an update JSON string.
|
|
922
975
|
*/
|
|
@@ -1020,7 +1073,18 @@ public func editorScalarToDoc(id: UInt64, scalar: UInt32) -> UInt32 {
|
|
|
1020
1073
|
})
|
|
1021
1074
|
}
|
|
1022
1075
|
/**
|
|
1023
|
-
* Set
|
|
1076
|
+
* Set a table cell selection. Anchor and head are document positions of cell nodes.
|
|
1077
|
+
*/
|
|
1078
|
+
public func editorSetCellSelection(id: UInt64, anchor: UInt32, head: UInt32) {try! rustCall() {
|
|
1079
|
+
uniffi_editor_core_fn_func_editor_set_cell_selection(
|
|
1080
|
+
FfiConverterUInt64.lower(id),
|
|
1081
|
+
FfiConverterUInt32.lower(anchor),
|
|
1082
|
+
FfiConverterUInt32.lower(head),$0
|
|
1083
|
+
)
|
|
1084
|
+
}
|
|
1085
|
+
}
|
|
1086
|
+
/**
|
|
1087
|
+
* Set the editor's content from an HTML string. Returns an editor update JSON payload.
|
|
1024
1088
|
*/
|
|
1025
1089
|
public func editorSetHtml(id: UInt64, html: String) -> String {
|
|
1026
1090
|
return try! FfiConverterString.lift(try! rustCall() {
|
|
@@ -1067,6 +1131,16 @@ public func editorSetMarkAtSelectionScalar(id: UInt64, scalarAnchor: UInt32, sca
|
|
|
1067
1131
|
)
|
|
1068
1132
|
})
|
|
1069
1133
|
}
|
|
1134
|
+
/**
|
|
1135
|
+
* Set a node selection at a selectable node's document position.
|
|
1136
|
+
*/
|
|
1137
|
+
public func editorSetNodeSelection(id: UInt64, pos: UInt32) {try! rustCall() {
|
|
1138
|
+
uniffi_editor_core_fn_func_editor_set_node_selection(
|
|
1139
|
+
FfiConverterUInt64.lower(id),
|
|
1140
|
+
FfiConverterUInt32.lower(pos),$0
|
|
1141
|
+
)
|
|
1142
|
+
}
|
|
1143
|
+
}
|
|
1070
1144
|
/**
|
|
1071
1145
|
* Set the selection. Anchor and head are document positions.
|
|
1072
1146
|
*/
|
|
@@ -1349,6 +1423,12 @@ private let initializationResult: InitializationResult = {
|
|
|
1349
1423
|
if (uniffi_editor_core_checksum_func_editor_delete_scalar_range() != 60098) {
|
|
1350
1424
|
return InitializationResult.apiChecksumMismatch
|
|
1351
1425
|
}
|
|
1426
|
+
if (uniffi_editor_core_checksum_func_editor_delete_table_column() != 12282) {
|
|
1427
|
+
return InitializationResult.apiChecksumMismatch
|
|
1428
|
+
}
|
|
1429
|
+
if (uniffi_editor_core_checksum_func_editor_delete_table_row() != 32001) {
|
|
1430
|
+
return InitializationResult.apiChecksumMismatch
|
|
1431
|
+
}
|
|
1352
1432
|
if (uniffi_editor_core_checksum_func_editor_destroy() != 35774) {
|
|
1353
1433
|
return InitializationResult.apiChecksumMismatch
|
|
1354
1434
|
}
|
|
@@ -1394,12 +1474,21 @@ private let initializationResult: InitializationResult = {
|
|
|
1394
1474
|
if (uniffi_editor_core_checksum_func_editor_insert_node_at_selection_scalar() != 32254) {
|
|
1395
1475
|
return InitializationResult.apiChecksumMismatch
|
|
1396
1476
|
}
|
|
1477
|
+
if (uniffi_editor_core_checksum_func_editor_insert_table_column() != 13873) {
|
|
1478
|
+
return InitializationResult.apiChecksumMismatch
|
|
1479
|
+
}
|
|
1480
|
+
if (uniffi_editor_core_checksum_func_editor_insert_table_row() != 58307) {
|
|
1481
|
+
return InitializationResult.apiChecksumMismatch
|
|
1482
|
+
}
|
|
1397
1483
|
if (uniffi_editor_core_checksum_func_editor_insert_text() != 22584) {
|
|
1398
1484
|
return InitializationResult.apiChecksumMismatch
|
|
1399
1485
|
}
|
|
1400
1486
|
if (uniffi_editor_core_checksum_func_editor_insert_text_scalar() != 30263) {
|
|
1401
1487
|
return InitializationResult.apiChecksumMismatch
|
|
1402
1488
|
}
|
|
1489
|
+
if (uniffi_editor_core_checksum_func_editor_move_table_cell() != 56610) {
|
|
1490
|
+
return InitializationResult.apiChecksumMismatch
|
|
1491
|
+
}
|
|
1403
1492
|
if (uniffi_editor_core_checksum_func_editor_outdent_list_item() != 55796) {
|
|
1404
1493
|
return InitializationResult.apiChecksumMismatch
|
|
1405
1494
|
}
|
|
@@ -1427,7 +1516,10 @@ private let initializationResult: InitializationResult = {
|
|
|
1427
1516
|
if (uniffi_editor_core_checksum_func_editor_scalar_to_doc() != 40126) {
|
|
1428
1517
|
return InitializationResult.apiChecksumMismatch
|
|
1429
1518
|
}
|
|
1430
|
-
if (
|
|
1519
|
+
if (uniffi_editor_core_checksum_func_editor_set_cell_selection() != 40422) {
|
|
1520
|
+
return InitializationResult.apiChecksumMismatch
|
|
1521
|
+
}
|
|
1522
|
+
if (uniffi_editor_core_checksum_func_editor_set_html() != 47581) {
|
|
1431
1523
|
return InitializationResult.apiChecksumMismatch
|
|
1432
1524
|
}
|
|
1433
1525
|
if (uniffi_editor_core_checksum_func_editor_set_json() != 18497) {
|
|
@@ -1439,6 +1531,9 @@ private let initializationResult: InitializationResult = {
|
|
|
1439
1531
|
if (uniffi_editor_core_checksum_func_editor_set_mark_at_selection_scalar() != 43994) {
|
|
1440
1532
|
return InitializationResult.apiChecksumMismatch
|
|
1441
1533
|
}
|
|
1534
|
+
if (uniffi_editor_core_checksum_func_editor_set_node_selection() != 61000) {
|
|
1535
|
+
return InitializationResult.apiChecksumMismatch
|
|
1536
|
+
}
|
|
1442
1537
|
if (uniffi_editor_core_checksum_func_editor_set_selection() != 28236) {
|
|
1443
1538
|
return InitializationResult.apiChecksumMismatch
|
|
1444
1539
|
}
|