@thomasfosterau/effect-richtext 0.0.0-stage → 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 +118 -2
- 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 +206 -3
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
import { AttributeError, PositionError } from "../model/errors.js";
|
|
2
|
+
import { NodeRange } from "../model/resolvedpos.js";
|
|
3
|
+
import { Slice } from "../model/replace.js";
|
|
4
|
+
import { AnySchema, MarkType, NodeAttrsInput, NodeNames, NodeType } from "../model/schema.js";
|
|
5
|
+
import { Mark } from "../model/mark.js";
|
|
6
|
+
import { Node } from "../model/node.js";
|
|
7
|
+
import { Fragment } from "../model/fragment.js";
|
|
8
|
+
import { ContentMatch } from "../model/content.js";
|
|
9
|
+
import "../model.js";
|
|
10
|
+
import { StepError, TransformError } from "./errors.js";
|
|
11
|
+
import { Mapping } from "./map.js";
|
|
12
|
+
import { Step, StepResult } from "./step.js";
|
|
13
|
+
import { NodeTypeWithAttrs } from "./structure.js";
|
|
14
|
+
import * as Effect from "effect/Effect";
|
|
15
|
+
import * as Option from "effect/Option";
|
|
16
|
+
/**
|
|
17
|
+
* Content accepted by `replaceWith` and `insert`.
|
|
18
|
+
*
|
|
19
|
+
* @since 0.1.0
|
|
20
|
+
* @category models
|
|
21
|
+
*/
|
|
22
|
+
export type ContentInput<Sc extends AnySchema = AnySchema> = Fragment<Sc> | Node<Sc> | ReadonlyArray<Node<Sc>>;
|
|
23
|
+
/**
|
|
24
|
+
* Errors that can occur when replacing content: invalid positions or a
|
|
25
|
+
* step that can't be applied.
|
|
26
|
+
*
|
|
27
|
+
* @since 0.1.0
|
|
28
|
+
* @category errors
|
|
29
|
+
*/
|
|
30
|
+
export type ReplaceFailure = StepError | PositionError;
|
|
31
|
+
/**
|
|
32
|
+
* Errors that can occur in structural transforms (`lift`, `wrap`,
|
|
33
|
+
* `split`, `setBlockType`, …).
|
|
34
|
+
*
|
|
35
|
+
* @since 0.1.0
|
|
36
|
+
* @category errors
|
|
37
|
+
*/
|
|
38
|
+
export type StructureFailure = TransformError | StepError | PositionError | AttributeError;
|
|
39
|
+
/**
|
|
40
|
+
* Abstraction to build up and track an array of steps representing a
|
|
41
|
+
* document transformation.
|
|
42
|
+
*
|
|
43
|
+
* Transforms are mutable builders: most transforming methods apply a
|
|
44
|
+
* change immediately and return the transform itself, so that they can
|
|
45
|
+
* be chained. Every method that can fail comes in two flavours:
|
|
46
|
+
*
|
|
47
|
+
* - `x(...)` returns an `Effect` that performs the change when run and
|
|
48
|
+
* succeeds with the transform (or fails with a tagged error, leaving
|
|
49
|
+
* any steps added before the failure in place).
|
|
50
|
+
* - `xUnsafe(...)` performs the change immediately, returning the
|
|
51
|
+
* transform, and throws the tagged error on failure.
|
|
52
|
+
*
|
|
53
|
+
* Methods that cannot fail for valid positions (`addMark`,
|
|
54
|
+
* `removeMark`) are plain chainable methods.
|
|
55
|
+
*
|
|
56
|
+
* @since 0.1.0
|
|
57
|
+
* @category models
|
|
58
|
+
*/
|
|
59
|
+
export declare class Transform<Sc extends AnySchema = AnySchema> {
|
|
60
|
+
/** The steps in this transform. */
|
|
61
|
+
readonly steps: Array<Step<Sc>>;
|
|
62
|
+
/** The documents before each of the steps. */
|
|
63
|
+
readonly docs: Array<Node<Sc>>;
|
|
64
|
+
/** A mapping with the maps for each of the steps in this transform. */
|
|
65
|
+
readonly mapping: Mapping;
|
|
66
|
+
/** @internal */
|
|
67
|
+
protected currentDoc: Node<Sc>;
|
|
68
|
+
/** Create a transform that starts with the given document. */
|
|
69
|
+
constructor(doc: Node<Sc>);
|
|
70
|
+
/** The current document (the result of applying the steps in the transform). */
|
|
71
|
+
get doc(): Node<Sc>;
|
|
72
|
+
/** The starting document. */
|
|
73
|
+
get before(): Node<Sc>;
|
|
74
|
+
/**
|
|
75
|
+
* Apply a new step in this transform, saving the result. Fails with
|
|
76
|
+
* a `StepError` when the step can't be applied.
|
|
77
|
+
*/
|
|
78
|
+
step(step: Step<Sc>): Effect.Effect<this, StepError>;
|
|
79
|
+
/** Like `step`, but throws a `StepError` when the step fails. */
|
|
80
|
+
stepUnsafe(step: Step<Sc>): this;
|
|
81
|
+
/**
|
|
82
|
+
* Try to apply a step in this transformation, ignoring it if it
|
|
83
|
+
* fails. Returns the step result.
|
|
84
|
+
*/
|
|
85
|
+
maybeStep(step: Step<Sc>): StepResult<Sc>;
|
|
86
|
+
/** True when the document has been changed (when there are any steps). */
|
|
87
|
+
get docChanged(): boolean;
|
|
88
|
+
/**
|
|
89
|
+
* Return a single range, in post-transform document positions, that
|
|
90
|
+
* covers all content changed by this transform. Returns `None` if no
|
|
91
|
+
* replacements are made. Note that this will ignore changes that
|
|
92
|
+
* add/remove marks without replacing the underlying content.
|
|
93
|
+
*/
|
|
94
|
+
changedRange(): Option.Option<{
|
|
95
|
+
readonly from: number;
|
|
96
|
+
readonly to: number;
|
|
97
|
+
}>;
|
|
98
|
+
/** @internal */
|
|
99
|
+
addStep(step: Step<Sc>, doc: Node<Sc>): void;
|
|
100
|
+
/** @internal */
|
|
101
|
+
protected effect<E>(f: () => unknown): Effect.Effect<this, E>;
|
|
102
|
+
/** Replace the part of the document between `from` and `to` with the given `slice`. */
|
|
103
|
+
replace(from: number, to?: number, slice?: Slice<Sc>): Effect.Effect<this, ReplaceFailure>;
|
|
104
|
+
/** Like `replace`, but throws on failure. */
|
|
105
|
+
replaceUnsafe(from: number, to?: number, slice?: Slice<Sc>): this;
|
|
106
|
+
/**
|
|
107
|
+
* Replace the given range with the given content, which may be a
|
|
108
|
+
* fragment, node, or array of nodes.
|
|
109
|
+
*/
|
|
110
|
+
replaceWith(from: number, to: number, content: ContentInput<Sc>): Effect.Effect<this, ReplaceFailure>;
|
|
111
|
+
/** Like `replaceWith`, but throws on failure. */
|
|
112
|
+
replaceWithUnsafe(from: number, to: number, content: ContentInput<Sc>): this;
|
|
113
|
+
/** Delete the content between the given positions. */
|
|
114
|
+
delete(from: number, to: number): Effect.Effect<this, ReplaceFailure>;
|
|
115
|
+
/** Like `delete`, but throws on failure. */
|
|
116
|
+
deleteUnsafe(from: number, to: number): this;
|
|
117
|
+
/** Insert the given content at the given position. */
|
|
118
|
+
insert(pos: number, content: ContentInput<Sc>): Effect.Effect<this, ReplaceFailure>;
|
|
119
|
+
/** Like `insert`, but throws on failure. */
|
|
120
|
+
insertUnsafe(pos: number, content: ContentInput<Sc>): this;
|
|
121
|
+
/**
|
|
122
|
+
* Replace a range of the document with a given slice, using `from`,
|
|
123
|
+
* `to`, and the slice's `openStart` property as hints, rather than
|
|
124
|
+
* fixed start and end points. This method may grow the replaced area
|
|
125
|
+
* or close open nodes in the slice in order to get a fit that is
|
|
126
|
+
* more in line with WYSIWYG expectations, by dropping fully covered
|
|
127
|
+
* parent nodes of the replaced region when they are marked
|
|
128
|
+
* non-defining as context, or including an open parent node from the
|
|
129
|
+
* slice that _is_ marked as defining its content.
|
|
130
|
+
*
|
|
131
|
+
* This is the method, for example, to handle paste. The similar
|
|
132
|
+
* `replace` method is a more primitive tool which will _not_ move the
|
|
133
|
+
* start and end of its given range, and is useful in situations where
|
|
134
|
+
* you need more precise control over what happens.
|
|
135
|
+
*/
|
|
136
|
+
replaceRange(from: number, to: number, slice: Slice<Sc>): Effect.Effect<this, ReplaceFailure>;
|
|
137
|
+
/** Like `replaceRange`, but throws on failure. */
|
|
138
|
+
replaceRangeUnsafe(from: number, to: number, slice: Slice<Sc>): this;
|
|
139
|
+
/**
|
|
140
|
+
* Replace the given range with a node, but use `from` and `to` as
|
|
141
|
+
* hints, rather than precise positions. When from and to are the same
|
|
142
|
+
* and are at the start or end of a parent node in which the given
|
|
143
|
+
* node doesn't fit, this method may _move_ them out towards a parent
|
|
144
|
+
* that does allow the given node to be placed. When the given range
|
|
145
|
+
* completely covers a parent node, this method may completely replace
|
|
146
|
+
* that parent node.
|
|
147
|
+
*/
|
|
148
|
+
replaceRangeWith(from: number, to: number, node: Node<Sc>): Effect.Effect<this, ReplaceFailure>;
|
|
149
|
+
/** Like `replaceRangeWith`, but throws on failure. */
|
|
150
|
+
replaceRangeWithUnsafe(from: number, to: number, node: Node<Sc>): this;
|
|
151
|
+
/**
|
|
152
|
+
* Delete the given range, expanding it to cover fully covered parent
|
|
153
|
+
* nodes until a valid replace is found.
|
|
154
|
+
*/
|
|
155
|
+
deleteRange(from: number, to: number): Effect.Effect<this, ReplaceFailure>;
|
|
156
|
+
/** Like `deleteRange`, but throws on failure. */
|
|
157
|
+
deleteRangeUnsafe(from: number, to: number): this;
|
|
158
|
+
/**
|
|
159
|
+
* Split the content in the given range off from its parent, if there
|
|
160
|
+
* is sibling content before or after it, and move it up the tree to
|
|
161
|
+
* the depth specified by `target`. You'll probably want to use
|
|
162
|
+
* `liftTarget` to compute `target`, to make sure the lift is valid.
|
|
163
|
+
*/
|
|
164
|
+
lift(range: NodeRange<Sc>, target: number): Effect.Effect<this, StructureFailure>;
|
|
165
|
+
/** Like `lift`, but throws on failure. */
|
|
166
|
+
liftUnsafe(range: NodeRange<Sc>, target: number): this;
|
|
167
|
+
/**
|
|
168
|
+
* Join the blocks around the given position. If depth is 2, their
|
|
169
|
+
* last and first siblings are also joined, and so on.
|
|
170
|
+
*/
|
|
171
|
+
join(pos: number, depth?: number): Effect.Effect<this, StructureFailure>;
|
|
172
|
+
/** Like `join`, but throws on failure. */
|
|
173
|
+
joinUnsafe(pos: number, depth?: number): this;
|
|
174
|
+
/**
|
|
175
|
+
* Wrap the given range in the given set of wrappers. The wrappers are
|
|
176
|
+
* assumed to be valid in this position, and should probably be
|
|
177
|
+
* computed with `findWrapping`.
|
|
178
|
+
*/
|
|
179
|
+
wrap(range: NodeRange<Sc>, wrappers: ReadonlyArray<NodeTypeWithAttrs<Sc>>): Effect.Effect<this, StructureFailure>;
|
|
180
|
+
/** Like `wrap`, but throws on failure. */
|
|
181
|
+
wrapUnsafe(range: NodeRange<Sc>, wrappers: ReadonlyArray<NodeTypeWithAttrs<Sc>>): this;
|
|
182
|
+
/**
|
|
183
|
+
* Set the type of all textblocks (partly) between `from` and `to` to
|
|
184
|
+
* the given node type with the given attributes. `to` defaults to
|
|
185
|
+
* `from`.
|
|
186
|
+
*/
|
|
187
|
+
setBlockType<N extends NodeNames<Sc>>(from: number, to: number | undefined, type: NodeType<Sc, N>, attrs?: NodeAttrsInput<Sc, N> | null | ((oldNode: Node<Sc>) => NodeAttrsInput<Sc, N>)): Effect.Effect<this, StructureFailure>;
|
|
188
|
+
/** Like `setBlockType`, but throws on failure. */
|
|
189
|
+
setBlockTypeUnsafe<N extends NodeNames<Sc>>(from: number, to: number | undefined, type: NodeType<Sc, N>, attrs?: NodeAttrsInput<Sc, N> | null | ((oldNode: Node<Sc>) => NodeAttrsInput<Sc, N>)): this;
|
|
190
|
+
/**
|
|
191
|
+
* Change the type, attributes, and/or marks of the node at `pos`.
|
|
192
|
+
* When `type` isn't given, the existing node type is preserved.
|
|
193
|
+
*/
|
|
194
|
+
setNodeMarkup<N extends NodeNames<Sc>>(pos: number, type?: NodeType<Sc, N> | null, attrs?: NodeAttrsInput<Sc, N> | null, marks?: ReadonlyArray<Mark<Sc>>): Effect.Effect<this, StructureFailure>;
|
|
195
|
+
/** Like `setNodeMarkup`, but throws on failure. */
|
|
196
|
+
setNodeMarkupUnsafe<N extends NodeNames<Sc>>(pos: number, type?: NodeType<Sc, N> | null, attrs?: NodeAttrsInput<Sc, N> | null, marks?: ReadonlyArray<Mark<Sc>>): this;
|
|
197
|
+
/**
|
|
198
|
+
* Set a single attribute on a given node to a new value. The `pos`
|
|
199
|
+
* addresses the document content. Use `setDocAttribute` to set
|
|
200
|
+
* attributes on the document itself.
|
|
201
|
+
*/
|
|
202
|
+
setNodeAttribute(pos: number, attr: string, value: unknown): Effect.Effect<this, StepError>;
|
|
203
|
+
/** Like `setNodeAttribute`, but throws on failure. */
|
|
204
|
+
setNodeAttributeUnsafe(pos: number, attr: string, value: unknown): this;
|
|
205
|
+
/** Set a single attribute on the document to a new value. */
|
|
206
|
+
setDocAttribute(attr: string, value: unknown): Effect.Effect<this, StepError>;
|
|
207
|
+
/** Like `setDocAttribute`, but throws on failure. */
|
|
208
|
+
setDocAttributeUnsafe(attr: string, value: unknown): this;
|
|
209
|
+
/** Add a mark to the node at position `pos`. */
|
|
210
|
+
addNodeMark(pos: number, mark: Mark<Sc>): Effect.Effect<this, StepError>;
|
|
211
|
+
/** Like `addNodeMark`, but throws on failure. */
|
|
212
|
+
addNodeMarkUnsafe(pos: number, mark: Mark<Sc>): this;
|
|
213
|
+
/**
|
|
214
|
+
* Remove a mark (or all marks of the given type) from the node at
|
|
215
|
+
* position `pos`. Fails with a `TransformError` when there is no node
|
|
216
|
+
* at that position.
|
|
217
|
+
*/
|
|
218
|
+
removeNodeMark(pos: number, mark: Mark<Sc> | MarkType<Sc>): Effect.Effect<this, TransformError | StepError>;
|
|
219
|
+
/** Like `removeNodeMark`, but throws on failure. */
|
|
220
|
+
removeNodeMarkUnsafe(pos: number, mark: Mark<Sc> | MarkType<Sc>): this;
|
|
221
|
+
/**
|
|
222
|
+
* Split the node at the given position, and optionally, if `depth` is
|
|
223
|
+
* greater than one, any number of nodes above that. By default, the
|
|
224
|
+
* parts split off will inherit the node type of the original node.
|
|
225
|
+
* This can be changed by passing an array of types and attributes to
|
|
226
|
+
* use after the split (with the outermost nodes coming first).
|
|
227
|
+
*/
|
|
228
|
+
split(pos: number, depth?: number, typesAfter?: ReadonlyArray<NodeTypeWithAttrs<Sc> | null | undefined>): Effect.Effect<this, StructureFailure>;
|
|
229
|
+
/** Like `split`, but throws on failure. */
|
|
230
|
+
splitUnsafe(pos: number, depth?: number, typesAfter?: ReadonlyArray<NodeTypeWithAttrs<Sc> | null | undefined>): this;
|
|
231
|
+
/** Add the given mark to the inline content between `from` and `to`. */
|
|
232
|
+
addMark(from: number, to: number, mark: Mark<Sc>): this;
|
|
233
|
+
/**
|
|
234
|
+
* Remove marks from inline nodes between `from` and `to`. When `mark`
|
|
235
|
+
* is a single mark, remove precisely that mark. When it is a mark
|
|
236
|
+
* type, remove all marks of that type. When it is null, remove all
|
|
237
|
+
* marks of any type.
|
|
238
|
+
*/
|
|
239
|
+
removeMark(from: number, to: number, mark?: Mark<Sc> | MarkType<Sc> | null): this;
|
|
240
|
+
/**
|
|
241
|
+
* Removes all marks and nodes from the content of the node at `pos`
|
|
242
|
+
* that don't match the given new parent node type. Accepts an
|
|
243
|
+
* optional starting content match as third argument.
|
|
244
|
+
*/
|
|
245
|
+
clearIncompatible(pos: number, parentType: NodeType<Sc, any>, match?: ContentMatch): Effect.Effect<this, TransformError | StepError | PositionError>;
|
|
246
|
+
/** Like `clearIncompatible`, but throws on failure. */
|
|
247
|
+
clearIncompatibleUnsafe(pos: number, parentType: NodeType<Sc, any>, match?: ContentMatch): this;
|
|
248
|
+
}
|
|
@@ -0,0 +1,373 @@
|
|
|
1
|
+
import { attempt } from "../internal/attempt.js";
|
|
2
|
+
import { Fragment } from "../model/fragment.js";
|
|
3
|
+
import { Mark } from "../model/mark.js";
|
|
4
|
+
import { Slice } from "../model/replace.js";
|
|
5
|
+
import { AttrStep, DocAttrStep } from "./attr_step.js";
|
|
6
|
+
import { TransformError, isTransformOrModelError } from "./errors.js";
|
|
7
|
+
import { Mapping } from "./map.js";
|
|
8
|
+
import { addMark, clearIncompatible, removeMark } from "./mark.js";
|
|
9
|
+
import { AddNodeMarkStep, RemoveNodeMarkStep } from "./mark_step.js";
|
|
10
|
+
import { deleteRange, replaceRange, replaceRangeWith, replaceStepOrNull } from "./replace.js";
|
|
11
|
+
import { applyStep } from "./step.js";
|
|
12
|
+
import { join, lift, setBlockType, setNodeMarkup, split, wrap } from "./structure.js";
|
|
13
|
+
import * as Arr from "effect/Array";
|
|
14
|
+
import * as Option from "effect/Option";
|
|
15
|
+
// src/transform/transform.ts
|
|
16
|
+
/**
|
|
17
|
+
* The `Transform` class: a mutable, chainable builder of document
|
|
18
|
+
* changes.
|
|
19
|
+
*
|
|
20
|
+
* @since 0.1.0
|
|
21
|
+
*/
|
|
22
|
+
/**
|
|
23
|
+
* Abstraction to build up and track an array of steps representing a
|
|
24
|
+
* document transformation.
|
|
25
|
+
*
|
|
26
|
+
* Transforms are mutable builders: most transforming methods apply a
|
|
27
|
+
* change immediately and return the transform itself, so that they can
|
|
28
|
+
* be chained. Every method that can fail comes in two flavours:
|
|
29
|
+
*
|
|
30
|
+
* - `x(...)` returns an `Effect` that performs the change when run and
|
|
31
|
+
* succeeds with the transform (or fails with a tagged error, leaving
|
|
32
|
+
* any steps added before the failure in place).
|
|
33
|
+
* - `xUnsafe(...)` performs the change immediately, returning the
|
|
34
|
+
* transform, and throws the tagged error on failure.
|
|
35
|
+
*
|
|
36
|
+
* Methods that cannot fail for valid positions (`addMark`,
|
|
37
|
+
* `removeMark`) are plain chainable methods.
|
|
38
|
+
*
|
|
39
|
+
* @since 0.1.0
|
|
40
|
+
* @category models
|
|
41
|
+
*/
|
|
42
|
+
var Transform = class {
|
|
43
|
+
/** Create a transform that starts with the given document. */
|
|
44
|
+
constructor(doc) {
|
|
45
|
+
this.steps = [];
|
|
46
|
+
this.docs = [];
|
|
47
|
+
this.mapping = new Mapping();
|
|
48
|
+
this.currentDoc = doc;
|
|
49
|
+
}
|
|
50
|
+
/** The current document (the result of applying the steps in the transform). */
|
|
51
|
+
get doc() {
|
|
52
|
+
return this.currentDoc;
|
|
53
|
+
}
|
|
54
|
+
/** The starting document. */
|
|
55
|
+
get before() {
|
|
56
|
+
return this.docs.length ? this.docs[0] : this.currentDoc;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Apply a new step in this transform, saving the result. Fails with
|
|
60
|
+
* a `StepError` when the step can't be applied.
|
|
61
|
+
*/
|
|
62
|
+
step(step) {
|
|
63
|
+
return attempt(() => this.stepUnsafe(step), isTransformOrModelError);
|
|
64
|
+
}
|
|
65
|
+
/** Like `step`, but throws a `StepError` when the step fails. */
|
|
66
|
+
stepUnsafe(step) {
|
|
67
|
+
const result = this.maybeStep(step);
|
|
68
|
+
if (result.failedOrNull !== null) result.getUnsafe();
|
|
69
|
+
return this;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Try to apply a step in this transformation, ignoring it if it
|
|
73
|
+
* fails. Returns the step result.
|
|
74
|
+
*/
|
|
75
|
+
maybeStep(step) {
|
|
76
|
+
const result = applyStep(step, this.currentDoc);
|
|
77
|
+
if (result.failedOrNull === null) this.addStep(step, result.docOrNull);
|
|
78
|
+
return result;
|
|
79
|
+
}
|
|
80
|
+
/** True when the document has been changed (when there are any steps). */
|
|
81
|
+
get docChanged() {
|
|
82
|
+
return Arr.isReadonlyArrayNonEmpty(this.steps);
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Return a single range, in post-transform document positions, that
|
|
86
|
+
* covers all content changed by this transform. Returns `None` if no
|
|
87
|
+
* replacements are made. Note that this will ignore changes that
|
|
88
|
+
* add/remove marks without replacing the underlying content.
|
|
89
|
+
*/
|
|
90
|
+
changedRange() {
|
|
91
|
+
let from = 1e9, to = -1e9;
|
|
92
|
+
for (let i = 0; i < this.mapping.maps.length; i++) {
|
|
93
|
+
const map = this.mapping.maps[i];
|
|
94
|
+
if (i) {
|
|
95
|
+
from = map.map(from, 1);
|
|
96
|
+
to = map.map(to, -1);
|
|
97
|
+
}
|
|
98
|
+
map.forEach((_f, _t, fromB, toB) => {
|
|
99
|
+
from = Math.min(from, fromB);
|
|
100
|
+
to = Math.max(to, toB);
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
return from === 1e9 ? Option.none() : Option.some({
|
|
104
|
+
from,
|
|
105
|
+
to
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
/** @internal */
|
|
109
|
+
addStep(step, doc) {
|
|
110
|
+
this.docs.push(this.currentDoc);
|
|
111
|
+
this.steps.push(step);
|
|
112
|
+
this.mapping.appendMap(step.getMap());
|
|
113
|
+
this.currentDoc = doc;
|
|
114
|
+
}
|
|
115
|
+
/** @internal */
|
|
116
|
+
effect(f) {
|
|
117
|
+
return attempt(() => {
|
|
118
|
+
f();
|
|
119
|
+
return this;
|
|
120
|
+
}, isTransformOrModelError);
|
|
121
|
+
}
|
|
122
|
+
/** Replace the part of the document between `from` and `to` with the given `slice`. */
|
|
123
|
+
replace(from, to = from, slice = Slice.empty) {
|
|
124
|
+
return this.effect(() => this.replaceUnsafe(from, to, slice));
|
|
125
|
+
}
|
|
126
|
+
/** Like `replace`, but throws on failure. */
|
|
127
|
+
replaceUnsafe(from, to = from, slice = Slice.empty) {
|
|
128
|
+
const step = replaceStepOrNull(this.currentDoc, from, to, slice);
|
|
129
|
+
if (step) this.stepUnsafe(step);
|
|
130
|
+
return this;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Replace the given range with the given content, which may be a
|
|
134
|
+
* fragment, node, or array of nodes.
|
|
135
|
+
*/
|
|
136
|
+
replaceWith(from, to, content) {
|
|
137
|
+
return this.effect(() => this.replaceWithUnsafe(from, to, content));
|
|
138
|
+
}
|
|
139
|
+
/** Like `replaceWith`, but throws on failure. */
|
|
140
|
+
replaceWithUnsafe(from, to, content) {
|
|
141
|
+
return this.replaceUnsafe(from, to, new Slice(Fragment.from(content), 0, 0));
|
|
142
|
+
}
|
|
143
|
+
/** Delete the content between the given positions. */
|
|
144
|
+
delete(from, to) {
|
|
145
|
+
return this.effect(() => this.deleteUnsafe(from, to));
|
|
146
|
+
}
|
|
147
|
+
/** Like `delete`, but throws on failure. */
|
|
148
|
+
deleteUnsafe(from, to) {
|
|
149
|
+
return this.replaceUnsafe(from, to, Slice.empty);
|
|
150
|
+
}
|
|
151
|
+
/** Insert the given content at the given position. */
|
|
152
|
+
insert(pos, content) {
|
|
153
|
+
return this.effect(() => this.insertUnsafe(pos, content));
|
|
154
|
+
}
|
|
155
|
+
/** Like `insert`, but throws on failure. */
|
|
156
|
+
insertUnsafe(pos, content) {
|
|
157
|
+
return this.replaceWithUnsafe(pos, pos, content);
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Replace a range of the document with a given slice, using `from`,
|
|
161
|
+
* `to`, and the slice's `openStart` property as hints, rather than
|
|
162
|
+
* fixed start and end points. This method may grow the replaced area
|
|
163
|
+
* or close open nodes in the slice in order to get a fit that is
|
|
164
|
+
* more in line with WYSIWYG expectations, by dropping fully covered
|
|
165
|
+
* parent nodes of the replaced region when they are marked
|
|
166
|
+
* non-defining as context, or including an open parent node from the
|
|
167
|
+
* slice that _is_ marked as defining its content.
|
|
168
|
+
*
|
|
169
|
+
* This is the method, for example, to handle paste. The similar
|
|
170
|
+
* `replace` method is a more primitive tool which will _not_ move the
|
|
171
|
+
* start and end of its given range, and is useful in situations where
|
|
172
|
+
* you need more precise control over what happens.
|
|
173
|
+
*/
|
|
174
|
+
replaceRange(from, to, slice) {
|
|
175
|
+
return this.effect(() => this.replaceRangeUnsafe(from, to, slice));
|
|
176
|
+
}
|
|
177
|
+
/** Like `replaceRange`, but throws on failure. */
|
|
178
|
+
replaceRangeUnsafe(from, to, slice) {
|
|
179
|
+
replaceRange(this, from, to, slice);
|
|
180
|
+
return this;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Replace the given range with a node, but use `from` and `to` as
|
|
184
|
+
* hints, rather than precise positions. When from and to are the same
|
|
185
|
+
* and are at the start or end of a parent node in which the given
|
|
186
|
+
* node doesn't fit, this method may _move_ them out towards a parent
|
|
187
|
+
* that does allow the given node to be placed. When the given range
|
|
188
|
+
* completely covers a parent node, this method may completely replace
|
|
189
|
+
* that parent node.
|
|
190
|
+
*/
|
|
191
|
+
replaceRangeWith(from, to, node) {
|
|
192
|
+
return this.effect(() => this.replaceRangeWithUnsafe(from, to, node));
|
|
193
|
+
}
|
|
194
|
+
/** Like `replaceRangeWith`, but throws on failure. */
|
|
195
|
+
replaceRangeWithUnsafe(from, to, node) {
|
|
196
|
+
replaceRangeWith(this, from, to, node);
|
|
197
|
+
return this;
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Delete the given range, expanding it to cover fully covered parent
|
|
201
|
+
* nodes until a valid replace is found.
|
|
202
|
+
*/
|
|
203
|
+
deleteRange(from, to) {
|
|
204
|
+
return this.effect(() => this.deleteRangeUnsafe(from, to));
|
|
205
|
+
}
|
|
206
|
+
/** Like `deleteRange`, but throws on failure. */
|
|
207
|
+
deleteRangeUnsafe(from, to) {
|
|
208
|
+
deleteRange(this, from, to);
|
|
209
|
+
return this;
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Split the content in the given range off from its parent, if there
|
|
213
|
+
* is sibling content before or after it, and move it up the tree to
|
|
214
|
+
* the depth specified by `target`. You'll probably want to use
|
|
215
|
+
* `liftTarget` to compute `target`, to make sure the lift is valid.
|
|
216
|
+
*/
|
|
217
|
+
lift(range, target) {
|
|
218
|
+
return this.effect(() => this.liftUnsafe(range, target));
|
|
219
|
+
}
|
|
220
|
+
/** Like `lift`, but throws on failure. */
|
|
221
|
+
liftUnsafe(range, target) {
|
|
222
|
+
lift(this, range, target);
|
|
223
|
+
return this;
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Join the blocks around the given position. If depth is 2, their
|
|
227
|
+
* last and first siblings are also joined, and so on.
|
|
228
|
+
*/
|
|
229
|
+
join(pos, depth = 1) {
|
|
230
|
+
return this.effect(() => this.joinUnsafe(pos, depth));
|
|
231
|
+
}
|
|
232
|
+
/** Like `join`, but throws on failure. */
|
|
233
|
+
joinUnsafe(pos, depth = 1) {
|
|
234
|
+
join(this, pos, depth);
|
|
235
|
+
return this;
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Wrap the given range in the given set of wrappers. The wrappers are
|
|
239
|
+
* assumed to be valid in this position, and should probably be
|
|
240
|
+
* computed with `findWrapping`.
|
|
241
|
+
*/
|
|
242
|
+
wrap(range, wrappers) {
|
|
243
|
+
return this.effect(() => this.wrapUnsafe(range, wrappers));
|
|
244
|
+
}
|
|
245
|
+
/** Like `wrap`, but throws on failure. */
|
|
246
|
+
wrapUnsafe(range, wrappers) {
|
|
247
|
+
wrap(this, range, wrappers);
|
|
248
|
+
return this;
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Set the type of all textblocks (partly) between `from` and `to` to
|
|
252
|
+
* the given node type with the given attributes. `to` defaults to
|
|
253
|
+
* `from`.
|
|
254
|
+
*/
|
|
255
|
+
setBlockType(from, to, type, attrs) {
|
|
256
|
+
return this.effect(() => this.setBlockTypeUnsafe(from, to, type, attrs));
|
|
257
|
+
}
|
|
258
|
+
/** Like `setBlockType`, but throws on failure. */
|
|
259
|
+
setBlockTypeUnsafe(from, to, type, attrs) {
|
|
260
|
+
setBlockType(this, from, to ?? from, type, attrs);
|
|
261
|
+
return this;
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Change the type, attributes, and/or marks of the node at `pos`.
|
|
265
|
+
* When `type` isn't given, the existing node type is preserved.
|
|
266
|
+
*/
|
|
267
|
+
setNodeMarkup(pos, type, attrs, marks) {
|
|
268
|
+
return this.effect(() => this.setNodeMarkupUnsafe(pos, type, attrs, marks));
|
|
269
|
+
}
|
|
270
|
+
/** Like `setNodeMarkup`, but throws on failure. */
|
|
271
|
+
setNodeMarkupUnsafe(pos, type, attrs, marks) {
|
|
272
|
+
setNodeMarkup(this, pos, type, attrs, marks);
|
|
273
|
+
return this;
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Set a single attribute on a given node to a new value. The `pos`
|
|
277
|
+
* addresses the document content. Use `setDocAttribute` to set
|
|
278
|
+
* attributes on the document itself.
|
|
279
|
+
*/
|
|
280
|
+
setNodeAttribute(pos, attr, value) {
|
|
281
|
+
return this.effect(() => this.setNodeAttributeUnsafe(pos, attr, value));
|
|
282
|
+
}
|
|
283
|
+
/** Like `setNodeAttribute`, but throws on failure. */
|
|
284
|
+
setNodeAttributeUnsafe(pos, attr, value) {
|
|
285
|
+
return this.stepUnsafe(new AttrStep(pos, attr, value));
|
|
286
|
+
}
|
|
287
|
+
/** Set a single attribute on the document to a new value. */
|
|
288
|
+
setDocAttribute(attr, value) {
|
|
289
|
+
return this.effect(() => this.setDocAttributeUnsafe(attr, value));
|
|
290
|
+
}
|
|
291
|
+
/** Like `setDocAttribute`, but throws on failure. */
|
|
292
|
+
setDocAttributeUnsafe(attr, value) {
|
|
293
|
+
return this.stepUnsafe(new DocAttrStep(attr, value));
|
|
294
|
+
}
|
|
295
|
+
/** Add a mark to the node at position `pos`. */
|
|
296
|
+
addNodeMark(pos, mark) {
|
|
297
|
+
return this.effect(() => this.addNodeMarkUnsafe(pos, mark));
|
|
298
|
+
}
|
|
299
|
+
/** Like `addNodeMark`, but throws on failure. */
|
|
300
|
+
addNodeMarkUnsafe(pos, mark) {
|
|
301
|
+
return this.stepUnsafe(new AddNodeMarkStep(pos, mark));
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Remove a mark (or all marks of the given type) from the node at
|
|
305
|
+
* position `pos`. Fails with a `TransformError` when there is no node
|
|
306
|
+
* at that position.
|
|
307
|
+
*/
|
|
308
|
+
removeNodeMark(pos, mark) {
|
|
309
|
+
return this.effect(() => this.removeNodeMarkUnsafe(pos, mark));
|
|
310
|
+
}
|
|
311
|
+
/** Like `removeNodeMark`, but throws on failure. */
|
|
312
|
+
removeNodeMarkUnsafe(pos, mark) {
|
|
313
|
+
const node = this.currentDoc.nodeAtOrNull(pos);
|
|
314
|
+
if (!node) throw new TransformError({ message: "No node at position " + pos });
|
|
315
|
+
if (mark instanceof Mark) {
|
|
316
|
+
if (mark.isInSet(node.marks)) this.stepUnsafe(new RemoveNodeMarkStep(pos, mark));
|
|
317
|
+
} else {
|
|
318
|
+
let set = node.marks, found;
|
|
319
|
+
const steps = [];
|
|
320
|
+
while (found = mark.findInSet(set)) {
|
|
321
|
+
steps.push(new RemoveNodeMarkStep(pos, found));
|
|
322
|
+
set = found.removeFromSet(set);
|
|
323
|
+
}
|
|
324
|
+
for (let i = steps.length - 1; i >= 0; i--) this.stepUnsafe(steps[i]);
|
|
325
|
+
}
|
|
326
|
+
return this;
|
|
327
|
+
}
|
|
328
|
+
/**
|
|
329
|
+
* Split the node at the given position, and optionally, if `depth` is
|
|
330
|
+
* greater than one, any number of nodes above that. By default, the
|
|
331
|
+
* parts split off will inherit the node type of the original node.
|
|
332
|
+
* This can be changed by passing an array of types and attributes to
|
|
333
|
+
* use after the split (with the outermost nodes coming first).
|
|
334
|
+
*/
|
|
335
|
+
split(pos, depth = 1, typesAfter) {
|
|
336
|
+
return this.effect(() => this.splitUnsafe(pos, depth, typesAfter));
|
|
337
|
+
}
|
|
338
|
+
/** Like `split`, but throws on failure. */
|
|
339
|
+
splitUnsafe(pos, depth = 1, typesAfter) {
|
|
340
|
+
split(this, pos, depth, typesAfter);
|
|
341
|
+
return this;
|
|
342
|
+
}
|
|
343
|
+
/** Add the given mark to the inline content between `from` and `to`. */
|
|
344
|
+
addMark(from, to, mark) {
|
|
345
|
+
addMark(this, from, to, mark);
|
|
346
|
+
return this;
|
|
347
|
+
}
|
|
348
|
+
/**
|
|
349
|
+
* Remove marks from inline nodes between `from` and `to`. When `mark`
|
|
350
|
+
* is a single mark, remove precisely that mark. When it is a mark
|
|
351
|
+
* type, remove all marks of that type. When it is null, remove all
|
|
352
|
+
* marks of any type.
|
|
353
|
+
*/
|
|
354
|
+
removeMark(from, to, mark) {
|
|
355
|
+
removeMark(this, from, to, mark);
|
|
356
|
+
return this;
|
|
357
|
+
}
|
|
358
|
+
/**
|
|
359
|
+
* Removes all marks and nodes from the content of the node at `pos`
|
|
360
|
+
* that don't match the given new parent node type. Accepts an
|
|
361
|
+
* optional starting content match as third argument.
|
|
362
|
+
*/
|
|
363
|
+
clearIncompatible(pos, parentType, match) {
|
|
364
|
+
return this.effect(() => this.clearIncompatibleUnsafe(pos, parentType, match));
|
|
365
|
+
}
|
|
366
|
+
/** Like `clearIncompatible`, but throws on failure. */
|
|
367
|
+
clearIncompatibleUnsafe(pos, parentType, match) {
|
|
368
|
+
if (!this.currentDoc.nodeAtOrNull(pos)) throw new TransformError({ message: "No node at position " + pos });
|
|
369
|
+
clearIncompatible(this, pos, parentType, match);
|
|
370
|
+
return this;
|
|
371
|
+
}
|
|
372
|
+
};
|
|
373
|
+
export { Transform };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { AttrStep, DocAttrStep } from "./transform/attr_step.js";
|
|
2
|
+
import { StepError, TransformError, TransformFailure, TransformOrModelError, isTransformFailure, isTransformOrModelError } from "./transform/errors.js";
|
|
3
|
+
import { MapResult, Mappable, Mapping, StepMap } from "./transform/map.js";
|
|
4
|
+
import { AddMarkStep, AddNodeMarkStep, RemoveMarkStep, RemoveNodeMarkStep } from "./transform/mark_step.js";
|
|
5
|
+
import { replaceStep } from "./transform/replace.js";
|
|
6
|
+
import { ReplaceAroundStep, ReplaceStep } from "./transform/replace_step.js";
|
|
7
|
+
import { Step, StepDeserializer, StepFromJSON, StepJSON, StepResult, applyStep } from "./transform/step.js";
|
|
8
|
+
import { NodeTypeWithAttrs, canJoin, canSplit, dropPoint, findWrapping, insertPoint, joinPoint, liftTarget } from "./transform/structure.js";
|
|
9
|
+
import { ContentInput, ReplaceFailure, StructureFailure, Transform } from "./transform/transform.js";
|
|
10
|
+
export { AddMarkStep, AddNodeMarkStep, AttrStep, ContentInput, DocAttrStep, MapResult, Mappable, Mapping, type NodeTypeWithAttrs, RemoveMarkStep, RemoveNodeMarkStep, ReplaceAroundStep, ReplaceFailure, ReplaceStep, Step, StepDeserializer, StepError, StepFromJSON, StepJSON, StepMap, StepResult, StructureFailure, Transform, TransformError, TransformFailure, TransformOrModelError, applyStep, canJoin, canSplit, dropPoint, findWrapping, insertPoint, isTransformFailure, isTransformOrModelError, joinPoint, liftTarget, replaceStep };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { AttrStep, DocAttrStep } from "./transform/attr_step.js";
|
|
2
|
+
import { StepError, TransformError, isTransformFailure, isTransformOrModelError } from "./transform/errors.js";
|
|
3
|
+
import { MapResult, Mapping, StepMap } from "./transform/map.js";
|
|
4
|
+
import { AddMarkStep, AddNodeMarkStep, RemoveMarkStep, RemoveNodeMarkStep } from "./transform/mark_step.js";
|
|
5
|
+
import { replaceStep } from "./transform/replace.js";
|
|
6
|
+
import { ReplaceAroundStep, ReplaceStep } from "./transform/replace_step.js";
|
|
7
|
+
import { Step, StepFromJSON, StepResult, applyStep } from "./transform/step.js";
|
|
8
|
+
import { canJoin, canSplit, dropPoint, findWrapping, insertPoint, joinPoint, liftTarget } from "./transform/structure.js";
|
|
9
|
+
import { Transform } from "./transform/transform.js";
|
|
10
|
+
export { AddMarkStep, AddNodeMarkStep, AttrStep, DocAttrStep, MapResult, Mapping, RemoveMarkStep, RemoveNodeMarkStep, ReplaceAroundStep, ReplaceStep, Step, StepError, StepFromJSON, StepMap, StepResult, Transform, TransformError, applyStep, canJoin, canSplit, dropPoint, findWrapping, insertPoint, isTransformFailure, isTransformOrModelError, joinPoint, liftTarget, replaceStep };
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// src/view/browser.ts
|
|
2
|
+
/**
|
|
3
|
+
* Browser detection.
|
|
4
|
+
*
|
|
5
|
+
* @internal
|
|
6
|
+
*/
|
|
7
|
+
const nav = typeof navigator != "undefined" ? navigator : null;
|
|
8
|
+
const doc = typeof document != "undefined" ? document : null;
|
|
9
|
+
const agent = nav && nav.userAgent || "";
|
|
10
|
+
const ie_edge = /Edge\/(\d+)/.exec(agent);
|
|
11
|
+
const ie_upto10 = /MSIE \d/.exec(agent);
|
|
12
|
+
const ie_11up = /Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(agent);
|
|
13
|
+
/** @internal */
|
|
14
|
+
const ie = !!(ie_upto10 || ie_11up || ie_edge);
|
|
15
|
+
/** @internal */
|
|
16
|
+
const ie_version = ie_upto10 ? document.documentMode : ie_11up ? +ie_11up[1] : ie_edge ? +ie_edge[1] : 0;
|
|
17
|
+
/** @internal */
|
|
18
|
+
const gecko = !ie && /gecko\/(\d+)/i.test(agent);
|
|
19
|
+
gecko && +(/Firefox\/(\d+)/.exec(agent) || [0, 0])[1];
|
|
20
|
+
const _chrome = !ie && /Chrome\/(\d+)/.exec(agent);
|
|
21
|
+
/** @internal */
|
|
22
|
+
const chrome = !!_chrome;
|
|
23
|
+
/** @internal */
|
|
24
|
+
const chrome_version = _chrome ? +_chrome[1] : 0;
|
|
25
|
+
/** @internal */
|
|
26
|
+
const safari = !ie && !!nav && /Apple Computer/.test(nav.vendor);
|
|
27
|
+
/** @internal */
|
|
28
|
+
const ios = safari && (/Mobile\/\w+/.test(agent) || !!nav && nav.maxTouchPoints > 2);
|
|
29
|
+
/** @internal */
|
|
30
|
+
const mac = ios || (nav ? /Mac/.test(nav.platform) : false);
|
|
31
|
+
/** @internal */
|
|
32
|
+
const windows = nav ? /Win/.test(nav.platform) : false;
|
|
33
|
+
/** @internal */
|
|
34
|
+
const android = /Android \d/.test(agent);
|
|
35
|
+
/** @internal */
|
|
36
|
+
const webkit = !!doc && "webkitFontSmoothing" in doc.documentElement.style;
|
|
37
|
+
/** @internal */
|
|
38
|
+
const webkit_version = webkit ? +(/\bAppleWebKit\/(\d+)/.exec(navigator.userAgent) || [0, 0])[1] : 0;
|
|
39
|
+
export { android, chrome, chrome_version, gecko, ie, ie_version, ios, mac, safari, webkit, webkit_version, windows };
|