@thomasfosterau/effect-richtext 0.0.0 → 0.1.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 +48 -0
- package/README.md +117 -1
- package/dist/_virtual/_rolldown/runtime.js +12 -0
- package/dist/commands/commands.d.ts +323 -0
- package/dist/commands/commands.js +722 -0
- package/dist/commands/internal.js +43 -0
- package/dist/commands/keymaps.d.ts +46 -0
- package/dist/commands/keymaps.js +64 -0
- package/dist/commands.d.ts +3 -0
- package/dist/commands.js +3 -0
- package/dist/compat/commands.d.ts +250 -0
- package/dist/compat/commands.js +275 -0
- package/dist/compat/internal/core.d.ts +20 -0
- package/dist/compat/internal/core.js +148 -0
- package/dist/compat/internal/props.js +82 -0
- package/dist/compat/keymap.d.ts +21 -0
- package/dist/compat/keymap.js +38 -0
- package/dist/compat/model.d.ts +893 -0
- package/dist/compat/model.js +1212 -0
- package/dist/compat/orderedmap.d.ts +74 -0
- package/dist/compat/orderedmap.js +124 -0
- package/dist/compat/schema-basic.d.ts +38 -0
- package/dist/compat/schema-basic.js +238 -0
- package/dist/compat/schema-list.d.ts +81 -0
- package/dist/compat/schema-list.js +156 -0
- package/dist/compat/state.d.ts +415 -0
- package/dist/compat/state.js +689 -0
- package/dist/compat/test-builder.d.ts +98 -0
- package/dist/compat/test-builder.js +197 -0
- package/dist/compat/transform.d.ts +458 -0
- package/dist/compat/transform.js +803 -0
- package/dist/compat/view.d.ts +411 -0
- package/dist/compat/view.js +409 -0
- package/dist/dropcursor.d.ts +46 -0
- package/dist/dropcursor.js +176 -0
- package/dist/extensions/defaults.d.ts +716 -0
- package/dist/extensions/defaults.js +209 -0
- package/dist/extensions/editor.d.ts +246 -0
- package/dist/extensions/editor.js +271 -0
- package/dist/extensions/extension.d.ts +375 -0
- package/dist/extensions/extension.js +233 -0
- package/dist/extensions.d.ts +4 -0
- package/dist/extensions.js +4 -0
- package/dist/gapcursor.d.ts +66 -0
- package/dist/gapcursor.js +273 -0
- package/dist/history.d.ts +178 -0
- package/dist/history.js +412 -0
- package/dist/html.d.ts +158 -0
- package/dist/html.js +164 -0
- package/dist/inputrules.d.ts +271 -0
- package/dist/inputrules.js +321 -0
- package/dist/internal/attempt.js +15 -0
- package/dist/internal/json.js +29 -0
- package/dist/keymap/keymap.d.ts +130 -0
- package/dist/keymap/keymap.js +159 -0
- package/dist/keymap.d.ts +2 -0
- package/dist/keymap.js +1 -0
- package/dist/markdown/errors.d.ts +23 -0
- package/dist/markdown/errors.js +26 -0
- package/dist/markdown/from_markdown.d.ts +185 -0
- package/dist/markdown/from_markdown.js +266 -0
- package/dist/markdown/schema.d.ts +522 -0
- package/dist/markdown/schema.js +292 -0
- package/dist/markdown/to_markdown.d.ts +251 -0
- package/dist/markdown/to_markdown.js +413 -0
- package/dist/markdown.d.ts +5 -0
- package/dist/markdown.js +5 -0
- package/dist/model/attrsCodec.js +48 -0
- package/dist/model/comparedeep.js +17 -0
- package/dist/model/content.d.ts +232 -0
- package/dist/model/content.js +630 -0
- package/dist/model/diff.js +66 -0
- package/dist/model/dom.d.ts +3 -0
- package/dist/model/errors.d.ts +90 -0
- package/dist/model/errors.js +76 -0
- package/dist/model/fragment.d.ts +131 -0
- package/dist/model/fragment.js +262 -0
- package/dist/model/from_dom.d.ts +299 -0
- package/dist/model/from_dom.js +618 -0
- package/dist/model/json.d.ts +37 -0
- package/dist/model/json.js +126 -0
- package/dist/model/mark.d.ts +73 -0
- package/dist/model/mark.js +121 -0
- package/dist/model/node.d.ts +267 -0
- package/dist/model/node.js +434 -0
- package/dist/model/replace.d.ts +78 -0
- package/dist/model/replace.js +207 -0
- package/dist/model/resolvedpos.d.ts +196 -0
- package/dist/model/resolvedpos.js +305 -0
- package/dist/model/schema.d.ts +740 -0
- package/dist/model/schema.js +451 -0
- package/dist/model/to_dom.d.ts +169 -0
- package/dist/model/to_dom.js +238 -0
- package/dist/model.d.ts +12 -0
- package/dist/model.js +12 -0
- package/dist/placeholder.d.ts +53 -0
- package/dist/placeholder.js +79 -0
- package/dist/reactive/observer.d.ts +54 -0
- package/dist/reactive/observer.js +61 -0
- package/dist/reactive/selectors.d.ts +22 -0
- package/dist/reactive/selectors.js +61 -0
- package/dist/reactive/stateref.d.ts +72 -0
- package/dist/reactive/stateref.js +71 -0
- package/dist/reactive/streams.d.ts +83 -0
- package/dist/reactive/streams.js +85 -0
- package/dist/reactive.d.ts +16 -0
- package/dist/reactive.js +26 -0
- package/dist/schema-basic.d.ts +448 -0
- package/dist/schema-basic.js +269 -0
- package/dist/schema-list/commands.d.ts +66 -0
- package/dist/schema-list/commands.js +203 -0
- package/dist/schema-list.d.ts +92 -0
- package/dist/schema-list.js +100 -0
- package/dist/state/errors.d.ts +39 -0
- package/dist/state/errors.js +32 -0
- package/dist/state/plugin.d.ts +232 -0
- package/dist/state/plugin.js +82 -0
- package/dist/state/selection.d.ts +297 -0
- package/dist/state/selection.js +486 -0
- package/dist/state/state.d.ts +212 -0
- package/dist/state/state.js +489 -0
- package/dist/state/transaction.d.ts +145 -0
- package/dist/state/transaction.js +195 -0
- package/dist/state.d.ts +6 -0
- package/dist/state.js +6 -0
- package/dist/test-builder.d.ts +3582 -0
- package/dist/test-builder.js +239 -0
- package/dist/transform/attr_step.d.ts +60 -0
- package/dist/transform/attr_step.js +105 -0
- package/dist/transform/errors.d.ts +50 -0
- package/dist/transform/errors.js +35 -0
- package/dist/transform/map.d.ts +182 -0
- package/dist/transform/map.js +280 -0
- package/dist/transform/mark.js +98 -0
- package/dist/transform/mark_set_step.js +69 -0
- package/dist/transform/mark_step.d.ts +113 -0
- package/dist/transform/mark_step.js +225 -0
- package/dist/transform/replace.d.ts +18 -0
- package/dist/transform/replace.js +381 -0
- package/dist/transform/replace_step.d.ts +109 -0
- package/dist/transform/replace_step.js +175 -0
- package/dist/transform/step.d.ts +157 -0
- package/dist/transform/step.js +168 -0
- package/dist/transform/structure.d.ts +89 -0
- package/dist/transform/structure.js +350 -0
- package/dist/transform/transform.d.ts +248 -0
- package/dist/transform/transform.js +373 -0
- package/dist/transform.d.ts +10 -0
- package/dist/transform.js +10 -0
- package/dist/view/browser.js +39 -0
- package/dist/view/capturekeys.js +282 -0
- package/dist/view/clipboard.d.ts +8 -0
- package/dist/view/clipboard.js +245 -0
- package/dist/view/decoration.d.ts +339 -0
- package/dist/view/decoration.js +566 -0
- package/dist/view/dom.d.ts +18 -0
- package/dist/view/dom.js +140 -0
- package/dist/view/domchange.js +295 -0
- package/dist/view/domcoords.d.ts +22 -0
- package/dist/view/domcoords.js +448 -0
- package/dist/view/domobserver.d.ts +47 -0
- package/dist/view/domobserver.js +328 -0
- package/dist/view/errors.d.ts +18 -0
- package/dist/view/errors.js +21 -0
- package/dist/view/input.d.ts +58 -0
- package/dist/view/input.js +704 -0
- package/dist/view/selection.js +198 -0
- package/dist/view/view.d.ts +699 -0
- package/dist/view/view.js +623 -0
- package/dist/view/viewdesc.d.ts +236 -0
- package/dist/view/viewdesc.js +1205 -0
- package/dist/view-css.d.ts +43 -0
- package/dist/view-css.js +124 -0
- package/dist/view.d.ts +6 -0
- package/dist/view.js +4 -0
- package/package.json +200 -4
|
@@ -0,0 +1,689 @@
|
|
|
1
|
+
import { Plugin as Plugin$1, PluginKey as PluginKey$1 } from "../state/plugin.js";
|
|
2
|
+
import { AllSelection as AllSelection$1, NodeSelection as NodeSelection$1, Selection as Selection$1, SelectionRange as SelectionRange$1, TextSelection as TextSelection$1 } from "../state/selection.js";
|
|
3
|
+
import { Transaction as Transaction$1 } from "../state/transaction.js";
|
|
4
|
+
import { EditorState as EditorState$1 } from "../state/state.js";
|
|
5
|
+
import { BASE, CORE, adopt, callBase, getBase, guard, isFacade, link, registerWrapper, runSync, unwrap, unwrapArray, wrap, wrapArray } from "./internal/core.js";
|
|
6
|
+
import { propsFromCore, propsToCore } from "./internal/props.js";
|
|
7
|
+
import { Slice } from "./model.js";
|
|
8
|
+
import { Transform } from "./transform.js";
|
|
9
|
+
import * as Effect from "effect/Effect";
|
|
10
|
+
import * as Option from "effect/Option";
|
|
11
|
+
import * as Predicate from "effect/Predicate";
|
|
12
|
+
// src/compat/state.ts
|
|
13
|
+
/**
|
|
14
|
+
* A `prosemirror-state`-compatible facade over `@thomasfosterau/effect-richtext/state`.
|
|
15
|
+
*
|
|
16
|
+
* `Selection` can be subclassed like ProseMirror's: a subclass of the
|
|
17
|
+
* facade `Selection` is adapted into a core selection that calls back
|
|
18
|
+
* into it. Plugins are written with ProseMirror's plugin spec (hooks
|
|
19
|
+
* and props receive facades) and bridged to core plugins. Commands are
|
|
20
|
+
* plain `(state, dispatch?, view?) => boolean` functions;
|
|
21
|
+
* `fromCoreCommand` / `toCoreCommand` convert between them and core
|
|
22
|
+
* commands.
|
|
23
|
+
*
|
|
24
|
+
* Ported API surface from prosemirror-state (MIT, Marijn Haverbeke and others).
|
|
25
|
+
*
|
|
26
|
+
* @since 0.1.0
|
|
27
|
+
*/
|
|
28
|
+
const INTERNAL = Symbol("effect-richtext/compat/internal");
|
|
29
|
+
/**
|
|
30
|
+
* Represents a selected range in a document.
|
|
31
|
+
*
|
|
32
|
+
* @since 0.1.0
|
|
33
|
+
* @category models
|
|
34
|
+
*/
|
|
35
|
+
var SelectionRange = class {
|
|
36
|
+
/** Create a range. */
|
|
37
|
+
constructor($from, $to) {
|
|
38
|
+
link(this, new SelectionRange$1($from[CORE], $to[CORE]));
|
|
39
|
+
}
|
|
40
|
+
/** The lower bound of the range. */
|
|
41
|
+
get $from() {
|
|
42
|
+
return wrap(this[CORE].$from);
|
|
43
|
+
}
|
|
44
|
+
/** The upper bound of the range. */
|
|
45
|
+
get $to() {
|
|
46
|
+
return wrap(this[CORE].$to);
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
registerWrapper(SelectionRange$1, (core) => adopt(SelectionRange.prototype, core));
|
|
50
|
+
var BookmarkFacade = class {
|
|
51
|
+
map(mapping) {
|
|
52
|
+
return bookmarkFromCore(this[CORE].map(unwrap(mapping)));
|
|
53
|
+
}
|
|
54
|
+
resolve(doc) {
|
|
55
|
+
return wrap(this[CORE].resolve(doc[CORE]));
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
const bookmarkFacades = /* @__PURE__ */ new WeakMap();
|
|
59
|
+
const bookmarkCores = /* @__PURE__ */ new WeakMap();
|
|
60
|
+
const bookmarkFromCore = (core) => {
|
|
61
|
+
let found = bookmarkFacades.get(core);
|
|
62
|
+
if (!found) {
|
|
63
|
+
if (core[ADAPTED_BOOKMARK]) return core[ADAPTED_BOOKMARK];
|
|
64
|
+
found = link(new BookmarkFacade(), core);
|
|
65
|
+
bookmarkFacades.set(core, found);
|
|
66
|
+
}
|
|
67
|
+
return found;
|
|
68
|
+
};
|
|
69
|
+
const ADAPTED_BOOKMARK = Symbol("effect-richtext/compat/bookmark");
|
|
70
|
+
const bookmarkToCore = (bookmark) => {
|
|
71
|
+
if (isFacade(bookmark)) return bookmark[CORE];
|
|
72
|
+
let found = bookmarkCores.get(bookmark);
|
|
73
|
+
if (!found) {
|
|
74
|
+
found = {
|
|
75
|
+
[ADAPTED_BOOKMARK]: bookmark,
|
|
76
|
+
map: (mapping) => bookmarkToCore(bookmark.map(wrap(mapping))),
|
|
77
|
+
resolve: (doc) => bookmark.resolve(wrap(doc))[CORE]
|
|
78
|
+
};
|
|
79
|
+
bookmarkCores.set(bookmark, found);
|
|
80
|
+
}
|
|
81
|
+
return found;
|
|
82
|
+
};
|
|
83
|
+
/**
|
|
84
|
+
* Superclass for editor selections. Subclass it to define custom
|
|
85
|
+
* selection types: subclasses are adapted into core selections.
|
|
86
|
+
*
|
|
87
|
+
* @since 0.1.0
|
|
88
|
+
* @category models
|
|
89
|
+
*/
|
|
90
|
+
var Selection = class {
|
|
91
|
+
/** Initialize a selection with the head and anchor and ranges. */
|
|
92
|
+
constructor($anchor, $head, ranges) {
|
|
93
|
+
if ($anchor === INTERNAL) {
|
|
94
|
+
const [CoreClass, args] = $head;
|
|
95
|
+
link(this, guard(() => coreSelection(this, new.target, CoreClass, args)));
|
|
96
|
+
} else {
|
|
97
|
+
const args = [
|
|
98
|
+
$anchor[CORE],
|
|
99
|
+
$head[CORE],
|
|
100
|
+
ranges && unwrapArray(ranges)
|
|
101
|
+
];
|
|
102
|
+
link(this, coreSelection(this, new.target, Selection$1, args));
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/** The ranges covered by the selection. */
|
|
106
|
+
get ranges() {
|
|
107
|
+
return wrapArray(this[CORE].ranges);
|
|
108
|
+
}
|
|
109
|
+
/** The resolved anchor of the selection. */
|
|
110
|
+
get $anchor() {
|
|
111
|
+
return wrap(this[CORE].$anchor);
|
|
112
|
+
}
|
|
113
|
+
/** The resolved head of the selection. */
|
|
114
|
+
get $head() {
|
|
115
|
+
return wrap(this[CORE].$head);
|
|
116
|
+
}
|
|
117
|
+
/** The selection's anchor, as an unresolved position. */
|
|
118
|
+
get anchor() {
|
|
119
|
+
return this[CORE].anchor;
|
|
120
|
+
}
|
|
121
|
+
/** The selection's head. */
|
|
122
|
+
get head() {
|
|
123
|
+
return this[CORE].head;
|
|
124
|
+
}
|
|
125
|
+
/** The lower bound of the selection's main range. */
|
|
126
|
+
get from() {
|
|
127
|
+
return this[CORE].from;
|
|
128
|
+
}
|
|
129
|
+
/** The upper bound of the selection's main range. */
|
|
130
|
+
get to() {
|
|
131
|
+
return this[CORE].to;
|
|
132
|
+
}
|
|
133
|
+
/** The resolved lower bound of the selection's main range. */
|
|
134
|
+
get $from() {
|
|
135
|
+
return wrap(this[CORE].$from);
|
|
136
|
+
}
|
|
137
|
+
/** The resolved upper bound of the selection's main range. */
|
|
138
|
+
get $to() {
|
|
139
|
+
return wrap(this[CORE].$to);
|
|
140
|
+
}
|
|
141
|
+
/** Indicates whether the selection contains any content. */
|
|
142
|
+
get empty() {
|
|
143
|
+
return this[CORE].empty;
|
|
144
|
+
}
|
|
145
|
+
/** Controls whether, when a selection of this type is active in the browser, the selected range should be visible to the user. */
|
|
146
|
+
get visible() {
|
|
147
|
+
return getBase(this[CORE], "visible");
|
|
148
|
+
}
|
|
149
|
+
/** Get the content of this selection as a slice. */
|
|
150
|
+
content() {
|
|
151
|
+
return wrap(guard(() => callBase(this[CORE], "content")));
|
|
152
|
+
}
|
|
153
|
+
/** Replace the selection with a slice or, if no slice is given, delete the selection. */
|
|
154
|
+
replace(tr, content = Slice.empty) {
|
|
155
|
+
guard(() => callBase(this[CORE], "replace", [tr[CORE], content[CORE]]));
|
|
156
|
+
}
|
|
157
|
+
/** Replace the selection with the given node, appending the changes to the given transaction. */
|
|
158
|
+
replaceWith(tr, node) {
|
|
159
|
+
guard(() => callBase(this[CORE], "replaceWith", [tr[CORE], node[CORE]]));
|
|
160
|
+
}
|
|
161
|
+
/** Find a valid cursor or leaf node selection starting at the given position and searching back if `dir` is negative, and forward if positive. */
|
|
162
|
+
static findFrom($pos, dir, textOnly = false) {
|
|
163
|
+
return wrap(guard(() => Selection$1.findFromOrNull($pos[CORE], dir, textOnly)));
|
|
164
|
+
}
|
|
165
|
+
/** Find a valid cursor or leaf node selection near the given position. */
|
|
166
|
+
static near($pos, bias = 1) {
|
|
167
|
+
return wrap(guard(() => Selection$1.near($pos[CORE], bias)));
|
|
168
|
+
}
|
|
169
|
+
/** Find the cursor or leaf node selection closest to the start of the given document. */
|
|
170
|
+
static atStart(doc) {
|
|
171
|
+
return wrap(guard(() => Selection$1.atStart(doc[CORE])));
|
|
172
|
+
}
|
|
173
|
+
/** Find the cursor or leaf node selection closest to the end of the given document. */
|
|
174
|
+
static atEnd(doc) {
|
|
175
|
+
return wrap(guard(() => Selection$1.atEnd(doc[CORE])));
|
|
176
|
+
}
|
|
177
|
+
/** Deserialize the JSON representation of a selection. */
|
|
178
|
+
static fromJSON(doc, json) {
|
|
179
|
+
return wrap(guard(() => Selection$1.fromJSONUnsafe(doc[CORE], json)));
|
|
180
|
+
}
|
|
181
|
+
/** To be able to deserialize selections from JSON, custom selection classes must register themselves with an ID string. */
|
|
182
|
+
static jsonID(id, selectionClass) {
|
|
183
|
+
try {
|
|
184
|
+
Selection$1.jsonID(id, { fromJSONUnsafe: (doc, json) => selectionClass.fromJSON(wrap(doc), json)[CORE] });
|
|
185
|
+
} catch (e) {
|
|
186
|
+
throw new RangeError(e.message);
|
|
187
|
+
}
|
|
188
|
+
selectionClass.prototype.jsonID = id;
|
|
189
|
+
return selectionClass;
|
|
190
|
+
}
|
|
191
|
+
/** Get a bookmark for this selection. */
|
|
192
|
+
getBookmark() {
|
|
193
|
+
return bookmarkFromCore(callBase(this[CORE], "getBookmark"));
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
const getterOf = (proto, prop) => {
|
|
197
|
+
for (; proto; proto = Object.getPrototypeOf(proto)) {
|
|
198
|
+
const desc = Object.getOwnPropertyDescriptor(proto, prop);
|
|
199
|
+
if (desc) return desc.get;
|
|
200
|
+
}
|
|
201
|
+
};
|
|
202
|
+
const adaptedSelectionClasses = /* @__PURE__ */ new WeakMap();
|
|
203
|
+
/**
|
|
204
|
+
* The core class used for instances of user subclasses of a facade
|
|
205
|
+
* selection class: a subclass of the corresponding core class whose
|
|
206
|
+
* methods call the facade's overrides, when it has them. @internal
|
|
207
|
+
*/
|
|
208
|
+
const adaptedSelectionClass = (CoreClass, FacadeClass) => {
|
|
209
|
+
let found = adaptedSelectionClasses.get(CoreClass);
|
|
210
|
+
if (!found) {
|
|
211
|
+
const base = FacadeClass.prototype, baseVisible = getterOf(base, "visible");
|
|
212
|
+
found = class extends CoreClass {
|
|
213
|
+
get visible() {
|
|
214
|
+
const get = getterOf(Object.getPrototypeOf(this.facade), "visible");
|
|
215
|
+
return get && get !== baseVisible ? get.call(this.facade) : super.visible;
|
|
216
|
+
}
|
|
217
|
+
eq(other) {
|
|
218
|
+
return this.facade.eq === base.eq ? super.eq(other) : this.facade.eq(wrap(other));
|
|
219
|
+
}
|
|
220
|
+
map(doc, mapping) {
|
|
221
|
+
return this.facade.map === base.map ? super.map(doc, mapping) : this.facade.map(wrap(doc), wrap(mapping))[CORE];
|
|
222
|
+
}
|
|
223
|
+
content() {
|
|
224
|
+
return this.facade.content === base.content ? super.content() : this.facade.content()[CORE];
|
|
225
|
+
}
|
|
226
|
+
replace(tr, content) {
|
|
227
|
+
if (this.facade.replace === base.replace) super.replace(tr, content);
|
|
228
|
+
else this.facade.replace(wrap(tr), content === void 0 ? Slice.empty : wrap(content));
|
|
229
|
+
}
|
|
230
|
+
replaceWith(tr, node) {
|
|
231
|
+
if (this.facade.replaceWith === base.replaceWith) super.replaceWith(tr, node);
|
|
232
|
+
else this.facade.replaceWith(wrap(tr), wrap(node));
|
|
233
|
+
}
|
|
234
|
+
toJSON() {
|
|
235
|
+
return this.facade.toJSON === base.toJSON ? super.toJSON() : this.facade.toJSON();
|
|
236
|
+
}
|
|
237
|
+
getBookmark() {
|
|
238
|
+
return this.facade.getBookmark === base.getBookmark ? super.getBookmark() : bookmarkToCore(this.facade.getBookmark());
|
|
239
|
+
}
|
|
240
|
+
};
|
|
241
|
+
found.prototype[BASE] = CoreClass.prototype;
|
|
242
|
+
adaptedSelectionClasses.set(CoreClass, found);
|
|
243
|
+
}
|
|
244
|
+
return found;
|
|
245
|
+
};
|
|
246
|
+
const coreSelection = (facade, target, CoreClass, args) => {
|
|
247
|
+
const FacadeClass = CoreClass === TextSelection$1 ? TextSelection : CoreClass === NodeSelection$1 ? NodeSelection : CoreClass === AllSelection$1 ? AllSelection : Selection;
|
|
248
|
+
if (target === FacadeClass) return new CoreClass(...args);
|
|
249
|
+
const core = new (adaptedSelectionClass(CoreClass, FacadeClass))(...args);
|
|
250
|
+
core.facade = facade;
|
|
251
|
+
return core;
|
|
252
|
+
};
|
|
253
|
+
/**
|
|
254
|
+
* A text selection represents a classical editor selection, with a
|
|
255
|
+
* head (the moving side) and anchor (immobile side), both of which
|
|
256
|
+
* point into textblock nodes.
|
|
257
|
+
*
|
|
258
|
+
* @since 0.1.0
|
|
259
|
+
* @category models
|
|
260
|
+
*/
|
|
261
|
+
var TextSelection = class extends Selection {
|
|
262
|
+
/** Construct a text selection between the given points. */
|
|
263
|
+
constructor($anchor, $head = $anchor) {
|
|
264
|
+
super(INTERNAL, [TextSelection$1, [$anchor[CORE], $head[CORE]]]);
|
|
265
|
+
}
|
|
266
|
+
/** Returns a resolved position if this is a cursor selection (an empty text selection), and null otherwise. */
|
|
267
|
+
get $cursor() {
|
|
268
|
+
return wrap(this[CORE].$cursorOrNull);
|
|
269
|
+
}
|
|
270
|
+
map(doc, mapping) {
|
|
271
|
+
return wrap(guard(() => callBase(this[CORE], "map", [doc[CORE], unwrap(mapping)])));
|
|
272
|
+
}
|
|
273
|
+
eq(other) {
|
|
274
|
+
return callBase(this[CORE], "eq", [other[CORE]]);
|
|
275
|
+
}
|
|
276
|
+
toJSON() {
|
|
277
|
+
return callBase(this[CORE], "toJSON");
|
|
278
|
+
}
|
|
279
|
+
/** @internal */
|
|
280
|
+
static fromJSON(doc, json) {
|
|
281
|
+
return wrap(guard(() => TextSelection$1.fromJSONUnsafe(doc[CORE], json)));
|
|
282
|
+
}
|
|
283
|
+
/** Create a text selection from non-resolved positions. */
|
|
284
|
+
static create(doc, anchor, head = anchor) {
|
|
285
|
+
return wrap(guard(() => TextSelection$1.createUnsafe(doc[CORE], anchor, head)));
|
|
286
|
+
}
|
|
287
|
+
/** Return a text selection that spans the given positions or, if they aren't text positions, find a text selection near them. */
|
|
288
|
+
static between($anchor, $head, bias) {
|
|
289
|
+
return wrap(guard(() => TextSelection$1.between($anchor[CORE], $head[CORE], bias)));
|
|
290
|
+
}
|
|
291
|
+
};
|
|
292
|
+
/**
|
|
293
|
+
* A node selection is a selection that points at a single node.
|
|
294
|
+
*
|
|
295
|
+
* @since 0.1.0
|
|
296
|
+
* @category models
|
|
297
|
+
*/
|
|
298
|
+
var NodeSelection = class extends Selection {
|
|
299
|
+
/** Create a node selection. Does not verify the validity of its argument. */
|
|
300
|
+
constructor($pos) {
|
|
301
|
+
super(INTERNAL, [NodeSelection$1, [$pos[CORE]]]);
|
|
302
|
+
}
|
|
303
|
+
/** The selected node. */
|
|
304
|
+
get node() {
|
|
305
|
+
return wrap(this[CORE].node);
|
|
306
|
+
}
|
|
307
|
+
map(doc, mapping) {
|
|
308
|
+
return wrap(guard(() => callBase(this[CORE], "map", [doc[CORE], unwrap(mapping)])));
|
|
309
|
+
}
|
|
310
|
+
eq(other) {
|
|
311
|
+
return callBase(this[CORE], "eq", [other[CORE]]);
|
|
312
|
+
}
|
|
313
|
+
toJSON() {
|
|
314
|
+
return callBase(this[CORE], "toJSON");
|
|
315
|
+
}
|
|
316
|
+
/** @internal */
|
|
317
|
+
static fromJSON(doc, json) {
|
|
318
|
+
return wrap(guard(() => NodeSelection$1.fromJSONUnsafe(doc[CORE], json)));
|
|
319
|
+
}
|
|
320
|
+
/** Create a node selection from non-resolved positions. */
|
|
321
|
+
static create(doc, from) {
|
|
322
|
+
return wrap(guard(() => NodeSelection$1.createUnsafe(doc[CORE], from)));
|
|
323
|
+
}
|
|
324
|
+
/** Determines whether the given node may be selected as a node selection. */
|
|
325
|
+
static isSelectable(node) {
|
|
326
|
+
return NodeSelection$1.isSelectable(node[CORE]);
|
|
327
|
+
}
|
|
328
|
+
};
|
|
329
|
+
/**
|
|
330
|
+
* A selection type that represents selecting the whole document.
|
|
331
|
+
*
|
|
332
|
+
* @since 0.1.0
|
|
333
|
+
* @category models
|
|
334
|
+
*/
|
|
335
|
+
var AllSelection = class extends Selection {
|
|
336
|
+
/** Create an all-selection over the given document. */
|
|
337
|
+
constructor(doc) {
|
|
338
|
+
super(INTERNAL, [AllSelection$1, [doc[CORE]]]);
|
|
339
|
+
}
|
|
340
|
+
map(doc) {
|
|
341
|
+
return wrap(callBase(this[CORE], "map", [doc[CORE]]));
|
|
342
|
+
}
|
|
343
|
+
eq(other) {
|
|
344
|
+
return callBase(this[CORE], "eq", [other[CORE]]);
|
|
345
|
+
}
|
|
346
|
+
toJSON() {
|
|
347
|
+
return callBase(this[CORE], "toJSON");
|
|
348
|
+
}
|
|
349
|
+
};
|
|
350
|
+
registerWrapper(TextSelection$1, (core) => adopt(TextSelection.prototype, core));
|
|
351
|
+
registerWrapper(NodeSelection$1, (core) => adopt(NodeSelection.prototype, core));
|
|
352
|
+
registerWrapper(AllSelection$1, (core) => adopt(AllSelection.prototype, core));
|
|
353
|
+
const metaKey = (key) => typeof key === "string" ? key : key.key;
|
|
354
|
+
/**
|
|
355
|
+
* An editor state transaction, which can be applied to a state to
|
|
356
|
+
* create an updated state.
|
|
357
|
+
*
|
|
358
|
+
* @since 0.1.0
|
|
359
|
+
* @category models
|
|
360
|
+
*/
|
|
361
|
+
var Transaction = class extends Transform {
|
|
362
|
+
/** @internal */
|
|
363
|
+
constructor(state) {
|
|
364
|
+
super(state.doc);
|
|
365
|
+
link(this, new Transaction$1(state[CORE]));
|
|
366
|
+
}
|
|
367
|
+
/** The timestamp associated with this transaction. */
|
|
368
|
+
get time() {
|
|
369
|
+
return this[CORE].time;
|
|
370
|
+
}
|
|
371
|
+
set time(value) {
|
|
372
|
+
this[CORE].time = value;
|
|
373
|
+
}
|
|
374
|
+
/** The stored marks set by this transaction, if any. */
|
|
375
|
+
get storedMarks() {
|
|
376
|
+
const marks = this[CORE].storedMarksOrNull;
|
|
377
|
+
return marks && wrapArray(marks);
|
|
378
|
+
}
|
|
379
|
+
/** The transaction's current selection. */
|
|
380
|
+
get selection() {
|
|
381
|
+
return wrap(this[CORE].selection);
|
|
382
|
+
}
|
|
383
|
+
/** Update the transaction's current selection. */
|
|
384
|
+
setSelection(selection) {
|
|
385
|
+
guard(() => this[CORE].setSelectionUnsafe(selection[CORE]));
|
|
386
|
+
return this;
|
|
387
|
+
}
|
|
388
|
+
/** Whether the selection was explicitly updated by this transaction. */
|
|
389
|
+
get selectionSet() {
|
|
390
|
+
return this[CORE].selectionSet;
|
|
391
|
+
}
|
|
392
|
+
/** Set the current stored marks. */
|
|
393
|
+
setStoredMarks(marks) {
|
|
394
|
+
this[CORE].setStoredMarks(marks && unwrapArray(marks));
|
|
395
|
+
return this;
|
|
396
|
+
}
|
|
397
|
+
/** Make sure the current stored marks or, if that is null, the marks at the selection, match the given set of marks. */
|
|
398
|
+
ensureMarks(marks) {
|
|
399
|
+
this[CORE].ensureMarks(unwrapArray(marks));
|
|
400
|
+
return this;
|
|
401
|
+
}
|
|
402
|
+
/** Add a mark to the set of stored marks. */
|
|
403
|
+
addStoredMark(mark) {
|
|
404
|
+
this[CORE].addStoredMark(mark[CORE]);
|
|
405
|
+
return this;
|
|
406
|
+
}
|
|
407
|
+
/** Remove a mark or mark type from the set of stored marks. */
|
|
408
|
+
removeStoredMark(mark) {
|
|
409
|
+
this[CORE].removeStoredMark(mark[CORE]);
|
|
410
|
+
return this;
|
|
411
|
+
}
|
|
412
|
+
/** Whether the stored marks were explicitly set for this transaction. */
|
|
413
|
+
get storedMarksSet() {
|
|
414
|
+
return this[CORE].storedMarksSet;
|
|
415
|
+
}
|
|
416
|
+
/** Update the timestamp for the transaction. */
|
|
417
|
+
setTime(time) {
|
|
418
|
+
this[CORE].setTime(time);
|
|
419
|
+
return this;
|
|
420
|
+
}
|
|
421
|
+
/** Replace the current selection with the given slice. */
|
|
422
|
+
replaceSelection(slice) {
|
|
423
|
+
guard(() => this[CORE].replaceSelection(slice[CORE]));
|
|
424
|
+
return this;
|
|
425
|
+
}
|
|
426
|
+
/** Replace the selection with the given node. */
|
|
427
|
+
replaceSelectionWith(node, inheritMarks = true) {
|
|
428
|
+
guard(() => this[CORE].replaceSelectionWith(node[CORE], inheritMarks));
|
|
429
|
+
return this;
|
|
430
|
+
}
|
|
431
|
+
/** Delete the selection. */
|
|
432
|
+
deleteSelection() {
|
|
433
|
+
guard(() => this[CORE].deleteSelection());
|
|
434
|
+
return this;
|
|
435
|
+
}
|
|
436
|
+
/** Replace the given range, or the selection if no range is given, with a text node containing the given string. */
|
|
437
|
+
insertText(text, from, to) {
|
|
438
|
+
guard(() => this[CORE].insertTextUnsafe(text, from, to));
|
|
439
|
+
return this;
|
|
440
|
+
}
|
|
441
|
+
/** Store a metadata property in this transaction, keyed either by name or by plugin. */
|
|
442
|
+
setMeta(key, value) {
|
|
443
|
+
this[CORE].setMeta(metaKey(key), value);
|
|
444
|
+
return this;
|
|
445
|
+
}
|
|
446
|
+
/** Retrieve a metadata property for a given name or plugin. */
|
|
447
|
+
getMeta(key) {
|
|
448
|
+
return wrap(Option.getOrUndefined(this[CORE].getMeta(metaKey(key))));
|
|
449
|
+
}
|
|
450
|
+
/** Returns true if this transaction doesn't contain any metadata, and can thus safely be extended. */
|
|
451
|
+
get isGeneric() {
|
|
452
|
+
return this[CORE].isGeneric;
|
|
453
|
+
}
|
|
454
|
+
/** Indicate that the editor should scroll the selection into view when updated to the state produced by this transaction. */
|
|
455
|
+
scrollIntoView() {
|
|
456
|
+
this[CORE].scrollIntoView();
|
|
457
|
+
return this;
|
|
458
|
+
}
|
|
459
|
+
/** True when this transaction has had `scrollIntoView` called on it. */
|
|
460
|
+
get scrolledIntoView() {
|
|
461
|
+
return this[CORE].scrolledIntoView;
|
|
462
|
+
}
|
|
463
|
+
};
|
|
464
|
+
registerWrapper(Transaction$1, (core) => adopt(Transaction.prototype, core));
|
|
465
|
+
function bindProps(obj, self, target) {
|
|
466
|
+
for (const prop in obj) {
|
|
467
|
+
let val = obj[prop];
|
|
468
|
+
if (Predicate.isFunction(val)) val = val.bind(self);
|
|
469
|
+
else if (prop === "handleDOMEvents") val = bindProps(val, self, {});
|
|
470
|
+
target[prop] = val;
|
|
471
|
+
}
|
|
472
|
+
return target;
|
|
473
|
+
}
|
|
474
|
+
const configs = /* @__PURE__ */ new WeakMap();
|
|
475
|
+
const facadeConfig = (config) => configs.get(config) ?? config;
|
|
476
|
+
const pluginViewToCore = (pluginView) => ({
|
|
477
|
+
get update() {
|
|
478
|
+
return pluginView.update && ((view, prevState) => pluginView.update(wrap(view), wrap(prevState)));
|
|
479
|
+
},
|
|
480
|
+
get destroy() {
|
|
481
|
+
return pluginView.destroy && (() => pluginView.destroy());
|
|
482
|
+
}
|
|
483
|
+
});
|
|
484
|
+
const pluginSpecToCore = (spec, self) => {
|
|
485
|
+
const result = { ...spec };
|
|
486
|
+
result.key = spec.key && spec.key[CORE];
|
|
487
|
+
const state = spec.state;
|
|
488
|
+
if (state) result.state = {
|
|
489
|
+
init: (config, instance) => state.init.call(self, facadeConfig(config), wrap(instance)),
|
|
490
|
+
apply: (tr, value, oldState, newState) => state.apply.call(self, wrap(tr), value, wrap(oldState), wrap(newState)),
|
|
491
|
+
toJSON: state.toJSON && ((value) => state.toJSON.call(self, value)),
|
|
492
|
+
fromJSON: state.fromJSON && ((config, value, instance) => state.fromJSON.call(self, facadeConfig(config), value, wrap(instance)))
|
|
493
|
+
};
|
|
494
|
+
const filter = spec.filterTransaction;
|
|
495
|
+
if (filter) result.filterTransaction = (tr, s) => filter.call(self, wrap(tr), wrap(s));
|
|
496
|
+
const append = spec.appendTransaction;
|
|
497
|
+
if (append) result.appendTransaction = (trs, oldState, newState) => unwrap(append.call(self, trs.map(wrap), wrap(oldState), wrap(newState)));
|
|
498
|
+
const view = spec.view;
|
|
499
|
+
if (view) result.view = (v) => pluginViewToCore(view.call(self, wrap(v)));
|
|
500
|
+
result.props = spec.props ? propsToCore(spec.props, self) : void 0;
|
|
501
|
+
return result;
|
|
502
|
+
};
|
|
503
|
+
/**
|
|
504
|
+
* Plugins bundle functionality that can be added to an editor.
|
|
505
|
+
*
|
|
506
|
+
* @since 0.1.0
|
|
507
|
+
* @category models
|
|
508
|
+
*/
|
|
509
|
+
var Plugin = class {
|
|
510
|
+
/** Create a plugin. */
|
|
511
|
+
constructor(spec) {
|
|
512
|
+
this.spec = spec;
|
|
513
|
+
this.props = {};
|
|
514
|
+
if (spec.props) bindProps(spec.props, this, this.props);
|
|
515
|
+
link(this, guard(() => new Plugin$1(pluginSpecToCore(spec, this))));
|
|
516
|
+
}
|
|
517
|
+
/** @internal */
|
|
518
|
+
get key() {
|
|
519
|
+
return this[CORE].key;
|
|
520
|
+
}
|
|
521
|
+
/** Extract the plugin's state field from an editor state. */
|
|
522
|
+
getState(state) {
|
|
523
|
+
return state[CORE].slots[this.key];
|
|
524
|
+
}
|
|
525
|
+
};
|
|
526
|
+
registerWrapper(Plugin$1, (core) => {
|
|
527
|
+
const plugin = adopt(Plugin.prototype, core);
|
|
528
|
+
plugin.spec = core.spec;
|
|
529
|
+
plugin.props = propsFromCore(core.props, core);
|
|
530
|
+
return plugin;
|
|
531
|
+
});
|
|
532
|
+
/**
|
|
533
|
+
* A key is used to tag plugins in a way that makes it possible to find
|
|
534
|
+
* them, given an editor state.
|
|
535
|
+
*
|
|
536
|
+
* @since 0.1.0
|
|
537
|
+
* @category models
|
|
538
|
+
*/
|
|
539
|
+
var PluginKey = class {
|
|
540
|
+
/** Create a plugin key. */
|
|
541
|
+
constructor(name = "key") {
|
|
542
|
+
link(this, new PluginKey$1(name));
|
|
543
|
+
}
|
|
544
|
+
/** @internal */
|
|
545
|
+
get key() {
|
|
546
|
+
return this[CORE].key;
|
|
547
|
+
}
|
|
548
|
+
/** Get the active plugin with this key, if any, from an editor state. */
|
|
549
|
+
get(state) {
|
|
550
|
+
return wrap(state[CORE].config.pluginsByKey[this.key]);
|
|
551
|
+
}
|
|
552
|
+
/** Get the plugin's state from an editor state. */
|
|
553
|
+
getState(state) {
|
|
554
|
+
return state[CORE].slots[this.key];
|
|
555
|
+
}
|
|
556
|
+
};
|
|
557
|
+
registerWrapper(PluginKey$1, (core) => adopt(PluginKey.prototype, core));
|
|
558
|
+
const configToCore = (config) => {
|
|
559
|
+
const result = { ...config };
|
|
560
|
+
if (config.schema) result.schema = config.schema[CORE];
|
|
561
|
+
if (config.doc) result.doc = config.doc[CORE];
|
|
562
|
+
if (config.selection) result.selection = config.selection[CORE];
|
|
563
|
+
if (config.storedMarks) result.storedMarks = unwrapArray(config.storedMarks);
|
|
564
|
+
if (config.plugins) result.plugins = config.plugins.map(unwrap);
|
|
565
|
+
configs.set(result, config);
|
|
566
|
+
return result;
|
|
567
|
+
};
|
|
568
|
+
/**
|
|
569
|
+
* The state of a ProseMirror editor.
|
|
570
|
+
*
|
|
571
|
+
* @since 0.1.0
|
|
572
|
+
* @category models
|
|
573
|
+
*/
|
|
574
|
+
var EditorState = class {
|
|
575
|
+
/** @internal */
|
|
576
|
+
constructor() {}
|
|
577
|
+
/** The current document. */
|
|
578
|
+
get doc() {
|
|
579
|
+
return wrap(this[CORE].doc);
|
|
580
|
+
}
|
|
581
|
+
/** The selection. */
|
|
582
|
+
get selection() {
|
|
583
|
+
return wrap(this[CORE].selection);
|
|
584
|
+
}
|
|
585
|
+
/** A set of marks to apply to the next input. Will be null when no explicit marks have been set. */
|
|
586
|
+
get storedMarks() {
|
|
587
|
+
const marks = this[CORE].storedMarksOrNull;
|
|
588
|
+
return marks && wrapArray(marks);
|
|
589
|
+
}
|
|
590
|
+
/** @internal */
|
|
591
|
+
get scrollToSelection() {
|
|
592
|
+
return this[CORE].scrollToSelection;
|
|
593
|
+
}
|
|
594
|
+
/** The schema of the state's document. */
|
|
595
|
+
get schema() {
|
|
596
|
+
return wrap(this[CORE].schema);
|
|
597
|
+
}
|
|
598
|
+
/** The plugins that are active in this state. */
|
|
599
|
+
get plugins() {
|
|
600
|
+
return wrapArray(this[CORE].plugins);
|
|
601
|
+
}
|
|
602
|
+
/** Apply the given transaction to produce a new state. */
|
|
603
|
+
apply(tr) {
|
|
604
|
+
return this.applyTransaction(tr).state;
|
|
605
|
+
}
|
|
606
|
+
/** @internal */
|
|
607
|
+
filterTransaction(tr, ignore = -1) {
|
|
608
|
+
return runSync(this[CORE].filterTransaction(tr[CORE], ignore));
|
|
609
|
+
}
|
|
610
|
+
/** Verbose variant of `apply` that returns the precise transactions that were applied and the new state. */
|
|
611
|
+
applyTransaction(rootTr) {
|
|
612
|
+
const result = runSync(this[CORE].applyTransaction(rootTr[CORE]));
|
|
613
|
+
return {
|
|
614
|
+
state: wrap(result.state),
|
|
615
|
+
transactions: result.transactions.map(wrap)
|
|
616
|
+
};
|
|
617
|
+
}
|
|
618
|
+
/** Start a transaction from this state. */
|
|
619
|
+
get tr() {
|
|
620
|
+
return wrap(this[CORE].tr);
|
|
621
|
+
}
|
|
622
|
+
/** Create a new state based on this one, but with an adjusted set of active plugins. */
|
|
623
|
+
reconfigure(config) {
|
|
624
|
+
return wrap(runSync(this[CORE].reconfigure(configToCore(config))));
|
|
625
|
+
}
|
|
626
|
+
/** Serialize this state to JSON. */
|
|
627
|
+
toJSON(pluginFields) {
|
|
628
|
+
let fields;
|
|
629
|
+
if (pluginFields && typeof pluginFields == "object") {
|
|
630
|
+
fields = {};
|
|
631
|
+
for (const prop in pluginFields) fields[prop] = unwrap(pluginFields[prop]);
|
|
632
|
+
}
|
|
633
|
+
return guard(() => this[CORE].toJSON(fields));
|
|
634
|
+
}
|
|
635
|
+
/** Create a new state. */
|
|
636
|
+
static create(config) {
|
|
637
|
+
return wrap(runSync(EditorState$1.create(configToCore(config))));
|
|
638
|
+
}
|
|
639
|
+
/** Deserialize a JSON representation of a state. */
|
|
640
|
+
static fromJSON(config, json, pluginFields) {
|
|
641
|
+
const fields = pluginFields && {};
|
|
642
|
+
if (pluginFields) for (const prop in pluginFields) fields[prop] = unwrap(pluginFields[prop]);
|
|
643
|
+
return wrap(runSync(EditorState$1.fromJSON(configToCore(config), json, fields)));
|
|
644
|
+
}
|
|
645
|
+
};
|
|
646
|
+
registerWrapper(EditorState$1, (core) => adopt(EditorState.prototype, core));
|
|
647
|
+
const pmCommands = /* @__PURE__ */ new WeakMap();
|
|
648
|
+
const coreCommands = /* @__PURE__ */ new WeakMap();
|
|
649
|
+
/**
|
|
650
|
+
* Convert a core (Effect) command into a ProseMirror-style command. The
|
|
651
|
+
* command is run synchronously; failures are thrown.
|
|
652
|
+
*
|
|
653
|
+
* @since 0.1.0
|
|
654
|
+
* @category conversions
|
|
655
|
+
*/
|
|
656
|
+
const fromCoreCommand = (command) => {
|
|
657
|
+
let found = pmCommands.get(command);
|
|
658
|
+
if (!found) {
|
|
659
|
+
found = (state, dispatch, view) => runSync(command(state[CORE], dispatch && ((tr) => Effect.sync(() => dispatch(wrap(tr)))), view && unwrap(view)));
|
|
660
|
+
pmCommands.set(command, found);
|
|
661
|
+
coreCommands.set(found, command);
|
|
662
|
+
}
|
|
663
|
+
return found;
|
|
664
|
+
};
|
|
665
|
+
/**
|
|
666
|
+
* Convert a ProseMirror-style command into a core (Effect) command.
|
|
667
|
+
*
|
|
668
|
+
* @since 0.1.0
|
|
669
|
+
* @category conversions
|
|
670
|
+
*/
|
|
671
|
+
const toCoreCommand = (command) => {
|
|
672
|
+
let found = coreCommands.get(command);
|
|
673
|
+
if (!found) {
|
|
674
|
+
found = (state, dispatch, view) => Effect.sync(() => command(wrap(state), dispatch && ((tr) => runSync(dispatch(tr[CORE]))), view && wrap(view)));
|
|
675
|
+
coreCommands.set(command, found);
|
|
676
|
+
pmCommands.set(found, command);
|
|
677
|
+
}
|
|
678
|
+
return found;
|
|
679
|
+
};
|
|
680
|
+
function toCore(value) {
|
|
681
|
+
if (typeof value === "function") return toCoreCommand(value);
|
|
682
|
+
if (value instanceof BookmarkFacade || value && !isFacade(value) && typeof value.resolve === "function") return bookmarkToCore(value);
|
|
683
|
+
return unwrap(value);
|
|
684
|
+
}
|
|
685
|
+
function fromCore(value) {
|
|
686
|
+
if (typeof value === "function") return fromCoreCommand(value);
|
|
687
|
+
return wrap(value);
|
|
688
|
+
}
|
|
689
|
+
export { AllSelection, EditorState, NodeSelection, Plugin, PluginKey, Selection, SelectionRange, TextSelection, Transaction, fromCore, fromCoreCommand, toCore, toCoreCommand };
|