@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,207 @@
|
|
|
1
|
+
import { JSONError, PositionError, ReplaceError } from "./errors.js";
|
|
2
|
+
import { Fragment } from "./fragment.js";
|
|
3
|
+
import * as Equal from "effect/Equal";
|
|
4
|
+
import * as Hash from "effect/Hash";
|
|
5
|
+
// src/model/replace.ts
|
|
6
|
+
/**
|
|
7
|
+
* Slices and the replace algorithm.
|
|
8
|
+
*
|
|
9
|
+
* @since 0.1.0
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* A slice represents a piece cut out of a larger document. It stores
|
|
13
|
+
* not only a fragment, but also the depth up to which nodes on both
|
|
14
|
+
* side are ‘open’ (cut through).
|
|
15
|
+
*
|
|
16
|
+
* @since 0.1.0
|
|
17
|
+
* @category models
|
|
18
|
+
*/
|
|
19
|
+
var Slice = class Slice {
|
|
20
|
+
/**
|
|
21
|
+
* Create a slice. When specifying a non-zero open depth, you must
|
|
22
|
+
* make sure that there are nodes of at least that depth at the
|
|
23
|
+
* appropriate side of the fragment—i.e. if the fragment is an empty
|
|
24
|
+
* paragraph node, `openStart` and `openEnd` can't be greater than 1.
|
|
25
|
+
*
|
|
26
|
+
* It is not necessary for the content of open nodes to conform to the
|
|
27
|
+
* schema's content constraints, though it should be a valid
|
|
28
|
+
* start/end/middle for such a node, depending on which sides are
|
|
29
|
+
* open.
|
|
30
|
+
*/
|
|
31
|
+
constructor(content, openStart, openEnd) {
|
|
32
|
+
this.content = content;
|
|
33
|
+
this.openStart = openStart;
|
|
34
|
+
this.openEnd = openEnd;
|
|
35
|
+
}
|
|
36
|
+
/** The size this slice would add when inserted into a document. */
|
|
37
|
+
get size() {
|
|
38
|
+
return this.content.size - this.openStart - this.openEnd;
|
|
39
|
+
}
|
|
40
|
+
/** @internal */
|
|
41
|
+
insertAt(pos, fragment) {
|
|
42
|
+
const content = insertInto(this.content, pos + this.openStart, fragment, this.openStart + 1, this.openEnd + 1);
|
|
43
|
+
return content && new Slice(content, this.openStart, this.openEnd);
|
|
44
|
+
}
|
|
45
|
+
/** @internal */
|
|
46
|
+
removeBetween(from, to) {
|
|
47
|
+
return new Slice(removeRange(this.content, from + this.openStart, to + this.openStart), this.openStart, this.openEnd);
|
|
48
|
+
}
|
|
49
|
+
/** Tests whether this slice is equal to another slice. */
|
|
50
|
+
eq(other) {
|
|
51
|
+
return this.content.eq(other.content) && this.openStart === other.openStart && this.openEnd === other.openEnd;
|
|
52
|
+
}
|
|
53
|
+
/** @internal */
|
|
54
|
+
[Equal.symbol](that) {
|
|
55
|
+
return that instanceof Slice && this.eq(that);
|
|
56
|
+
}
|
|
57
|
+
/** @internal */
|
|
58
|
+
[Hash.symbol]() {
|
|
59
|
+
return Hash.combine(Hash.hash(this.content))(Hash.combine(Hash.number(this.openStart))(Hash.number(this.openEnd)));
|
|
60
|
+
}
|
|
61
|
+
/** @internal */
|
|
62
|
+
toString() {
|
|
63
|
+
return this.content + "(" + this.openStart + "," + this.openEnd + ")";
|
|
64
|
+
}
|
|
65
|
+
/** Convert a slice to a JSON-serializable representation. */
|
|
66
|
+
toJSON() {
|
|
67
|
+
if (!this.content.size) return null;
|
|
68
|
+
const json = { content: this.content.toJSON() };
|
|
69
|
+
if (this.openStart > 0) json.openStart = this.openStart;
|
|
70
|
+
if (this.openEnd > 0) json.openEnd = this.openEnd;
|
|
71
|
+
return json;
|
|
72
|
+
}
|
|
73
|
+
/** @internal */
|
|
74
|
+
static fromJSONUnsafe(schema, json) {
|
|
75
|
+
if (!json) return Slice.empty;
|
|
76
|
+
const openStart = json.openStart || 0, openEnd = json.openEnd || 0;
|
|
77
|
+
if (typeof openStart !== "number" || typeof openEnd !== "number") throw new JSONError({ message: "Invalid input for Slice.fromJSON" });
|
|
78
|
+
if (json.content != null && !Array.isArray(json.content)) throw new JSONError({ message: "Invalid input for Slice.fromJSON" });
|
|
79
|
+
const nodes = (json.content ?? []).map((n) => schema.nodeFromJSONUnsafe(n));
|
|
80
|
+
return new Slice(Fragment.fromArray(nodes), openStart, openEnd);
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Create a slice from a fragment by taking the maximum possible open
|
|
84
|
+
* value on both side of the fragment.
|
|
85
|
+
*/
|
|
86
|
+
static maxOpen(fragment, openIsolating = true) {
|
|
87
|
+
let openStart = 0, openEnd = 0;
|
|
88
|
+
for (let n = fragment.content[0]; n && !n.isLeaf; n = n.content.content[0]) {
|
|
89
|
+
if (!openIsolating && n.type.spec.isolating) break;
|
|
90
|
+
openStart++;
|
|
91
|
+
}
|
|
92
|
+
for (let n = fragment.content[fragment.content.length - 1]; n && !n.isLeaf; n = n.content.content[n.content.content.length - 1]) {
|
|
93
|
+
if (!openIsolating && n.type.spec.isolating) break;
|
|
94
|
+
openEnd++;
|
|
95
|
+
}
|
|
96
|
+
return new Slice(fragment, openStart, openEnd);
|
|
97
|
+
}
|
|
98
|
+
static {
|
|
99
|
+
this.empty = new Slice(Fragment.empty, 0, 0);
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
function removeRange(content, from, to) {
|
|
103
|
+
const { index, offset } = content.findIndex(from);
|
|
104
|
+
const child = content.content[index];
|
|
105
|
+
const { index: indexTo, offset: offsetTo } = content.findIndex(to);
|
|
106
|
+
if (offset === from || child.isText) {
|
|
107
|
+
if (offsetTo !== to && !content.content[indexTo].isText) throw new PositionError({ message: "Removing non-flat range" });
|
|
108
|
+
return content.cut(0, from).append(content.cut(to));
|
|
109
|
+
}
|
|
110
|
+
if (index !== indexTo) throw new PositionError({ message: "Removing non-flat range" });
|
|
111
|
+
return content.replaceChild(index, child.copy(removeRange(child.content, from - offset - 1, to - offset - 1)));
|
|
112
|
+
}
|
|
113
|
+
function insertInto(content, dist, insert, openStart, openEnd, parent) {
|
|
114
|
+
const { index, offset } = content.findIndex(dist);
|
|
115
|
+
const child = content.content[index];
|
|
116
|
+
if (offset === dist || child.isText) {
|
|
117
|
+
if (parent && openStart <= 0 && openEnd <= 0 && !parent.canReplace(index, index, insert)) return null;
|
|
118
|
+
return content.cut(0, dist).append(insert).append(content.cut(dist));
|
|
119
|
+
}
|
|
120
|
+
const inner = insertInto(child.content, dist - offset - 1, insert, index === 0 ? openStart - 1 : 0, index === content.childCount - 1 ? openEnd - 1 : 0, child);
|
|
121
|
+
return inner && content.replaceChild(index, child.copy(inner));
|
|
122
|
+
}
|
|
123
|
+
/** @internal */
|
|
124
|
+
function replace($from, $to, slice) {
|
|
125
|
+
if (slice.openStart > $from.depth) throw new ReplaceError({ message: "Inserted content deeper than insertion position" });
|
|
126
|
+
if ($from.depth - slice.openStart !== $to.depth - slice.openEnd) throw new ReplaceError({ message: "Inconsistent open depths" });
|
|
127
|
+
return replaceOuter($from, $to, slice, 0);
|
|
128
|
+
}
|
|
129
|
+
function replaceOuter($from, $to, slice, depth) {
|
|
130
|
+
const index = $from.index(depth), node = $from.node(depth);
|
|
131
|
+
if (index === $to.index(depth) && depth < $from.depth - slice.openStart) {
|
|
132
|
+
const inner = replaceOuter($from, $to, slice, depth + 1);
|
|
133
|
+
return node.copy(node.content.replaceChild(index, inner));
|
|
134
|
+
} else if (!slice.content.size) return close(node, replaceTwoWay($from, $to, depth));
|
|
135
|
+
else if (!slice.openStart && !slice.openEnd && $from.depth === depth && $to.depth === depth) {
|
|
136
|
+
const parent = $from.parent, content = parent.content;
|
|
137
|
+
return close(parent, content.cut(0, $from.parentOffset).append(slice.content).append(content.cut($to.parentOffset)));
|
|
138
|
+
} else {
|
|
139
|
+
const { end, start } = prepareSliceForReplace(slice, $from);
|
|
140
|
+
return close(node, replaceThreeWay($from, start, end, $to, depth));
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
function checkJoin(main, sub) {
|
|
144
|
+
if (!sub.type.compatibleContent(main.type)) throw new ReplaceError({ message: "Cannot join " + sub.type.name + " onto " + main.type.name });
|
|
145
|
+
}
|
|
146
|
+
function joinable($before, $after, depth) {
|
|
147
|
+
const node = $before.node(depth);
|
|
148
|
+
checkJoin(node, $after.node(depth));
|
|
149
|
+
return node;
|
|
150
|
+
}
|
|
151
|
+
function addNode(child, target) {
|
|
152
|
+
const last = target.length - 1;
|
|
153
|
+
if (last >= 0 && child.isText && child.sameMarkup(target[last])) target[last] = child.withText(target[last].text + child.text);
|
|
154
|
+
else target.push(child);
|
|
155
|
+
}
|
|
156
|
+
function addRange($start, $end, depth, target) {
|
|
157
|
+
const node = ($end || $start).node(depth);
|
|
158
|
+
let startIndex = 0;
|
|
159
|
+
const endIndex = $end ? $end.index(depth) : node.childCount;
|
|
160
|
+
if ($start) {
|
|
161
|
+
startIndex = $start.index(depth);
|
|
162
|
+
if ($start.depth > depth) startIndex++;
|
|
163
|
+
else if ($start.textOffset) {
|
|
164
|
+
addNode($start.nodeAfterOrNull, target);
|
|
165
|
+
startIndex++;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
for (let i = startIndex; i < endIndex; i++) addNode(node.content.content[i], target);
|
|
169
|
+
if ($end && $end.depth === depth && $end.textOffset) addNode($end.nodeBeforeOrNull, target);
|
|
170
|
+
}
|
|
171
|
+
function close(node, content) {
|
|
172
|
+
if (!node.type.validContent(content)) throw new ReplaceError({ message: `Invalid content for node ${node.type.name}: ${content.toString().slice(0, 50)}` });
|
|
173
|
+
return node.copy(content);
|
|
174
|
+
}
|
|
175
|
+
function replaceThreeWay($from, $start, $end, $to, depth) {
|
|
176
|
+
const openStart = $from.depth > depth && joinable($from, $start, depth + 1);
|
|
177
|
+
const openEnd = $to.depth > depth && joinable($end, $to, depth + 1);
|
|
178
|
+
const content = [];
|
|
179
|
+
addRange(null, $from, depth, content);
|
|
180
|
+
if (openStart && openEnd && $start.index(depth) === $end.index(depth)) {
|
|
181
|
+
checkJoin(openStart, openEnd);
|
|
182
|
+
addNode(close(openStart, replaceThreeWay($from, $start, $end, $to, depth + 1)), content);
|
|
183
|
+
} else {
|
|
184
|
+
if (openStart) addNode(close(openStart, replaceTwoWay($from, $start, depth + 1)), content);
|
|
185
|
+
addRange($start, $end, depth, content);
|
|
186
|
+
if (openEnd) addNode(close(openEnd, replaceTwoWay($end, $to, depth + 1)), content);
|
|
187
|
+
}
|
|
188
|
+
addRange($to, null, depth, content);
|
|
189
|
+
return new Fragment(content);
|
|
190
|
+
}
|
|
191
|
+
function replaceTwoWay($from, $to, depth) {
|
|
192
|
+
const content = [];
|
|
193
|
+
addRange(null, $from, depth, content);
|
|
194
|
+
if ($from.depth > depth) addNode(close(joinable($from, $to, depth + 1), replaceTwoWay($from, $to, depth + 1)), content);
|
|
195
|
+
addRange($to, null, depth, content);
|
|
196
|
+
return new Fragment(content);
|
|
197
|
+
}
|
|
198
|
+
function prepareSliceForReplace(slice, $along) {
|
|
199
|
+
const extra = $along.depth - slice.openStart;
|
|
200
|
+
let node = $along.node(extra).copy(slice.content);
|
|
201
|
+
for (let i = extra - 1; i >= 0; i--) node = $along.node(i).copy(Fragment.from(node));
|
|
202
|
+
return {
|
|
203
|
+
start: node.resolveNoCache(slice.openStart + extra),
|
|
204
|
+
end: node.resolveNoCache(node.content.size - slice.openEnd - extra)
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
export { Slice, replace };
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import { PositionError } from "./errors.js";
|
|
2
|
+
import { Mark } from "./mark.js";
|
|
3
|
+
import { Node } from "./node.js";
|
|
4
|
+
import { AnySchema } from "./schema.js";
|
|
5
|
+
import * as Effect from "effect/Effect";
|
|
6
|
+
import * as Option from "effect/Option";
|
|
7
|
+
/**
|
|
8
|
+
* You can resolve a position to get more information about it. Objects
|
|
9
|
+
* of this class represent such a resolved position, providing various
|
|
10
|
+
* pieces of context information, and some helper methods.
|
|
11
|
+
*
|
|
12
|
+
* Throughout this interface, methods that take an optional `depth`
|
|
13
|
+
* parameter will interpret `undefined` as `this.depth` and negative
|
|
14
|
+
* numbers as `this.depth + value`.
|
|
15
|
+
*
|
|
16
|
+
* @since 0.1.0
|
|
17
|
+
* @category models
|
|
18
|
+
*/
|
|
19
|
+
export declare class ResolvedPos<Sc extends AnySchema = AnySchema> {
|
|
20
|
+
/** The position that was resolved. */
|
|
21
|
+
readonly pos: number;
|
|
22
|
+
/** @internal */
|
|
23
|
+
readonly path: ReadonlyArray<any>;
|
|
24
|
+
/** The offset this position has into its parent node. */
|
|
25
|
+
readonly parentOffset: number;
|
|
26
|
+
/**
|
|
27
|
+
* The number of levels the parent node is from the root. If this
|
|
28
|
+
* position points directly into the root node, it is 0. If it points
|
|
29
|
+
* into a top-level paragraph, 1, and so on.
|
|
30
|
+
*/
|
|
31
|
+
readonly depth: number;
|
|
32
|
+
/** @internal */
|
|
33
|
+
constructor(
|
|
34
|
+
/** The position that was resolved. */
|
|
35
|
+
pos: number,
|
|
36
|
+
/** @internal */
|
|
37
|
+
path: ReadonlyArray<any>,
|
|
38
|
+
/** The offset this position has into its parent node. */
|
|
39
|
+
parentOffset: number);
|
|
40
|
+
/** @internal */
|
|
41
|
+
resolveDepth(val: number | undefined | null): number;
|
|
42
|
+
/**
|
|
43
|
+
* The parent node that the position points into. Note that even if a
|
|
44
|
+
* position points into a text node, that node is not considered the
|
|
45
|
+
* parent—text nodes are ‘flat’ in this model, and have no content.
|
|
46
|
+
*/
|
|
47
|
+
get parent(): Node<Sc>;
|
|
48
|
+
/** The root node in which the position was resolved. */
|
|
49
|
+
get doc(): Node<Sc>;
|
|
50
|
+
/** The ancestor node at the given level. `p.node(p.depth)` is the same as `p.parent`. */
|
|
51
|
+
node(depth?: number | null): Node<Sc>;
|
|
52
|
+
/**
|
|
53
|
+
* The index into the ancestor at the given level. If this points at
|
|
54
|
+
* the 3rd node in the 2nd paragraph on the top level, for example,
|
|
55
|
+
* `p.index(0)` is 1 and `p.index(1)` is 2.
|
|
56
|
+
*/
|
|
57
|
+
index(depth?: number | null): number;
|
|
58
|
+
/** The index pointing after this position into the ancestor at the given level. */
|
|
59
|
+
indexAfter(depth?: number | null): number;
|
|
60
|
+
/** The (absolute) position at the start of the node at the given level. */
|
|
61
|
+
start(depth?: number | null): number;
|
|
62
|
+
/** The (absolute) position at the end of the node at the given level. */
|
|
63
|
+
end(depth?: number | null): number;
|
|
64
|
+
/**
|
|
65
|
+
* The (absolute) position directly before the wrapping node at the
|
|
66
|
+
* given level, or, when `depth` is `this.depth + 1`, the original
|
|
67
|
+
* position. Fails for depth 0, since there is no position before the
|
|
68
|
+
* top-level node.
|
|
69
|
+
*/
|
|
70
|
+
before(depth?: number | null): Effect.Effect<number, PositionError>;
|
|
71
|
+
/** Like `before`, but throws a `PositionError` for depth 0. */
|
|
72
|
+
beforeUnsafe(depth?: number | null): number;
|
|
73
|
+
/**
|
|
74
|
+
* The (absolute) position directly after the wrapping node at the
|
|
75
|
+
* given level, or the original position when `depth` is
|
|
76
|
+
* `this.depth + 1`. Fails for depth 0.
|
|
77
|
+
*/
|
|
78
|
+
after(depth?: number | null): Effect.Effect<number, PositionError>;
|
|
79
|
+
/** Like `after`, but throws a `PositionError` for depth 0. */
|
|
80
|
+
afterUnsafe(depth?: number | null): number;
|
|
81
|
+
/**
|
|
82
|
+
* When this position points into a text node, this returns the
|
|
83
|
+
* distance between the position and the start of the text node. Will
|
|
84
|
+
* be zero for positions that point between nodes.
|
|
85
|
+
*/
|
|
86
|
+
get textOffset(): number;
|
|
87
|
+
/**
|
|
88
|
+
* Get the node directly after the position, if any. If the position
|
|
89
|
+
* points into a text node, only the part of that node after the
|
|
90
|
+
* position is returned.
|
|
91
|
+
*/
|
|
92
|
+
get nodeAfter(): Option.Option<Node<Sc>>;
|
|
93
|
+
/** @internal */
|
|
94
|
+
get nodeAfterOrNull(): Node<Sc> | null;
|
|
95
|
+
/**
|
|
96
|
+
* Get the node directly before the position, if any. If the position
|
|
97
|
+
* points into a text node, only the part of that node before the
|
|
98
|
+
* position is returned.
|
|
99
|
+
*/
|
|
100
|
+
get nodeBefore(): Option.Option<Node<Sc>>;
|
|
101
|
+
/** @internal */
|
|
102
|
+
get nodeBeforeOrNull(): Node<Sc> | null;
|
|
103
|
+
/** Get the position at the given index in the parent node at the given depth (which defaults to `this.depth`). */
|
|
104
|
+
posAtIndex(index: number, depth?: number | null): number;
|
|
105
|
+
/**
|
|
106
|
+
* Get the marks at this position, factoring in the surrounding marks'
|
|
107
|
+
* `inclusive` property. If the position is at the start of a
|
|
108
|
+
* non-empty node, the marks of the node after it (if any) are
|
|
109
|
+
* returned.
|
|
110
|
+
*/
|
|
111
|
+
marks(): ReadonlyArray<Mark<Sc>>;
|
|
112
|
+
/**
|
|
113
|
+
* Get the marks after the current position, if any, except those that
|
|
114
|
+
* are non-inclusive and not present at position `$end`. This is
|
|
115
|
+
* mostly useful for getting the set of marks to preserve after a
|
|
116
|
+
* deletion. Will return `None` if this position is at the end of its
|
|
117
|
+
* parent node or its parent node isn't a textblock (in which case no
|
|
118
|
+
* marks should be preserved).
|
|
119
|
+
*/
|
|
120
|
+
marksAcross($end: ResolvedPos<Sc>): Option.Option<ReadonlyArray<Mark<Sc>>>;
|
|
121
|
+
/** @internal */
|
|
122
|
+
marksAcrossOrNull($end: ResolvedPos<Sc>): ReadonlyArray<Mark<Sc>> | null;
|
|
123
|
+
/** The depth up to which this position and the given (non-resolved) position share the same parent nodes. */
|
|
124
|
+
sharedDepth(pos: number): number;
|
|
125
|
+
/**
|
|
126
|
+
* Returns a range based on the place where this position and the given
|
|
127
|
+
* position diverge around block content. If both point into the same
|
|
128
|
+
* textblock, for example, a range around that textblock will be
|
|
129
|
+
* returned. If they point into different blocks, the range around
|
|
130
|
+
* those blocks in their shared ancestor is returned. You can pass in
|
|
131
|
+
* an optional predicate that will be called with a parent node to see
|
|
132
|
+
* if a range into that parent is acceptable.
|
|
133
|
+
*/
|
|
134
|
+
blockRange(other?: ResolvedPos<Sc>, pred?: (node: Node<Sc>) => boolean): Option.Option<NodeRange<Sc>>;
|
|
135
|
+
/** @internal */
|
|
136
|
+
blockRangeOrNull(other?: ResolvedPos<Sc>, pred?: (node: Node<Sc>) => boolean): NodeRange<Sc> | null;
|
|
137
|
+
/** Query whether the given position shares the same parent node. */
|
|
138
|
+
sameParent(other: ResolvedPos<any>): boolean;
|
|
139
|
+
/** Return the greater of this and the given position. */
|
|
140
|
+
max(other: ResolvedPos<Sc>): ResolvedPos<Sc>;
|
|
141
|
+
/** Return the smaller of this and the given position. */
|
|
142
|
+
min(other: ResolvedPos<Sc>): ResolvedPos<Sc>;
|
|
143
|
+
/** @internal */
|
|
144
|
+
toString(): string;
|
|
145
|
+
/** @internal */
|
|
146
|
+
static resolve<Sc extends AnySchema>(doc: Node<Sc>, pos: number): ResolvedPos<Sc>;
|
|
147
|
+
/** @internal */
|
|
148
|
+
static resolveCached<Sc extends AnySchema>(doc: Node<Sc>, pos: number): ResolvedPos<Sc>;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Represents a flat range of content, i.e. one that starts and ends in
|
|
152
|
+
* the same node.
|
|
153
|
+
*
|
|
154
|
+
* @since 0.1.0
|
|
155
|
+
* @category models
|
|
156
|
+
*/
|
|
157
|
+
export declare class NodeRange<Sc extends AnySchema = AnySchema> {
|
|
158
|
+
/**
|
|
159
|
+
* A resolved position along the start of the content. May have a
|
|
160
|
+
* `depth` greater than this object's `depth` property, since these
|
|
161
|
+
* are the positions that were used to compute the range, not
|
|
162
|
+
* re-resolved positions directly at its boundaries.
|
|
163
|
+
*/
|
|
164
|
+
readonly $from: ResolvedPos<Sc>;
|
|
165
|
+
/** A position along the end of the content. */
|
|
166
|
+
readonly $to: ResolvedPos<Sc>;
|
|
167
|
+
/** The depth of the node that this range points into. */
|
|
168
|
+
readonly depth: number;
|
|
169
|
+
/**
|
|
170
|
+
* Construct a node range. `$from` and `$to` should point into the
|
|
171
|
+
* same node until at least the given `depth`, since a node range
|
|
172
|
+
* denotes an adjacent set of nodes in a single parent node.
|
|
173
|
+
*/
|
|
174
|
+
constructor(
|
|
175
|
+
/**
|
|
176
|
+
* A resolved position along the start of the content. May have a
|
|
177
|
+
* `depth` greater than this object's `depth` property, since these
|
|
178
|
+
* are the positions that were used to compute the range, not
|
|
179
|
+
* re-resolved positions directly at its boundaries.
|
|
180
|
+
*/
|
|
181
|
+
$from: ResolvedPos<Sc>,
|
|
182
|
+
/** A position along the end of the content. */
|
|
183
|
+
$to: ResolvedPos<Sc>,
|
|
184
|
+
/** The depth of the node that this range points into. */
|
|
185
|
+
depth: number);
|
|
186
|
+
/** The position at the start of the range. */
|
|
187
|
+
get start(): number;
|
|
188
|
+
/** The position at the end of the range. */
|
|
189
|
+
get end(): number;
|
|
190
|
+
/** The parent node that the range points into. */
|
|
191
|
+
get parent(): Node<Sc>;
|
|
192
|
+
/** The start index of the range in the parent node. */
|
|
193
|
+
get startIndex(): number;
|
|
194
|
+
/** The end index of the range in the parent node. */
|
|
195
|
+
get endIndex(): number;
|
|
196
|
+
}
|