@octane-xplat/tiptap 0.0.1 → 0.10.0
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/LICENSE +21 -0
- package/README.md +78 -2
- package/dist/macos/browser.d.ts +1 -0
- package/dist/macos/browser.js +2 -0
- package/dist/native/index.js +3 -0
- package/dist/native/index2.js +82 -0
- package/dist/native/index3.js +211 -0
- package/dist/native/octane-client-build.json +8 -0
- package/dist/web/index.js +12 -0
- package/dist/web/index2.js +183 -0
- package/dist/web/octane-client-build.json +8 -0
- package/package.json +85 -11
- package/src/Editor.macos.tsx +9 -0
- package/src/TiptapEditor.tsrx +109 -0
- package/src/TiptapEditor.web.tsrx +155 -0
- package/src/browser-entry.web.tsx +5 -0
- package/src/index.macos.ts +13 -0
- package/src/index.ts +3 -0
- package/src/index.web.ts +12 -0
- package/src/json-bridge.ts +124 -0
- package/src/types.ts +102 -0
- package/types/index.d.ts +8 -0
- package/types/index.macos.d.ts +7 -0
- package/types/types.d.ts +80 -0
- package/index.d.ts +0 -1
- package/index.js +0 -2
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
//#region src/json-bridge.ts
|
|
2
|
+
var bridge;
|
|
3
|
+
/** zeed-dom's classList is a plain {contains,add,remove} object; tiptap's
|
|
4
|
+
* codeBlock parseHTML spreads it. Wrap the VElement getter so it hands back
|
|
5
|
+
* an iterable array that keeps the mutation methods. */
|
|
6
|
+
function patchClassList(VElement) {
|
|
7
|
+
const proto = VElement?.prototype;
|
|
8
|
+
if (!proto) throw new Error("VElement.prototype unavailable");
|
|
9
|
+
const desc = Object.getOwnPropertyDescriptor(proto, "classList");
|
|
10
|
+
if (!desc?.get) throw new Error("classList is not a prototype getter");
|
|
11
|
+
if (desc.get.__xplatPatched) return;
|
|
12
|
+
const patched = function() {
|
|
13
|
+
const cl = desc.get.call(this);
|
|
14
|
+
if (cl && typeof cl[Symbol.iterator] !== "function") {
|
|
15
|
+
const tokens = String(this.getAttribute("class") ?? "").split(/\s+/).filter(Boolean);
|
|
16
|
+
return Object.assign(tokens, cl);
|
|
17
|
+
}
|
|
18
|
+
return cl;
|
|
19
|
+
};
|
|
20
|
+
patched.__xplatPatched = true;
|
|
21
|
+
Object.defineProperty(proto, "classList", {
|
|
22
|
+
configurable: true,
|
|
23
|
+
get: patched,
|
|
24
|
+
set: desc.set
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
/** Install the minimal parse globals generateJSON's elementFromString
|
|
28
|
+
* reads. Only installs when the host lacks them, so a real DOM (web
|
|
29
|
+
* target) is never clobbered. */
|
|
30
|
+
function installDomShim(zeed) {
|
|
31
|
+
const g = globalThis;
|
|
32
|
+
if (g.window?.DOMParser) return;
|
|
33
|
+
class ZeedDOMParser {
|
|
34
|
+
parseFromString(html) {
|
|
35
|
+
const doc = zeed.createHTMLDocument();
|
|
36
|
+
doc.body.innerHTML = html;
|
|
37
|
+
return doc;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
g.window = { DOMParser: ZeedDOMParser };
|
|
41
|
+
g.document = zeed.createHTMLDocument();
|
|
42
|
+
}
|
|
43
|
+
async function ensureJSONBridge() {
|
|
44
|
+
if (bridge !== void 0) return bridge !== null;
|
|
45
|
+
try {
|
|
46
|
+
const [core, sk, sr, zeed] = await Promise.all([
|
|
47
|
+
import("@tiptap/core"),
|
|
48
|
+
import("@tiptap/starter-kit"),
|
|
49
|
+
import("@tiptap/static-renderer"),
|
|
50
|
+
import("zeed-dom")
|
|
51
|
+
]);
|
|
52
|
+
patchClassList(zeed.VElement);
|
|
53
|
+
installDomShim(zeed);
|
|
54
|
+
const StarterKit = sk.default ?? sk.StarterKit;
|
|
55
|
+
bridge = {
|
|
56
|
+
generateJSON: core.generateJSON,
|
|
57
|
+
renderToHTMLString: sr.renderToHTMLString,
|
|
58
|
+
extensions: [StarterKit]
|
|
59
|
+
};
|
|
60
|
+
return true;
|
|
61
|
+
} catch {
|
|
62
|
+
bridge = null;
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/** HTML → doc JSON through tiptap's own parseHTML rules. Null when the
|
|
67
|
+
* bridge hasn't loaded (call ensureJSONBridge first / check `ready`). */
|
|
68
|
+
function htmlToJSON(html) {
|
|
69
|
+
return bridge?.generateJSON(html, bridge.extensions) ?? null;
|
|
70
|
+
}
|
|
71
|
+
/** Doc JSON → HTML via tiptap's own renderHTML rules (no DOM). */
|
|
72
|
+
function jsonToHTML(doc) {
|
|
73
|
+
return bridge?.renderToHTMLString({
|
|
74
|
+
extensions: bridge.extensions,
|
|
75
|
+
content: doc
|
|
76
|
+
}) ?? null;
|
|
77
|
+
}
|
|
78
|
+
function jsonBridgeReady() {
|
|
79
|
+
return bridge != null;
|
|
80
|
+
}
|
|
81
|
+
//#endregion
|
|
82
|
+
export { ensureJSONBridge, htmlToJSON, jsonBridgeReady, jsonToHTML };
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import { ensureJSONBridge, htmlToJSON, jsonBridgeReady, jsonToHTML } from "./index2.js";
|
|
2
|
+
import { defineUniversalComponent, hookSlots, universalComponent, universalPlan, universalProps, universalValue, useCallback, useEffect, useImperativeHandle, useRef, useState } from "@nativescript-community/octane";
|
|
3
|
+
import { RichTextEditor, supported } from "@octane-xplat/richtext";
|
|
4
|
+
//#region src/TiptapEditor.tsrx
|
|
5
|
+
var _hs$ = /* @__PURE__ */ hookSlots(8);
|
|
6
|
+
var _h$0 = /* @__PURE__ */ Symbol(_hs$);
|
|
7
|
+
var _h$1 = /* @__PURE__ */ Symbol(_hs$ + 1);
|
|
8
|
+
var _h$2 = /* @__PURE__ */ Symbol(_hs$ + 2);
|
|
9
|
+
var _h$3 = /* @__PURE__ */ Symbol(_hs$ + 3);
|
|
10
|
+
var _h$4 = /* @__PURE__ */ Symbol(_hs$ + 4);
|
|
11
|
+
var _h$5 = /* @__PURE__ */ Symbol(_hs$ + 5);
|
|
12
|
+
var _h$6 = /* @__PURE__ */ Symbol(_hs$ + 6);
|
|
13
|
+
var _h$7 = /* @__PURE__ */ Symbol(_hs$ + 7);
|
|
14
|
+
var __octaneUniversalPlan0 = universalPlan("nativescript", {
|
|
15
|
+
"kind": "slot",
|
|
16
|
+
"slot": 0
|
|
17
|
+
});
|
|
18
|
+
var supported$1 = supported;
|
|
19
|
+
var TiptapEditor = defineUniversalComponent("nativescript", function TiptapEditor(props) {
|
|
20
|
+
const inner = useRef(null, _h$0);
|
|
21
|
+
const [exposedHandle, setHandle] = useState(null, _h$1);
|
|
22
|
+
useImperativeHandle(props.ref, () => exposedHandle, [exposedHandle], _h$2);
|
|
23
|
+
const jsonReady = useRef(false, _h$3);
|
|
24
|
+
const lastJSON = useRef(void 0, _h$4);
|
|
25
|
+
const bindHost = useCallback((h) => {
|
|
26
|
+
inner.current = h;
|
|
27
|
+
setHandle((previous) => previous?.native === h?.native ? previous : h ? {
|
|
28
|
+
getHTML: () => h.getHTML(),
|
|
29
|
+
setHTML: (html) => h.setHTML(html),
|
|
30
|
+
getJSON: () => jsonBridgeReady() ? htmlToJSON(h.getHTML()) : null,
|
|
31
|
+
setJSON: (doc) => {
|
|
32
|
+
const html = jsonBridgeReady() ? jsonToHTML(doc) : null;
|
|
33
|
+
if (html != null) {
|
|
34
|
+
lastJSON.current = JSON.stringify(doc);
|
|
35
|
+
h.setHTML(html);
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
apply: (format) => h.apply(format),
|
|
39
|
+
linkTo: (url, anchor) => h.linkTo(url, anchor),
|
|
40
|
+
removeLink: () => h.removeLink(),
|
|
41
|
+
isActive: (format) => h.isActive(format),
|
|
42
|
+
undo: () => h.undo(),
|
|
43
|
+
redo: () => h.redo(),
|
|
44
|
+
focus: () => h.focus(),
|
|
45
|
+
blur: () => h.blur(),
|
|
46
|
+
isFocused: () => h.isFocused(),
|
|
47
|
+
native: h.native
|
|
48
|
+
} : null);
|
|
49
|
+
}, [], _h$5);
|
|
50
|
+
useEffect(() => {
|
|
51
|
+
ensureJSONBridge().then((ok) => {
|
|
52
|
+
jsonReady.current = ok;
|
|
53
|
+
props.onJSONReady?.(ok);
|
|
54
|
+
});
|
|
55
|
+
}, [], _h$6);
|
|
56
|
+
useEffect(() => {
|
|
57
|
+
if (!props.json || !jsonBridgeReady() || !inner.current) return;
|
|
58
|
+
const stamp = JSON.stringify(props.json);
|
|
59
|
+
if (stamp === lastJSON.current) return;
|
|
60
|
+
const html = jsonToHTML(props.json);
|
|
61
|
+
if (html != null) {
|
|
62
|
+
lastJSON.current = stamp;
|
|
63
|
+
inner.current.setHTML(html);
|
|
64
|
+
}
|
|
65
|
+
}, [props.json], _h$7);
|
|
66
|
+
const emitJSON = () => {
|
|
67
|
+
if (!inner.current || !jsonBridgeReady()) return;
|
|
68
|
+
const doc = htmlToJSON(inner.current.getHTML());
|
|
69
|
+
if (doc) {
|
|
70
|
+
lastJSON.current = JSON.stringify(doc);
|
|
71
|
+
props.onJSONChange?.(doc);
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
return universalValue(__octaneUniversalPlan0, [universalComponent("nativescript", RichTextEditor, universalProps([
|
|
75
|
+
[
|
|
76
|
+
"set",
|
|
77
|
+
"id",
|
|
78
|
+
props.id
|
|
79
|
+
],
|
|
80
|
+
[
|
|
81
|
+
"set",
|
|
82
|
+
"className",
|
|
83
|
+
props.className
|
|
84
|
+
],
|
|
85
|
+
[
|
|
86
|
+
"set",
|
|
87
|
+
"style",
|
|
88
|
+
props.style
|
|
89
|
+
],
|
|
90
|
+
[
|
|
91
|
+
"set",
|
|
92
|
+
"value",
|
|
93
|
+
props.value
|
|
94
|
+
],
|
|
95
|
+
[
|
|
96
|
+
"set",
|
|
97
|
+
"placeholder",
|
|
98
|
+
props.placeholder
|
|
99
|
+
],
|
|
100
|
+
[
|
|
101
|
+
"set",
|
|
102
|
+
"editable",
|
|
103
|
+
props.editable
|
|
104
|
+
],
|
|
105
|
+
[
|
|
106
|
+
"set",
|
|
107
|
+
"autofocus",
|
|
108
|
+
props.autofocus
|
|
109
|
+
],
|
|
110
|
+
[
|
|
111
|
+
"set",
|
|
112
|
+
"onReady",
|
|
113
|
+
props.onReady
|
|
114
|
+
],
|
|
115
|
+
[
|
|
116
|
+
"set",
|
|
117
|
+
"onChange",
|
|
118
|
+
(html) => {
|
|
119
|
+
props.onChange?.(html);
|
|
120
|
+
emitJSON();
|
|
121
|
+
}
|
|
122
|
+
],
|
|
123
|
+
[
|
|
124
|
+
"set",
|
|
125
|
+
"onSelectionChange",
|
|
126
|
+
props.onSelectionChange
|
|
127
|
+
],
|
|
128
|
+
[
|
|
129
|
+
"set",
|
|
130
|
+
"onFocus",
|
|
131
|
+
props.onFocus
|
|
132
|
+
],
|
|
133
|
+
[
|
|
134
|
+
"set",
|
|
135
|
+
"onBlur",
|
|
136
|
+
props.onBlur
|
|
137
|
+
],
|
|
138
|
+
[
|
|
139
|
+
"set",
|
|
140
|
+
"ref",
|
|
141
|
+
bindHost
|
|
142
|
+
],
|
|
143
|
+
[
|
|
144
|
+
"set",
|
|
145
|
+
"android",
|
|
146
|
+
props.android
|
|
147
|
+
],
|
|
148
|
+
[
|
|
149
|
+
"set",
|
|
150
|
+
"ios",
|
|
151
|
+
props.ios
|
|
152
|
+
],
|
|
153
|
+
[
|
|
154
|
+
"set",
|
|
155
|
+
"row",
|
|
156
|
+
props.row
|
|
157
|
+
],
|
|
158
|
+
[
|
|
159
|
+
"set",
|
|
160
|
+
"col",
|
|
161
|
+
props.col
|
|
162
|
+
],
|
|
163
|
+
[
|
|
164
|
+
"set",
|
|
165
|
+
"rowSpan",
|
|
166
|
+
props.rowSpan
|
|
167
|
+
],
|
|
168
|
+
[
|
|
169
|
+
"set",
|
|
170
|
+
"colSpan",
|
|
171
|
+
props.colSpan
|
|
172
|
+
],
|
|
173
|
+
[
|
|
174
|
+
"set",
|
|
175
|
+
"dock",
|
|
176
|
+
props.dock
|
|
177
|
+
],
|
|
178
|
+
[
|
|
179
|
+
"set",
|
|
180
|
+
"left",
|
|
181
|
+
props.left
|
|
182
|
+
],
|
|
183
|
+
[
|
|
184
|
+
"set",
|
|
185
|
+
"top",
|
|
186
|
+
props.top
|
|
187
|
+
],
|
|
188
|
+
[
|
|
189
|
+
"set",
|
|
190
|
+
"flexGrow",
|
|
191
|
+
props.flexGrow
|
|
192
|
+
],
|
|
193
|
+
[
|
|
194
|
+
"set",
|
|
195
|
+
"flexShrink",
|
|
196
|
+
props.flexShrink
|
|
197
|
+
],
|
|
198
|
+
[
|
|
199
|
+
"set",
|
|
200
|
+
"alignSelf",
|
|
201
|
+
props.alignSelf
|
|
202
|
+
],
|
|
203
|
+
[
|
|
204
|
+
"set",
|
|
205
|
+
"order",
|
|
206
|
+
props.order
|
|
207
|
+
]
|
|
208
|
+
]))]);
|
|
209
|
+
}, { "module": "@nativescript-community/octane" });
|
|
210
|
+
//#endregion
|
|
211
|
+
export { TiptapEditor, supported$1 as supported };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { TiptapEditor, supported } from "./index2.js";
|
|
2
|
+
//#region src/index.web.ts
|
|
3
|
+
/** Web needs no lazy bridge — tiptap is in the bundle already. Kept for
|
|
4
|
+
* call-site parity with the native entry. */
|
|
5
|
+
function ensureJSONBridge() {
|
|
6
|
+
return Promise.resolve(true);
|
|
7
|
+
}
|
|
8
|
+
function jsonBridgeReady() {
|
|
9
|
+
return true;
|
|
10
|
+
}
|
|
11
|
+
//#endregion
|
|
12
|
+
export { TiptapEditor, ensureJSONBridge, jsonBridgeReady, supported };
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { __s, bag3, clone, componentSlot, hookSlots, setStyle, template, useEffect, useImperativeHandle, useRef, withSlot } from "octane";
|
|
2
|
+
import { updateFreshClassName } from "octane/internal/client";
|
|
3
|
+
import { EditorContent, useEditor } from "@octanejs/tiptap";
|
|
4
|
+
import StarterKit from "@tiptap/starter-kit";
|
|
5
|
+
//#region src/TiptapEditor.web.tsrx
|
|
6
|
+
var _t$0 = /* @__PURE__ */ template("<div></div>");
|
|
7
|
+
var _hs$ = /* @__PURE__ */ hookSlots(10);
|
|
8
|
+
var _h$5 = /* @__PURE__ */ Symbol(_hs$ + 5);
|
|
9
|
+
var supported = true;
|
|
10
|
+
var COMMAND = {
|
|
11
|
+
bold: (c) => c.toggleBold(),
|
|
12
|
+
italic: (c) => c.toggleItalic(),
|
|
13
|
+
underline: (c) => c.toggleUnderline(),
|
|
14
|
+
strikethrough: (c) => c.toggleStrike(),
|
|
15
|
+
code: (c) => c.toggleCode(),
|
|
16
|
+
blockquote: (c) => c.toggleBlockquote(),
|
|
17
|
+
bulletList: (c) => c.toggleBulletList(),
|
|
18
|
+
orderedList: (c) => c.toggleOrderedList(),
|
|
19
|
+
codeBlock: (c) => c.toggleCodeBlock(),
|
|
20
|
+
horizontalRule: (c) => c.setHorizontalRule(),
|
|
21
|
+
paragraph: (c) => c.setParagraph(),
|
|
22
|
+
heading1: (c) => c.toggleHeading({ level: 1 }),
|
|
23
|
+
heading2: (c) => c.toggleHeading({ level: 2 }),
|
|
24
|
+
heading3: (c) => c.toggleHeading({ level: 3 }),
|
|
25
|
+
heading4: (c) => c.toggleHeading({ level: 4 }),
|
|
26
|
+
heading5: (c) => c.toggleHeading({ level: 5 }),
|
|
27
|
+
heading6: (c) => c.toggleHeading({ level: 6 })
|
|
28
|
+
};
|
|
29
|
+
var ACTIVE_OF = [
|
|
30
|
+
["bold", "bold"],
|
|
31
|
+
["italic", "italic"],
|
|
32
|
+
["underline", "underline"],
|
|
33
|
+
["strikethrough", "strike"],
|
|
34
|
+
["code", "code"],
|
|
35
|
+
["blockquote", "blockquote"],
|
|
36
|
+
["bulletList", "bulletList"],
|
|
37
|
+
["orderedList", "orderedList"],
|
|
38
|
+
["codeBlock", "codeBlock"],
|
|
39
|
+
["link", "link"],
|
|
40
|
+
[
|
|
41
|
+
"heading1",
|
|
42
|
+
"heading",
|
|
43
|
+
{ level: 1 }
|
|
44
|
+
],
|
|
45
|
+
[
|
|
46
|
+
"heading2",
|
|
47
|
+
"heading",
|
|
48
|
+
{ level: 2 }
|
|
49
|
+
],
|
|
50
|
+
[
|
|
51
|
+
"heading3",
|
|
52
|
+
"heading",
|
|
53
|
+
{ level: 3 }
|
|
54
|
+
],
|
|
55
|
+
[
|
|
56
|
+
"heading4",
|
|
57
|
+
"heading",
|
|
58
|
+
{ level: 4 }
|
|
59
|
+
],
|
|
60
|
+
[
|
|
61
|
+
"heading5",
|
|
62
|
+
"heading",
|
|
63
|
+
{ level: 5 }
|
|
64
|
+
],
|
|
65
|
+
[
|
|
66
|
+
"heading6",
|
|
67
|
+
"heading",
|
|
68
|
+
{ level: 6 }
|
|
69
|
+
],
|
|
70
|
+
["paragraph", "paragraph"]
|
|
71
|
+
];
|
|
72
|
+
function activeFormats(editor) {
|
|
73
|
+
const out = [];
|
|
74
|
+
for (const [name, kind, attrs] of ACTIVE_OF) if (editor.isActive(kind, attrs)) out.push(name);
|
|
75
|
+
return out;
|
|
76
|
+
}
|
|
77
|
+
var TiptapEditor = /* @__PURE__ */ __s(function TiptapEditor(props, __s, __extra) {
|
|
78
|
+
const lastEmitted = useRef(void 0, _hs$ + 0);
|
|
79
|
+
const lastJSON = useRef(void 0, _hs$ + 1);
|
|
80
|
+
const lastHTMLInput = useRef(JSON.stringify([props.json !== void 0, props.value]), _hs$ + 2);
|
|
81
|
+
const lastJSONInput = useRef(JSON.stringify(props.json), _hs$ + 3);
|
|
82
|
+
const bound = useRef(void 0, _hs$ + 4);
|
|
83
|
+
const editor = withSlot(_h$5, useEditor, {
|
|
84
|
+
extensions: [StarterKit],
|
|
85
|
+
content: props.json ?? props.value ?? "",
|
|
86
|
+
editable: props.editable !== false,
|
|
87
|
+
autofocus: props.autofocus ?? false,
|
|
88
|
+
onCreate: () => props.onReady?.(),
|
|
89
|
+
onUpdate: ({ editor: e }) => {
|
|
90
|
+
const html = e.getHTML();
|
|
91
|
+
lastEmitted.current = html;
|
|
92
|
+
props.onChange?.(html);
|
|
93
|
+
const doc = e.getJSON();
|
|
94
|
+
lastJSON.current = JSON.stringify(doc);
|
|
95
|
+
props.onJSONChange?.(doc);
|
|
96
|
+
},
|
|
97
|
+
onFocus: () => props.onFocus?.(),
|
|
98
|
+
onBlur: () => props.onBlur?.(),
|
|
99
|
+
onSelectionUpdate: ({ editor: e }) => props.onSelectionChange?.({
|
|
100
|
+
start: e.state.selection.from,
|
|
101
|
+
end: e.state.selection.to,
|
|
102
|
+
active: activeFormats(e)
|
|
103
|
+
})
|
|
104
|
+
});
|
|
105
|
+
useEffect(() => {
|
|
106
|
+
if (!editor) return;
|
|
107
|
+
const stamp = JSON.stringify([props.json !== void 0, props.value]);
|
|
108
|
+
if (stamp === lastHTMLInput.current) return;
|
|
109
|
+
lastHTMLInput.current = stamp;
|
|
110
|
+
if (props.value === void 0 || props.json !== void 0) return;
|
|
111
|
+
if (props.value === lastEmitted.current) return;
|
|
112
|
+
editor.commands.setContent(props.value);
|
|
113
|
+
}, [
|
|
114
|
+
editor,
|
|
115
|
+
props.value,
|
|
116
|
+
props.json
|
|
117
|
+
], _hs$ + 6);
|
|
118
|
+
useEffect(() => {
|
|
119
|
+
if (!editor) return;
|
|
120
|
+
const stamp = JSON.stringify(props.json);
|
|
121
|
+
if (stamp === lastJSONInput.current) return;
|
|
122
|
+
lastJSONInput.current = stamp;
|
|
123
|
+
if (props.json === void 0 || stamp === lastJSON.current) return;
|
|
124
|
+
editor.commands.setContent(props.json);
|
|
125
|
+
}, [editor, props.json], _hs$ + 7);
|
|
126
|
+
useEffect(() => {
|
|
127
|
+
if (!editor) return;
|
|
128
|
+
editor.setEditable(props.editable !== false);
|
|
129
|
+
}, [editor, props.editable], _hs$ + 8);
|
|
130
|
+
useImperativeHandle(props.ref, () => {
|
|
131
|
+
if (!editor) return null;
|
|
132
|
+
const e = editor;
|
|
133
|
+
bound.current = {
|
|
134
|
+
getHTML: () => e.getHTML(),
|
|
135
|
+
setHTML: (html) => e.commands.setContent(html),
|
|
136
|
+
getJSON: () => e.getJSON(),
|
|
137
|
+
setJSON: (doc) => e.commands.setContent(doc),
|
|
138
|
+
apply: (format) => {
|
|
139
|
+
const run = COMMAND[format];
|
|
140
|
+
if (run) run(e.chain().focus()).run();
|
|
141
|
+
},
|
|
142
|
+
linkTo: (url, anchor) => {
|
|
143
|
+
if (anchor != null && anchor !== "") e.chain().focus().insertContent({
|
|
144
|
+
type: "text",
|
|
145
|
+
text: anchor,
|
|
146
|
+
marks: [{
|
|
147
|
+
type: "link",
|
|
148
|
+
attrs: { href: url }
|
|
149
|
+
}]
|
|
150
|
+
}).run();
|
|
151
|
+
else e.chain().focus().extendMarkRange("link").setLink({ href: url }).run();
|
|
152
|
+
},
|
|
153
|
+
removeLink: () => e.chain().focus().unsetLink().run(),
|
|
154
|
+
isActive: (format) => activeFormats(e).includes(format),
|
|
155
|
+
undo: () => e.commands.undo(),
|
|
156
|
+
redo: () => e.commands.redo(),
|
|
157
|
+
focus: () => e.commands.focus(),
|
|
158
|
+
blur: () => e.commands.blur(),
|
|
159
|
+
isFocused: () => e.isFocused,
|
|
160
|
+
native: e
|
|
161
|
+
};
|
|
162
|
+
return bound.current;
|
|
163
|
+
}, [editor], _hs$ + 9);
|
|
164
|
+
if (__s.block.pending && !__s.block.crossRenderUpdate) return;
|
|
165
|
+
let _b = __s.slots[0];
|
|
166
|
+
if (_b === void 0) {
|
|
167
|
+
let _m1;
|
|
168
|
+
const _root = clone(_t$0);
|
|
169
|
+
_m1 = _root;
|
|
170
|
+
_b = bag3(__s, _root, void 0, _m1, void 0);
|
|
171
|
+
}
|
|
172
|
+
_b.a = updateFreshClassName(["vx-richtext", props.className], _b.a, _b.b);
|
|
173
|
+
{
|
|
174
|
+
const _v = props.style;
|
|
175
|
+
if (_b.c !== _v) {
|
|
176
|
+
setStyle(_b.b, _v, _b.c);
|
|
177
|
+
_b.c = _v;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
componentSlot(__s, 1, _b.b, EditorContent, { "editor": editor }, void 0, void 0, 2, void 0, void 0, "c:e9be3bbb");
|
|
181
|
+
});
|
|
182
|
+
//#endregion
|
|
183
|
+
export { TiptapEditor, supported };
|
package/package.json
CHANGED
|
@@ -1,19 +1,93 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@octane-xplat/tiptap",
|
|
3
|
-
"version": "0.0
|
|
4
|
-
"description": "Unified rich-text editor facade for Octane xplat —
|
|
3
|
+
"version": "0.10.0",
|
|
4
|
+
"description": "Unified rich-text editor facade for Octane xplat — live tiptap on web/AppKit, Aztec + tiptap document model on Android",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"cross-platform",
|
|
7
|
+
"editor",
|
|
8
|
+
"octane",
|
|
9
|
+
"prosemirror",
|
|
10
|
+
"rich-text",
|
|
11
|
+
"richtext",
|
|
12
|
+
"tiptap",
|
|
13
|
+
"xplat"
|
|
14
|
+
],
|
|
15
|
+
"homepage": "https://github.com/octane-xplat/octane-xplat/tree/main/packages/tiptap",
|
|
5
16
|
"license": "MIT",
|
|
6
17
|
"repository": {
|
|
7
18
|
"type": "git",
|
|
8
|
-
"url": "https://github.com/octane-xplat/octane-xplat
|
|
19
|
+
"url": "https://github.com/octane-xplat/octane-xplat",
|
|
9
20
|
"directory": "packages/tiptap"
|
|
10
21
|
},
|
|
11
|
-
"homepage": "https://github.com/octane-xplat/octane-xplat/tree/main/packages/tiptap",
|
|
12
|
-
"main": "./index.js",
|
|
13
|
-
"types": "./index.d.ts",
|
|
14
22
|
"files": [
|
|
15
|
-
"
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
|
|
19
|
-
|
|
23
|
+
"dist",
|
|
24
|
+
"types",
|
|
25
|
+
"src",
|
|
26
|
+
"platforms"
|
|
27
|
+
],
|
|
28
|
+
"type": "module",
|
|
29
|
+
"exports": {
|
|
30
|
+
".": {
|
|
31
|
+
"macos": {
|
|
32
|
+
"types": "./types/index.macos.d.ts",
|
|
33
|
+
"default": "./src/index.macos.ts"
|
|
34
|
+
},
|
|
35
|
+
"web": {
|
|
36
|
+
"types": "./types/index.d.ts",
|
|
37
|
+
"default": "./dist/web/index.js"
|
|
38
|
+
},
|
|
39
|
+
"native": {
|
|
40
|
+
"types": "./types/index.d.ts",
|
|
41
|
+
"default": "./dist/native/index.js"
|
|
42
|
+
},
|
|
43
|
+
"types": "./types/index.d.ts",
|
|
44
|
+
"default": "./dist/native/index.js"
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"publishConfig": {
|
|
48
|
+
"access": "public"
|
|
49
|
+
},
|
|
50
|
+
"dependencies": {
|
|
51
|
+
"@octane-xplat/richtext": "0.10.0",
|
|
52
|
+
"@octanejs/tiptap": "0.0.51",
|
|
53
|
+
"@tiptap/core": "3.28.0",
|
|
54
|
+
"@tiptap/pm": "3.28.0",
|
|
55
|
+
"@tiptap/starter-kit": "3.28.0",
|
|
56
|
+
"@tiptap/static-renderer": "3.28.0",
|
|
57
|
+
"zeed-dom": "^0.15.1"
|
|
58
|
+
},
|
|
59
|
+
"devDependencies": {
|
|
60
|
+
"@nativescript-community/octane": "0.2.4",
|
|
61
|
+
"@nativescript/core": "9.1.2",
|
|
62
|
+
"@octane-xplat/macos-renderer": "0.10.0",
|
|
63
|
+
"@octanejs/vite-plugin": "0.1.61",
|
|
64
|
+
"octane": "0.6.3",
|
|
65
|
+
"typescript": "5.9.3",
|
|
66
|
+
"vite": "8.3.0"
|
|
67
|
+
},
|
|
68
|
+
"peerDependencies": {
|
|
69
|
+
"@nativescript-community/octane": ">=0.2.1 <1",
|
|
70
|
+
"@nativescript/core": ">=9.1.0 <10",
|
|
71
|
+
"octane": ">=0.6.3 <1"
|
|
72
|
+
},
|
|
73
|
+
"peerDependenciesMeta": {
|
|
74
|
+
"@nativescript-community/octane": {
|
|
75
|
+
"optional": true
|
|
76
|
+
},
|
|
77
|
+
"@nativescript/core": {
|
|
78
|
+
"optional": true
|
|
79
|
+
},
|
|
80
|
+
"octane": {
|
|
81
|
+
"optional": true
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
"nativescript": {
|
|
85
|
+
"platforms": {
|
|
86
|
+
"android": "9.1.0",
|
|
87
|
+
"ios": "9.1.0"
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
"scripts": {
|
|
91
|
+
"build": "vite build && vite build --mode native && tsc -p tsconfig.types.json && node ../../scripts/check-native-dist.mjs && node ../richtext/build-browser.mjs"
|
|
92
|
+
}
|
|
93
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** @jsxImportSource @octane-xplat/macos-renderer */
|
|
2
|
+
import type { TiptapEditorProps } from './types'
|
|
3
|
+
import browser from '../dist/macos/browser.js'
|
|
4
|
+
import { NativeEditor } from '@octane-xplat/richtext/macos-host'
|
|
5
|
+
|
|
6
|
+
/** AppKit mounts the local editor engine in WKWebView. */
|
|
7
|
+
export function TiptapEditor(props: TiptapEditorProps) {
|
|
8
|
+
return <NativeEditor {...props} browser={browser} />
|
|
9
|
+
}
|