@lexical/clipboard 0.4.1 → 0.5.1-next.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.
@@ -28,11 +28,13 @@ function $getHtmlContent(editor) {
28
28
 
29
29
 
30
30
  if (lexical.$isRangeSelection(selection) && selection.isCollapsed() || selection.getNodes().length === 0) {
31
- return null;
31
+ return '';
32
32
  }
33
33
 
34
34
  return html.$generateHtmlFromNodes(editor, selection);
35
- }
35
+ } // TODO 0.6.0 Return a blank string instead
36
+ // TODO 0.6.0 Rename to $getJSON
37
+
36
38
  function $getLexicalContent(editor) {
37
39
  const selection = lexical.$getSelection();
38
40
 
@@ -101,11 +103,10 @@ function $insertDataTransferForRichText(dataTransfer, selection, editor) {
101
103
  }
102
104
  }
103
105
  }
104
-
105
106
  function $insertGeneratedNodes(editor, nodes, selection) {
106
- 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;
107
+ const isSelectionInsideOfGrid = lexical.DEPRECATED_$isGridSelection(selection) || utils.$findMatchingParent(selection.anchor.getNode(), n => lexical.DEPRECATED_$isGridCellNode(n)) !== null && utils.$findMatchingParent(selection.focus.getNode(), n => lexical.DEPRECATED_$isGridCellNode(n)) !== null;
107
108
 
108
- if (isSelectionInsideOfGrid && nodes.length === 1 && lexical.$isGridNode(nodes[0])) {
109
+ if (isSelectionInsideOfGrid && nodes.length === 1 && lexical.DEPRECATED_$isGridNode(nodes[0])) {
109
110
  $mergeGridNodesStrategy(nodes, selection, false, editor);
110
111
  return;
111
112
  }
@@ -141,10 +142,17 @@ function $basicInsertStrategy(nodes, selection) {
141
142
  list$1 = null;
142
143
  }
143
144
 
144
- if (lexical.$isDecoratorNode(node) && !node.isTopLevel() || lexical.$isElementNode(node) && node.isInline() || lexical.$isTextNode(node) || lexical.$isLineBreakNode(node)) {
145
+ const isLineBreakNode = lexical.$isLineBreakNode(node);
146
+
147
+ if (isLineBreakNode || lexical.$isDecoratorNode(node) && node.isInline() || lexical.$isElementNode(node) && node.isInline() || lexical.$isTextNode(node)) {
145
148
  if (currentBlock === null) {
146
149
  currentBlock = lexical.$createParagraphNode();
147
- topLevelBlocks.push(currentBlock);
150
+ topLevelBlocks.push(currentBlock); // In the case of LineBreakNode, we just need to
151
+ // add an empty ParagraphNode to the topLevelBlocks.
152
+
153
+ if (isLineBreakNode) {
154
+ continue;
155
+ }
148
156
  }
149
157
 
150
158
  if (currentBlock !== null) {
@@ -158,11 +166,11 @@ function $basicInsertStrategy(nodes, selection) {
158
166
 
159
167
  if (lexical.$isRangeSelection(selection)) {
160
168
  selection.insertNodes(topLevelBlocks);
161
- } else if (lexical.$isGridSelection(selection)) {
169
+ } else if (lexical.DEPRECATED_$isGridSelection(selection)) {
162
170
  // If there's an active grid selection and a non grid is pasted, add to the anchor.
163
171
  const anchorCell = selection.anchor.getNode();
164
172
 
165
- if (!lexical.$isGridCellNode(anchorCell)) {
173
+ if (!lexical.DEPRECATED_$isGridCellNode(anchorCell)) {
166
174
  {
167
175
  throw Error(`Expected Grid Cell in Grid Selection`);
168
176
  }
@@ -173,7 +181,7 @@ function $basicInsertStrategy(nodes, selection) {
173
181
  }
174
182
 
175
183
  function $mergeGridNodesStrategy(nodes, selection, isFromLexical, editor) {
176
- if (nodes.length !== 1 || !lexical.$isGridNode(nodes[0])) {
184
+ if (nodes.length !== 1 || !lexical.DEPRECATED_$isGridNode(nodes[0])) {
177
185
  {
178
186
  throw Error(`$mergeGridNodesStrategy: Expected Grid insertion.`);
179
187
  }
@@ -183,11 +191,11 @@ function $mergeGridNodesStrategy(nodes, selection, isFromLexical, editor) {
183
191
  const newGridRows = newGrid.getChildren();
184
192
  const newColumnCount = newGrid.getFirstChildOrThrow().getChildrenSize();
185
193
  const newRowCount = newGrid.getChildrenSize();
186
- const gridCellNode = utils.$findMatchingParent(selection.anchor.getNode(), n => lexical.$isGridCellNode(n));
187
- const gridRowNode = gridCellNode && utils.$findMatchingParent(gridCellNode, n => lexical.$isGridRowNode(n));
188
- const gridNode = gridRowNode && utils.$findMatchingParent(gridRowNode, n => lexical.$isGridNode(n));
194
+ const gridCellNode = utils.$findMatchingParent(selection.anchor.getNode(), n => lexical.DEPRECATED_$isGridCellNode(n));
195
+ const gridRowNode = gridCellNode && utils.$findMatchingParent(gridCellNode, n => lexical.DEPRECATED_$isGridRowNode(n));
196
+ const gridNode = gridRowNode && utils.$findMatchingParent(gridRowNode, n => lexical.DEPRECATED_$isGridNode(n));
189
197
 
190
- if (!lexical.$isGridCellNode(gridCellNode) || !lexical.$isGridRowNode(gridRowNode) || !lexical.$isGridNode(gridNode)) {
198
+ if (!lexical.DEPRECATED_$isGridCellNode(gridCellNode) || !lexical.DEPRECATED_$isGridRowNode(gridRowNode) || !lexical.DEPRECATED_$isGridNode(gridNode)) {
191
199
  {
192
200
  throw Error(`$mergeGridNodesStrategy: Expected selection to be inside of a Grid.`);
193
201
  }
@@ -209,7 +217,7 @@ function $mergeGridNodesStrategy(nodes, selection, isFromLexical, editor) {
209
217
  for (let r = fromY; r <= toY; r++) {
210
218
  const currentGridRowNode = gridRowNodes[r];
211
219
 
212
- if (!lexical.$isGridRowNode(currentGridRowNode)) {
220
+ if (!lexical.DEPRECATED_$isGridRowNode(currentGridRowNode)) {
213
221
  {
214
222
  throw Error(`getNodes: expected to find GridRowNode`);
215
223
  }
@@ -217,7 +225,7 @@ function $mergeGridNodesStrategy(nodes, selection, isFromLexical, editor) {
217
225
 
218
226
  const newGridRowNode = newGridRows[newRowIdx];
219
227
 
220
- if (!lexical.$isGridRowNode(newGridRowNode)) {
228
+ if (!lexical.DEPRECATED_$isGridRowNode(newGridRowNode)) {
221
229
  {
222
230
  throw Error(`getNodes: expected to find GridRowNode`);
223
231
  }
@@ -230,7 +238,7 @@ function $mergeGridNodesStrategy(nodes, selection, isFromLexical, editor) {
230
238
  for (let c = fromX; c <= toX; c++) {
231
239
  const currentGridCellNode = gridCellNodes[c];
232
240
 
233
- if (!lexical.$isGridCellNode(currentGridCellNode)) {
241
+ if (!lexical.DEPRECATED_$isGridCellNode(currentGridCellNode)) {
234
242
  {
235
243
  throw Error(`getNodes: expected to find GridCellNode`);
236
244
  }
@@ -238,7 +246,7 @@ function $mergeGridNodesStrategy(nodes, selection, isFromLexical, editor) {
238
246
 
239
247
  const newGridCellNode = newGridCellNodes[newColumnIdx];
240
248
 
241
- if (!lexical.$isGridCellNode(newGridCellNode)) {
249
+ if (!lexical.DEPRECATED_$isGridCellNode(newGridCellNode)) {
242
250
  {
243
251
  throw Error(`getNodes: expected to find GridCellNode`);
244
252
  }
@@ -268,7 +276,7 @@ function $mergeGridNodesStrategy(nodes, selection, isFromLexical, editor) {
268
276
  }
269
277
 
270
278
  if (newAnchorCellKey && newFocusCellKey) {
271
- const newGridSelection = lexical.$createGridSelection();
279
+ const newGridSelection = lexical.DEPRECATED_$createGridSelection();
272
280
  newGridSelection.set(gridNode.getKey(), newAnchorCellKey, newFocusCellKey);
273
281
  lexical.$setSelection(newGridSelection);
274
282
  editor.dispatchCommand(lexical.SELECTION_CHANGE_COMMAND, undefined);
@@ -302,18 +310,24 @@ function exportNodeToJSON(node) {
302
310
  function $appendNodesToJSON(editor, selection$1, currentNode, targetArray = []) {
303
311
  let shouldInclude = selection$1 != null ? currentNode.isSelected() : true;
304
312
  const shouldExclude = lexical.$isElementNode(currentNode) && currentNode.excludeFromCopy('html');
305
- let clone = selection.$cloneWithProperties(currentNode);
306
- clone = lexical.$isTextNode(clone) && selection$1 != null ? selection.$sliceSelectedTextNodeContent(selection$1, clone) : clone;
307
- const children = lexical.$isElementNode(clone) ? clone.getChildren() : [];
308
- const serializedNode = exportNodeToJSON(clone); // TODO: TextNode calls getTextContent() (NOT node.__text) within it's exportJSON method
313
+ let target = currentNode;
314
+
315
+ if (selection$1 !== null) {
316
+ let clone = selection.$cloneWithProperties(currentNode);
317
+ clone = lexical.$isTextNode(clone) && selection$1 != null ? selection.$sliceSelectedTextNodeContent(selection$1, clone) : clone;
318
+ target = clone;
319
+ }
320
+
321
+ const children = lexical.$isElementNode(target) ? target.getChildren() : [];
322
+ const serializedNode = exportNodeToJSON(target); // TODO: TextNode calls getTextContent() (NOT node.__text) within it's exportJSON method
309
323
  // which uses getLatest() to get the text from the original node with the same key.
310
324
  // This is a deeper issue with the word "clone" here, it's still a reference to the
311
325
  // same node as far as the LexicalEditor is concerned since it shares a key.
312
326
  // We need a way to create a clone of a Node in memory with it's own key, but
313
327
  // until then this hack will work for the selected text extract use case.
314
328
 
315
- if (lexical.$isTextNode(clone)) {
316
- serializedNode.text = clone.__text;
329
+ if (lexical.$isTextNode(target)) {
330
+ serializedNode.text = target.__text;
317
331
  }
318
332
 
319
333
  for (let i = 0; i < children.length; i++) {
@@ -335,7 +349,8 @@ function $appendNodesToJSON(editor, selection$1, currentNode, targetArray = [])
335
349
  }
336
350
 
337
351
  return shouldInclude;
338
- }
352
+ } // TODO why $ function with Editor instance?
353
+
339
354
 
340
355
  function $generateJSONFromSelectedNodes(editor, selection) {
341
356
  const nodes = [];
@@ -368,8 +383,103 @@ function $generateNodesFromSerializedNodes(serializedNodes) {
368
383
 
369
384
  return nodes;
370
385
  }
386
+ const EVENT_LATENCY = 50;
387
+ let clipboardEventTimeout = null; // TODO custom selection
388
+ // TODO potentially have a node customizable version for plain text
389
+
390
+ async function copyToClipboard__EXPERIMENTAL(editor, event) {
391
+ if (clipboardEventTimeout !== null) {
392
+ // Prevent weird race conditions that can happen when this function is run multiple times
393
+ // synchronously. In the future, we can do better, we can cancel/override the previously running job.
394
+ return false;
395
+ }
396
+
397
+ if (event !== null) {
398
+ return new Promise((resolve, reject) => {
399
+ editor.update(() => {
400
+ resolve($copyToClipboardEvent(editor, event));
401
+ });
402
+ });
403
+ }
404
+
405
+ const rootElement = editor.getRootElement();
406
+ const domSelection = document.getSelection();
407
+
408
+ if (rootElement === null || domSelection === null) {
409
+ return false;
410
+ }
411
+
412
+ const element = document.createElement('span');
413
+ element.style.cssText = 'position: fixed; top: -1000px;';
414
+ element.append(document.createTextNode('#'));
415
+ rootElement.append(element);
416
+ const range = new Range();
417
+ range.setStart(element, 0);
418
+ range.setEnd(element, 1);
419
+ domSelection.removeAllRanges();
420
+ domSelection.addRange(range);
421
+ return new Promise((resolve, reject) => {
422
+ const removeListener = editor.registerCommand(lexical.COPY_COMMAND, secondEvent => {
423
+ if (secondEvent instanceof ClipboardEvent) {
424
+ removeListener();
425
+
426
+ if (clipboardEventTimeout !== null) {
427
+ window.clearTimeout(clipboardEventTimeout);
428
+ clipboardEventTimeout = null;
429
+ }
430
+
431
+ resolve($copyToClipboardEvent(editor, secondEvent));
432
+ } // Block the entire copy flow while we wait for the next ClipboardEvent
433
+
434
+
435
+ return true;
436
+ }, lexical.COMMAND_PRIORITY_CRITICAL); // If the above hack execCommand hack works, this timeout code should never fire. Otherwise,
437
+ // the listener will be quickly freed so that the user can reuse it again
438
+
439
+ clipboardEventTimeout = window.setTimeout(() => {
440
+ removeListener();
441
+ clipboardEventTimeout = null;
442
+ resolve(false);
443
+ }, EVENT_LATENCY);
444
+ document.execCommand('copy');
445
+ element.remove();
446
+ });
447
+ } // TODO shouldn't pass editor (pass namespace directly)
448
+
449
+ function $copyToClipboardEvent(editor, event) {
450
+ event.preventDefault();
451
+ const clipboardData = event.clipboardData;
452
+
453
+ if (clipboardData === null) {
454
+ return false;
455
+ }
456
+
457
+ const selection = lexical.$getSelection();
458
+ const htmlString = $getHtmlContent(editor);
459
+ const lexicalString = $getLexicalContent(editor);
460
+ let plainString = '';
461
+
462
+ if (selection !== null) {
463
+ plainString = selection.getTextContent();
464
+ }
465
+
466
+ if (htmlString !== null) {
467
+ clipboardData.setData('text/html', htmlString);
468
+ }
469
+
470
+ if (lexicalString !== null) {
471
+ clipboardData.setData('application/x-lexical-editor', lexicalString);
472
+ }
473
+
474
+ clipboardData.setData('text/plain', plainString);
475
+ return true;
476
+ }
371
477
 
478
+ exports.$generateJSONFromSelectedNodes = $generateJSONFromSelectedNodes;
479
+ exports.$generateNodesFromSerializedNodes = $generateNodesFromSerializedNodes;
372
480
  exports.$getHtmlContent = $getHtmlContent;
373
481
  exports.$getLexicalContent = $getLexicalContent;
374
482
  exports.$insertDataTransferForPlainText = $insertDataTransferForPlainText;
375
483
  exports.$insertDataTransferForRichText = $insertDataTransferForRichText;
484
+ exports.$insertGeneratedNodes = $insertGeneratedNodes;
485
+ exports.copyToClipboard__EXPERIMENTAL = copyToClipboard__EXPERIMENTAL;
@@ -29,6 +29,12 @@ declare export function $getHtmlContent(editor: LexicalEditor): string | null;
29
29
  declare export function $getLexicalContent(
30
30
  editor: LexicalEditor,
31
31
  ): string | null;
32
+
33
+ declare export function $insertGeneratedNodes(
34
+ editor: LexicalEditor,
35
+ nodes: Array<LexicalNode>,
36
+ selection: RangeSelection | GridSelection,
37
+ ): void;
32
38
  /*
33
39
  * Plain Text
34
40
  */
@@ -61,3 +67,8 @@ declare export function $generateJSONFromSelectedNodes<
61
67
  declare export function $generateNodesFromSerializedNodes(
62
68
  serializedNodes: Array<BaseSerializedNode>,
63
69
  ): Array<LexicalNode>;
70
+
71
+ declare export function copyToClipboard__EXPERIMENTAL(
72
+ editor: LexicalEditor,
73
+ event: null | ClipboardEvent,
74
+ ): Promise<boolean>;
@@ -4,15 +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
- 'use strict';var d=require("@lexical/html"),p=require("@lexical/list"),r=require("@lexical/selection"),y=require("@lexical/utils"),z=require("lexical");function A(a){throw Error(`Minified Lexical error #${a}; visit https://lexical.dev/docs/error?code=${a} for the full message or `+"use the non-minified dev environment for full errors and additional helpful warnings.");}
8
- function B(a,c,e){(z.$isGridSelection(e)||null!==y.$findMatchingParent(e.anchor.getNode(),g=>z.$isGridCellNode(g))&&null!==y.$findMatchingParent(e.focus.getNode(),g=>z.$isGridCellNode(g)))&&1===c.length&&z.$isGridNode(c[0])?E(c,e,!1,a):F(c,e)}
9
- function F(a,c){let e=[],g=null,f=null;for(let h=0;h<a.length;h++){let b=a[h];p.$isListItemNode(b)?(null==f&&(f=p.$createListNode("bullet"),e.push(f)),f.append(b)):(null!=f&&(f=null),z.$isDecoratorNode(b)&&!b.isTopLevel()||z.$isElementNode(b)&&b.isInline()||z.$isTextNode(b)||z.$isLineBreakNode(b)?(null===g&&(g=z.$createParagraphNode(),e.push(g)),null!==g&&g.append(b)):(e.push(b),g=null))}z.$isRangeSelection(c)?c.insertNodes(e):z.$isGridSelection(c)&&(a=c.anchor.getNode(),z.$isGridCellNode(a)||A(41),
10
- a.append(...e))}
11
- function E(a,c,e,g){1===a.length&&z.$isGridNode(a[0])||A(42);var f=a[0];a=f.getChildren();e=f.getFirstChildOrThrow().getChildrenSize();var h=f.getChildrenSize(),b=y.$findMatchingParent(c.anchor.getNode(),m=>z.$isGridCellNode(m));c=(f=b&&y.$findMatchingParent(b,m=>z.$isGridRowNode(m)))&&y.$findMatchingParent(f,m=>z.$isGridNode(m));z.$isGridCellNode(b)&&z.$isGridRowNode(f)&&z.$isGridNode(c)||A(43);var k=f.getIndexWithinParent(),n=Math.min(c.getChildrenSize()-1,k+h-1);h=b.getIndexWithinParent();b=Math.min(f.getChildrenSize()-
12
- 1,h+e-1);e=Math.min(h,b);f=Math.min(k,n);h=Math.max(h,b);k=Math.max(k,n);n=c.getChildren();b=0;let l,q;for(let m=f;m<=k;m++){var w=n[m];z.$isGridRowNode(w)||A(24);var x=a[b];z.$isGridRowNode(x)||A(24);w=w.getChildren();x=x.getChildren();let C=0;for(let t=e;t<=h;t++){let u=w[t];z.$isGridCellNode(u)||A(25);let D=x[C];z.$isGridCellNode(D)||A(25);m===f&&t===e?l=u.getKey():m===k&&t===h&&(q=u.getKey());let H=u.getChildren();D.getChildren().forEach(v=>{z.$isTextNode(v)&&z.$createParagraphNode().append(v);
13
- u.append(v)});H.forEach(v=>v.remove());C++}b++}l&&q&&(a=z.$createGridSelection(),a.set(c.getKey(),l,q),z.$setSelection(a),g.dispatchCommand(z.SELECTION_CHANGE_COMMAND,void 0))}
14
- function G(a,c,e,g=[]){let f=null!=c?e.isSelected():!0,h=z.$isElementNode(e)&&e.excludeFromCopy("html");var b=r.$cloneWithProperties(e);b=z.$isTextNode(b)&&null!=c?r.$sliceSelectedTextNodeContent(c,b):b;let k=z.$isElementNode(b)?b.getChildren():[];var n=b;let l=n.exportJSON();l.type!==n.constructor.getType()&&A(58);var q=l.children;z.$isElementNode(n)&&(Array.isArray(q)||A(59));z.$isTextNode(b)&&(l.text=b.__text);for(b=0;b<k.length;b++)n=k[b],q=G(a,c,n,l.children),!f&&z.$isElementNode(e)&&q&&e.extractWithChild(n,
15
- c,"clone")&&(f=!0);if(f&&!h)g.push(l);else if(Array.isArray(l.children))for(a=0;a<l.children.length;a++)g.push(l.children[a]);return f}exports.$getHtmlContent=function(a){let c=z.$getSelection();if(null==c)throw Error("Expected valid LexicalSelection");return z.$isRangeSelection(c)&&c.isCollapsed()||0===c.getNodes().length?null:d.$generateHtmlFromNodes(a,c)};
16
- exports.$getLexicalContent=function(a){let c=z.$getSelection();if(null==c)throw Error("Expected valid LexicalSelection");if(z.$isRangeSelection(c)&&c.isCollapsed()||0===c.getNodes().length)return null;var e=JSON,g=e.stringify;let f=[],h=z.$getRoot().getChildren();for(let b=0;b<h.length;b++)G(a,c,h[b],f);return g.call(e,{namespace:a._config.namespace,nodes:f})};exports.$insertDataTransferForPlainText=function(a,c){a=a.getData("text/plain");null!=a&&c.insertRawText(a)};
17
- exports.$insertDataTransferForRichText=function(a,c,e){var g=a.getData("application/x-lexical-editor");if(g)try{var f=JSON.parse(g);if(f.namespace===e._config.namespace&&Array.isArray(f.nodes)){var h=f.nodes;g=[];for(f=0;f<h.length;f++){let k=z.$parseSerializedNode(h[f]);z.$isTextNode(k)&&r.$addNodeStyle(k);g.push(k)}return B(e,g,c)}}catch{}if(h=a.getData("text/html"))try{var b=(new DOMParser).parseFromString(h,"text/html");let k=d.$generateNodesFromDOM(e,b);return B(e,k,c)}catch{}a=a.getData("text/plain");
18
- if(null!=a)if(z.$isRangeSelection(c))for(a=a.split(/\r?\n/),e=a.length,b=0;b<e;b++)c.insertText(a[b]),b<e-1&&c.insertParagraph();else c.insertRawText(a)}
7
+ 'use strict';var d=require("@lexical/html"),n=require("@lexical/list"),r=require("@lexical/selection"),t=require("@lexical/utils"),z=require("lexical");function A(a){throw Error(`Minified Lexical error #${a}; visit https://lexical.dev/docs/error?code=${a} for the full message or `+"use the non-minified dev environment for full errors and additional helpful warnings.");}
8
+ function B(a){let b=z.$getSelection();if(null==b)throw Error("Expected valid LexicalSelection");return z.$isRangeSelection(b)&&b.isCollapsed()||0===b.getNodes().length?"":d.$generateHtmlFromNodes(a,b)}function C(a){let b=z.$getSelection();if(null==b)throw Error("Expected valid LexicalSelection");return z.$isRangeSelection(b)&&b.isCollapsed()||0===b.getNodes().length?null:JSON.stringify(D(a,b))}
9
+ function E(a,b,c){(z.DEPRECATED_$isGridSelection(c)||null!==t.$findMatchingParent(c.anchor.getNode(),g=>z.DEPRECATED_$isGridCellNode(g))&&null!==t.$findMatchingParent(c.focus.getNode(),g=>z.DEPRECATED_$isGridCellNode(g)))&&1===b.length&&z.DEPRECATED_$isGridNode(b[0])?F(b,c,!1,a):I(b,c)}
10
+ function I(a,b){let c=[],g=null,e=null;for(let k=0;k<a.length;k++){let f=a[k];if(n.$isListItemNode(f)){null==e&&(e=n.$createListNode("bullet"),c.push(e));e.append(f);continue}else null!=e&&(e=null);let h=z.$isLineBreakNode(f);if(h||z.$isDecoratorNode(f)&&f.isInline()||z.$isElementNode(f)&&f.isInline()||z.$isTextNode(f)){if(null===g&&(g=z.$createParagraphNode(),c.push(g),h))continue;null!==g&&g.append(f)}else c.push(f),g=null}z.$isRangeSelection(b)?b.insertNodes(c):z.DEPRECATED_$isGridSelection(b)&&
11
+ (a=b.anchor.getNode(),z.DEPRECATED_$isGridCellNode(a)||A(41),a.append(...c))}
12
+ function F(a,b,c,g){1===a.length&&z.DEPRECATED_$isGridNode(a[0])||A(42);var e=a[0];a=e.getChildren();c=e.getFirstChildOrThrow().getChildrenSize();var k=e.getChildrenSize(),f=t.$findMatchingParent(b.anchor.getNode(),l=>z.DEPRECATED_$isGridCellNode(l));b=(e=f&&t.$findMatchingParent(f,l=>z.DEPRECATED_$isGridRowNode(l)))&&t.$findMatchingParent(e,l=>z.DEPRECATED_$isGridNode(l));z.DEPRECATED_$isGridCellNode(f)&&z.DEPRECATED_$isGridRowNode(e)&&z.DEPRECATED_$isGridNode(b)||A(43);var h=e.getIndexWithinParent(),
13
+ p=Math.min(b.getChildrenSize()-1,h+k-1);k=f.getIndexWithinParent();f=Math.min(e.getChildrenSize()-1,k+c-1);c=Math.min(k,f);e=Math.min(h,p);k=Math.max(k,f);h=Math.max(h,p);p=b.getChildren();f=0;let m,q;for(let l=e;l<=h;l++){var x=p[l];z.DEPRECATED_$isGridRowNode(x)||A(24);var y=a[f];z.DEPRECATED_$isGridRowNode(y)||A(24);x=x.getChildren();y=y.getChildren();let G=0;for(let u=c;u<=k;u++){let v=x[u];z.DEPRECATED_$isGridCellNode(v)||A(25);let H=y[G];z.DEPRECATED_$isGridCellNode(H)||A(25);l===e&&u===c?m=
14
+ v.getKey():l===h&&u===k&&(q=v.getKey());let N=v.getChildren();H.getChildren().forEach(w=>{z.$isTextNode(w)&&z.$createParagraphNode().append(w);v.append(w)});N.forEach(w=>w.remove());G++}f++}m&&q&&(a=z.DEPRECATED_$createGridSelection(),a.set(b.getKey(),m,q),z.$setSelection(a),g.dispatchCommand(z.SELECTION_CHANGE_COMMAND,void 0))}
15
+ function J(a,b,c,g=[]){let e=null!=b?c.isSelected():!0,k=z.$isElementNode(c)&&c.excludeFromCopy("html");var f=c;if(null!==b){var h=r.$cloneWithProperties(c);f=h=z.$isTextNode(h)&&null!=b?r.$sliceSelectedTextNodeContent(b,h):h}let p=z.$isElementNode(f)?f.getChildren():[];var m=f;h=m.exportJSON();h.type!==m.constructor.getType()&&A(58);var q=h.children;z.$isElementNode(m)&&(Array.isArray(q)||A(59));z.$isTextNode(f)&&(h.text=f.__text);for(f=0;f<p.length;f++)m=p[f],q=J(a,b,m,h.children),!e&&z.$isElementNode(c)&&
16
+ q&&c.extractWithChild(m,b,"clone")&&(e=!0);if(e&&!k)g.push(h);else if(Array.isArray(h.children))for(a=0;a<h.children.length;a++)g.push(h.children[a]);return e}function D(a,b){let c=[],g=z.$getRoot().getChildren();for(let e=0;e<g.length;e++)J(a,b,g[e],c);return{namespace:a._config.namespace,nodes:c}}function K(a){let b=[];for(let c=0;c<a.length;c++){let g=z.$parseSerializedNode(a[c]);z.$isTextNode(g)&&r.$addNodeStyle(g);b.push(g)}return b}let L=null;
17
+ function M(a,b){b.preventDefault();b=b.clipboardData;if(null===b)return!1;let c=z.$getSelection(),g=B(a);a=C(a);let e="";null!==c&&(e=c.getTextContent());null!==g&&b.setData("text/html",g);null!==a&&b.setData("application/x-lexical-editor",a);b.setData("text/plain",e);return!0}exports.$generateJSONFromSelectedNodes=D;exports.$generateNodesFromSerializedNodes=K;exports.$getHtmlContent=B;exports.$getLexicalContent=C;
18
+ exports.$insertDataTransferForPlainText=function(a,b){a=a.getData("text/plain");null!=a&&b.insertRawText(a)};
19
+ exports.$insertDataTransferForRichText=function(a,b,c){var g=a.getData("application/x-lexical-editor");if(g)try{let k=JSON.parse(g);if(k.namespace===c._config.namespace&&Array.isArray(k.nodes)){let f=K(k.nodes);return E(c,f,b)}}catch{}if(g=a.getData("text/html"))try{var e=(new DOMParser).parseFromString(g,"text/html");let k=d.$generateNodesFromDOM(c,e);return E(c,k,b)}catch{}a=a.getData("text/plain");if(null!=a)if(z.$isRangeSelection(b))for(a=a.split(/\r?\n/),c=a.length,e=0;e<c;e++)b.insertText(a[e]),
20
+ e<c-1&&b.insertParagraph();else b.insertRawText(a)};exports.$insertGeneratedNodes=E;
21
+ exports.copyToClipboard__EXPERIMENTAL=async function(a,b){if(null!==L)return!1;if(null!==b)return new Promise(k=>{a.update(()=>{k(M(a,b))})});var c=a.getRootElement();let g=document.getSelection();if(null===c||null===g)return!1;let e=document.createElement("span");e.style.cssText="position: fixed; top: -1000px;";e.append(document.createTextNode("#"));c.append(e);c=new Range;c.setStart(e,0);c.setEnd(e,1);g.removeAllRanges();g.addRange(c);return new Promise(k=>{let f=a.registerCommand(z.COPY_COMMAND,
22
+ h=>{h instanceof ClipboardEvent&&(f(),null!==L&&(window.clearTimeout(L),L=null),k(M(a,h)));return!0},z.COMMAND_PRIORITY_CRITICAL);L=window.setTimeout(()=>{f();L=null;k(!1)},50);document.execCommand("copy");e.remove()})}
package/clipboard.d.ts CHANGED
@@ -5,12 +5,13 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  *
7
7
  */
8
- import type { GridSelection, LexicalEditor, LexicalNode, NodeSelection, RangeSelection } from 'lexical';
9
- export declare function $getHtmlContent(editor: LexicalEditor): string | null;
10
- export declare function $getLexicalContent(editor: LexicalEditor): string | null;
8
+ import { GridSelection, LexicalEditor, LexicalNode, NodeSelection, RangeSelection } from 'lexical';
9
+ export declare function $getHtmlContent(editor: LexicalEditor): string;
10
+ export declare function $getLexicalContent(editor: LexicalEditor): null | string;
11
11
  export declare function $insertDataTransferForPlainText(dataTransfer: DataTransfer, selection: RangeSelection | GridSelection): void;
12
12
  export declare function $insertDataTransferForRichText(dataTransfer: DataTransfer, selection: RangeSelection | GridSelection, editor: LexicalEditor): void;
13
- interface BaseSerializedNode {
13
+ export declare function $insertGeneratedNodes(editor: LexicalEditor, nodes: Array<LexicalNode>, selection: RangeSelection | GridSelection): void;
14
+ export interface BaseSerializedNode {
14
15
  children?: Array<BaseSerializedNode>;
15
16
  type: string;
16
17
  version: number;
@@ -20,4 +21,4 @@ export declare function $generateJSONFromSelectedNodes<SerializedNode extends Ba
20
21
  nodes: Array<SerializedNode>;
21
22
  };
22
23
  export declare function $generateNodesFromSerializedNodes(serializedNodes: Array<BaseSerializedNode>): Array<LexicalNode>;
23
- export {};
24
+ export declare function copyToClipboard__EXPERIMENTAL(editor: LexicalEditor, event: null | ClipboardEvent): Promise<boolean>;
package/index.d.ts CHANGED
@@ -6,5 +6,4 @@
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  *
8
8
  */
9
- import { $getHtmlContent, $getLexicalContent, $insertDataTransferForPlainText, $insertDataTransferForRichText } from './clipboard';
10
- export { $getHtmlContent, $getLexicalContent, $insertDataTransferForPlainText, $insertDataTransferForRichText, };
9
+ export { $generateJSONFromSelectedNodes, $generateNodesFromSerializedNodes, $getHtmlContent, $getLexicalContent, $insertDataTransferForPlainText, $insertDataTransferForRichText, $insertGeneratedNodes, copyToClipboard__EXPERIMENTAL, } from './clipboard';
package/package.json CHANGED
@@ -9,16 +9,16 @@
9
9
  "paste"
10
10
  ],
11
11
  "license": "MIT",
12
- "version": "0.4.1",
12
+ "version": "0.5.1-next.0",
13
13
  "main": "LexicalClipboard.js",
14
14
  "peerDependencies": {
15
- "lexical": "0.4.1"
15
+ "lexical": "0.5.1-next.0"
16
16
  },
17
17
  "dependencies": {
18
- "@lexical/utils": "0.4.1",
19
- "@lexical/list": "0.4.1",
20
- "@lexical/selection": "0.4.1",
21
- "@lexical/html": "0.4.1"
18
+ "@lexical/utils": "0.5.1-next.0",
19
+ "@lexical/list": "0.5.1-next.0",
20
+ "@lexical/selection": "0.5.1-next.0",
21
+ "@lexical/html": "0.5.1-next.0"
22
22
  },
23
23
  "repository": {
24
24
  "type": "git",