@lexical/clipboard 0.2.4 → 0.2.7

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.
@@ -6,7 +6,12 @@
6
6
  *
7
7
  */
8
8
 
9
- import type {LexicalEditor, RangeSelection} from 'lexical';
9
+ import type {
10
+ GridSelection,
11
+ LexicalEditor,
12
+ NodeSelection,
13
+ RangeSelection,
14
+ } from 'lexical';
10
15
 
11
16
  /*
12
17
  * Rich Text
@@ -14,11 +19,11 @@ import type {LexicalEditor, RangeSelection} from 'lexical';
14
19
 
15
20
  export function $insertDataTransferForRichText(
16
21
  dataTransfer: DataTransfer,
17
- selection: RangeSelection,
22
+ selection: RangeSelection | GridSelection | NodeSelection,
18
23
  editor: LexicalEditor,
19
24
  ): void;
20
25
 
21
- export function getHtmlContent(editor: LexicalEditor): string;
26
+ export function $getHtmlContent(editor: LexicalEditor): string;
22
27
  export function $getLexicalContent(editor: LexicalEditor): string;
23
28
 
24
29
  /*
@@ -7,6 +7,7 @@
7
7
  'use strict';
8
8
 
9
9
  var selection = require('@lexical/selection');
10
+ var utils = require('@lexical/utils');
10
11
  var lexical = require('lexical');
11
12
 
12
13
  /**
@@ -18,101 +19,176 @@ var lexical = require('lexical');
18
19
  *
19
20
  */
20
21
  const IGNORE_TAGS = new Set(['STYLE']);
