@lexical/clipboard
Advanced tools
Comparing version 0.5.0 to 0.5.1-next.0
@@ -8,5 +8,5 @@ /** | ||
*/ | ||
import type { GridSelection, LexicalEditor, LexicalNode, NodeSelection, RangeSelection } from 'lexical'; | ||
export declare function $getHtmlContent(editor: LexicalEditor): string | null; | ||
export declare function $getLexicalContent(editor: LexicalEditor): string | null; | ||
import { GridSelection, LexicalEditor, LexicalNode, NodeSelection, RangeSelection } from 'lexical'; | ||
export declare function $getHtmlContent(editor: LexicalEditor): string; | ||
export declare function $getLexicalContent(editor: LexicalEditor): null | string; | ||
export declare function $insertDataTransferForPlainText(dataTransfer: DataTransfer, selection: RangeSelection | GridSelection): void; | ||
@@ -25,1 +25,2 @@ export declare function $insertDataTransferForRichText(dataTransfer: DataTransfer, selection: RangeSelection | GridSelection, editor: LexicalEditor): void; | ||
export declare function $generateNodesFromSerializedNodes(serializedNodes: Array<BaseSerializedNode>): Array<LexicalNode>; | ||
export declare function copyToClipboard__EXPERIMENTAL(editor: LexicalEditor, event: null | ClipboardEvent): Promise<boolean>; |
@@ -9,3 +9,2 @@ /** @module @lexical/clipboard */ | ||
*/ | ||
import { $generateJSONFromSelectedNodes, $generateNodesFromSerializedNodes, $getHtmlContent, $getLexicalContent, $insertDataTransferForPlainText, $insertDataTransferForRichText, $insertGeneratedNodes } from './clipboard'; | ||
export { $generateJSONFromSelectedNodes, $generateNodesFromSerializedNodes, $getHtmlContent, $getLexicalContent, $insertDataTransferForPlainText, $insertDataTransferForRichText, $insertGeneratedNodes, }; | ||
export { $generateJSONFromSelectedNodes, $generateNodesFromSerializedNodes, $getHtmlContent, $getLexicalContent, $insertDataTransferForPlainText, $insertDataTransferForRichText, $insertGeneratedNodes, copyToClipboard__EXPERIMENTAL, } from './clipboard'; |
@@ -31,7 +31,9 @@ /** | ||
if (lexical.$isRangeSelection(selection) && selection.isCollapsed() || selection.getNodes().length === 0) { | ||
return null; | ||
return ''; | ||
} | ||
return html.$generateHtmlFromNodes(editor, selection); | ||
} | ||
} // TODO 0.6.0 Return a blank string instead | ||
// TODO 0.6.0 Rename to $getJSON | ||
function $getLexicalContent(editor) { | ||
@@ -144,6 +146,13 @@ const selection = lexical.$getSelection(); | ||
if (lexical.$isDecoratorNode(node) && node.isInline() || lexical.$isElementNode(node) && node.isInline() || lexical.$isTextNode(node) || lexical.$isLineBreakNode(node)) { | ||
const isLineBreakNode = lexical.$isLineBreakNode(node); | ||
if (isLineBreakNode || lexical.$isDecoratorNode(node) && node.isInline() || lexical.$isElementNode(node) && node.isInline() || lexical.$isTextNode(node)) { | ||
if (currentBlock === null) { | ||
currentBlock = lexical.$createParagraphNode(); | ||
topLevelBlocks.push(currentBlock); | ||
topLevelBlocks.push(currentBlock); // In the case of LineBreakNode, we just need to | ||
// add an empty ParagraphNode to the topLevelBlocks. | ||
if (isLineBreakNode) { | ||
continue; | ||
} | ||
} | ||
@@ -345,4 +354,5 @@ | ||
return shouldInclude; | ||
} | ||
} // TODO why $ function with Editor instance? | ||
function $generateJSONFromSelectedNodes(editor, selection) { | ||
@@ -379,3 +389,94 @@ const nodes = []; | ||
} | ||
const EVENT_LATENCY = 50; | ||
let clipboardEventTimeout = null; // TODO custom selection | ||
// TODO potentially have a node customizable version for plain text | ||
async function copyToClipboard__EXPERIMENTAL(editor, event) { | ||
if (clipboardEventTimeout !== null) { | ||
// Prevent weird race conditions that can happen when this function is run multiple times | ||
// synchronously. In the future, we can do better, we can cancel/override the previously running job. | ||
return false; | ||
} | ||
if (event !== null) { | ||
return new Promise((resolve, reject) => { | ||
editor.update(() => { | ||
resolve($copyToClipboardEvent(editor, event)); | ||
}); | ||
}); | ||
} | ||
const rootElement = editor.getRootElement(); | ||
const domSelection = document.getSelection(); | ||
if (rootElement === null || domSelection === null) { | ||
return false; | ||
} | ||
const element = document.createElement('span'); | ||
element.style.cssText = 'position: fixed; top: -1000px;'; | ||
element.append(document.createTextNode('#')); | ||
rootElement.append(element); | ||
const range = new Range(); | ||
range.setStart(element, 0); | ||
range.setEnd(element, 1); | ||
domSelection.removeAllRanges(); | ||
domSelection.addRange(range); | ||
return new Promise((resolve, reject) => { | ||
const removeListener = editor.registerCommand(lexical.COPY_COMMAND, secondEvent => { | ||
if (secondEvent instanceof ClipboardEvent) { | ||
removeListener(); | ||
if (clipboardEventTimeout !== null) { | ||
window.clearTimeout(clipboardEventTimeout); | ||
clipboardEventTimeout = null; | ||
} | ||
resolve($copyToClipboardEvent(editor, secondEvent)); | ||
} // Block the entire copy flow while we wait for the next ClipboardEvent | ||
return true; | ||
}, lexical.COMMAND_PRIORITY_CRITICAL); // If the above hack execCommand hack works, this timeout code should never fire. Otherwise, | ||
// the listener will be quickly freed so that the user can reuse it again | ||
clipboardEventTimeout = window.setTimeout(() => { | ||
removeListener(); | ||
clipboardEventTimeout = null; | ||
resolve(false); | ||
}, EVENT_LATENCY); | ||
document.execCommand('copy'); | ||
element.remove(); | ||
}); | ||
} // TODO shouldn't pass editor (pass namespace directly) | ||
function $copyToClipboardEvent(editor, event) { | ||
event.preventDefault(); | ||
const clipboardData = event.clipboardData; | ||
if (clipboardData === null) { | ||
return false; | ||
} | ||
const selection = lexical.$getSelection(); | ||
const htmlString = $getHtmlContent(editor); | ||
const lexicalString = $getLexicalContent(editor); | ||
let plainString = ''; | ||
if (selection !== null) { | ||
plainString = selection.getTextContent(); | ||
} | ||
if (htmlString !== null) { | ||
clipboardData.setData('text/html', htmlString); | ||
} | ||
if (lexicalString !== null) { | ||
clipboardData.setData('application/x-lexical-editor', lexicalString); | ||
} | ||
clipboardData.setData('text/plain', plainString); | ||
return true; | ||
} | ||
exports.$generateJSONFromSelectedNodes = $generateJSONFromSelectedNodes; | ||
@@ -388,1 +489,2 @@ exports.$generateNodesFromSerializedNodes = $generateNodesFromSerializedNodes; | ||
exports.$insertGeneratedNodes = $insertGeneratedNodes; | ||
exports.copyToClipboard__EXPERIMENTAL = copyToClipboard__EXPERIMENTAL; |
@@ -7,14 +7,17 @@ /** | ||
*/ | ||
'use strict';var c=require("@lexical/html"),n=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.");} | ||
function B(a,b,d){(z.DEPRECATED_$isGridSelection(d)||null!==y.$findMatchingParent(d.anchor.getNode(),g=>z.DEPRECATED_$isGridCellNode(g))&&null!==y.$findMatchingParent(d.focus.getNode(),g=>z.DEPRECATED_$isGridCellNode(g)))&&1===b.length&&z.DEPRECATED_$isGridNode(b[0])?E(b,d,!1,a):F(b,d)} | ||
function F(a,b){let d=[],g=null,e=null;for(let h=0;h<a.length;h++){let f=a[h];n.$isListItemNode(f)?(null==e&&(e=n.$createListNode("bullet"),d.push(e)),e.append(f)):(null!=e&&(e=null),z.$isDecoratorNode(f)&&f.isInline()||z.$isElementNode(f)&&f.isInline()||z.$isTextNode(f)||z.$isLineBreakNode(f)?(null===g&&(g=z.$createParagraphNode(),d.push(g)),null!==g&&g.append(f)):(d.push(f),g=null))}z.$isRangeSelection(b)?b.insertNodes(d):z.DEPRECATED_$isGridSelection(b)&&(a=b.anchor.getNode(),z.DEPRECATED_$isGridCellNode(a)|| | ||
A(41),a.append(...d))} | ||
function E(a,b,d,g){1===a.length&&z.DEPRECATED_$isGridNode(a[0])||A(42);var e=a[0];a=e.getChildren();d=e.getFirstChildOrThrow().getChildrenSize();var h=e.getChildrenSize(),f=y.$findMatchingParent(b.anchor.getNode(),l=>z.DEPRECATED_$isGridCellNode(l));b=(e=f&&y.$findMatchingParent(f,l=>z.DEPRECATED_$isGridRowNode(l)))&&y.$findMatchingParent(e,l=>z.DEPRECATED_$isGridNode(l));z.DEPRECATED_$isGridCellNode(f)&&z.DEPRECATED_$isGridRowNode(e)&&z.DEPRECATED_$isGridNode(b)||A(43);var k=e.getIndexWithinParent(), | ||
p=Math.min(b.getChildrenSize()-1,k+h-1);h=f.getIndexWithinParent();f=Math.min(e.getChildrenSize()-1,h+d-1);d=Math.min(h,f);e=Math.min(k,p);h=Math.max(h,f);k=Math.max(k,p);p=b.getChildren();f=0;let m,q;for(let l=e;l<=k;l++){var w=p[l];z.DEPRECATED_$isGridRowNode(w)||A(24);var x=a[f];z.DEPRECATED_$isGridRowNode(x)||A(24);w=w.getChildren();x=x.getChildren();let C=0;for(let t=d;t<=h;t++){let u=w[t];z.DEPRECATED_$isGridCellNode(u)||A(25);let D=x[C];z.DEPRECATED_$isGridCellNode(D)||A(25);l===e&&t===d?m= | ||
u.getKey():l===k&&t===h&&(q=u.getKey());let J=u.getChildren();D.getChildren().forEach(v=>{z.$isTextNode(v)&&z.$createParagraphNode().append(v);u.append(v)});J.forEach(v=>v.remove());C++}f++}m&&q&&(a=z.DEPRECATED_$createGridSelection(),a.set(b.getKey(),m,q),z.$setSelection(a),g.dispatchCommand(z.SELECTION_CHANGE_COMMAND,void 0))} | ||
function G(a,b,d,g=[]){let e=null!=b?d.isSelected():!0,h=z.$isElementNode(d)&&d.excludeFromCopy("html");var f=d;if(null!==b){var k=r.$cloneWithProperties(d);f=k=z.$isTextNode(k)&&null!=b?r.$sliceSelectedTextNodeContent(b,k):k}let p=z.$isElementNode(f)?f.getChildren():[];var m=f;k=m.exportJSON();k.type!==m.constructor.getType()&&A(58);var q=k.children;z.$isElementNode(m)&&(Array.isArray(q)||A(59));z.$isTextNode(f)&&(k.text=f.__text);for(f=0;f<p.length;f++)m=p[f],q=G(a,b,m,k.children),!e&&z.$isElementNode(d)&& | ||
q&&d.extractWithChild(m,b,"clone")&&(e=!0);if(e&&!h)g.push(k);else if(Array.isArray(k.children))for(a=0;a<k.children.length;a++)g.push(k.children[a]);return e}function H(a,b){let d=[],g=z.$getRoot().getChildren();for(let e=0;e<g.length;e++)G(a,b,g[e],d);return{namespace:a._config.namespace,nodes:d}}function I(a){let b=[];for(let d=0;d<a.length;d++){let g=z.$parseSerializedNode(a[d]);z.$isTextNode(g)&&r.$addNodeStyle(g);b.push(g)}return b}exports.$generateJSONFromSelectedNodes=H; | ||
exports.$generateNodesFromSerializedNodes=I;exports.$getHtmlContent=function(a){let b=z.$getSelection();if(null==b)throw Error("Expected valid LexicalSelection");return z.$isRangeSelection(b)&&b.isCollapsed()||0===b.getNodes().length?null:c.$generateHtmlFromNodes(a,b)};exports.$getLexicalContent=function(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(H(a,b))}; | ||
'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.");} | ||
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))} | ||
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)} | ||
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)&& | ||
(a=b.anchor.getNode(),z.DEPRECATED_$isGridCellNode(a)||A(41),a.append(...c))} | ||
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(), | ||
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= | ||
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))} | ||
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)&& | ||
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; | ||
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; | ||
exports.$insertDataTransferForPlainText=function(a,b){a=a.getData("text/plain");null!=a&&b.insertRawText(a)}; | ||
exports.$insertDataTransferForRichText=function(a,b,d){var g=a.getData("application/x-lexical-editor");if(g)try{let h=JSON.parse(g);if(h.namespace===d._config.namespace&&Array.isArray(h.nodes)){let f=I(h.nodes);return B(d,f,b)}}catch{}if(g=a.getData("text/html"))try{var e=(new DOMParser).parseFromString(g,"text/html");let h=c.$generateNodesFromDOM(d,e);return B(d,h,b)}catch{}a=a.getData("text/plain");if(null!=a)if(z.$isRangeSelection(b))for(a=a.split(/\r?\n/),d=a.length,e=0;e<d;e++)b.insertText(a[e]), | ||
e<d-1&&b.insertParagraph();else b.insertRawText(a)};exports.$insertGeneratedNodes=B | ||
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]), | ||
e<c-1&&b.insertParagraph();else b.insertRawText(a)};exports.$insertGeneratedNodes=E; | ||
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, | ||
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()})} |
@@ -12,12 +12,12 @@ { | ||
"license": "MIT", | ||
"version": "0.5.0", | ||
"version": "0.5.1-next.0", | ||
"main": "LexicalClipboard.js", | ||
"peerDependencies": { | ||
"lexical": "0.5.0" | ||
"lexical": "0.5.1-next.0" | ||
}, | ||
"dependencies": { | ||
"@lexical/utils": "0.5.0", | ||
"@lexical/list": "0.5.0", | ||
"@lexical/selection": "0.5.0", | ||
"@lexical/html": "0.5.0" | ||
"@lexical/utils": "0.5.1-next.0", | ||
"@lexical/list": "0.5.1-next.0", | ||
"@lexical/selection": "0.5.1-next.0", | ||
"@lexical/html": "0.5.1-next.0" | ||
}, | ||
@@ -24,0 +24,0 @@ "repository": { |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
28218
469
171
104
45
+ Added@lexical/html@0.5.1-next.0(transitive)
+ Added@lexical/list@0.5.1-next.0(transitive)
+ Added@lexical/selection@0.5.1-next.0(transitive)
+ Added@lexical/table@0.5.1-next.0(transitive)
+ Added@lexical/utils@0.5.1-next.0(transitive)
+ Addedlexical@0.5.1-next.0(transitive)
- Removed@lexical/html@0.5.0(transitive)
- Removed@lexical/list@0.5.0(transitive)
- Removed@lexical/selection@0.5.0(transitive)
- Removed@lexical/table@0.5.0(transitive)
- Removed@lexical/utils@0.5.0(transitive)
- Removedlexical@0.5.0(transitive)
Updated@lexical/html@0.5.1-next.0
Updated@lexical/list@0.5.1-next.0
Updated@lexical/utils@0.5.1-next.0