@lexical/offset 0.8.1 → 0.9.1
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/LexicalOffset.dev.js +83 -8
- package/package.json +2 -2
package/LexicalOffset.dev.js
CHANGED
|
@@ -15,42 +15,52 @@ class OffsetView {
|
|
|
15
15
|
this._firstNode = firstNode;
|
|
16
16
|
this._blockOffsetSize = blockOffsetSize;
|
|
17
17
|
}
|
|
18
|
+
|
|
18
19
|
createSelectionFromOffsets(originalStart, originalEnd, diffOffsetView) {
|
|
19
20
|
const firstNode = this._firstNode;
|
|
21
|
+
|
|
20
22
|
if (firstNode === null) {
|
|
21
23
|
return null;
|
|
22
24
|
}
|
|
25
|
+
|
|
23
26
|
let start = originalStart;
|
|
24
27
|
let end = originalEnd;
|
|
25
28
|
let startOffsetNode = $searchForNodeWithOffset(firstNode, start, this._blockOffsetSize);
|
|
26
29
|
let endOffsetNode = $searchForNodeWithOffset(firstNode, end, this._blockOffsetSize);
|
|
30
|
+
|
|
27
31
|
if (diffOffsetView !== undefined) {
|
|
28
32
|
start = $getAdjustedOffsetFromDiff(start, startOffsetNode, diffOffsetView, this, this._blockOffsetSize);
|
|
29
33
|
startOffsetNode = $searchForNodeWithOffset(firstNode, start, this._blockOffsetSize);
|
|
30
34
|
end = $getAdjustedOffsetFromDiff(end, endOffsetNode, diffOffsetView, this, this._blockOffsetSize);
|
|
31
35
|
endOffsetNode = $searchForNodeWithOffset(firstNode, end, this._blockOffsetSize);
|
|
32
36
|
}
|
|
37
|
+
|
|
33
38
|
if (startOffsetNode === null || endOffsetNode === null) {
|
|
34
39
|
return null;
|
|
35
40
|
}
|
|
41
|
+
|
|
36
42
|
let startKey = startOffsetNode.key;
|
|
37
43
|
let endKey = endOffsetNode.key;
|
|
38
44
|
const startNode = lexical.$getNodeByKey(startKey);
|
|
39
45
|
const endNode = lexical.$getNodeByKey(endKey);
|
|
46
|
+
|
|
40
47
|
if (startNode === null || endNode === null) {
|
|
41
48
|
return null;
|
|
42
49
|
}
|
|
50
|
+
|
|
43
51
|
let startOffset = 0;
|
|
44
52
|
let endOffset = 0;
|
|
45
53
|
let startType = 'element';
|
|
46
54
|
let endType = 'element';
|
|
55
|
+
|
|
47
56
|
if (startOffsetNode.type === 'text') {
|
|
48
57
|
startOffset = start - startOffsetNode.start;
|
|
49
|
-
startType = 'text';
|
|
50
|
-
// If we are at the edge of a text node and we
|
|
58
|
+
startType = 'text'; // If we are at the edge of a text node and we
|
|
51
59
|
// don't have a collapsed selection, then let's
|
|
52
60
|
// try and correct the offset node.
|
|
61
|
+
|
|
53
62
|
const sibling = startNode.getNextSibling();
|
|
63
|
+
|
|
54
64
|
if (start !== end && startOffset === startNode.getTextContentSize() && lexical.$isTextNode(sibling)) {
|
|
55
65
|
startOffset = 0;
|
|
56
66
|
startKey = sibling.__key;
|
|
@@ -59,6 +69,7 @@ class OffsetView {
|
|
|
59
69
|
startKey = startNode.getParentOrThrow().getKey();
|
|
60
70
|
startOffset = end > startOffsetNode.start ? startOffsetNode.end : startOffsetNode.start;
|
|
61
71
|
}
|
|
72
|
+
|
|
62
73
|
if (endOffsetNode.type === 'text') {
|
|
63
74
|
endOffset = end - endOffsetNode.start;
|
|
64
75
|
endType = 'text';
|
|
@@ -66,14 +77,18 @@ class OffsetView {
|
|
|
66
77
|
endKey = endNode.getParentOrThrow().getKey();
|
|
67
78
|
endOffset = end > endOffsetNode.start ? endOffsetNode.end : endOffsetNode.start;
|
|
68
79
|
}
|
|
80
|
+
|
|
69
81
|
const selection = lexical.$createRangeSelection();
|
|
82
|
+
|
|
70
83
|
if (selection === null) {
|
|
71
84
|
return null;
|
|
72
85
|
}
|
|
86
|
+
|
|
73
87
|
selection.anchor.set(startKey, startOffset, startType);
|
|
74
88
|
selection.focus.set(endKey, endOffset, endType);
|
|
75
89
|
return selection;
|
|
76
90
|
}
|
|
91
|
+
|
|
77
92
|
getOffsetsFromSelection(selection) {
|
|
78
93
|
const anchor = selection.anchor;
|
|
79
94
|
const focus = selection.focus;
|
|
@@ -82,141 +97,184 @@ class OffsetView {
|
|
|
82
97
|
const focusOffset = focus.offset;
|
|
83
98
|
let start = -1;
|
|
84
99
|
let end = -1;
|
|
100
|
+
|
|
85
101
|
if (anchor.type === 'text') {
|
|
86
102
|
const offsetNode = offsetMap.get(anchor.key);
|
|
103
|
+
|
|
87
104
|
if (offsetNode !== undefined) {
|
|
88
105
|
start = offsetNode.start + anchorOffset;
|
|
89
106
|
}
|
|
90
107
|
} else {
|
|
91
108
|
const node = anchor.getNode().getDescendantByIndex(anchorOffset);
|
|
109
|
+
|
|
92
110
|
if (node !== null) {
|
|
93
111
|
const offsetNode = offsetMap.get(node.getKey());
|
|
112
|
+
|
|
94
113
|
if (offsetNode !== undefined) {
|
|
95
114
|
const isAtEnd = node.getIndexWithinParent() !== anchorOffset;
|
|
96
115
|
start = isAtEnd ? offsetNode.end : offsetNode.start;
|
|
97
116
|
}
|
|
98
117
|
}
|
|
99
118
|
}
|
|
119
|
+
|
|
100
120
|
if (focus.type === 'text') {
|
|
101
121
|
const offsetNode = offsetMap.get(focus.key);
|
|
122
|
+
|
|
102
123
|
if (offsetNode !== undefined) {
|
|
103
124
|
end = offsetNode.start + focus.offset;
|
|
104
125
|
}
|
|
105
126
|
} else {
|
|
106
127
|
const node = focus.getNode().getDescendantByIndex(focusOffset);
|
|
128
|
+
|
|
107
129
|
if (node !== null) {
|
|
108
130
|
const offsetNode = offsetMap.get(node.getKey());
|
|
131
|
+
|
|
109
132
|
if (offsetNode !== undefined) {
|
|
110
133
|
const isAtEnd = node.getIndexWithinParent() !== focusOffset;
|
|
111
134
|
end = isAtEnd ? offsetNode.end : offsetNode.start;
|
|
112
135
|
}
|
|
113
136
|
}
|
|
114
137
|
}
|
|
138
|
+
|
|
115
139
|
return [start, end];
|
|
116
140
|
}
|
|
141
|
+
|
|
117
142
|
}
|
|
143
|
+
|
|
118
144
|
function $getAdjustedOffsetFromDiff(offset, offsetNode, prevOffsetView, offsetView, blockOffsetSize) {
|
|
119
145
|
const prevOffsetMap = prevOffsetView._offsetMap;
|
|
120
146
|
const offsetMap = offsetView._offsetMap;
|
|
121
147
|
const visited = new Set();
|
|
122
148
|
let adjustedOffset = offset;
|
|
123
149
|
let currentNode = offsetNode;
|
|
150
|
+
|
|
124
151
|
while (currentNode !== null) {
|
|
125
152
|
const key = currentNode.key;
|
|
126
153
|
const prevNode = prevOffsetMap.get(key);
|
|
127
154
|
const diff = currentNode.end - currentNode.start;
|
|
128
155
|
visited.add(key);
|
|
156
|
+
|
|
129
157
|
if (prevNode === undefined) {
|
|
130
158
|
adjustedOffset += diff;
|
|
131
159
|
} else {
|
|
132
160
|
const prevDiff = prevNode.end - prevNode.start;
|
|
161
|
+
|
|
133
162
|
if (prevDiff !== diff) {
|
|
134
163
|
adjustedOffset += diff - prevDiff;
|
|
135
164
|
}
|
|
136
165
|
}
|
|
166
|
+
|
|
137
167
|
const sibling = currentNode.prev;
|
|
168
|
+
|
|
138
169
|
if (sibling !== null) {
|
|
139
170
|
currentNode = sibling;
|
|
140
171
|
continue;
|
|
141
172
|
}
|
|
173
|
+
|
|
142
174
|
let parent = currentNode.parent;
|
|
175
|
+
|
|
143
176
|
while (parent !== null) {
|
|
144
177
|
let parentSibling = parent.prev;
|
|
178
|
+
|
|
145
179
|
if (parentSibling !== null) {
|
|
146
180
|
const parentSiblingKey = parentSibling.key;
|
|
147
181
|
const prevParentSibling = prevOffsetMap.get(parentSiblingKey);
|
|
148
182
|
const parentDiff = parentSibling.end - parentSibling.start;
|
|
149
183
|
visited.add(parentSiblingKey);
|
|
184
|
+
|
|
150
185
|
if (prevParentSibling === undefined) {
|
|
151
186
|
adjustedOffset += parentDiff;
|
|
152
187
|
} else {
|
|
153
188
|
const prevParentDiff = prevParentSibling.end - prevParentSibling.start;
|
|
189
|
+
|
|
154
190
|
if (prevParentDiff !== parentDiff) {
|
|
155
191
|
adjustedOffset += parentDiff - prevParentDiff;
|
|
156
192
|
}
|
|
157
193
|
}
|
|
194
|
+
|
|
158
195
|
parentSibling = parentSibling.prev;
|
|
159
196
|
}
|
|
197
|
+
|
|
160
198
|
parent = parent.parent;
|
|
161
199
|
}
|
|
162
|
-
break;
|
|
163
|
-
}
|
|
164
200
|
|
|
165
|
-
|
|
201
|
+
break;
|
|
202
|
+
} // Now traverse through the old offsets nodes and find any nodes we missed
|
|
166
203
|
// above, because they were not in the latest offset node view (they have been
|
|
167
204
|
// deleted).
|
|
205
|
+
|
|
206
|
+
|
|
168
207
|
const prevFirstNode = prevOffsetView._firstNode;
|
|
208
|
+
|
|
169
209
|
if (prevFirstNode !== null) {
|
|
170
210
|
currentNode = $searchForNodeWithOffset(prevFirstNode, offset, blockOffsetSize);
|
|
171
211
|
let alreadyVisitedParentOfCurrentNode = false;
|
|
212
|
+
|
|
172
213
|
while (currentNode !== null) {
|
|
173
214
|
if (!visited.has(currentNode.key)) {
|
|
174
215
|
alreadyVisitedParentOfCurrentNode = true;
|
|
175
216
|
break;
|
|
176
217
|
}
|
|
218
|
+
|
|
177
219
|
currentNode = currentNode.parent;
|
|
178
220
|
}
|
|
221
|
+
|
|
179
222
|
if (!alreadyVisitedParentOfCurrentNode) {
|
|
180
223
|
while (currentNode !== null) {
|
|
181
224
|
const key = currentNode.key;
|
|
225
|
+
|
|
182
226
|
if (!visited.has(key)) {
|
|
183
227
|
const node = offsetMap.get(key);
|
|
184
228
|
const prevDiff = currentNode.end - currentNode.start;
|
|
229
|
+
|
|
185
230
|
if (node === undefined) {
|
|
186
231
|
adjustedOffset -= prevDiff;
|
|
187
232
|
} else {
|
|
188
233
|
const diff = node.end - node.start;
|
|
234
|
+
|
|
189
235
|
if (prevDiff !== diff) {
|
|
190
236
|
adjustedOffset += diff - prevDiff;
|
|
191
237
|
}
|
|
192
238
|
}
|
|
193
239
|
}
|
|
240
|
+
|
|
194
241
|
currentNode = currentNode.prev;
|
|
195
242
|
}
|
|
196
243
|
}
|
|
197
244
|
}
|
|
245
|
+
|
|
198
246
|
return adjustedOffset;
|
|
199
247
|
}
|
|
248
|
+
|
|
200
249
|
function $searchForNodeWithOffset(firstNode, offset, blockOffsetSize) {
|
|
201
250
|
let currentNode = firstNode;
|
|
251
|
+
|
|
202
252
|
while (currentNode !== null) {
|
|
203
253
|
const end = currentNode.end + (currentNode.type !== 'element' || blockOffsetSize === 0 ? 1 : 0);
|
|
254
|
+
|
|
204
255
|
if (offset < end) {
|
|
205
256
|
const child = currentNode.child;
|
|
257
|
+
|
|
206
258
|
if (child !== null) {
|
|
207
259
|
currentNode = child;
|
|
208
260
|
continue;
|
|
209
261
|
}
|
|
262
|
+
|
|
210
263
|
return currentNode;
|
|
211
264
|
}
|
|
265
|
+
|
|
212
266
|
const sibling = currentNode.next;
|
|
267
|
+
|
|
213
268
|
if (sibling === null) {
|
|
214
269
|
break;
|
|
215
270
|
}
|
|
271
|
+
|
|
216
272
|
currentNode = sibling;
|
|
217
273
|
}
|
|
274
|
+
|
|
218
275
|
return null;
|
|
219
276
|
}
|
|
277
|
+
|
|
220
278
|
function $createInternalOffsetNode(child, type, start, end, key, parent) {
|
|
221
279
|
return {
|
|
222
280
|
child,
|
|
@@ -229,34 +287,41 @@ function $createInternalOffsetNode(child, type, start, end, key, parent) {
|
|
|
229
287
|
type
|
|
230
288
|
};
|
|
231
289
|
}
|
|
290
|
+
|
|
232
291
|
function $createOffsetNode(state, key, parent, nodeMap, offsetMap, blockOffsetSize) {
|
|
233
292
|
const node = nodeMap.get(key);
|
|
293
|
+
|
|
234
294
|
if (node === undefined) {
|
|
235
295
|
{
|
|
236
296
|
throw Error(`createOffsetModel: could not find node by key`);
|
|
237
297
|
}
|
|
238
298
|
}
|
|
299
|
+
|
|
239
300
|
const start = state.offset;
|
|
301
|
+
|
|
240
302
|
if (lexical.$isElementNode(node)) {
|
|
241
303
|
const childKeys = createChildrenArray(node, nodeMap);
|
|
242
304
|
const blockIsEmpty = childKeys.length === 0;
|
|
243
|
-
const child = blockIsEmpty ? null : $createOffsetChild(state, childKeys, null, nodeMap, offsetMap, blockOffsetSize);
|
|
244
|
-
|
|
245
|
-
// If the prev node was not a block or the block is empty, we should
|
|
305
|
+
const child = blockIsEmpty ? null : $createOffsetChild(state, childKeys, null, nodeMap, offsetMap, blockOffsetSize); // If the prev node was not a block or the block is empty, we should
|
|
246
306
|
// account for the user being able to selection the block (due to the \n).
|
|
307
|
+
|
|
247
308
|
if (!state.prevIsBlock || blockIsEmpty) {
|
|
248
309
|
state.prevIsBlock = true;
|
|
249
310
|
state.offset += blockOffsetSize;
|
|
250
311
|
}
|
|
312
|
+
|
|
251
313
|
const offsetNode = $createInternalOffsetNode(child, 'element', start, start, key, parent);
|
|
314
|
+
|
|
252
315
|
if (child !== null) {
|
|
253
316
|
child.parent = offsetNode;
|
|
254
317
|
}
|
|
318
|
+
|
|
255
319
|
const end = state.offset;
|
|
256
320
|
offsetNode.end = end;
|
|
257
321
|
offsetMap.set(key, offsetNode);
|
|
258
322
|
return offsetNode;
|
|
259
323
|
}
|
|
324
|
+
|
|
260
325
|
state.prevIsBlock = false;
|
|
261
326
|
const isText = lexical.$isTextNode(node);
|
|
262
327
|
const length = isText ? node.__text.length : 1;
|
|
@@ -265,36 +330,46 @@ function $createOffsetNode(state, key, parent, nodeMap, offsetMap, blockOffsetSi
|
|
|
265
330
|
offsetMap.set(key, offsetNode);
|
|
266
331
|
return offsetNode;
|
|
267
332
|
}
|
|
333
|
+
|
|
268
334
|
function $createOffsetChild(state, children, parent, nodeMap, offsetMap, blockOffsetSize) {
|
|
269
335
|
let firstNode = null;
|
|
270
336
|
let currentNode = null;
|
|
271
337
|
const childrenLength = children.length;
|
|
338
|
+
|
|
272
339
|
for (let i = 0; i < childrenLength; i++) {
|
|
273
340
|
const childKey = children[i];
|
|
274
341
|
const offsetNode = $createOffsetNode(state, childKey, parent, nodeMap, offsetMap, blockOffsetSize);
|
|
342
|
+
|
|
275
343
|
if (currentNode === null) {
|
|
276
344
|
firstNode = offsetNode;
|
|
277
345
|
} else {
|
|
278
346
|
offsetNode.prev = currentNode;
|
|
279
347
|
currentNode.next = offsetNode;
|
|
280
348
|
}
|
|
349
|
+
|
|
281
350
|
currentNode = offsetNode;
|
|
282
351
|
}
|
|
352
|
+
|
|
283
353
|
return firstNode;
|
|
284
354
|
}
|
|
355
|
+
|
|
285
356
|
function createChildrenArray(element, nodeMap) {
|
|
286
357
|
const children = [];
|
|
287
358
|
let nodeKey = element.__first;
|
|
359
|
+
|
|
288
360
|
while (nodeKey !== null) {
|
|
289
361
|
const node = nodeMap === null ? lexical.$getNodeByKey(nodeKey) : nodeMap.get(nodeKey);
|
|
362
|
+
|
|
290
363
|
if (node === null || node === undefined) {
|
|
291
364
|
{
|
|
292
365
|
throw Error(`createChildrenArray: node does not exist in nodeMap`);
|
|
293
366
|
}
|
|
294
367
|
}
|
|
368
|
+
|
|
295
369
|
children.push(nodeKey);
|
|
296
370
|
nodeKey = node.__next;
|
|
297
371
|
}
|
|
372
|
+
|
|
298
373
|
return children;
|
|
299
374
|
}
|
|
300
375
|
function $createOffsetView(editor, blockOffsetSize = 1, editorState) {
|
package/package.json
CHANGED