@lexical/clipboard 0.3.3 → 0.3.6
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/LexicalClipboard.dev.js +70 -33
- package/LexicalClipboard.js.flow +26 -1
- package/LexicalClipboard.prod.js +12 -10
- package/clipboard.d.ts +23 -0
- package/index.d.ts +9 -0
- package/package.json +5 -5
- package/LexicalClipboard.d.ts +0 -35
package/LexicalClipboard.dev.js
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
'use strict';
|
|
8
8
|
|
|
9
9
|
var html = require('@lexical/html');
|
|
10
|
+
var list = require('@lexical/list');
|
|
10
11
|
var selection = require('@lexical/selection');
|
|
11
12
|
var utils = require('@lexical/utils');
|
|
12
13
|
var lexical = require('lexical');
|
|
@@ -54,7 +55,6 @@ function $insertDataTransferForPlainText(dataTransfer, selection) {
|
|
|
54
55
|
}
|
|
55
56
|
}
|
|
56
57
|
function $insertDataTransferForRichText(dataTransfer, selection, editor) {
|
|
57
|
-
const htmlString = dataTransfer.getData('text/html');
|
|
58
58
|
const lexicalString = dataTransfer.getData('application/x-lexical-editor');
|
|
59
59
|
|
|
60
60
|
if (lexicalString) {
|
|
@@ -69,15 +69,36 @@ function $insertDataTransferForRichText(dataTransfer, selection, editor) {
|
|
|
69
69
|
} catch {}
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
+
const htmlString = dataTransfer.getData('text/html');
|
|
73
|
+
|
|
72
74
|
if (htmlString) {
|
|
73
75
|
try {
|
|
74
76
|
const parser = new DOMParser();
|
|
75
77
|
const dom = parser.parseFromString(htmlString, 'text/html');
|
|
76
78
|
return $insertGeneratedNodes(editor, html.$generateNodesFromDOM(editor, dom), selection); // eslint-disable-next-line no-empty
|
|
77
79
|
} catch {}
|
|
78
|
-
}
|
|
80
|
+
} // Multi-line plain text in rich text mode pasted as separate paragrahs
|
|
81
|
+
// instead of single paragraph with linebreaks.
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
const text = dataTransfer.getData('text/plain');
|
|
85
|
+
|
|
86
|
+
if (text != null) {
|
|
87
|
+
if (lexical.$isRangeSelection(selection)) {
|
|
88
|
+
const lines = text.split(/\r?\n/);
|
|
89
|
+
const linesLength = lines.length;
|
|
79
90
|
|
|
80
|
-
|
|
91
|
+
for (let i = 0; i < linesLength; i++) {
|
|
92
|
+
selection.insertText(lines[i]);
|
|
93
|
+
|
|
94
|
+
if (i < linesLength - 1) {
|
|
95
|
+
selection.insertParagraph();
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
} else {
|
|
99
|
+
selection.insertRawText(text);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
81
102
|
}
|
|
82
103
|
|
|
83
104
|
function $insertGeneratedNodes(editor, nodes, selection) {
|
|
@@ -88,43 +109,54 @@ function $insertGeneratedNodes(editor, nodes, selection) {
|
|
|
88
109
|
return;
|
|
89
110
|
}
|
|
90
111
|
|
|
91
|
-
$basicInsertStrategy(nodes, selection
|
|
112
|
+
$basicInsertStrategy(nodes, selection);
|
|
92
113
|
return;
|
|
93
114
|
}
|
|
94
115
|
|
|
95
|
-
function $basicInsertStrategy(nodes, selection
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
116
|
+
function $basicInsertStrategy(nodes, selection) {
|
|
117
|
+
// Wrap text and inline nodes in paragraph nodes so we have all blocks at the top-level
|
|
118
|
+
const topLevelBlocks = [];
|
|
119
|
+
let currentBlock = null;
|
|
120
|
+
let list$1 = null;
|
|
121
|
+
|
|
122
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
123
|
+
const node = nodes[i];
|
|
124
|
+
/**
|
|
125
|
+
* There's no good way to add this to importDOM or importJSON directly,
|
|
126
|
+
* so this is here in order to safely correct faulty clipboard data
|
|
127
|
+
* that we can't control and avoid crashing the app.
|
|
128
|
+
* https://github.com/facebook/lexical/issues/2405
|
|
129
|
+
*/
|
|
130
|
+
|
|
131
|
+
if (list.$isListItemNode(node)) {
|
|
132
|
+
if (list$1 == null) {
|
|
133
|
+
list$1 = list.$createListNode('bullet');
|
|
134
|
+
topLevelBlocks.push(list$1);
|
|
135
|
+
}
|
|
102
136
|
|
|
103
|
-
|
|
104
|
-
|
|
137
|
+
list$1.append(node);
|
|
138
|
+
continue;
|
|
139
|
+
} else if (list$1 != null) {
|
|
140
|
+
list$1 = null;
|
|
141
|
+
}
|
|
105
142
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
143
|
+
if (lexical.$isDecoratorNode(node) && !node.isTopLevel() || lexical.$isElementNode(node) && node.isInline() || lexical.$isTextNode(node) || lexical.$isLineBreakNode(node)) {
|
|
144
|
+
if (currentBlock === null) {
|
|
145
|
+
currentBlock = lexical.$createParagraphNode();
|
|
146
|
+
topLevelBlocks.push(currentBlock);
|
|
147
|
+
}
|
|
111
148
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
}
|
|
115
|
-
} else {
|
|
116
|
-
topLevelBlocks.push(node);
|
|
117
|
-
currentBlock = null;
|
|
149
|
+
if (currentBlock !== null) {
|
|
150
|
+
currentBlock.append(node);
|
|
118
151
|
}
|
|
152
|
+
} else {
|
|
153
|
+
topLevelBlocks.push(node);
|
|
154
|
+
currentBlock = null;
|
|
119
155
|
}
|
|
120
|
-
|
|
121
|
-
nodesToInsert = topLevelBlocks;
|
|
122
|
-
} else {
|
|
123
|
-
nodesToInsert = nodes;
|
|
124
156
|
}
|
|
125
157
|
|
|
126
158
|
if (lexical.$isRangeSelection(selection)) {
|
|
127
|
-
selection.insertNodes(
|
|
159
|
+
selection.insertNodes(topLevelBlocks);
|
|
128
160
|
} else if (lexical.$isGridSelection(selection)) {
|
|
129
161
|
// If there's an active grid selection and a non grid is pasted, add to the anchor.
|
|
130
162
|
const anchorCell = selection.anchor.getNode();
|
|
@@ -135,7 +167,7 @@ function $basicInsertStrategy(nodes, selection, isFromLexical) {
|
|
|
135
167
|
}
|
|
136
168
|
}
|
|
137
169
|
|
|
138
|
-
anchorCell.append(...
|
|
170
|
+
anchorCell.append(...topLevelBlocks);
|
|
139
171
|
}
|
|
140
172
|
}
|
|
141
173
|
|
|
@@ -266,7 +298,7 @@ function exportNodeToJSON(node) {
|
|
|
266
298
|
return serializedNode;
|
|
267
299
|
}
|
|
268
300
|
|
|
269
|
-
function $appendNodesToJSON(editor, selection$1, currentNode, targetArray) {
|
|
301
|
+
function $appendNodesToJSON(editor, selection$1, currentNode, targetArray = []) {
|
|
270
302
|
let shouldInclude = selection$1 != null ? currentNode.isSelected() : true;
|
|
271
303
|
const shouldExclude = lexical.$isElementNode(currentNode) && currentNode.excludeFromCopy('html');
|
|
272
304
|
let clone = selection.$cloneWithProperties(currentNode);
|
|
@@ -280,7 +312,6 @@ function $appendNodesToJSON(editor, selection$1, currentNode, targetArray) {
|
|
|
280
312
|
// until then this hack will work for the selected text extract use case.
|
|
281
313
|
|
|
282
314
|
if (lexical.$isTextNode(clone)) {
|
|
283
|
-
// @ts-ignore
|
|
284
315
|
serializedNode.text = clone.__text;
|
|
285
316
|
}
|
|
286
317
|
|
|
@@ -325,7 +356,13 @@ function $generateNodesFromSerializedNodes(serializedNodes) {
|
|
|
325
356
|
|
|
326
357
|
for (let i = 0; i < serializedNodes.length; i++) {
|
|
327
358
|
const serializedNode = serializedNodes[i];
|
|
328
|
-
|
|
359
|
+
const node = lexical.$parseSerializedNode(serializedNode);
|
|
360
|
+
|
|
361
|
+
if (lexical.$isTextNode(node)) {
|
|
362
|
+
selection.$addNodeStyle(node);
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
nodes.push(node);
|
|
329
366
|
}
|
|
330
367
|
|
|
331
368
|
return nodes;
|
package/LexicalClipboard.js.flow
CHANGED
|
@@ -12,6 +12,7 @@ import type {
|
|
|
12
12
|
LexicalEditor,
|
|
13
13
|
NodeSelection,
|
|
14
14
|
RangeSelection,
|
|
15
|
+
LexicalNode,
|
|
15
16
|
} from 'lexical';
|
|
16
17
|
|
|
17
18
|
/*
|
|
@@ -20,7 +21,7 @@ import type {
|
|
|
20
21
|
|
|
21
22
|
declare export function $insertDataTransferForRichText(
|
|
22
23
|
dataTransfer: DataTransfer,
|
|
23
|
-
selection: RangeSelection | GridSelection
|
|
24
|
+
selection: RangeSelection | GridSelection,
|
|
24
25
|
editor: LexicalEditor,
|
|
25
26
|
): void;
|
|
26
27
|
|
|
@@ -32,7 +33,31 @@ declare export function $getLexicalContent(
|
|
|
32
33
|
* Plain Text
|
|
33
34
|
*/
|
|
34
35
|
|
|
36
|
+
/*
|
|
37
|
+
* Export as JSON
|
|
38
|
+
*/
|
|
39
|
+
|
|
35
40
|
declare export function $insertDataTransferForPlainText(
|
|
36
41
|
dataTransfer: DataTransfer,
|
|
37
42
|
selection: RangeSelection,
|
|
38
43
|
): void;
|
|
44
|
+
|
|
45
|
+
interface BaseSerializedNode {
|
|
46
|
+
children?: Array<BaseSerializedNode>;
|
|
47
|
+
type: string;
|
|
48
|
+
version: number;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
declare export function $generateJSONFromSelectedNodes<
|
|
52
|
+
SerializedNode: BaseSerializedNode,
|
|
53
|
+
>(
|
|
54
|
+
editor: LexicalEditor,
|
|
55
|
+
selection: RangeSelection | NodeSelection | GridSelection | null,
|
|
56
|
+
): {
|
|
57
|
+
namespace: string,
|
|
58
|
+
nodes: Array<SerializedNode>,
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
declare export function $generateNodesFromSerializedNodes(
|
|
62
|
+
serializedNodes: Array<BaseSerializedNode>,
|
|
63
|
+
): Array<LexicalNode>;
|
package/LexicalClipboard.prod.js
CHANGED
|
@@ -4,13 +4,15 @@
|
|
|
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
|
|
8
|
-
function B(c,
|
|
9
|
-
function F(c
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
exports.$
|
|
16
|
-
exports.$
|
|
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(b){throw Error(`Minified Lexical error #${b}; see codes.json for the full message or `+"use the non-minified dev environment for full errors and additional helpful warnings.");}
|
|
8
|
+
function B(b,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,b):F(c,e)}
|
|
9
|
+
function F(b,c){let e=[],g=null,f=null;for(let h=0;h<b.length;h++){let a=b[h];p.$isListItemNode(a)?(null==f&&(f=p.$createListNode("bullet"),e.push(f)),f.append(a)):(null!=f&&(f=null),z.$isDecoratorNode(a)&&!a.isTopLevel()||z.$isElementNode(a)&&a.isInline()||z.$isTextNode(a)||z.$isLineBreakNode(a)?(null===g&&(g=z.$createParagraphNode(),e.push(g)),null!==g&&g.append(a)):(e.push(a),g=null))}z.$isRangeSelection(c)?c.insertNodes(e):z.$isGridSelection(c)&&(b=c.anchor.getNode(),z.$isGridCellNode(b)||A(41),
|
|
10
|
+
b.append(...e))}
|
|
11
|
+
function E(b,c,e,g){1===b.length&&z.$isGridNode(b[0])||A(42);var f=b[0];b=f.getChildren();e=f.getFirstChildOrThrow().getChildrenSize();var h=f.getChildrenSize(),a=y.$findMatchingParent(c.anchor.getNode(),m=>z.$isGridCellNode(m));c=(f=a&&y.$findMatchingParent(a,m=>z.$isGridRowNode(m)))&&y.$findMatchingParent(f,m=>z.$isGridNode(m));z.$isGridCellNode(a)&&z.$isGridRowNode(f)&&z.$isGridNode(c)||A(43);var k=f.getIndexWithinParent(),n=Math.min(c.getChildrenSize()-1,k+h-1);h=a.getIndexWithinParent();a=Math.min(f.getChildrenSize()-
|
|
12
|
+
1,h+e-1);e=Math.min(h,a);f=Math.min(k,n);h=Math.max(h,a);k=Math.max(k,n);n=c.getChildren();a=0;let l,q;for(let m=f;m<=k;m++){var w=n[m];z.$isGridRowNode(w)||A(24);var x=b[a];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++}a++}l&&q&&(b=z.$createGridSelection(),b.set(c.getKey(),l,q),z.$setSelection(b),g.dispatchCommand(z.SELECTION_CHANGE_COMMAND,void 0))}
|
|
14
|
+
function G(b,c,e,g=[]){let f=null!=c?e.isSelected():!0,h=z.$isElementNode(e)&&e.excludeFromCopy("html");var a=r.$cloneWithProperties(e);a=z.$isTextNode(a)&&null!=c?r.$sliceSelectedTextNodeContent(c,a):a;let k=z.$isElementNode(a)?a.getChildren():[];var n=a;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(a)&&(l.text=a.__text);for(a=0;a<k.length;a++)n=k[a],q=G(b,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(b=0;b<l.children.length;b++)g.push(l.children[b]);return f}exports.$getHtmlContent=function(b){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(b,c)};
|
|
16
|
+
exports.$getLexicalContent=function(b){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 a=0;a<h.length;a++)G(b,c,h[a],f);return g.call(e,{namespace:b._config.namespace,nodes:f})};exports.$insertDataTransferForPlainText=function(b,c){b=b.getData("text/plain");null!=b&&c.insertRawText(b)};
|
|
17
|
+
exports.$insertDataTransferForRichText=function(b,c,e){var g=b.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=b.getData("text/html"))try{var a=(new DOMParser).parseFromString(h,"text/html");return B(e,d.$generateNodesFromDOM(e,a),c)}catch{}b=b.getData("text/plain");
|
|
18
|
+
if(null!=b)if(z.$isRangeSelection(c))for(b=b.split(/\r?\n/),e=b.length,a=0;a<e;a++)c.insertText(b[a]),a<e-1&&c.insertParagraph();else c.insertRawText(b)}
|
package/clipboard.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
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;
|
|
11
|
+
export declare function $insertDataTransferForPlainText(dataTransfer: DataTransfer, selection: RangeSelection | GridSelection): void;
|
|
12
|
+
export declare function $insertDataTransferForRichText(dataTransfer: DataTransfer, selection: RangeSelection | GridSelection, editor: LexicalEditor): void;
|
|
13
|
+
interface BaseSerializedNode {
|
|
14
|
+
children?: Array<BaseSerializedNode>;
|
|
15
|
+
type: string;
|
|
16
|
+
version: number;
|
|
17
|
+
}
|
|
18
|
+
export declare function $generateJSONFromSelectedNodes<SerializedNode extends BaseSerializedNode>(editor: LexicalEditor, selection: RangeSelection | NodeSelection | GridSelection | null): {
|
|
19
|
+
namespace: string;
|
|
20
|
+
nodes: Array<SerializedNode>;
|
|
21
|
+
};
|
|
22
|
+
export declare function $generateNodesFromSerializedNodes(serializedNodes: Array<BaseSerializedNode>): Array<LexicalNode>;
|
|
23
|
+
export {};
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
*/
|
|
8
|
+
import { $getHtmlContent, $getLexicalContent, $insertDataTransferForPlainText, $insertDataTransferForRichText } from './clipboard';
|
|
9
|
+
export { $getHtmlContent, $getLexicalContent, $insertDataTransferForPlainText, $insertDataTransferForRichText, };
|
package/package.json
CHANGED
|
@@ -9,15 +9,15 @@
|
|
|
9
9
|
"paste"
|
|
10
10
|
],
|
|
11
11
|
"license": "MIT",
|
|
12
|
-
"version": "0.3.
|
|
12
|
+
"version": "0.3.6",
|
|
13
13
|
"main": "LexicalClipboard.js",
|
|
14
14
|
"peerDependencies": {
|
|
15
|
-
"lexical": "0.3.
|
|
15
|
+
"lexical": "0.3.6"
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@lexical/utils": "0.3.
|
|
19
|
-
"@lexical/selection": "0.3.
|
|
20
|
-
"@lexical/html": "0.3.
|
|
18
|
+
"@lexical/utils": "0.3.6",
|
|
19
|
+
"@lexical/selection": "0.3.6",
|
|
20
|
+
"@lexical/html": "0.3.6"
|
|
21
21
|
},
|
|
22
22
|
"repository": {
|
|
23
23
|
"type": "git",
|
package/LexicalClipboard.d.ts
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
-
*
|
|
4
|
-
* This source code is licensed under the MIT license found in the
|
|
5
|
-
* LICENSE file in the root directory of this source tree.
|
|
6
|
-
*
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import type {
|
|
10
|
-
GridSelection,
|
|
11
|
-
LexicalEditor,
|
|
12
|
-
NodeSelection,
|
|
13
|
-
RangeSelection,
|
|
14
|
-
} from 'lexical';
|
|
15
|
-
|
|
16
|
-
/*
|
|
17
|
-
* Rich Text
|
|
18
|
-
*/
|
|
19
|
-
|
|
20
|
-
export function $insertDataTransferForRichText(
|
|
21
|
-
dataTransfer: DataTransfer,
|
|
22
|
-
selection: RangeSelection | GridSelection | NodeSelection,
|
|
23
|
-
editor: LexicalEditor,
|
|
24
|
-
): void;
|
|
25
|
-
|
|
26
|
-
export function $getHtmlContent(editor: LexicalEditor): string | null;
|
|
27
|
-
export function $getLexicalContent(editor: LexicalEditor): string | null;
|
|
28
|
-
/*
|
|
29
|
-
* Plain Text
|
|
30
|
-
*/
|
|
31
|
-
|
|
32
|
-
export function $insertDataTransferForPlainText(
|
|
33
|
-
dataTransfer: DataTransfer,
|
|
34
|
-
selection: RangeSelection,
|
|
35
|
-
): void;
|