@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.
Files changed (176) hide show
  1. package/LICENSE +48 -0
  2. package/README.md +117 -1
  3. package/dist/_virtual/_rolldown/runtime.js +12 -0
  4. package/dist/commands/commands.d.ts +323 -0
  5. package/dist/commands/commands.js +722 -0
  6. package/dist/commands/internal.js +43 -0
  7. package/dist/commands/keymaps.d.ts +46 -0
  8. package/dist/commands/keymaps.js +64 -0
  9. package/dist/commands.d.ts +3 -0
  10. package/dist/commands.js +3 -0
  11. package/dist/compat/commands.d.ts +250 -0
  12. package/dist/compat/commands.js +275 -0
  13. package/dist/compat/internal/core.d.ts +20 -0
  14. package/dist/compat/internal/core.js +148 -0
  15. package/dist/compat/internal/props.js +82 -0
  16. package/dist/compat/keymap.d.ts +21 -0
  17. package/dist/compat/keymap.js +38 -0
  18. package/dist/compat/model.d.ts +893 -0
  19. package/dist/compat/model.js +1212 -0
  20. package/dist/compat/orderedmap.d.ts +74 -0
  21. package/dist/compat/orderedmap.js +124 -0
  22. package/dist/compat/schema-basic.d.ts +38 -0
  23. package/dist/compat/schema-basic.js +238 -0
  24. package/dist/compat/schema-list.d.ts +81 -0
  25. package/dist/compat/schema-list.js +156 -0
  26. package/dist/compat/state.d.ts +415 -0
  27. package/dist/compat/state.js +689 -0
  28. package/dist/compat/test-builder.d.ts +98 -0
  29. package/dist/compat/test-builder.js +197 -0
  30. package/dist/compat/transform.d.ts +458 -0
  31. package/dist/compat/transform.js +803 -0
  32. package/dist/compat/view.d.ts +411 -0
  33. package/dist/compat/view.js +409 -0
  34. package/dist/dropcursor.d.ts +46 -0
  35. package/dist/dropcursor.js +176 -0
  36. package/dist/extensions/defaults.d.ts +716 -0
  37. package/dist/extensions/defaults.js +209 -0
  38. package/dist/extensions/editor.d.ts +246 -0
  39. package/dist/extensions/editor.js +271 -0
  40. package/dist/extensions/extension.d.ts +375 -0
  41. package/dist/extensions/extension.js +233 -0
  42. package/dist/extensions.d.ts +4 -0
  43. package/dist/extensions.js +4 -0
  44. package/dist/gapcursor.d.ts +66 -0
  45. package/dist/gapcursor.js +273 -0
  46. package/dist/history.d.ts +178 -0
  47. package/dist/history.js +412 -0
  48. package/dist/html.d.ts +158 -0
  49. package/dist/html.js +164 -0
  50. package/dist/inputrules.d.ts +271 -0
  51. package/dist/inputrules.js +321 -0
  52. package/dist/internal/attempt.js +15 -0
  53. package/dist/internal/json.js +29 -0
  54. package/dist/keymap/keymap.d.ts +130 -0
  55. package/dist/keymap/keymap.js +159 -0
  56. package/dist/keymap.d.ts +2 -0
  57. package/dist/keymap.js +1 -0
  58. package/dist/markdown/errors.d.ts +23 -0
  59. package/dist/markdown/errors.js +26 -0
  60. package/dist/markdown/from_markdown.d.ts +185 -0
  61. package/dist/markdown/from_markdown.js +266 -0
  62. package/dist/markdown/schema.d.ts +522 -0
  63. package/dist/markdown/schema.js +292 -0
  64. package/dist/markdown/to_markdown.d.ts +251 -0
  65. package/dist/markdown/to_markdown.js +413 -0
  66. package/dist/markdown.d.ts +5 -0
  67. package/dist/markdown.js +5 -0
  68. package/dist/model/attrsCodec.js +48 -0
  69. package/dist/model/comparedeep.js +17 -0
  70. package/dist/model/content.d.ts +232 -0
  71. package/dist/model/content.js +630 -0
  72. package/dist/model/diff.js +66 -0
  73. package/dist/model/dom.d.ts +3 -0
  74. package/dist/model/errors.d.ts +90 -0
  75. package/dist/model/errors.js +76 -0
  76. package/dist/model/fragment.d.ts +131 -0
  77. package/dist/model/fragment.js +262 -0
  78. package/dist/model/from_dom.d.ts +299 -0
  79. package/dist/model/from_dom.js +618 -0
  80. package/dist/model/json.d.ts +37 -0
  81. package/dist/model/json.js +126 -0
  82. package/dist/model/mark.d.ts +73 -0
  83. package/dist/model/mark.js +121 -0
  84. package/dist/model/node.d.ts +267 -0
  85. package/dist/model/node.js +434 -0
  86. package/dist/model/replace.d.ts +78 -0
  87. package/dist/model/replace.js +207 -0
  88. package/dist/model/resolvedpos.d.ts +196 -0
  89. package/dist/model/resolvedpos.js +305 -0
  90. package/dist/model/schema.d.ts +740 -0
  91. package/dist/model/schema.js +451 -0
  92. package/dist/model/to_dom.d.ts +169 -0
  93. package/dist/model/to_dom.js +238 -0
  94. package/dist/model.d.ts +12 -0
  95. package/dist/model.js +12 -0
  96. package/dist/placeholder.d.ts +53 -0
  97. package/dist/placeholder.js +79 -0
  98. package/dist/reactive/observer.d.ts +54 -0
  99. package/dist/reactive/observer.js +61 -0
  100. package/dist/reactive/selectors.d.ts +22 -0
  101. package/dist/reactive/selectors.js +61 -0
  102. package/dist/reactive/stateref.d.ts +72 -0
  103. package/dist/reactive/stateref.js +71 -0
  104. package/dist/reactive/streams.d.ts +83 -0
  105. package/dist/reactive/streams.js +85 -0
  106. package/dist/reactive.d.ts +16 -0
  107. package/dist/reactive.js +26 -0
  108. package/dist/schema-basic.d.ts +448 -0
  109. package/dist/schema-basic.js +269 -0
  110. package/dist/schema-list/commands.d.ts +66 -0
  111. package/dist/schema-list/commands.js +203 -0
  112. package/dist/schema-list.d.ts +92 -0
  113. package/dist/schema-list.js +100 -0
  114. package/dist/state/errors.d.ts +39 -0
  115. package/dist/state/errors.js +32 -0
  116. package/dist/state/plugin.d.ts +232 -0
  117. package/dist/state/plugin.js +82 -0
  118. package/dist/state/selection.d.ts +297 -0
  119. package/dist/state/selection.js +486 -0
  120. package/dist/state/state.d.ts +212 -0
  121. package/dist/state/state.js +489 -0
  122. package/dist/state/transaction.d.ts +145 -0
  123. package/dist/state/transaction.js +195 -0
  124. package/dist/state.d.ts +6 -0
  125. package/dist/state.js +6 -0
  126. package/dist/test-builder.d.ts +3582 -0
  127. package/dist/test-builder.js +239 -0
  128. package/dist/transform/attr_step.d.ts +60 -0
  129. package/dist/transform/attr_step.js +105 -0
  130. package/dist/transform/errors.d.ts +50 -0
  131. package/dist/transform/errors.js +35 -0
  132. package/dist/transform/map.d.ts +182 -0
  133. package/dist/transform/map.js +280 -0
  134. package/dist/transform/mark.js +98 -0
  135. package/dist/transform/mark_set_step.js +69 -0
  136. package/dist/transform/mark_step.d.ts +113 -0
  137. package/dist/transform/mark_step.js +225 -0
  138. package/dist/transform/replace.d.ts +18 -0
  139. package/dist/transform/replace.js +381 -0
  140. package/dist/transform/replace_step.d.ts +109 -0
  141. package/dist/transform/replace_step.js +175 -0
  142. package/dist/transform/step.d.ts +157 -0
  143. package/dist/transform/step.js +168 -0
  144. package/dist/transform/structure.d.ts +89 -0
  145. package/dist/transform/structure.js +350 -0
  146. package/dist/transform/transform.d.ts +248 -0
  147. package/dist/transform/transform.js +373 -0
  148. package/dist/transform.d.ts +10 -0
  149. package/dist/transform.js +10 -0
  150. package/dist/view/browser.js +39 -0
  151. package/dist/view/capturekeys.js +282 -0
  152. package/dist/view/clipboard.d.ts +8 -0
  153. package/dist/view/clipboard.js +245 -0
  154. package/dist/view/decoration.d.ts +339 -0
  155. package/dist/view/decoration.js +566 -0
  156. package/dist/view/dom.d.ts +18 -0
  157. package/dist/view/dom.js +140 -0
  158. package/dist/view/domchange.js +295 -0
  159. package/dist/view/domcoords.d.ts +22 -0
  160. package/dist/view/domcoords.js +448 -0
  161. package/dist/view/domobserver.d.ts +47 -0
  162. package/dist/view/domobserver.js +328 -0
  163. package/dist/view/errors.d.ts +18 -0
  164. package/dist/view/errors.js +21 -0
  165. package/dist/view/input.d.ts +58 -0
  166. package/dist/view/input.js +704 -0
  167. package/dist/view/selection.js +198 -0
  168. package/dist/view/view.d.ts +699 -0
  169. package/dist/view/view.js +623 -0
  170. package/dist/view/viewdesc.d.ts +236 -0
  171. package/dist/view/viewdesc.js +1205 -0
  172. package/dist/view-css.d.ts +43 -0
  173. package/dist/view-css.js +124 -0
  174. package/dist/view.d.ts +6 -0
  175. package/dist/view.js +4 -0
  176. package/package.json +200 -4
