@lexical/offset 0.8.0 → 0.9.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.
@@ -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
- // Now traverse through the old offsets nodes and find any nodes we missed
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
@@ -8,10 +8,10 @@
8
8
  "offset"
9
9
  ],
10
10
  "license": "MIT",
11
- "version": "0.8.0",
11
+ "version": "0.9.0",
12
12
  "main": "LexicalOffset.js",
13
13
  "peerDependencies": {
14
- "lexical": "0.8.0"
14
+ "lexical": "0.9.0"
15
15
  },
16
16
  "repository": {
17
17
  "type": "git",