21
- function getHtmlContent(editor) {
22
- const selection$1 = lexical.$getSelection();
22
+ function $getHtmlContent(editor) {
23
+ const selection = lexical.$getSelection();
23
24
 
24
- if (selection$1 == null) {
25
+ if (selection == null) {
25
26
  throw new Error('Expected valid LexicalSelection');
26
27
  } // If we haven't selected anything
27
28
 
28
29
 
29
- if (lexical.$isRangeSelection(selection$1) && selection$1.isCollapsed() || selection$1.getNodes().length === 0) {
30
+ if (lexical.$isRangeSelection(selection) && selection.isCollapsed() || selection.getNodes().length === 0) {
30
31
  return null;
31
32
  }
32
33
 
33
- const state = selection.$cloneContents(selection$1);
34
- return $convertSelectedLexicalContentToHtml(editor, selection$1, state);
34
+ return $convertSelectedContentToHtml(editor, selection);
35
35
  }
36
- function $convertSelectedLexicalNodeToHTMLElement(editor, selection, node) {
37
- let nodeToConvert = node;
38
-
39
- if (lexical.$isRangeSelection(selection) || lexical.$isGridSelection(selection)) {
40
- const anchor = selection.anchor.getNode();
41
- const focus = selection.focus.getNode();
42
- const isAnchor = node.is(anchor);
43
- const isFocus = node.is(focus);
44
-
45
- if (lexical.$isTextNode(node) && (isAnchor || isFocus)) {
46
- const anchorOffset = selection.anchor.getCharacterOffset();
47
- const focusOffset = selection.focus.getCharacterOffset();
48
- const isBackward = selection.isBackward();
49
- const isSame = anchor.is(focus);
50
- const isFirst = node.is(isBackward ? focus : anchor);
51
- const nodeText = node.getTextContent();
52
- const nodeTextLength = nodeText.length;
36
+ function $appendSelectedNodesToHTML(editor, selection$1, currentNode, parentElement) {
37
+ let shouldInclude = currentNode.isSelected();
38
+ const shouldExclude = lexical.$isElementNode(currentNode) && currentNode.excludeFromCopy('html');
39
+ let clone = selection.$cloneWithProperties(currentNode);
40
+ clone = lexical.$isTextNode(clone) ? $splitClonedTextNode(selection$1, clone) : clone;
41
+ const children = lexical.$isElementNode(clone) ? clone.getChildren() : [];
42
+ const {
43
+ element,
44
+ after
45
+ } = clone.exportDOM(editor);
53
46
 
54
- if (isSame) {
55
- const startOffset = anchorOffset > focusOffset ? focusOffset : anchorOffset;
56
- const endOffset = anchorOffset > focusOffset ? anchorOffset : focusOffset;
57
- const splitNodes = node.splitText(startOffset, endOffset);
58
- nodeToConvert = startOffset === 0 ? splitNodes[0] : splitNodes[1];
59
- } else {
60
- let endOffset;
47
+ if (!element) {
48
+ return false;
49
+ }
61
50
 
62
- if (isFirst) {
63
- endOffset = isBackward ? focusOffset : anchorOffset;
64
- } else {
65
- endOffset = isBackward ? anchorOffset : focusOffset;
66
- }
51
+ const fragment = new DocumentFragment();
67
52
 
68
- if (!isBackward && endOffset === 0) {
69
- return null;
70
- } else if (endOffset !== nodeTextLength) {
71
- nodeToConvert = node.splitText(endOffset)[isFirst && endOffset !== 0 ? 1 : 0];
72
- }
73
- }
53
+ for (let i = 0; i < children.length; i++) {
54
+ const childNode = children[i];
55
+ const shouldIncludeChild = $appendSelectedNodesToHTML(editor, selection$1, childNode, fragment);
56
+
57
+ if (!shouldInclude && lexical.$isElementNode(currentNode) && shouldIncludeChild && currentNode.extractWithChild(childNode, selection$1, 'html')) {
58
+ shouldInclude = true;
74
59
  }
75
60
  }
76
61
 
77
- const {
78
- element,
79
- after
80
- } = nodeToConvert.exportDOM(editor);
81
- if (!element) return null;
82
- const children = lexical.$isElementNode(nodeToConvert) ? nodeToConvert.getChildren() : [];
62
+ if (shouldInclude && !shouldExclude) {
63
+ element.append(fragment);
64
+ parentElement.append(element);
65
+
66
+ if (after) {
67
+ const newElement = after.call(clone, element);
68
+ if (newElement) element.replaceWith(newElement);
69
+ }
70
+ } else {
71
+ parentElement.append(fragment);
72
+ }
73
+
74
+ return shouldInclude;
75
+ }
76
+ function $convertSelectedContentToHtml(editor, selection) {
77
+ const container = document.createElement('div');
78
+ const root = lexical.$getRoot();
79
+ const topLevelChildren = root.getChildren();
80
+
81
+ for (let i = 0; i < topLevelChildren.length; i++) {
82
+ const topLevelNode = topLevelChildren[i];
83
+ $appendSelectedNodesToHTML(editor, selection, topLevelNode, container);
84
+ }
85
+
86
+ return container.innerHTML;
87
+ }
88
+ function $appendSelectedNodesToClone(editor, selection$1, currentNode, nodeMap, range, shouldIncludeInRange = true) {
89
+ let shouldInclude = currentNode.isSelected();
90
+ const shouldExclude = lexical.$isElementNode(currentNode) && currentNode.excludeFromCopy('clone');
91
+ let clone = selection.$cloneWithProperties(currentNode);
92
+ clone = lexical.$isTextNode(clone) ? $splitClonedTextNode(selection$1, clone) : clone;
93
+ const children = lexical.$isElementNode(clone) ? clone.getChildren() : [];
94
+ const nodeKeys = [];
95
+ let shouldIncludeChildrenInRange = shouldIncludeInRange;
96
+
97
+ if (shouldInclude && !shouldExclude) {
98
+ nodeMap.set(clone.getKey(), clone);
99
+
100
+ if (shouldIncludeInRange) {
101
+ shouldIncludeChildrenInRange = false;
102
+ }
103
+ }
83
104
 
84
105
  for (let i = 0; i < children.length; i++) {
85
106
  const childNode = children[i];
107
+ const childNodeKeys = $appendSelectedNodesToClone(editor, selection$1, childNode, nodeMap, range, shouldIncludeChildrenInRange);
108
+
109
+ for (let j = 0; j < childNodeKeys.length; j++) {
110
+ const childNodeKey = childNodeKeys[j];
111
+ nodeKeys.push(childNodeKey);
112
+ }
113
+
114
+ if (!shouldInclude && lexical.$isElementNode(currentNode) && nodeKeys.includes(childNode.getKey()) && currentNode.extractWithChild(childNode, selection$1, 'clone')) {
115
+ shouldInclude = true;
116
+ }
117
+ } // The tree is later built using $generateNodes which works
118
+ // by going through the nodes specified in the "range" & their children
119
+ // while filtering out nodes not found in the "nodeMap".
120
+ // This gets complicated when we want to "exclude" a node but
121
+ // keep it's children i.e. a MarkNode and it's Text children.
122
+ // The solution is to check if there's a cloned parent already in our map and
123
+ // splice the current node's children into the nearest parent.
124
+ // If there is no parent in the map already, the children will be added to the
125
+ // top level range be default.
126
+
127
+
128
+ if (lexical.$isElementNode(clone) && shouldExclude && shouldInclude) {
129
+ let nearestClonedParent;
130
+ let idxWithinClonedParent;
131
+ let prev = clone;
132
+ let curr = clone.getParent();
133
+ const root = lexical.$getRoot();
134
+
135
+ while (curr != null && !curr.is(root)) {
136
+ if (nodeMap.has(curr.getKey()) || curr.extractWithChild(currentNode, selection$1, 'clone')) {
137
+ nearestClonedParent = selection.$cloneWithProperties(curr);
138
+ idxWithinClonedParent = prev.getIndexWithinParent();
139
+ nodeMap.set(nearestClonedParent.getKey(), nearestClonedParent);
140
+ break;
141
+ }
142
+
143
+ prev = curr;
144
+ curr = curr.getParent();
145
+ } // Add children to nearest cloned parent at the correct position.
146
+
86
147
 
87
- if (childNode.isSelected()) {
88
- const newElement = $convertSelectedLexicalNodeToHTMLElement(editor, selection, childNode);
89
- if (newElement) element.append(newElement);
148
+ if (lexical.$isElementNode(nearestClonedParent) && idxWithinClonedParent != null) {
149
+ nearestClonedParent.__children.splice(idxWithinClonedParent, 1, ...clone.__children);
90
150
  }
91
151
  }
92
152
 
93
- return after ? after.call(nodeToConvert, element) : element;
94
- }
95
- function $convertSelectedLexicalContentToHtml(editor, selection, state) {
96
- const container = document.createElement('div');
153
+ if (shouldInclude && !shouldExclude) {
154
+ if (!nodeMap.has(clone.getKey())) {
155
+ nodeMap.set(clone.getKey(), clone);
156
+ }
97
157
 
98
- for (let i = 0; i < state.range.length; i++) {
99
- const nodeKey = state.range[i];
100
- const node = lexical.$getNodeByKey(nodeKey);
158
+ if (shouldIncludeInRange) {
159
+ return [clone.getKey()];
160
+ }
161
+ }
101
162
 
102
- if (node && node.isSelected()) {
103
- const element = $convertSelectedLexicalNodeToHTMLElement(editor, selection, node);
104
- if (element) container.append(element);
163
+ return shouldIncludeChildrenInRange ? nodeKeys : [];
164
+ }
165
+ function $cloneSelectedContent(editor, selection) {
166
+ const root = lexical.$getRoot();
167
+ const nodeMap = new Map();
168
+ const range = [];
169
+ const topLevelChildren = root.getChildren();
170
+
171
+ for (let i = 0; i < topLevelChildren.length; i++) {
172
+ const topLevelNode = topLevelChildren[i];
173
+ const childNodeKeys = $appendSelectedNodesToClone(editor, selection, topLevelNode, nodeMap, range, true);
174
+
175
+ for (let j = 0; j < childNodeKeys.length; j++) {
176
+ const childNodeKey = childNodeKeys[j];
177
+ range.push(childNodeKey);
105
178
  }
106
179
  }
107
180
 
108
- return container.innerHTML;
181
+ return {
182
+ nodeMap: Array.from(nodeMap),
183
+ range
184
+ };
109
185
  }
110
186
  function $getLexicalContent(editor) {
111
- const selection$1 = lexical.$getSelection();
187
+ const selection = lexical.$getSelection();
112
188
 
113
- if (selection$1 !== null) {
189
+ if (selection !== null) {
114
190
  const namespace = editor._config.namespace;
115
- const state = selection.$cloneContents(selection$1);
191
+ const state = $cloneSelectedContent(editor, selection);
116
192
  return JSON.stringify({
117
193
  namespace,
118
194
  state
@@ -130,6 +206,7 @@ function $insertDataTransferForPlainText(dataTransfer, selection) {
130
206
  }
131
207
  function $insertDataTransferForRichText(dataTransfer, selection, editor) {
132
208
  const lexicalNodesString = dataTransfer.getData('application/x-lexical-editor');
209
+ const isSelectionInsideOfGrid = lexical.$isGridSelection(selection) || utils.$findMatchingParent(selection.anchor.getNode(), n => lexical.$isGridCellNode(n)) !== null && utils.$findMatchingParent(selection.focus.getNode(), n => lexical.$isGridCellNode(n)) !== null;
133
210
 
134
211
  if (lexicalNodesString) {
135
212
  const namespace = editor._config.namespace;
@@ -140,7 +217,13 @@ function $insertDataTransferForRichText(dataTransfer, selection, editor) {
140
217
  if (lexicalClipboardData.namespace === namespace) {
141
218
  const nodeRange = lexicalClipboardData.state;
142
219
  const nodes = $generateNodes(nodeRange);
143
- selection.insertNodes(nodes);
220
+
221
+ if (isSelectionInsideOfGrid && nodes.length === 1 && lexical.$isGridNode(nodes[0])) {
222
+ $mergeGridNodesStrategy(nodes, selection, false, editor);
223
+ return;
224
+ }
225
+
226
+ $basicInsertStrategy(nodes, selection, true);
144
227
  return;
145
228
  }
146
229
  } catch (e) {// Malformed, missing nodes..
@@ -153,8 +236,25 @@ function $insertDataTransferForRichText(dataTransfer, selection, editor) {
153
236
  if (htmlString) {
154
237
  const parser = new DOMParser();
155
238
  const dom = parser.parseFromString(htmlString, textHtmlMimeType);
156
- const nodes = $generateNodesFromDOM(dom, editor); // Wrap text and inline nodes in paragraph nodes so we have all blocks at the top-level
239
+ const nodes = $generateNodesFromDOM(dom, editor);
157
240
 
241
+ if (isSelectionInsideOfGrid && nodes.length === 1 && lexical.$isGridNode(nodes[0])) {
242
+ $mergeGridNodesStrategy(nodes, selection, false, editor);
243
+ return;
244
+ }
245
+
246
+ $basicInsertStrategy(nodes, selection, false);
247
+ return;
248
+ }
249
+
250
+ $insertDataTransferForPlainText(dataTransfer, selection);
251
+ }
252
+
253
+ function $basicInsertStrategy(nodes, selection, isFromLexical) {
254
+ let nodesToInsert;
255
+
256
+ if (!isFromLexical) {
257
+ // Wrap text and inline nodes in paragraph nodes so we have all blocks at the top-level
158
258
  const topLevelBlocks = [];
159
259
  let currentBlock = null;
160
260
 
@@ -176,11 +276,128 @@ function $insertDataTransferForRichText(dataTransfer, selection, editor) {
176
276
  }
177
277
  }
178
278
 
179
- selection.insertNodes(topLevelBlocks);
180
- return;
279
+ nodesToInsert = topLevelBlocks;
280
+ } else {
281
+ nodesToInsert = nodes;
181
282
  }
182
283
 
183
- $insertDataTransferForPlainText(dataTransfer, selection);
284
+ if (lexical.$isRangeSelection(selection)) {
285
+ selection.insertNodes(nodesToInsert);
286
+ } else if (lexical.$isGridSelection(selection)) {
287
+ // If there's an active grid selection and a non grid is pasted, add to the anchor.
288
+ const anchorCell = selection.anchor.getNode();
289
+
290
+ if (!lexical.$isGridCellNode(anchorCell)) {
291
+ {
292
+ throw Error(`Expected Grid Cell in Grid Selection`);
293
+ }
294
+ }
295
+
296
+ anchorCell.append(...nodesToInsert);
297
+ }
298
+ }
299
+
300
+ function $mergeGridNodesStrategy(nodes, selection, isFromLexical, editor) {
301
+ if (nodes.length !== 1 || !lexical.$isGridNode(nodes[0])) {
302
+ {
303
+ throw Error(`$mergeGridNodesStrategy: Expected Grid insertion.`);
304
+ }
305
+ }
306
+
307
+ const newGrid = nodes[0];
308
+ const newGridRows = newGrid.getChildren();
309
+ const newColumnCount = newGrid.getFirstChildOrThrow().getChildrenSize();
310
+ const newRowCount = newGrid.getChildrenSize();
311
+ const gridCellNode = utils.$findMatchingParent(selection.anchor.getNode(), n => lexical.$isGridCellNode(n));
312
+ const gridRowNode = gridCellNode && utils.$findMatchingParent(gridCellNode, n => lexical.$isGridRowNode(n));
313
+ const gridNode = gridRowNode && utils.$findMatchingParent(gridRowNode, n => lexical.$isGridNode(n));
314
+
315
+ if (!lexical.$isGridCellNode(gridCellNode) || !lexical.$isGridRowNode(gridRowNode) || !lexical.$isGridNode(gridNode)) {
316
+ {
317
+ throw Error(`$mergeGridNodesStrategy: Expected selection to be inside of a Grid.`);
318
+ }
319
+ }
320
+
321
+ const startY = gridRowNode.getIndexWithinParent();
322
+ const stopY = Math.min(gridNode.getChildrenSize() - 1, startY + newRowCount - 1);
323
+ const startX = gridCellNode.getIndexWithinParent();
324
+ const stopX = Math.min(gridRowNode.getChildrenSize() - 1, startX + newColumnCount - 1);
325
+ const fromX = Math.min(startX, stopX);
326
+ const fromY = Math.min(startY, stopY);
327
+ const toX = Math.max(startX, stopX);
328
+ const toY = Math.max(startY, stopY);
329
+ const gridRowNodes = gridNode.getChildren();
330
+ let newRowIdx = 0;
331
+ let newAnchorCellKey;
332
+ let newFocusCellKey;
333
+
334
+ for (let r = fromY; r <= toY; r++) {
335
+ const currentGridRowNode = gridRowNodes[r];
336
+
337
+ if (!lexical.$isGridRowNode(currentGridRowNode)) {
338
+ {
339
+ throw Error(`getNodes: expected to find GridRowNode`);
340
+ }
341
+ }
342
+
343
+ const newGridRowNode = newGridRows[newRowIdx];
344
+
345
+ if (!lexical.$isGridRowNode(newGridRowNode)) {
346
+ {
347
+ throw Error(`getNodes: expected to find GridRowNode`);
348
+ }
349
+ }
350
+
351
+ const gridCellNodes = currentGridRowNode.getChildren();
352
+ const newGridCellNodes = newGridRowNode.getChildren();
353
+ let newColumnIdx = 0;
354
+
355
+ for (let c = fromX; c <= toX; c++) {
356
+ const currentGridCellNode = gridCellNodes[c];
357
+
358
+ if (!lexical.$isGridCellNode(currentGridCellNode)) {
359
+ {
360
+ throw Error(`getNodes: expected to find GridCellNode`);
361
+ }
362
+ }
363
+
364
+ const newGridCellNode = newGridCellNodes[newColumnIdx];
365
+
366
+ if (!lexical.$isGridCellNode(newGridCellNode)) {
367
+ {
368
+ throw Error(`getNodes: expected to find GridCellNode`);
369
+ }
370
+ }
371
+
372
+ if (r === fromY && c === fromX) {
373
+ newAnchorCellKey = currentGridCellNode.getKey();
374
+ } else if (r === toY && c === toX) {
375
+ newFocusCellKey = currentGridCellNode.getKey();
376
+ }
377
+
378
+ const originalChildren = currentGridCellNode.getChildren();
379
+ newGridCellNode.getChildren().forEach(child => {
380
+ if (lexical.$isTextNode(child)) {
381
+ const paragraphNode = lexical.$createParagraphNode();
382
+ paragraphNode.append(child);
383
+ currentGridCellNode.append(child);
384
+ } else {
385
+ currentGridCellNode.append(child);
386
+ }
387
+ });
388
+ originalChildren.forEach(n => n.remove());
389
+ newColumnIdx++;
390
+ }
391
+
392
+ newRowIdx++;
393
+ }
394
+
395
+ if (newAnchorCellKey && newFocusCellKey) {
396
+ const newGridSelection = lexical.$createGridSelection();
397
+ newGridSelection.set(gridNode.getKey(), newAnchorCellKey, newFocusCellKey);
398
+ lexical.$setSelection(newGridSelection);
399
+ editor.dispatchCommand(lexical.SELECTION_CHANGE_COMMAND);
400
+ }
184
401
  }
185
402
 
186
403
  function $generateNodes(nodeRange) {
@@ -310,8 +527,44 @@ function $generateNodesFromDOM(dom, editor) {
310
527
 
311
528
  return lexicalNodes;
312
529
  }
530
+ function $splitClonedTextNode(selection, clone) {
531
+ if (clone.isSelected() && !clone.isSegmented() && !clone.isToken() && (lexical.$isRangeSelection(selection) || lexical.$isGridSelection(selection))) {
532
+ const anchorNode = selection.anchor.getNode();
533
+ const focusNode = selection.focus.getNode();
534
+ const isAnchor = clone.is(anchorNode);
535
+ const isFocus = clone.is(focusNode);
536
+
537
+ if (isAnchor || isFocus) {
538
+ const isBackward = selection.isBackward();
539
+ const [anchorOffset, focusOffset] = selection.getCharacterOffsets();
540
+ const isSame = anchorNode.is(focusNode);
541
+ const isFirst = clone.is(isBackward ? focusNode : anchorNode);
542
+ const isLast = clone.is(isBackward ? anchorNode : focusNode);
543
+ let startOffset = 0;
544
+ let endOffset = undefined;
545
+
546
+ if (isSame) {
547
+ startOffset = anchorOffset > focusOffset ? focusOffset : anchorOffset;
548
+ endOffset = anchorOffset > focusOffset ? anchorOffset : focusOffset;
549
+ } else if (isFirst) {
550
+ const offset = isBackward ? focusOffset : anchorOffset;
551
+ startOffset = offset;
552
+ endOffset = undefined;
553
+ } else if (isLast) {
554
+ const offset = isBackward ? anchorOffset : focusOffset;
555
+ startOffset = 0;
556
+ endOffset = offset;
557
+ }
558
+
559
+ clone.__text = clone.__text.slice(startOffset, endOffset);
560
+ return clone;
561
+ }
562
+ }
563
+
564
+ return clone;
565
+ }
313
566
 
567
+ exports.$getHtmlContent = $getHtmlContent;
314
568
  exports.$getLexicalContent = $getLexicalContent;
315
569
  exports.$insertDataTransferForPlainText = $insertDataTransferForPlainText;
316
570
  exports.$insertDataTransferForRichText = $insertDataTransferForRichText;
317
- exports.getHtmlContent = getHtmlContent;
@@ -7,7 +7,12 @@
7
7
  * @flow strict
8
8
  */
9
9
 
10
- import type {LexicalEditor, RangeSelection} from 'lexical';
10
+ import type {
11
+ GridSelection,
12
+ LexicalEditor,
13
+ NodeSelection,
14
+ RangeSelection,
15
+ } from 'lexical';
11
16
 
12
17
  /*
13
18
  * Rich Text
@@ -15,11 +20,11 @@ import type {LexicalEditor, RangeSelection} from 'lexical';
15
20
 
16
21
  declare export function $insertDataTransferForRichText(
17
22
  dataTransfer: DataTransfer,
18
- selection: RangeSelection,
23
+ selection: RangeSelection | GridSelection | NodeSelection,
19
24
  editor: LexicalEditor,
20
25
  ): void;
21
26
 
22
- declare export function getHtmlContent(editor: LexicalEditor): string;
27
+ declare export function $getHtmlContent(editor: LexicalEditor): string;
23
28
  declare export function $getLexicalContent(editor: LexicalEditor): string;
24
29
 
25
30
  /*
@@ -4,11 +4,19 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
- var l=require("@lexical/selection"),p=require("lexical");const q=new Set(["STYLE"]);
8
- function r(c,d,h){var b=h;if(p.$isRangeSelection(d)||p.$isGridSelection(d)){var f=d.anchor.getNode(),a=d.focus.getNode(),e=h.is(f),g=h.is(a);if(p.$isTextNode(h)&&(e||g)){e=d.anchor.getCharacterOffset();g=d.focus.getCharacterOffset();const m=d.isBackward(),v=f.is(a);f=h.is(m?a:f);a=h.getTextContent().length;if(v)b=e>g?g:e,h=h.splitText(b,e>g?e:g),b=0===b?h[0]:h[1];else if(e=f?m?g:e:m?e:g,m||0!==e)e!==a&&(b=h.splitText(e)[f&&0!==e?1:0]);else return null}}const {element:k,after:n}=b.exportDOM(c);if(!k)return null;
9
- h=p.$isElementNode(b)?b.getChildren():[];for(e=0;e<h.length;e++)g=h[e],g.isSelected()&&(g=r(c,d,g))&&k.append(g);return n?n.call(b,k):k}function t(c,d){c=c.getData("text/plain");null!=c&&d.insertRawText(c)}function u(c,d){const {nodeName:h}=c;d=d._htmlConversions.get(h.toLowerCase());let b=null;void 0!==d&&d.forEach(f=>{f=f(c);null!==f&&(null===b||b.priority<f.priority)&&(b=f)});return null!==b?b.conversion:null}
10
- function w(c,d,h=new Map,b){let f=[];if(q.has(c.nodeName))return f;let a=null;var e=u(c,d);const g=e?e(c):null;e=null;if(null!==g){e=g.after;a=g.node;if(null!==a){for(var [,k]of h)if(a=k(a,b),!a)break;a&&f.push(a)}null!=g.forChild&&h.set(c.nodeName,g.forChild)}c=c.childNodes;b=[];for(k=0;k<c.length;k++)b.push(...w(c[k],d,h,a));null!=e&&(b=e(b));null==a?f=f.concat(b):p.$isElementNode(a)&&a.append(...b);return f}
11
- exports.$getLexicalContent=function(c){var d=p.$getSelection();return null!==d?(c=c._config.namespace,d=l.$cloneContents(d),JSON.stringify({namespace:c,state:d})):null};exports.$insertDataTransferForPlainText=t;
12
- exports.$insertDataTransferForRichText=function(c,d,h){var b=c.getData("application/x-lexical-editor");if(b){var f=h._config.namespace;try{const k=JSON.parse(b);if(k.namespace===f){const {range:n,nodeMap:m}=k.state;var a=new Map(m);b=[];for(f=0;f<n.length;f++){var e=a.get(n[f]);if(void 0!==e){var g=p.$createNodeFromParse(e,a);b.push(g)}}d.insertNodes(b);return}}catch(k){}}if(a=c.getData("text/html")){a=(new DOMParser).parseFromString(a,"text/html");c=[];a=a.body?Array.from(a.body.childNodes):[];e=
13
- a.length;for(g=0;g<e;g++)b=a[g],q.has(b.nodeName)||(b=w(b,h),null!==b&&(c=c.concat(b)));h=c;c=[];a=null;for(e=0;e<h.length;e++)g=h[e],!p.$isElementNode(g)||g.isInline()?(null===a&&(a=p.$createParagraphNode(),c.push(a)),null!==a&&a.append(g)):(c.push(g),a=null);d.insertNodes(c)}else t(c,d)};
14
- exports.getHtmlContent=function(c){const d=p.$getSelection();if(null==d)throw Error("Expected valid LexicalSelection");if(p.$isRangeSelection(d)&&d.isCollapsed()||0===d.getNodes().length)return null;var h=l.$cloneContents(d);const b=document.createElement("div");for(let a=0;a<h.range.length;a++){var f=p.$getNodeByKey(h.range[a]);f&&f.isSelected()&&(f=r(c,d,f))&&b.append(f)}return b.innerHTML};
7
+ var h=require("@lexical/selection"),u=require("@lexical/utils"),v=require("lexical");function z(a){throw Error(`Minified Lexical error #${a}; see codes.json for the full message or `+"use the non-minified dev environment for full errors and additional helpful warnings.");}const A=new Set(["STYLE"]);
8
+ function B(a,c,d,e){let b=d.isSelected();const f=v.$isElementNode(d)&&d.excludeFromCopy("html");let g=h.$cloneWithProperties(d);g=v.$isTextNode(g)?C(c,g):g;const l=v.$isElementNode(g)?g.getChildren():[],{element:k,after:q}=g.exportDOM(a);if(!k)return!1;const r=new DocumentFragment;for(let p=0;p<l.length;p++){const n=l[p],m=B(a,c,n,r);!b&&v.$isElementNode(d)&&m&&d.extractWithChild(n,c,"html")&&(b=!0)}b&&!f?(k.append(r),e.append(k),q&&(a=q.call(g,k))&&k.replaceWith(a)):e.append(r);return b}
9
+ function D(a,c,d,e,b,f=!0){let g=d.isSelected();const l=v.$isElementNode(d)&&d.excludeFromCopy("clone");let k=h.$cloneWithProperties(d);k=v.$isTextNode(k)?C(c,k):k;var q=v.$isElementNode(k)?k.getChildren():[];const r=[];let p=f;g&&!l&&(e.set(k.getKey(),k),f&&(p=!1));for(let n=0;n<q.length;n++){const m=q[n],w=D(a,c,m,e,b,p);for(let t=0;t<w.length;t++)r.push(w[t]);!g&&v.$isElementNode(d)&&r.includes(m.getKey())&&d.extractWithChild(m,c,"clone")&&(g=!0)}if(v.$isElementNode(k)&&l&&g){let n,m;a=k;b=k.getParent();
10
+ for(q=v.$getRoot();null!=b&&!b.is(q);){if(e.has(b.getKey())||b.extractWithChild(d,c,"clone")){n=h.$cloneWithProperties(b);m=a.getIndexWithinParent();e.set(n.getKey(),n);break}a=b;b=b.getParent()}v.$isElementNode(n)&&null!=m&&n.__children.splice(m,1,...k.__children)}return g&&!l&&(e.has(k.getKey())||e.set(k.getKey(),k),f)?[k.getKey()]:p?r:[]}function E(a,c){a=a.getData("text/plain");null!=a&&c.insertRawText(a)}
11
+ function F(a,c,d){if(!d){d=[];let e=null;for(let b=0;b<a.length;b++){const f=a[b];!v.$isElementNode(f)||f.isInline()?(null===e&&(e=v.$createParagraphNode(),d.push(e)),null!==e&&e.append(f)):(d.push(f),e=null)}a=d}v.$isRangeSelection(c)?c.insertNodes(a):v.$isGridSelection(c)&&(c=c.anchor.getNode(),v.$isGridCellNode(c)||z(15),c.append(...a))}
12
+ function G(a,c,d,e){1===a.length&&v.$isGridNode(a[0])||z(16);var b=a[0];a=b.getChildren();d=b.getFirstChildOrThrow().getChildrenSize();var f=b.getChildrenSize(),g=u.$findMatchingParent(c.anchor.getNode(),m=>v.$isGridCellNode(m));c=(b=g&&u.$findMatchingParent(g,m=>v.$isGridRowNode(m)))&&u.$findMatchingParent(b,m=>v.$isGridNode(m));v.$isGridCellNode(g)&&v.$isGridRowNode(b)&&v.$isGridNode(c)||z(17);var l=b.getIndexWithinParent(),k=Math.min(c.getChildrenSize()-1,l+f-1);f=g.getIndexWithinParent();g=Math.min(b.getChildrenSize()-
13
+ 1,f+d-1);d=Math.min(f,g);b=Math.min(l,k);f=Math.max(f,g);l=Math.max(l,k);k=c.getChildren();g=0;let q,r;for(let m=b;m<=l;m++){var p=k[m];v.$isGridRowNode(p)||z(18);var n=a[g];v.$isGridRowNode(n)||z(18);p=p.getChildren();n=n.getChildren();let w=0;for(let t=d;t<=f;t++){const x=p[t];v.$isGridCellNode(x)||z(19);const H=n[w];v.$isGridCellNode(H)||z(19);m===b&&t===d?q=x.getKey():m===l&&t===f&&(r=x.getKey());const J=x.getChildren();H.getChildren().forEach(y=>{v.$isTextNode(y)&&v.$createParagraphNode().append(y);
14
+ x.append(y)});J.forEach(y=>y.remove());w++}g++}q&&r&&(a=v.$createGridSelection(),a.set(c.getKey(),q,r),v.$setSelection(a),e.dispatchCommand(v.SELECTION_CHANGE_COMMAND))}function I(a){const {range:c,nodeMap:d}=a;a=new Map(d);const e=[];for(let f=0;f<c.length;f++){var b=a.get(c[f]);void 0!==b&&(b=v.$createNodeFromParse(b,a),e.push(b))}return e}
15
+ function K(a,c){const {nodeName:d}=a;c=c._htmlConversions.get(d.toLowerCase());let e=null;void 0!==c&&c.forEach(b=>{b=b(a);null!==b&&(null===e||e.priority<b.priority)&&(e=b)});return null!==e?e.conversion:null}
16
+ function L(a,c,d=new Map,e){let b=[];if(A.has(a.nodeName))return b;let f=null;var g=K(a,c);const l=g?g(a):null;g=null;if(null!==l){g=l.after;f=l.node;if(null!==f){for(var [,k]of d)if(f=k(f,e),!f)break;f&&b.push(f)}null!=l.forChild&&d.set(a.nodeName,l.forChild)}a=a.childNodes;e=[];for(k=0;k<a.length;k++)e.push(...L(a[k],c,d,f));null!=g&&(e=g(e));null==f?b=b.concat(e):v.$isElementNode(f)&&f.append(...e);return b}
17
+ function M(a,c){let d=[];a=a.body?Array.from(a.body.childNodes):[];const e=a.length;for(let f=0;f<e;f++){var b=a[f];A.has(b.nodeName)||(b=L(b,c),null!==b&&(d=d.concat(b)))}return d}
18
+ function C(a,c){if(c.isSelected()&&!c.isSegmented()&&!c.isToken()&&(v.$isRangeSelection(a)||v.$isGridSelection(a))){var d=a.anchor.getNode(),e=a.focus.getNode(),b=c.is(d),f=c.is(e);if(b||f){b=a.isBackward();const [g,l]=a.getCharacterOffsets();a=d.is(e);f=c.is(b?e:d);e=c.is(b?d:e);d=0;let k=void 0;a?(d=g>l?l:g,k=g>l?g:l):f?(d=b?l:g,k=void 0):e&&(b=b?g:l,d=0,k=b);c.__text=c.__text.slice(d,k)}}return c}
19
+ exports.$getHtmlContent=function(a){const c=v.$getSelection();if(null==c)throw Error("Expected valid LexicalSelection");if(v.$isRangeSelection(c)&&c.isCollapsed()||0===c.getNodes().length)return null;const d=document.createElement("div"),e=v.$getRoot().getChildren();for(let b=0;b<e.length;b++)B(a,c,e[b],d);return d.innerHTML};
20
+ exports.$getLexicalContent=function(a){const c=v.$getSelection();if(null!==c){const e=a._config.namespace;var d=v.$getRoot();const b=new Map,f=[];d=d.getChildren();for(let g=0;g<d.length;g++){const l=D(a,c,d[g],b,f,!0);for(let k=0;k<l.length;k++)f.push(l[k])}a={nodeMap:Array.from(b),range:f};return JSON.stringify({namespace:e,state:a})}return null};exports.$insertDataTransferForPlainText=E;
21
+ exports.$insertDataTransferForRichText=function(a,c,d){var e=a.getData("application/x-lexical-editor");const b=v.$isGridSelection(c)||null!==u.$findMatchingParent(c.anchor.getNode(),f=>v.$isGridCellNode(f))&&null!==u.$findMatchingParent(c.focus.getNode(),f=>v.$isGridCellNode(f));if(e){const f=d._config.namespace;try{const g=JSON.parse(e);if(g.namespace===f){const l=I(g.state);if(b&&1===l.length&&v.$isGridNode(l[0])){G(l,c,!1,d);return}F(l,c,!0);return}}catch(g){}}(e=a.getData("text/html"))?(a=(new DOMParser).parseFromString(e,
22
+ "text/html"),a=M(a,d),b&&1===a.length&&v.$isGridNode(a[0])?G(a,c,!1,d):F(a,c,!1)):E(a,c)};
package/package.json CHANGED
@@ -9,14 +9,14 @@
9
9
  "paste"
10
10
  ],
11
11
  "license": "MIT",
12
- "version": "0.2.4",
12
+ "version": "0.2.7",
13
13
  "main": "LexicalClipboard.js",
14
14
  "peerDependencies": {
15
- "lexical": "0.2.4"
15
+ "lexical": "0.2.7"
16
16
  },
17
17
  "dependencies": {
18
- "@lexical/utils": "0.2.4",
19
- "@lexical/selection": "0.2.4"
18
+ "@lexical/utils": "0.2.7",
19
+ "@lexical/selection": "0.2.7"
20
20
  },
21
21
  "repository": {
22
22
  "type": "git",