@lexical/mark 0.8.1 → 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.
Files changed (2) hide show
  1. package/LexicalMark.dev.js +57 -9
  2. package/package.json +3 -3
@@ -16,19 +16,22 @@ var utils = require('@lexical/utils');
16
16
  * LICENSE file in the root directory of this source tree.
17
17
  *
18
18
  */
19
+
19
20
  /** @noInheritDoc */
20
21
  class MarkNode extends lexical.ElementNode {
21
22
  /** @internal */
22
-
23
23
  static getType() {
24
24
  return 'mark';
25
25
  }
26
+
26
27
  static clone(node) {
27
28
  return new MarkNode(Array.from(node.__ids), node.__key);
28
29
  }
30
+
29
31
  static importDOM() {
30
32
  return null;
31
33
  }
34
+
32
35
  static importJSON(serializedNode) {
33
36
  const node = $createMarkNode(serializedNode.ids);
34
37
  node.setFormat(serializedNode.format);
@@ -36,32 +39,38 @@ class MarkNode extends lexical.ElementNode {
36
39
  node.setDirection(serializedNode.direction);
37
40
  return node;
38
41
  }
42
+
39
43
  exportJSON() {
40
- return {
41
- ...super.exportJSON(),
44
+ return { ...super.exportJSON(),
42
45
  ids: this.getIDs(),
43
46
  type: 'mark',
44
47
  version: 1
45
48
  };
46
49
  }
50
+
47
51
  constructor(ids, key) {
48
52
  super(key);
49
53
  this.__ids = ids || [];
50
54
  }
55
+
51
56
  createDOM(config) {
52
57
  const element = document.createElement('mark');
53
58
  utils.addClassNamesToElement(element, config.theme.mark);
59
+
54
60
  if (this.__ids.length > 1) {
55
61
  utils.addClassNamesToElement(element, config.theme.markOverlap);
56
62
  }
63
+
57
64
  return element;
58
65
  }
66
+
59
67
  updateDOM(prevNode, element, config) {
60
68
  const prevIDs = prevNode.__ids;
61
69
  const nextIDs = this.__ids;
62
70
  const prevIDsCount = prevIDs.length;
63
71
  const nextIDsCount = nextIDs.length;
64
72
  const overlapTheme = config.theme.markOverlap;
73
+
65
74
  if (prevIDsCount !== nextIDsCount) {
66
75
  if (prevIDsCount === 1) {
67
76
  if (nextIDsCount === 2) {
@@ -71,38 +80,50 @@ class MarkNode extends lexical.ElementNode {
71
80
  utils.removeClassNamesFromElement(element, overlapTheme);
72
81
  }
73
82
  }
83
+
74
84
  return false;
75
85
  }
86
+
76
87
  hasID(id) {
77
88
  const ids = this.getIDs();
89
+
78
90
  for (let i = 0; i < ids.length; i++) {
79
91
  if (id === ids[i]) {
80
92
  return true;
81
93
  }
82
94
  }
95
+
83
96
  return false;
84
97
  }
98
+
85
99
  getIDs() {
86
100
  const self = this.getLatest();
87
101
  return $isMarkNode(self) ? self.__ids : [];
88
102
  }
103
+
89
104
  addID(id) {
90
105
  const self = this.getWritable();
106
+
91
107
  if ($isMarkNode(self)) {
92
108
  const ids = self.__ids;
93
109
  self.__ids = ids;
110
+
94
111
  for (let i = 0; i < ids.length; i++) {
95
112
  // If we already have it, don't add again
96
113
  if (id === ids[i]) return;
97
114
  }
115
+
98
116
  ids.push(id);
99
117
  }
100
118
  }
119
+
101
120
  deleteID(id) {
102
121
  const self = this.getWritable();
122
+
103
123
  if ($isMarkNode(self)) {
104
124
  const ids = self.__ids;
105
125
  self.__ids = ids;
126
+
106
127
  for (let i = 0; i < ids.length; i++) {
107
128
  if (id === ids[i]) {
108
129
  ids.splice(i, 1);
@@ -111,31 +132,40 @@ class MarkNode extends lexical.ElementNode {
111
132
  }
112
133
  }
113
134
  }
135
+
114
136
  insertNewAfter(selection, restoreSelection = true) {
115
137
  const element = this.getParentOrThrow().insertNewAfter(selection, restoreSelection);
138
+
116
139
  if (lexical.$isElementNode(element)) {
117
140
  const markNode = $createMarkNode(this.__ids);
118
141
  element.append(markNode);
119
142
  return markNode;
120
143
  }
144
+
121
145
  return null;
122
146
  }
147
+
123
148
  canInsertTextBefore() {
124
149
  return false;
125
150
  }
151
+
126
152
  canInsertTextAfter() {
127
153
  return false;
128
154
  }
155
+
129
156
  canBeEmpty() {
130
157
  return false;
131
158
  }
159
+
132
160
  isInline() {
133
161
  return true;
134
162
  }
163
+
135
164
  extractWithChild(child, selection, destination) {
136
165
  if (!lexical.$isRangeSelection(selection) || destination === 'html') {
137
166
  return false;
138
167
  }
168
+
139
169
  const anchor = selection.anchor;
140
170
  const focus = selection.focus;
141
171
  const anchorNode = anchor.getNode();
@@ -144,9 +174,11 @@ class MarkNode extends lexical.ElementNode {
144
174
  const selectionLength = isBackward ? anchor.offset - focus.offset : focus.offset - anchor.offset;
145
175
  return this.isParentOf(anchorNode) && this.isParentOf(focusNode) && this.getTextContent().length === selectionLength;
146
176
  }
177
+
147
178
  excludeFromCopy(destination) {
148
179
  return destination !== 'clone';
149
180
  }
181
+
150
182
  }
151
183
  function $createMarkNode(ids) {
152
184
  return lexical.$applyNodeReplacement(new MarkNode(ids));
@@ -159,15 +191,19 @@ function $isMarkNode(node) {
159
191
  function $unwrapMarkNode(node) {
160
192
  const children = node.getChildren();
161
193
  let target = null;
194
+
162
195
  for (let i = 0; i < children.length; i++) {
163
196
  const child = children[i];
197
+
164
198
  if (target === null) {
165
199
  node.insertBefore(child);
166
200
  } else {
167
201
  target.insertAfter(child);
168
202
  }
203
+
169
204
  target = child;
170
205
  }
206
+
171
207
  node.remove();
172
208
  }
173
209
  function $wrapSelectionInMarkNode(selection, isBackward, id, createNode) {
@@ -178,29 +214,33 @@ function $wrapSelectionInMarkNode(selection, isBackward, id, createNode) {
178
214
  const startOffset = isBackward ? focusOffset : anchorOffset;
179
215
  const endOffset = isBackward ? anchorOffset : focusOffset;
180
216
  let currentNodeParent;
181
- let lastCreatedMarkNode;
182
-
183
- // We only want wrap adjacent text nodes, line break nodes
217
+ let lastCreatedMarkNode; // We only want wrap adjacent text nodes, line break nodes
184
218
  // and inline element nodes. For decorator nodes and block
185
219
  // element nodes, we step out of their boundary and start
186
220
  // again after, if there are more nodes.
221
+
187
222
  for (let i = 0; i < nodesLength; i++) {
188
223
  const node = nodes[i];
224
+
189
225
  if (lexical.$isElementNode(lastCreatedMarkNode) && lastCreatedMarkNode.isParentOf(node)) {
190
226
  // If the current node is a child of the last created mark node, there is nothing to do here
191
227
  continue;
192
228
  }
229
+
193
230
  const isFirstNode = i === 0;
194
231
  const isLastNode = i === nodesLength - 1;
195
232
  let targetNode = null;
233
+
196
234
  if (lexical.$isTextNode(node)) {
197
235
  // Case 1: The node is a text node and we can split it
198
236
  const textContentSize = node.getTextContentSize();
199
237
  const startTextOffset = isFirstNode ? startOffset : 0;
200
238
  const endTextOffset = isLastNode ? endOffset : textContentSize;
239
+
201
240
  if (startTextOffset === 0 && endTextOffset === 0) {
202
241
  continue;
203
242
  }
243
+
204
244
  const splitNodes = node.splitText(startTextOffset, endTextOffset);
205
245
  targetNode = splitNodes.length > 1 && (splitNodes.length === 3 || isFirstNode && !isLastNode || endTextOffset === textContentSize) ? splitNodes[1] : splitNodes[0];
206
246
  } else if ($isMarkNode(node)) {
@@ -209,13 +249,13 @@ function $wrapSelectionInMarkNode(selection, isBackward, id, createNode) {
209
249
  // another mark, it may utlimately be unnested by a call to
210
250
  // `registerNestedElementResolver<MarkNode>` somewhere else in the
211
251
  // codebase.
212
-
213
252
  continue;
214
253
  } else if (lexical.$isElementNode(node) && node.isInline()) {
215
254
  // Case 3: inline element nodes can be added in their entirety to the new
216
255
  // mark
217
256
  targetNode = node;
218
257
  }
258
+
219
259
  if (targetNode !== null) {
220
260
  // Now that we have a target node for wrapping with a mark, we can run
221
261
  // through special cases.
@@ -224,21 +264,25 @@ function $wrapSelectionInMarkNode(selection, isBackward, id, createNode) {
224
264
  // is nothing to do here.
225
265
  continue;
226
266
  }
267
+
227
268
  const parentNode = targetNode.getParent();
269
+
228
270
  if (parentNode == null || !parentNode.is(currentNodeParent)) {
229
271
  // If the parent node is not the current node's parent node, we can
230
272
  // clear the last created mark node.
231
273
  lastCreatedMarkNode = undefined;
232
274
  }
275
+
233
276
  currentNodeParent = parentNode;
277
+
234
278
  if (lastCreatedMarkNode === undefined) {
235
279
  // If we don't have a created mark node, we can make one
236
280
  const createMarkNode = createNode || $createMarkNode;
237
281
  lastCreatedMarkNode = createMarkNode([id]);
238
282
  targetNode.insertBefore(lastCreatedMarkNode);
239
- }
283
+ } // Add the target node to be wrapped in the latest created mark node
284
+
240
285
 
241
- // Add the target node to be wrapped in the latest created mark node
242
286
  lastCreatedMarkNode.append(targetNode);
243
287
  } else {
244
288
  // If we don't have a target node to wrap we can clear our state and
@@ -250,17 +294,21 @@ function $wrapSelectionInMarkNode(selection, isBackward, id, createNode) {
250
294
  }
251
295
  function $getMarkIDs(node, offset) {
252
296
  let currentNode = node;
297
+
253
298
  while (currentNode !== null) {
254
299
  if ($isMarkNode(currentNode)) {
255
300
  return currentNode.getIDs();
256
301
  } else if (lexical.$isTextNode(currentNode) && offset === currentNode.getTextContentSize()) {
257
302
  const nextSibling = currentNode.getNextSibling();
303
+
258
304
  if ($isMarkNode(nextSibling)) {
259
305
  return nextSibling.getIDs();
260
306
  }
261
307
  }
308
+
262
309
  currentNode = currentNode.getParent();
263
310
  }
311
+
264
312
  return null;
265
313
  }
266
314
 
package/package.json CHANGED
@@ -8,13 +8,13 @@
8
8
  "mark"
9
9
  ],
10
10
  "license": "MIT",
11
- "version": "0.8.1",
11
+ "version": "0.9.0",
12
12
  "main": "LexicalMark.js",
13
13
  "peerDependencies": {
14
- "lexical": "0.8.1"
14
+ "lexical": "0.9.0"
15
15
  },
16
16
  "dependencies": {
17
- "@lexical/utils": "0.8.1"
17
+ "@lexical/utils": "0.9.0"
18
18
  },
19
19
  "repository": {
20
20
  "type": "git",