@@ -0,0 +1,232 @@
1
+ import { AnySchema } from "../model/schema.js";
2
+ import "../model.js";
3
+ import { EditorProps, EditorView } from "../view/view.js";
4
+ import { EditorState, EditorStateConfig } from "./state.js";
5
+ import { Transaction } from "./transaction.js";
6
+ import * as Effect from "effect/Effect";
7
+ import * as Option from "effect/Option";
8
+ /**
9
+ * A value, or an Effect producing it. Plugin hooks may return either:
10
+ * plain values keep simple plugins simple, while Effects let plugins use
11
+ * services (reflected in the plugin's `R` type) and fail with typed
12
+ * errors (`E`).
13
+ *
14
+ * Note that a hook result is treated as an Effect whenever
15
+ * `Effect.isEffect` is true for it, so a plugin whose state is itself
16
+ * an Effect must wrap it in `Effect.succeed`.
17
+ *
18
+ * @since 0.1.0
19
+ * @category models
20
+ */
21
+ export type MaybeEffect<A, E = never, R = never> = A | Effect.Effect<A, E, R>;
22
+ /**
23
+ * The editor view type, as passed to commands (which may be called
24
+ * without a view, hence `undefined`).
25
+ *
26
+ * @since 0.1.0
27
+ * @category models
28
+ */
29
+ export type EditorViewLike = EditorView<any, any, any> | undefined;
30
+ /**
31
+ * The props a plugin adds to the editor view: the view's `EditorProps`.
32
+ * Function-valued props are bound to the plugin instance.
33
+ *
34
+ * @since 0.1.0
35
+ * @category models
36
+ */
37
+ export type PluginProps<Sc extends AnySchema = AnySchema, E = never, R = never> = EditorProps<Sc, R, E, Plugin<any, Sc, never, never>>;
38
+ /**
39
+ * A stateful object that can be installed in an editor by a plugin's
40
+ * `view` hook.
41
+ *
42
+ * @since 0.1.0
43
+ * @category models
44
+ */
45
+ export interface PluginView<Sc extends AnySchema = AnySchema> {
46
+ /** Called whenever the view's state is updated. */
47
+ readonly update?: ((view: EditorView<Sc, any, any>, prevState: EditorState<Sc, any, any>) => void) | undefined;
48
+ /** Called when the view is destroyed or receives a state with different plugins. */
49
+ readonly destroy?: (() => void) | undefined;
50
+ }
51
+ /**
52
+ * A plugin spec may provide a state field (under its `state` property)
53
+ * of this type, which describes the state it wants to keep. Functions
54
+ * provided here are always called with the plugin instance as their
55
+ * `this` binding, and may return either a plain value or an Effect.
56
+ *
57
+ * @since 0.1.0
58
+ * @category models
59
+ */
60
+ export interface StateField<PState, Sc extends AnySchema = AnySchema, E = never, R = never> {
61
+ /**
62
+ * Initialize the value of the field. `config` will be the object
63
+ * passed to `EditorState.create`. Note that `instance` is a
64
+ * half-initialized state instance, and will not have values for
65
+ * plugin fields initialized after this one.
66
+ */
67
+ readonly init: (config: EditorStateConfig<Sc>, instance: EditorState<Sc, any, any>) => MaybeEffect<PState, E, R>;
68
+ /**
69
+ * Apply the given transaction to this state field, producing a new
70
+ * field value. Note that the `newState` argument is again a partially
71
+ * constructed state does not yet contain the state from plugins coming
72
+ * after this one.
73
+ */
74
+ readonly apply: (tr: Transaction<Sc>, value: PState, oldState: EditorState<Sc, any, any>, newState: EditorState<Sc, any, any>) => MaybeEffect<PState, E, R>;
75
+ /**
76
+ * Convert this field to JSON. Optional, can be left off to disable
77
+ * JSON serialization for the field.
78
+ */
79
+ readonly toJSON?: ((value: PState) => unknown) | undefined;
80
+ /**
81
+ * Deserialize the JSON representation of this field. Note that the
82
+ * `state` argument is again a half-initialized state.
83
+ */
84
+ readonly fromJSON?: ((config: EditorStateConfig<Sc>, value: unknown, state: EditorState<Sc, any, any>) => MaybeEffect<PState, E, R>) | undefined;
85
+ }
86
+ /**
87
+ * This is the type passed to the `Plugin` constructor. It provides a
88
+ * definition for a plugin.
89
+ *
90
+ * The hooks that run while creating or updating states (`state.init`,
91
+ * `state.apply`, `state.fromJSON`, `filterTransaction` and
92
+ * `appendTransaction`) may return Effects; their error and requirement
93
+ * types become the plugin's `E` and `R`.
94
+ *
95
+ * @since 0.1.0
96
+ * @category models
97
+ */
98
+ export interface PluginSpec<PState = any, Sc extends AnySchema = AnySchema, E = never, R = never> {
99
+ /**
100
+ * The view props added by this plugin. Props that are functions will
101
+ * be bound to have the plugin instance as their `this` binding.
102
+ */
103
+ readonly props?: PluginProps<Sc, E, R> | undefined;
104
+ /**
105
+ * Allows a plugin to define a state field, an extra slot in the state
106
+ * object in which it can keep its own data.
107
+ */
108
+ readonly state?: StateField<PState, Sc, E, R> | undefined;
109
+ /**
110
+ * Can be used to make this a keyed plugin. You can have only one
111
+ * plugin with a given key in a given state, but it is possible to
112
+ * access the plugin's configuration and state through the key,
113
+ * without having access to the plugin instance object.
114
+ */
115
+ readonly key?: PluginKey<PState> | undefined;
116
+ /**
117
+ * When the plugin needs to interact with the editor view, or set
118
+ * something up in the DOM, use this field. The function will be
119
+ * called when the plugin's state is associated with an editor view.
120
+ */
121
+ readonly view?: ((view: EditorView<Sc, any, any>) => PluginView<Sc>) | undefined;
122
+ /**
123
+ * When present, this will be called before a transaction is applied
124
+ * by the state, allowing the plugin to cancel it (by returning
125
+ * false).
126
+ */
127
+ readonly filterTransaction?: ((tr: Transaction<Sc>, state: EditorState<Sc, any, any>) => MaybeEffect<boolean, E, R>) | undefined;
128
+ /**
129
+ * Allows the plugin to append another transaction to be applied after
130
+ * the given array of transactions. When another plugin appends a
131
+ * transaction after this was called, it is called again with the new
132
+ * state and new transactions—but only the new transactions, i.e. it
133
+ * won't be passed transactions that it already saw.
134
+ */
135
+ readonly appendTransaction?: ((transactions: ReadonlyArray<Transaction<Sc>>, oldState: EditorState<Sc, any, any>, newState: EditorState<Sc, any, any>) => MaybeEffect<Transaction<Sc> | null | undefined | void, E, R>) | undefined;
136
+ /**
137
+ * Additional properties are allowed on plugin specs, which can be
138
+ * read via `Plugin.spec`.
139
+ */
140
+ readonly [key: string]: unknown;
141
+ }
142
+ /**
143
+ * @since 0.1.0
144
+ * @category symbols
145
+ */
146
+ export declare const PluginTypeId: unique symbol;
147
+ /**
148
+ * @since 0.1.0
149
+ * @category symbols
150
+ */
151
+ export type PluginTypeId = typeof PluginTypeId;
152
+ /**
153
+ * Plugins bundle functionality that can be added to an editor. They are
154
+ * part of the editor state and may influence that state and the view
155
+ * that contains it.
156
+ *
157
+ * The type parameters are the plugin's state type, the schema it works
158
+ * with, and the errors (`E`) and requirements (`R`) of its effectful
159
+ * hooks, which are inferred from the spec:
160
+ *
161
+ * ```ts skip-type-checking
162
+ * const counter = new Plugin({
163
+ * state: {
164
+ * init: () => 0,
165
+ * apply: (_tr, n) => Effect.map(Clock.currentTimeMillis, () => n + 1)
166
+ * }
167
+ * }) // Plugin<number, AnySchema, never, never>
168
+ * ```
169
+ *
170
+ * @since 0.1.0
171
+ * @category models
172
+ */
173
+ export declare class Plugin<PState = any, Sc extends AnySchema = AnySchema, E = never, R = never> {
174
+ /** The plugin's spec object. */
175
+ readonly spec: PluginSpec<PState, Sc, E, R>;
176
+ readonly [PluginTypeId]: {
177
+ readonly _PState: (_: never) => PState;
178
+ readonly _E: (_: never) => E;
179
+ readonly _R: (_: never) => R;
180
+ };
181
+ /** The props exported by this plugin. */
182
+ readonly props: PluginProps<Sc, E, R>;
183
+ /** @internal */
184
+ readonly key: string;
185
+ /** Create a plugin. */
186
+ constructor(
187
+ /** The plugin's spec object. */
188
+ spec: PluginSpec<PState, Sc, E, R>);
189
+ /** Extract the plugin's state field from an editor state. */
190
+ getState(state: EditorState<any, any, any>): Option.Option<PState>;
191
+ }
192
+ /**
193
+ * Any plugin.
194
+ *
195
+ * @since 0.1.0
196
+ * @category models
197
+ */
198
+ export type AnyPlugin = Plugin<any, any, any, any>;
199
+ /**
200
+ * The union of the error types of the given plugins.
201
+ *
202
+ * @since 0.1.0
203
+ * @category type-level
204
+ */
205
+ export type PluginErrors<P extends ReadonlyArray<AnyPlugin>> = P[number] extends (infer X) ? X extends Plugin<any, any, infer E, any> ? E : never : never;
206
+ /**
207
+ * The union of the requirements of the given plugins.
208
+ *
209
+ * @since 0.1.0
210
+ * @category type-level
211
+ */
212
+ export type PluginRequirements<P extends ReadonlyArray<AnyPlugin>> = P[number] extends (infer X) ? X extends Plugin<any, any, any, infer R> ? R : never : never;
213
+ /** @internal */
214
+ export declare const getField: <A>(state: EditorState<any, any, any>, key: string) => Option.Option<A>;
215
+ /**
216
+ * A key is used to tag plugins in a way that makes it possible to find
217
+ * them, given an editor state. Assigning a key does mean only one plugin
218
+ * of that type can be active in a state.
219
+ *
220
+ * @since 0.1.0
221
+ * @category models
222
+ */
223
+ export declare class PluginKey<PState = any> {
224
+ /** @internal */
225
+ readonly key: string;
226
+ /** Create a plugin key. */
227
+ constructor(name?: string);
228
+ /** Get the active plugin with this key, if any, from an editor state. */
229
+ get(state: EditorState<any, any, any>): Option.Option<Plugin<PState, any, any, any>>;
230
+ /** Get the plugin's state from an editor state. */
231
+ getState(state: EditorState<any, any, any>): Option.Option<PState>;
232
+ }
@@ -0,0 +1,82 @@
1
+ import * as Option from "effect/Option";
2
+ import * as Predicate from "effect/Predicate";
3
+ // src/state/plugin.ts
4
+ function bindProps(obj, self, target) {
5
+ for (const prop in obj) {
6
+ let val = obj[prop];
7
+ if (Predicate.isFunction(val)) val = val.bind(self);
8
+ else if (prop === "handleDOMEvents") val = bindProps(val, self, {});
9
+ target[prop] = val;
10
+ }
11
+ return target;
12
+ }
13
+ const keys = Object.create(null);
14
+ function createKey(name) {
15
+ if (name in keys) return name + "$" + ++keys[name];
16
+ keys[name] = 0;
17
+ return name + "$";
18
+ }
19
+ /**
20
+ * @since 0.1.0
21
+ * @category symbols
22
+ */
23
+ const PluginTypeId = Symbol.for("effect-richtext/state/Plugin");
24
+ /**
25
+ * Plugins bundle functionality that can be added to an editor. They are
26
+ * part of the editor state and may influence that state and the view
27
+ * that contains it.
28
+ *
29
+ * The type parameters are the plugin's state type, the schema it works
30
+ * with, and the errors (`E`) and requirements (`R`) of its effectful
31
+ * hooks, which are inferred from the spec:
32
+ *
33
+ * ```ts skip-type-checking
34
+ * const counter = new Plugin({
35
+ * state: {
36
+ * init: () => 0,
37
+ * apply: (_tr, n) => Effect.map(Clock.currentTimeMillis, () => n + 1)
38
+ * }
39
+ * }) // Plugin<number, AnySchema, never, never>
40
+ * ```
41
+ *
42
+ * @since 0.1.0
43
+ * @category models
44
+ */
45
+ var Plugin = class {
46
+ /** Create a plugin. */
47
+ constructor(spec) {
48
+ this.spec = spec;
49
+ this.props = {};
50
+ if (spec.props) bindProps(spec.props, this, this.props);
51
+ this.key = spec.key ? spec.key.key : createKey("plugin");
52
+ }
53
+ /** Extract the plugin's state field from an editor state. */
54
+ getState(state) {
55
+ return getField(state, this.key);
56
+ }
57
+ };
58
+ /** @internal */
59
+ const getField = (state, key) => Object.prototype.hasOwnProperty.call(state.slots, key) ? Option.some(state.slots[key]) : Option.none();
60
+ /**
61
+ * A key is used to tag plugins in a way that makes it possible to find
62
+ * them, given an editor state. Assigning a key does mean only one plugin
63
+ * of that type can be active in a state.
64
+ *
65
+ * @since 0.1.0
66
+ * @category models
67
+ */
68
+ var PluginKey = class {
69
+ /** Create a plugin key. */
70
+ constructor(name = "key") {
71
+ this.key = createKey(name);
72
+ }
73
+ /** Get the active plugin with this key, if any, from an editor state. */
74
+ get(state) {
75
+ return Option.fromUndefinedOr(state.config.pluginsByKey[this.key]);
76
+ }
77
+ /** Get the plugin's state from an editor state. */
78
+ getState(state) {
79
+ return getField(state, this.key);
80
+ }
81
+ };
82
+ export { Plugin, PluginKey, PluginTypeId, getField };
@@ -0,0 +1,297 @@
1
+ import { ModelError, PositionError } from "../model/errors.js";
2
+ import { ResolvedPos } from "../model/resolvedpos.js";
3
+ import { Slice } from "../model/replace.js";
4
+ import { AnySchema } from "../model/schema.js";
5
+ import { Node } from "../model/node.js";
6
+ import "../model.js";
7
+ import "../transform.js";
8
+ import { Mappable } from "../transform/map.js";
9
+ import { SelectionError } from "./errors.js";
10
+ import { Transaction } from "./transaction.js";
11
+ import * as Effect from "effect/Effect";
12
+ import * as Option from "effect/Option";
13
+ import * as S from "effect/Schema";
14
+ /**
15
+ * The JSON representation of a selection. It always includes the
16
+ * selection class's JSON id (see `Selection.jsonID`) under `type`.
17
+ *
18
+ * @since 0.1.0
19
+ * @category models
20
+ */
21
+ export interface SelectionJSON {
22
+ readonly type: string;
23
+ readonly [key: string]: unknown;
24
+ }
25
+ /**
26
+ * Something that can deserialize selections of a given type: usually
27
+ * the selection class itself, via a static `fromJSONUnsafe` method that
28
+ * throws a tagged error for invalid input.
29
+ *
30
+ * @since 0.1.0
31
+ * @category models
32
+ */
33
+ export interface SelectionDeserializer {
34
+ readonly fromJSONUnsafe: (doc: Node<any>, json: any) => Selection<any>;
35
+ }
36
+ /**
37
+ * Superclass for editor selections. Every selection type should extend
38
+ * this. Should not be instantiated directly.
39
+ *
40
+ * @since 0.1.0
41
+ * @category models
42
+ */
43
+ export declare abstract class Selection<Sc extends AnySchema = AnySchema> {
44
+ /**
45
+ * The resolved anchor of the selection (the side that stays in
46
+ * place when the selection is modified).
47
+ */
48
+ readonly $anchor: ResolvedPos<Sc>;
49
+ /**
50
+ * The resolved head of the selection (the side that moves when the
51
+ * selection is modified).
52
+ */
53
+ readonly $head: ResolvedPos<Sc>;
54
+ /** The ranges covered by the selection. */
55
+ readonly ranges: ReadonlyArray<SelectionRange<Sc>>;
56
+ /**
57
+ * Initialize a selection with the head and anchor and ranges. If no
58
+ * ranges are given, constructs a single range across `$anchor` and
59
+ * `$head`.
60
+ */
61
+ constructor(
62
+ /**
63
+ * The resolved anchor of the selection (the side that stays in
64
+ * place when the selection is modified).
65
+ */
66
+ $anchor: ResolvedPos<Sc>,
67
+ /**
68
+ * The resolved head of the selection (the side that moves when the
69
+ * selection is modified).
70
+ */
71
+ $head: ResolvedPos<Sc>, ranges?: ReadonlyArray<SelectionRange<Sc>>);
72
+ /** The selection's anchor, as an unresolved position. */
73
+ get anchor(): number;
74
+ /** The selection's head. */
75
+ get head(): number;
76
+ /** The lower bound of the selection's main range. */
77
+ get from(): number;
78
+ /** The upper bound of the selection's main range. */
79
+ get to(): number;
80
+ /** The resolved lower bound of the selection's main range. */
81
+ get $from(): ResolvedPos<Sc>;
82
+ /** The resolved upper bound of the selection's main range. */
83
+ get $to(): ResolvedPos<Sc>;
84
+ /** Indicates whether the selection contains any content. */
85
+ get empty(): boolean;
86
+ /**
87
+ * Controls whether, when a selection of this type is active in the
88
+ * browser, the selected range should be visible to the user.
89
+ * Defaults to `true`.
90
+ */
91
+ get visible(): boolean;
92
+ /** Test whether the selection is the same as another selection. */
93
+ abstract eq(selection: Selection<any>): boolean;
94
+ /**
95
+ * Map this selection through a mappable thing. `doc` should be the
96
+ * new document to which we are mapping.
97
+ */
98
+ abstract map(doc: Node<Sc>, mapping: Mappable): Selection<Sc>;
99
+ /** Get the content of this selection as a slice. */
100
+ content(): Slice<Sc>;
101
+ /**
102
+ * Replace the selection with a slice or, if no slice is given, delete
103
+ * the selection. Will append to the given transaction.
104
+ */
105
+ replace(tr: Transaction<Sc>, content?: Slice<Sc>): void;
106
+ /** Replace the selection with the given node, appending the changes to the given transaction. */
107
+ replaceWith(tr: Transaction<Sc>, node: Node<Sc>): void;
108
+ /**
109
+ * Convert the selection to a JSON representation. When implementing
110
+ * this for a custom selection class, make sure to give the object a
111
+ * `type` property whose value matches the ID under which you
112
+ * registered your class.
113
+ */
114
+ abstract toJSON(): SelectionJSON;
115
+ /**
116
+ * Find a valid cursor or leaf node selection starting at the given
117
+ * position and searching back if `dir` is negative, and forward if
118
+ * positive. When `textOnly` is true, only consider cursor selections.
119
+ * Will return `None` when no valid selection position is found.
120
+ */
121
+ static findFrom<Sc extends AnySchema>($pos: ResolvedPos<Sc>, dir: number, textOnly?: boolean): Option.Option<Selection<Sc>>;
122
+ /** @internal */
123
+ static findFromOrNull<Sc extends AnySchema>($pos: ResolvedPos<Sc>, dir: number, textOnly?: boolean): Selection<Sc> | null;
124
+ /**
125
+ * Find a valid cursor or leaf node selection near the given position.
126
+ * Searches forward first by default, but if `bias` is negative, it
127
+ * will search backwards first.
128
+ */
129
+ static near<Sc extends AnySchema>($pos: ResolvedPos<Sc>, bias?: number): Selection<Sc>;
130
+ /**
131
+ * Find the cursor or leaf node selection closest to the start of the
132
+ * given document. Will return an `AllSelection` if no valid position
133
+ * exists.
134
+ */
135
+ static atStart<Sc extends AnySchema>(doc: Node<Sc>): Selection<Sc>;
136
+ /** Find the cursor or leaf node selection closest to the end of the given document. */
137
+ static atEnd<Sc extends AnySchema>(doc: Node<Sc>): Selection<Sc>;
138
+ /**
139
+ * Deserialize the JSON representation of a selection. Dispatches to
140
+ * the selection class registered (with `jsonID`) for the JSON's
141
+ * `type`.
142
+ */
143
+ static fromJSON<Sc extends AnySchema>(doc: Node<Sc>, json: unknown): Effect.Effect<Selection<Sc>, ModelError | SelectionError>;
144
+ /** Like `fromJSON`, but throws on invalid input. */
145
+ static fromJSONUnsafe<Sc extends AnySchema>(doc: Node<Sc>, json: any): Selection<Sc>;
146
+ /**
147
+ * To be able to deserialize selections from JSON, custom selection
148
+ * classes must register themselves with an ID string, so that they
149
+ * can be disambiguated. Try to pick something that's unlikely to
150
+ * clash with classes from other modules. Throws a `SelectionError`
151
+ * when the ID is already in use.
152
+ */
153
+ static jsonID<C extends SelectionDeserializer>(id: string, selectionClass: C): C;
154
+ /**
155
+ * Get a bookmark for this selection, which is a value that can be
156
+ * mapped without having access to a current document, and later
157
+ * resolved to a real selection for a given document again. (This is
158
+ * used mostly by the history to track and restore old selections.)
159
+ * The default implementation of this method just converts the
160
+ * selection to a text selection and returns the bookmark for that.
161
+ */
162
+ getBookmark(): SelectionBookmark<Sc>;
163
+ }
164
+ /**
165
+ * A lightweight, document-independent representation of a selection.
166
+ * You can define a custom bookmark type for a custom selection class to
167
+ * make the history handle it well.
168
+ *
169
+ * @since 0.1.0
170
+ * @category models
171
+ */
172
+ export interface SelectionBookmark<Sc extends AnySchema = AnySchema> {
173
+ /** Map the bookmark through a set of changes. */
174
+ readonly map: (mapping: Mappable) => SelectionBookmark<Sc>;
175
+ /**
176
+ * Resolve the bookmark to a real selection again. This may need to do
177
+ * some error checking and may fall back to a default (usually
178
+ * `TextSelection.between`) if mapping made the bookmark invalid.
179
+ */
180
+ readonly resolve: (doc: Node<Sc>) => Selection<Sc>;
181
+ }
182
+ /**
183
+ * Represents a selected range in a document.
184
+ *
185
+ * @since 0.1.0
186
+ * @category models
187
+ */
188
+ export declare class SelectionRange<Sc extends AnySchema = AnySchema> {
189
+ /** The lower bound of the range. */
190
+ readonly $from: ResolvedPos<Sc>;
191
+ /** The upper bound of the range. */
192
+ readonly $to: ResolvedPos<Sc>;
193
+ /** Create a range. */
194
+ constructor(
195
+ /** The lower bound of the range. */
196
+ $from: ResolvedPos<Sc>,
197
+ /** The upper bound of the range. */
198
+ $to: ResolvedPos<Sc>);
199
+ }
200
+ /**
201
+ * A text selection represents a classical editor selection, with a head
202
+ * (the moving side) and anchor (immobile side), both of which point into
203
+ * textblock nodes. It can be empty (a regular cursor position).
204
+ *
205
+ * @since 0.1.0
206
+ * @category models
207
+ */
208
+ export declare class TextSelection<Sc extends AnySchema = AnySchema> extends Selection<Sc> {
209
+ /** Construct a text selection between the given points. */
210
+ constructor($anchor: ResolvedPos<Sc>, $head?: ResolvedPos<Sc>);
211
+ /** Returns a resolved position if this is a cursor selection (an empty text selection). */
212
+ get $cursor(): Option.Option<ResolvedPos<Sc>>;
213
+ /** @internal */
214
+ get $cursorOrNull(): ResolvedPos<Sc> | null;
215
+ map(doc: Node<Sc>, mapping: Mappable): Selection<Sc>;
216
+ replace(tr: Transaction<Sc>, content?: Slice<Sc>): void;
217
+ eq(other: Selection<any>): boolean;
218
+ getBookmark(): SelectionBookmark<Sc>;
219
+ toJSON(): SelectionJSON;
220
+ /** @internal */
221
+ static fromJSONUnsafe<Sc extends AnySchema>(doc: Node<Sc>, json: any): TextSelection<Sc>;
222
+ /** Create a text selection from non-resolved positions. */
223
+ static create<Sc extends AnySchema>(doc: Node<Sc>, anchor: number, head?: number): Effect.Effect<TextSelection<Sc>, PositionError>;
224
+ /** Like `create`, but throws a `PositionError` for positions outside of the document. */
225
+ static createUnsafe<Sc extends AnySchema>(doc: Node<Sc>, anchor: number, head?: number): TextSelection<Sc>;
226
+ /**
227
+ * Return a text selection that spans the given positions or, if they
228
+ * aren't text positions, find a text selection near them. `bias`
229
+ * determines whether the method searches forward (default) or
230
+ * backwards (negative number) first. Will fall back to calling
231
+ * `Selection.near` when the document doesn't contain a valid text
232
+ * position.
233
+ */
234
+ static between<Sc extends AnySchema>($anchor: ResolvedPos<Sc>, $head: ResolvedPos<Sc>, bias?: number): Selection<Sc>;
235
+ }
236
+ /**
237
+ * A node selection is a selection that points at a single node. All
238
+ * nodes marked selectable can be the target of a node selection. In
239
+ * such a selection, `from` and `to` point directly before and after the
240
+ * selected node, `anchor` equals `from`, and `head` equals `to`.
241
+ *
242
+ * @since 0.1.0
243
+ * @category models
244
+ */
245
+ export declare class NodeSelection<Sc extends AnySchema = AnySchema> extends Selection<Sc> {
246
+ /** The selected node. */
247
+ readonly node: Node<Sc>;
248
+ /**
249
+ * Create a node selection. Does not verify the validity of its
250
+ * argument beyond requiring a node after `$pos` (throwing a
251
+ * `SelectionError` otherwise).
252
+ */
253
+ constructor($pos: ResolvedPos<Sc>);
254
+ get visible(): boolean;
255
+ map(doc: Node<Sc>, mapping: Mappable): Selection<Sc>;
256
+ content(): Slice<Sc>;
257
+ eq(other: Selection<any>): boolean;
258
+ toJSON(): SelectionJSON;
259
+ getBookmark(): SelectionBookmark<Sc>;
260
+ /** @internal */
261
+ static fromJSONUnsafe<Sc extends AnySchema>(doc: Node<Sc>, json: any): NodeSelection<Sc>;
262
+ /** Create a node selection from a non-resolved position. */
263
+ static create<Sc extends AnySchema>(doc: Node<Sc>, from: number): Effect.Effect<NodeSelection<Sc>, PositionError | SelectionError>;
264
+ /** Like `create`, but throws for invalid positions. */
265
+ static createUnsafe<Sc extends AnySchema>(doc: Node<Sc>, from: number): NodeSelection<Sc>;
266
+ /** Determines whether the given node may be selected as a node selection. */
267
+ static isSelectable(node: Node<any>): boolean;
268
+ }
269
+ /**
270
+ * A selection type that represents selecting the whole document (which
271
+ * can not necessarily be expressed with a text selection, when there
272
+ * are for example leaf block nodes at the start or end of the
273
+ * document).
274
+ *
275
+ * @since 0.1.0
276
+ * @category models
277
+ */
278
+ export declare class AllSelection<Sc extends AnySchema = AnySchema> extends Selection<Sc> {
279
+ /** Create an all-selection over the given document. */
280
+ constructor(doc: Node<Sc>);
281
+ replace(tr: Transaction<Sc>, content?: Slice<Sc>): void;
282
+ toJSON(): SelectionJSON;
283
+ /** @internal */
284
+ static fromJSONUnsafe<Sc extends AnySchema>(doc: Node<Sc>): AllSelection<Sc>;
285
+ map(doc: Node<Sc>): Selection<Sc>;
286
+ eq(other: Selection<any>): boolean;
287
+ getBookmark(): SelectionBookmark<Sc>;
288
+ }
289
+ /**
290
+ * An Effect `Schema` that decodes the JSON representation of a
291
+ * selection (using the `Selection.jsonID` registry) into a selection in
292
+ * the given document, and encodes selections back to JSON.
293
+ *
294
+ * @since 0.1.0
295
+ * @category schemas
296
+ */
297
+ export declare const SelectionFromJSON: <Sc extends AnySchema>(doc: Node<Sc>) => S.Codec<Selection<Sc>, SelectionJSON>;