mirror of
https://github.com/standardnotes/app.git
synced 2026-01-16 23:01:30 +00:00
chore: upgrade lexical (#2889)
This commit is contained in:
parent
5c23a11b5a
commit
1456950a63
73 changed files with 700 additions and 1288 deletions
Binary file not shown.
BIN
.yarn/cache/@lexical-clipboard-npm-0.22.0-e950aa6a7f-c6869ec54c.zip
vendored
Normal file
BIN
.yarn/cache/@lexical-clipboard-npm-0.22.0-e950aa6a7f-c6869ec54c.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@lexical-clipboard-patch-f38883999e-8972b49800.zip
vendored
Normal file
BIN
.yarn/cache/@lexical-clipboard-patch-f38883999e-8972b49800.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@lexical-code-npm-0.22.0-421f0c2d2a-6e7ff958d5.zip
vendored
Normal file
BIN
.yarn/cache/@lexical-code-npm-0.22.0-421f0c2d2a-6e7ff958d5.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@lexical-devtools-core-npm-0.22.0-7aa26b96d3-e8c75cd1fb.zip
vendored
Normal file
BIN
.yarn/cache/@lexical-devtools-core-npm-0.22.0-7aa26b96d3-e8c75cd1fb.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@lexical-hashtag-npm-0.22.0-f14a9bf13e-368cf96b08.zip
vendored
Normal file
BIN
.yarn/cache/@lexical-hashtag-npm-0.22.0-f14a9bf13e-368cf96b08.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@lexical-history-npm-0.22.0-7851715090-8eb683a5bb.zip
vendored
Normal file
BIN
.yarn/cache/@lexical-history-npm-0.22.0-7851715090-8eb683a5bb.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@lexical-html-npm-0.22.0-a51c36910b-14e32af4fb.zip
vendored
Normal file
BIN
.yarn/cache/@lexical-html-npm-0.22.0-a51c36910b-14e32af4fb.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@lexical-link-npm-0.22.0-744858e6de-f36c3d3a7e.zip
vendored
Normal file
BIN
.yarn/cache/@lexical-link-npm-0.22.0-744858e6de-f36c3d3a7e.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@lexical-list-npm-0.22.0-979bed97d8-7ee86ccc56.zip
vendored
Normal file
BIN
.yarn/cache/@lexical-list-npm-0.22.0-979bed97d8-7ee86ccc56.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@lexical-mark-npm-0.22.0-724843edb5-c3cf36c47b.zip
vendored
Normal file
BIN
.yarn/cache/@lexical-mark-npm-0.22.0-724843edb5-c3cf36c47b.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@lexical-markdown-npm-0.22.0-b4c001dc78-0e2c371ead.zip
vendored
Normal file
BIN
.yarn/cache/@lexical-markdown-npm-0.22.0-b4c001dc78-0e2c371ead.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@lexical-overflow-npm-0.22.0-bd40be9d93-9b48668292.zip
vendored
Normal file
BIN
.yarn/cache/@lexical-overflow-npm-0.22.0-bd40be9d93-9b48668292.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@lexical-plain-text-npm-0.22.0-d159d3e9a7-1093ebfc11.zip
vendored
Normal file
BIN
.yarn/cache/@lexical-plain-text-npm-0.22.0-d159d3e9a7-1093ebfc11.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@lexical-react-npm-0.22.0-d8774fb2db-6d4f56be0b.zip
vendored
Normal file
BIN
.yarn/cache/@lexical-react-npm-0.22.0-d8774fb2db-6d4f56be0b.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@lexical-rich-text-npm-0.22.0-1c32cc4b16-f7c7153b16.zip
vendored
Normal file
BIN
.yarn/cache/@lexical-rich-text-npm-0.22.0-1c32cc4b16-f7c7153b16.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@lexical-rich-text-patch-bfbc9fddb3-c6523beac5.zip
vendored
Normal file
BIN
.yarn/cache/@lexical-rich-text-patch-bfbc9fddb3-c6523beac5.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@lexical-selection-npm-0.22.0-4a213f5e36-5c3f80944e.zip
vendored
Normal file
BIN
.yarn/cache/@lexical-selection-npm-0.22.0-4a213f5e36-5c3f80944e.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@lexical-table-npm-0.22.0-0aa6b73b6f-6a8e3564ef.zip
vendored
Normal file
BIN
.yarn/cache/@lexical-table-npm-0.22.0-0aa6b73b6f-6a8e3564ef.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@lexical-utils-npm-0.22.0-8b465096d0-45e1e60f89.zip
vendored
Normal file
BIN
.yarn/cache/@lexical-utils-npm-0.22.0-8b465096d0-45e1e60f89.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@lexical-yjs-npm-0.22.0-21fa141871-3ffe2fa446.zip
vendored
Normal file
BIN
.yarn/cache/@lexical-yjs-npm-0.22.0-21fa141871-3ffe2fa446.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/lexical-npm-0.22.0-3ef92eee29-54153b6d31.zip
vendored
Normal file
BIN
.yarn/cache/lexical-npm-0.22.0-3ef92eee29-54153b6d31.zip
vendored
Normal file
Binary file not shown.
|
|
@ -1,151 +0,0 @@
|
|||
diff --git a/LexicalClipboard.dev.js b/LexicalClipboard.dev.js
|
||||
index 3fad3811aa254c5b1b02e039c0d1f21c2a28562f..78aa3bc5048bb4354339efc558031ec0185163dd 100644
|
||||
--- a/LexicalClipboard.dev.js
|
||||
+++ b/LexicalClipboard.dev.js
|
||||
@@ -30,7 +30,6 @@ const CAN_USE_DOM = typeof window !== 'undefined' && typeof window.document !==
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
*/
|
||||
-
|
||||
const getDOMSelection = targetWindow => CAN_USE_DOM ? (targetWindow || window).getSelection() : null;
|
||||
|
||||
/**
|
||||
@@ -105,7 +104,7 @@ function $insertDataTransferForPlainText(dataTransfer, selection) {
|
||||
* @param selection the selection to use as the insertion point for the content in the DataTransfer object
|
||||
* @param editor the LexicalEditor the content is being inserted into.
|
||||
*/
|
||||
-function $insertDataTransferForRichText(dataTransfer, selection, editor) {
|
||||
+function $insertDataTransferForRichText(dataTransfer, selection, editor, event) {
|
||||
const lexicalString = dataTransfer.getData('application/x-lexical-editor');
|
||||
if (lexicalString) {
|
||||
try {
|
||||
@@ -118,15 +117,18 @@ function $insertDataTransferForRichText(dataTransfer, selection, editor) {
|
||||
// Fail silently.
|
||||
}
|
||||
}
|
||||
- const htmlString = dataTransfer.getData('text/html');
|
||||
- if (htmlString) {
|
||||
- try {
|
||||
- const parser = new DOMParser();
|
||||
- const dom = parser.parseFromString(htmlString, 'text/html');
|
||||
- const nodes = html.$generateNodesFromDOM(editor, dom);
|
||||
- return $insertGeneratedNodes(editor, nodes, selection);
|
||||
- } catch (_unused2) {
|
||||
- // Fail silently.
|
||||
+ const shouldIgnoreHTML = event && event.inputType === 'insertReplacementText' && dataTransfer.types.includes('text/plain');
|
||||
+ if (!shouldIgnoreHTML) {
|
||||
+ const htmlString = dataTransfer.getData('text/html');
|
||||
+ if (htmlString) {
|
||||
+ try {
|
||||
+ const parser = new DOMParser();
|
||||
+ const dom = parser.parseFromString(htmlString, 'text/html');
|
||||
+ const nodes = html.$generateNodesFromDOM(editor, dom);
|
||||
+ return $insertGeneratedNodes(editor, nodes, selection);
|
||||
+ } catch (_unused2) {
|
||||
+ // Fail silently.
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/LexicalClipboard.dev.mjs b/LexicalClipboard.dev.mjs
|
||||
index 9d1054125804bec18b6d2fc3b09386defa7c8be2..ef944d097da9cc4383c38c874a6d1e7c20ab22d0 100644
|
||||
--- a/LexicalClipboard.dev.mjs
|
||||
+++ b/LexicalClipboard.dev.mjs
|
||||
@@ -28,7 +28,6 @@ const CAN_USE_DOM = typeof window !== 'undefined' && typeof window.document !==
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
*/
|
||||
-
|
||||
const getDOMSelection = targetWindow => CAN_USE_DOM ? (targetWindow || window).getSelection() : null;
|
||||
|
||||
/**
|
||||
@@ -103,7 +102,7 @@ function $insertDataTransferForPlainText(dataTransfer, selection) {
|
||||
* @param selection the selection to use as the insertion point for the content in the DataTransfer object
|
||||
* @param editor the LexicalEditor the content is being inserted into.
|
||||
*/
|
||||
-function $insertDataTransferForRichText(dataTransfer, selection, editor) {
|
||||
+function $insertDataTransferForRichText(dataTransfer, selection, editor, event) {
|
||||
const lexicalString = dataTransfer.getData('application/x-lexical-editor');
|
||||
if (lexicalString) {
|
||||
try {
|
||||
@@ -116,15 +115,18 @@ function $insertDataTransferForRichText(dataTransfer, selection, editor) {
|
||||
// Fail silently.
|
||||
}
|
||||
}
|
||||
- const htmlString = dataTransfer.getData('text/html');
|
||||
- if (htmlString) {
|
||||
- try {
|
||||
- const parser = new DOMParser();
|
||||
- const dom = parser.parseFromString(htmlString, 'text/html');
|
||||
- const nodes = $generateNodesFromDOM(editor, dom);
|
||||
- return $insertGeneratedNodes(editor, nodes, selection);
|
||||
- } catch (_unused2) {
|
||||
- // Fail silently.
|
||||
+ const shouldIgnoreHTML = event && event.inputType === 'insertReplacementText' && dataTransfer.types.includes('text/plain');
|
||||
+ if (!shouldIgnoreHTML) {
|
||||
+ const htmlString = dataTransfer.getData('text/html');
|
||||
+ if (htmlString) {
|
||||
+ try {
|
||||
+ const parser = new DOMParser();
|
||||
+ const dom = parser.parseFromString(htmlString, 'text/html');
|
||||
+ const nodes = $generateNodesFromDOM(editor, dom);
|
||||
+ return $insertGeneratedNodes(editor, nodes, selection);
|
||||
+ } catch (_unused2) {
|
||||
+ // Fail silently.
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/LexicalClipboard.prod.js b/LexicalClipboard.prod.js
|
||||
index 38848b4d69dcae7d54a5ab99b8f3cdd9324e413f..7ddc6b87dd2c9c32973f4dc7ae552c8fdb80eeb0 100644
|
||||
--- a/LexicalClipboard.prod.js
|
||||
+++ b/LexicalClipboard.prod.js
|
||||
@@ -6,14 +6,14 @@
|
||||
*
|
||||
*/
|
||||
|
||||
-'use strict';var f=require("@lexical/html"),m=require("@lexical/selection"),n=require("@lexical/utils"),p=require("lexical"),t;function u(a){let b=new URLSearchParams;b.append("code",a);for(let c=1;c<arguments.length;c++)b.append("v",arguments[c]);throw Error(`Minified Lexical error #${a}; visit https://lexical.dev/docs/error?${b} for the full message or `+"use the non-minified dev environment for full errors and additional helpful warnings.");}
|
||||
-t=u&&u.__esModule&&Object.prototype.hasOwnProperty.call(u,"default")?u["default"]:u;let v="undefined"!==typeof window&&"undefined"!==typeof window.document&&"undefined"!==typeof window.document.createElement;function w(a){let b=p.$getSelection();null==b&&t(166);return p.$isRangeSelection(b)&&b.isCollapsed()||0===b.getNodes().length?"":f.$generateHtmlFromNodes(a,b)}
|
||||
-function x(a){let b=p.$getSelection();null==b&&t(166);return p.$isRangeSelection(b)&&b.isCollapsed()||0===b.getNodes().length?null:JSON.stringify(y(a,b))}function z(a,b,c){a.dispatchCommand(p.SELECTION_INSERT_CLIPBOARD_NODES_COMMAND,{nodes:b,selection:c})||c.insertNodes(b)}
|
||||
-function A(a,b,c,d=[]){let e=null!==b?c.isSelected(b):!0,h=p.$isElementNode(c)&&c.excludeFromCopy("html");var g=c;if(null!==b){var k=m.$cloneWithProperties(c);g=k=p.$isTextNode(k)&&null!==b?m.$sliceSelectedTextNodeContent(b,k):k}let q=p.$isElementNode(g)?g.getChildren():[];var l=g;k=l.exportJSON();var r=l.constructor;k.type!==r.getType()&&t(58,r.name);p.$isElementNode(l)&&(Array.isArray(k.children)||t(59,r.name));p.$isTextNode(g)&&(g=g.__text,0<g.length?k.text=g:e=!1);for(g=0;g<q.length;g++)l=q[g],
|
||||
-r=A(a,b,l,k.children),!e&&p.$isElementNode(c)&&r&&c.extractWithChild(l,b,"clone")&&(e=!0);if(e&&!h)d.push(k);else if(Array.isArray(k.children))for(a=0;a<k.children.length;a++)d.push(k.children[a]);return e}function y(a,b){let c=[],d=p.$getRoot().getChildren();for(let e=0;e<d.length;e++)A(a,b,d[e],c);return{namespace:a._config.namespace,nodes:c}}function B(a){let b=[];for(let c=0;c<a.length;c++){let d=p.$parseSerializedNode(a[c]);p.$isTextNode(d)&&m.$addNodeStyle(d);b.push(d)}return b}let C=null;
|
||||
-function D(a,b){var c=v?(a._window||window).getSelection():null;if(!c)return!1;var d=c.anchorNode;c=c.focusNode;if(null!==d&&null!==c&&!p.isSelectionWithinEditor(a,d,c))return!1;b.preventDefault();b=b.clipboardData;d=p.$getSelection();if(null===b||null===d)return!1;c=w(a);a=x(a);let e="";null!==d&&(e=d.getTextContent());null!==c&&b.setData("text/html",c);null!==a&&b.setData("application/x-lexical-editor",a);b.setData("text/plain",e);return!0}exports.$generateJSONFromSelectedNodes=y;
|
||||
-exports.$generateNodesFromSerializedNodes=B;exports.$getHtmlContent=w;exports.$getLexicalContent=x;exports.$insertDataTransferForPlainText=function(a,b){a=a.getData("text/plain")||a.getData("text/uri-list");null!=a&&b.insertRawText(a)};
|
||||
-exports.$insertDataTransferForRichText=function(a,b,c){var d=a.getData("application/x-lexical-editor");if(d)try{let h=JSON.parse(d);if(h.namespace===c._config.namespace&&Array.isArray(h.nodes)){let g=B(h.nodes);return z(c,g,b)}}catch(h){}if(d=a.getData("text/html"))try{var e=(new DOMParser).parseFromString(d,"text/html");let h=f.$generateNodesFromDOM(c,e);return z(c,h,b)}catch(h){}a=a.getData("text/plain")||a.getData("text/uri-list");if(null!=a)if(p.$isRangeSelection(b))for(b=a.split(/(\r?\n|\t)/),
|
||||
-""===b[b.length-1]&&b.pop(),a=0;a<b.length;a++)c=p.$getSelection(),p.$isRangeSelection(c)&&(e=b[a],"\n"===e||"\r\n"===e?c.insertParagraph():"\t"===e?c.insertNodes([p.$createTabNode()]):c.insertText(e));else b.insertRawText(a)};exports.$insertGeneratedNodes=z;
|
||||
-exports.copyToClipboard=async function(a,b){if(null!==C)return!1;if(null!==b)return new Promise(g=>{a.update(()=>{g(D(a,b))})});var c=a.getRootElement();let d=null==a._window?window.document:a._window.document,e=v?(a._window||window).getSelection():null;if(null===c||null===e)return!1;let h=d.createElement("span");h.style.cssText="position: fixed; top: -1000px;";h.append(d.createTextNode("#"));c.append(h);c=new Range;c.setStart(h,0);c.setEnd(h,1);e.removeAllRanges();e.addRange(c);return new Promise(g=>
|
||||
-{let k=a.registerCommand(p.COPY_COMMAND,q=>{n.objectKlassEquals(q,ClipboardEvent)&&(k(),null!==C&&(window.clearTimeout(C),C=null),g(D(a,q)));return!0},p.COMMAND_PRIORITY_CRITICAL);C=window.setTimeout(()=>{k();C=null;g(!1)},50);d.execCommand("copy");h.remove()})}
|
||||
+'use strict';var f=require("@lexical/html"),m=require("@lexical/selection"),q=require("@lexical/utils"),r=require("lexical");function t(a){let b=new URLSearchParams;b.append("code",a);for(let c=1;c<arguments.length;c++)b.append("v",arguments[c]);throw Error(`Minified Lexical error #${a}; visit https://lexical.dev/docs/error?${b} for the full message or `+"use the non-minified dev environment for full errors and additional helpful warnings.");}
|
||||
+let u="undefined"!==typeof window&&"undefined"!==typeof window.document&&"undefined"!==typeof window.document.createElement;function v(a){let b=r.$getSelection();null==b&&t(166);return r.$isRangeSelection(b)&&b.isCollapsed()||0===b.getNodes().length?"":f.$generateHtmlFromNodes(a,b)}function w(a){let b=r.$getSelection();null==b&&t(166);return r.$isRangeSelection(b)&&b.isCollapsed()||0===b.getNodes().length?null:JSON.stringify(x(a,b))}
|
||||
+function y(a,b,c){a.dispatchCommand(r.SELECTION_INSERT_CLIPBOARD_NODES_COMMAND,{nodes:b,selection:c})||c.insertNodes(b)}
|
||||
+function z(a,b,c,e=[]){let g=null!==b?c.isSelected(b):!0,k=r.$isElementNode(c)&&c.excludeFromCopy("html");var d=c;if(null!==b){var h=m.$cloneWithProperties(c);d=h=r.$isTextNode(h)&&null!==b?m.$sliceSelectedTextNodeContent(b,h):h}let n=r.$isElementNode(d)?d.getChildren():[];var l=d;h=l.exportJSON();var p=l.constructor;h.type!==p.getType()&&t(58,p.name);r.$isElementNode(l)&&(Array.isArray(h.children)||t(59,p.name));r.$isTextNode(d)&&(d=d.__text,0<d.length?h.text=d:g=!1);for(d=0;d<n.length;d++)l=n[d],
|
||||
+p=z(a,b,l,h.children),!g&&r.$isElementNode(c)&&p&&c.extractWithChild(l,b,"clone")&&(g=!0);if(g&&!k)e.push(h);else if(Array.isArray(h.children))for(a=0;a<h.children.length;a++)e.push(h.children[a]);return g}function x(a,b){let c=[],e=r.$getRoot().getChildren();for(let g=0;g<e.length;g++)z(a,b,e[g],c);return{namespace:a._config.namespace,nodes:c}}function A(a){let b=[];for(let c=0;c<a.length;c++){let e=r.$parseSerializedNode(a[c]);r.$isTextNode(e)&&m.$addNodeStyle(e);b.push(e)}return b}let B=null;
|
||||
+function C(a,b){var c=u?(a._window||window).getSelection():null;if(!c)return!1;var e=c.anchorNode;c=c.focusNode;if(null!==e&&null!==c&&!r.isSelectionWithinEditor(a,e,c))return!1;b.preventDefault();b=b.clipboardData;e=r.$getSelection();if(null===b||null===e)return!1;c=v(a);a=w(a);let g="";null!==e&&(g=e.getTextContent());null!==c&&b.setData("text/html",c);null!==a&&b.setData("application/x-lexical-editor",a);b.setData("text/plain",g);return!0}exports.$generateJSONFromSelectedNodes=x;
|
||||
+exports.$generateNodesFromSerializedNodes=A;exports.$getHtmlContent=v;exports.$getLexicalContent=w;exports.$insertDataTransferForPlainText=function(a,b){a=a.getData("text/plain")||a.getData("text/uri-list");null!=a&&b.insertRawText(a)};
|
||||
+exports.$insertDataTransferForRichText=function(a,b,c,e){let g=a.getData("application/x-lexical-editor");if(g)try{let d=JSON.parse(g);if(d.namespace===c._config.namespace&&Array.isArray(d.nodes)){let h=A(d.nodes);return y(c,h,b)}}catch(d){}if(!e||"insertReplacementText"!==e.inputType||!a.types.includes("text/plain"))if(e=a.getData("text/html"))try{var k=(new DOMParser).parseFromString(e,"text/html");let d=f.$generateNodesFromDOM(c,k);return y(c,d,b)}catch(d){}a=a.getData("text/plain")||a.getData("text/uri-list");
|
||||
+if(null!=a)if(r.$isRangeSelection(b))for(b=a.split(/(\r?\n|\t)/),""===b[b.length-1]&&b.pop(),a=0;a<b.length;a++)c=r.$getSelection(),r.$isRangeSelection(c)&&(k=b[a],"\n"===k||"\r\n"===k?c.insertParagraph():"\t"===k?c.insertNodes([r.$createTabNode()]):c.insertText(k));else b.insertRawText(a)};exports.$insertGeneratedNodes=y;
|
||||
+exports.copyToClipboard=async function(a,b){if(null!==B)return!1;if(null!==b)return new Promise(d=>{a.update(()=>{d(C(a,b))})});var c=a.getRootElement();let e=null==a._window?window.document:a._window.document,g=u?(a._window||window).getSelection():null;if(null===c||null===g)return!1;let k=e.createElement("span");k.style.cssText="position: fixed; top: -1000px;";k.append(e.createTextNode("#"));c.append(k);c=new Range;c.setStart(k,0);c.setEnd(k,1);g.removeAllRanges();g.addRange(c);return new Promise(d=>
|
||||
+{let h=a.registerCommand(r.COPY_COMMAND,n=>{q.objectKlassEquals(n,ClipboardEvent)&&(h(),null!==B&&(window.clearTimeout(B),B=null),d(C(a,n)));return!0},r.COMMAND_PRIORITY_CRITICAL);B=window.setTimeout(()=>{h();B=null;d(!1)},50);e.execCommand("copy");k.remove()})}
|
||||
diff --git a/LexicalClipboard.prod.mjs b/LexicalClipboard.prod.mjs
|
||||
index 6b572db295155b182e3077f64b308cbbf993e241..32076e8a14b02d37e0a8302e51920f13dc211180 100644
|
||||
--- a/LexicalClipboard.prod.mjs
|
||||
+++ b/LexicalClipboard.prod.mjs
|
||||
@@ -6,4 +6,4 @@
|
||||
*
|
||||
*/
|
||||
|
||||
-import{$generateHtmlFromNodes as t,$generateNodesFromDOM as e}from"@lexical/html";import{$addNodeStyle as n,$cloneWithProperties as o,$sliceSelectedTextNodeContent as l}from"@lexical/selection";import{objectKlassEquals as r}from"@lexical/utils";import{$getSelection as i,$isRangeSelection as s,$createTabNode as a,SELECTION_INSERT_CLIPBOARD_NODES_COMMAND as c,$getRoot as u,$parseSerializedNode as d,$isTextNode as f,COPY_COMMAND as p,COMMAND_PRIORITY_CRITICAL as m,isSelectionWithinEditor as h,$isElementNode as g}from"lexical";function x(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var w=x((function(t){const e=new URLSearchParams;e.append("code",t);for(let t=1;t<arguments.length;t++)e.append("v",arguments[t]);throw Error(`Minified Lexical error #${t}; visit https://lexical.dev/docs/error?${e} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`)}));const y="undefined"!=typeof window&&void 0!==window.document&&void 0!==window.document.createElement,v=t=>y?(t||window).getSelection():null;function D(e){const n=i();return null==n&&w(166),s(n)&&n.isCollapsed()||0===n.getNodes().length?"":t(e,n)}function C(t){const e=i();return null==e&&w(166),s(e)&&e.isCollapsed()||0===e.getNodes().length?null:JSON.stringify(A(t,e))}function N(t,e){const n=t.getData("text/plain")||t.getData("text/uri-list");null!=n&&e.insertRawText(n)}function _(t,n,o){const l=t.getData("application/x-lexical-editor");if(l)try{const t=JSON.parse(l);if(t.namespace===o._config.namespace&&Array.isArray(t.nodes)){return T(o,R(t.nodes),n)}}catch(t){}const r=t.getData("text/html");if(r)try{const t=(new DOMParser).parseFromString(r,"text/html");return T(o,e(o,t),n)}catch(t){}const c=t.getData("text/plain")||t.getData("text/uri-list");if(null!=c)if(s(n)){const t=c.split(/(\r?\n|\t)/);""===t[t.length-1]&&t.pop();for(let e=0;e<t.length;e++){const n=i();if(s(n)){const o=t[e];"\n"===o||"\r\n"===o?n.insertParagraph():"\t"===o?n.insertNodes([a()]):n.insertText(o)}}}else n.insertRawText(c)}function T(t,e,n){t.dispatchCommand(c,{nodes:e,selection:n})||n.insertNodes(e)}function S(t,e,n,r=[]){let i=null===e||n.isSelected(e);const s=g(n)&&n.excludeFromCopy("html");let a=n;if(null!==e){let t=o(n);t=f(t)&&null!==e?l(e,t):t,a=t}const c=g(a)?a.getChildren():[],u=function(t){const e=t.exportJSON(),n=t.constructor;if(e.type!==n.getType()&&w(58,n.name),g(t)){const t=e.children;Array.isArray(t)||w(59,n.name)}return e}(a);if(f(a)){const t=a.__text;t.length>0?u.text=t:i=!1}for(let o=0;o<c.length;o++){const l=c[o],r=S(t,e,l,u.children);!i&&g(n)&&r&&n.extractWithChild(l,e,"clone")&&(i=!0)}if(i&&!s)r.push(u);else if(Array.isArray(u.children))for(let t=0;t<u.children.length;t++){const e=u.children[t];r.push(e)}return i}function A(t,e){const n=[],o=u().getChildren();for(let l=0;l<o.length;l++){S(t,e,o[l],n)}return{namespace:t._config.namespace,nodes:n}}function R(t){const e=[];for(let o=0;o<t.length;o++){const l=t[o],r=d(l);f(r)&&n(r),e.push(r)}return e}let E=null;async function O(t,e){if(null!==E)return!1;if(null!==e)return new Promise(((n,o)=>{t.update((()=>{n(P(t,e))}))}));const n=t.getRootElement(),o=null==t._window?window.document:t._window.document,l=v(t._window);if(null===n||null===l)return!1;const i=o.createElement("span");i.style.cssText="position: fixed; top: -1000px;",i.append(o.createTextNode("#")),n.append(i);const s=new Range;return s.setStart(i,0),s.setEnd(i,1),l.removeAllRanges(),l.addRange(s),new Promise(((e,n)=>{const l=t.registerCommand(p,(n=>(r(n,ClipboardEvent)&&(l(),null!==E&&(window.clearTimeout(E),E=null),e(P(t,n))),!0)),m);E=window.setTimeout((()=>{l(),E=null,e(!1)}),50),o.execCommand("copy"),i.remove()}))}function P(t,e){const n=v(t._window);if(!n)return!1;const o=n.anchorNode,l=n.focusNode;if(null!==o&&null!==l&&!h(t,o,l))return!1;e.preventDefault();const r=e.clipboardData,s=i();if(null===r||null===s)return!1;const a=D(t),c=C(t);let u="";return null!==s&&(u=s.getTextContent()),null!==a&&r.setData("text/html",a),null!==c&&r.setData("application/x-lexical-editor",c),r.setData("text/plain",u),!0}export{A as $generateJSONFromSelectedNodes,R as $generateNodesFromSerializedNodes,D as $getHtmlContent,C as $getLexicalContent,N as $insertDataTransferForPlainText,_ as $insertDataTransferForRichText,T as $insertGeneratedNodes,O as copyToClipboard};
|
||||
+import{$generateHtmlFromNodes as e,$generateNodesFromDOM as t}from"@lexical/html";import{$addNodeStyle as n,$cloneWithProperties as l,$sliceSelectedTextNodeContent as o}from"@lexical/selection";import{objectKlassEquals as r}from"@lexical/utils";import{$getSelection as i,$isRangeSelection as s,$createTabNode as a,SELECTION_INSERT_CLIPBOARD_NODES_COMMAND as c,$getRoot as u,$parseSerializedNode as d,$isTextNode as p,COPY_COMMAND as f,COMMAND_PRIORITY_CRITICAL as m,isSelectionWithinEditor as h,$isElementNode as g}from"lexical";var x=function(e){const t=new URLSearchParams;t.append("code",e);for(let e=1;e<arguments.length;e++)t.append("v",arguments[e]);throw Error(`Minified Lexical error #${e}; visit https://lexical.dev/docs/error?${t} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`)};const w="undefined"!=typeof window&&void 0!==window.document&&void 0!==window.document.createElement,y=e=>w?(e||window).getSelection():null;function v(t){const n=i();return null==n&&x(166),s(n)&&n.isCollapsed()||0===n.getNodes().length?"":e(t,n)}function D(e){const t=i();return null==t&&x(166),s(t)&&t.isCollapsed()||0===t.getNodes().length?null:JSON.stringify(S(e,t))}function C(e,t){const n=e.getData("text/plain")||e.getData("text/uri-list");null!=n&&t.insertRawText(n)}function T(e,n,l,o){const r=e.getData("application/x-lexical-editor");if(r)try{const e=JSON.parse(r);if(e.namespace===l._config.namespace&&Array.isArray(e.nodes)){return N(l,_(e.nodes),n)}}catch(e){}if(!(o&&"insertReplacementText"===o.inputType&&e.types.includes("text/plain"))){const o=e.getData("text/html");if(o)try{const e=(new DOMParser).parseFromString(o,"text/html");return N(l,t(l,e),n)}catch(e){}}const c=e.getData("text/plain")||e.getData("text/uri-list");if(null!=c)if(s(n)){const e=c.split(/(\r?\n|\t)/);""===e[e.length-1]&&e.pop();for(let t=0;t<e.length;t++){const n=i();if(s(n)){const l=e[t];"\n"===l||"\r\n"===l?n.insertParagraph():"\t"===l?n.insertNodes([a()]):n.insertText(l)}}}else n.insertRawText(c)}function N(e,t,n){e.dispatchCommand(c,{nodes:t,selection:n})||n.insertNodes(t)}function R(e,t,n,r=[]){let i=null===t||n.isSelected(t);const s=g(n)&&n.excludeFromCopy("html");let a=n;if(null!==t){let e=l(n);e=p(e)&&null!==t?o(t,e):e,a=e}const c=g(a)?a.getChildren():[],u=function(e){const t=e.exportJSON(),n=e.constructor;if(t.type!==n.getType()&&x(58,n.name),g(e)){const e=t.children;Array.isArray(e)||x(59,n.name)}return t}(a);if(p(a)){const e=a.__text;e.length>0?u.text=e:i=!1}for(let l=0;l<c.length;l++){const o=c[l],r=R(e,t,o,u.children);!i&&g(n)&&r&&n.extractWithChild(o,t,"clone")&&(i=!0)}if(i&&!s)r.push(u);else if(Array.isArray(u.children))for(let e=0;e<u.children.length;e++){const t=u.children[e];r.push(t)}return i}function S(e,t){const n=[],l=u().getChildren();for(let o=0;o<l.length;o++){R(e,t,l[o],n)}return{namespace:e._config.namespace,nodes:n}}function _(e){const t=[];for(let l=0;l<e.length;l++){const o=e[l],r=d(o);p(r)&&n(r),t.push(r)}return t}let A=null;async function E(e,t){if(null!==A)return!1;if(null!==t)return new Promise(((n,l)=>{e.update((()=>{n(P(e,t))}))}));const n=e.getRootElement(),l=null==e._window?window.document:e._window.document,o=y(e._window);if(null===n||null===o)return!1;const i=l.createElement("span");i.style.cssText="position: fixed; top: -1000px;",i.append(l.createTextNode("#")),n.append(i);const s=new Range;return s.setStart(i,0),s.setEnd(i,1),o.removeAllRanges(),o.addRange(s),new Promise(((t,n)=>{const o=e.registerCommand(f,(n=>(r(n,ClipboardEvent)&&(o(),null!==A&&(window.clearTimeout(A),A=null),t(P(e,n))),!0)),m);A=window.setTimeout((()=>{o(),A=null,t(!1)}),50),l.execCommand("copy"),i.remove()}))}function P(e,t){const n=y(e._window);if(!n)return!1;const l=n.anchorNode,o=n.focusNode;if(null!==l&&null!==o&&!h(e,l,o))return!1;t.preventDefault();const r=t.clipboardData,s=i();if(null===r||null===s)return!1;const a=v(e),c=D(e);let u="";return null!==s&&(u=s.getTextContent()),null!==a&&r.setData("text/html",a),null!==c&&r.setData("application/x-lexical-editor",c),r.setData("text/plain",u),!0}export{S as $generateJSONFromSelectedNodes,_ as $generateNodesFromSerializedNodes,v as $getHtmlContent,D as $getLexicalContent,C as $insertDataTransferForPlainText,T as $insertDataTransferForRichText,N as $insertGeneratedNodes,E as copyToClipboard};
|
||||
diff --git a/clipboard.d.ts b/clipboard.d.ts
|
||||
index 99e2138389b64d298a1330d7b354ba87d2e6f24e..83250a4c2049f94e08bfdfc757e03e8a85a08dd4 100644
|
||||
--- a/clipboard.d.ts
|
||||
+++ b/clipboard.d.ts
|
||||
@@ -44,7 +44,7 @@ export declare function $insertDataTransferForPlainText(dataTransfer: DataTransf
|
||||
* @param selection the selection to use as the insertion point for the content in the DataTransfer object
|
||||
* @param editor the LexicalEditor the content is being inserted into.
|
||||
*/
|
||||
-export declare function $insertDataTransferForRichText(dataTransfer: DataTransfer, selection: BaseSelection, editor: LexicalEditor): void;
|
||||
+export declare function $insertDataTransferForRichText(dataTransfer: DataTransfer, selection: BaseSelection, editor: LexicalEditor, event?: InputEvent): void;
|
||||
/**
|
||||
* Inserts Lexical nodes into the editor using different strategies depending on
|
||||
* some simple selection-based heuristics. If you're looking for a generic way to
|
||||
134
.yarn/patches/@lexical-clipboard-npm-0.22.0-e950aa6a7f.patch
Normal file
134
.yarn/patches/@lexical-clipboard-npm-0.22.0-e950aa6a7f.patch
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
diff --git a/LexicalClipboard.dev.js b/LexicalClipboard.dev.js
|
||||
index 1bc958d606217588101f79ed3706669bb6b398ec..5c4e967e31d660504d41466b62e87449d4925ed2 100644
|
||||
--- a/LexicalClipboard.dev.js
|
||||
+++ b/LexicalClipboard.dev.js
|
||||
@@ -93,7 +93,7 @@ function $insertDataTransferForPlainText(dataTransfer, selection) {
|
||||
* @param selection the selection to use as the insertion point for the content in the DataTransfer object
|
||||
* @param editor the LexicalEditor the content is being inserted into.
|
||||
*/
|
||||
-function $insertDataTransferForRichText(dataTransfer, selection, editor) {
|
||||
+function $insertDataTransferForRichText(dataTransfer, selection, editor, event) {
|
||||
const lexicalString = dataTransfer.getData('application/x-lexical-editor');
|
||||
if (lexicalString) {
|
||||
try {
|
||||
@@ -106,15 +106,18 @@ function $insertDataTransferForRichText(dataTransfer, selection, editor) {
|
||||
// Fail silently.
|
||||
}
|
||||
}
|
||||
- const htmlString = dataTransfer.getData('text/html');
|
||||
- if (htmlString) {
|
||||
- try {
|
||||
- const parser = new DOMParser();
|
||||
- const dom = parser.parseFromString(trustHTML(htmlString), 'text/html');
|
||||
- const nodes = html.$generateNodesFromDOM(editor, dom);
|
||||
- return $insertGeneratedNodes(editor, nodes, selection);
|
||||
- } catch (_unused2) {
|
||||
- // Fail silently.
|
||||
+ const shouldIgnoreHTML = event && event.inputType === 'insertReplacementText' && dataTransfer.types.includes('text/plain');
|
||||
+ if (!shouldIgnoreHTML) {
|
||||
+ const htmlString = dataTransfer.getData('text/html');
|
||||
+ if (htmlString) {
|
||||
+ try {
|
||||
+ const parser = new DOMParser();
|
||||
+ const dom = parser.parseFromString(trustHTML(htmlString), 'text/html');
|
||||
+ const nodes = html.$generateNodesFromDOM(editor, dom);
|
||||
+ return $insertGeneratedNodes(editor, nodes, selection);
|
||||
+ } catch (_unused2) {
|
||||
+ // Fail silently.
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/LexicalClipboard.dev.mjs b/LexicalClipboard.dev.mjs
|
||||
index fd0c1b790dae92b742d569d62752d2c0b5705236..d00179beebd5d9f396fc3f7ab84745eea8959633 100644
|
||||
--- a/LexicalClipboard.dev.mjs
|
||||
+++ b/LexicalClipboard.dev.mjs
|
||||
@@ -91,7 +91,7 @@ function $insertDataTransferForPlainText(dataTransfer, selection) {
|
||||
* @param selection the selection to use as the insertion point for the content in the DataTransfer object
|
||||
* @param editor the LexicalEditor the content is being inserted into.
|
||||
*/
|
||||
-function $insertDataTransferForRichText(dataTransfer, selection, editor) {
|
||||
+function $insertDataTransferForRichText(dataTransfer, selection, editor, event) {
|
||||
const lexicalString = dataTransfer.getData('application/x-lexical-editor');
|
||||
if (lexicalString) {
|
||||
try {
|
||||
@@ -104,15 +104,18 @@ function $insertDataTransferForRichText(dataTransfer, selection, editor) {
|
||||
// Fail silently.
|
||||
}
|
||||
}
|
||||
- const htmlString = dataTransfer.getData('text/html');
|
||||
- if (htmlString) {
|
||||
- try {
|
||||
- const parser = new DOMParser();
|
||||
- const dom = parser.parseFromString(trustHTML(htmlString), 'text/html');
|
||||
- const nodes = $generateNodesFromDOM(editor, dom);
|
||||
- return $insertGeneratedNodes(editor, nodes, selection);
|
||||
- } catch (_unused2) {
|
||||
- // Fail silently.
|
||||
+ const shouldIgnoreHTML = event && event.inputType === 'insertReplacementText' && dataTransfer.types.includes('text/plain');
|
||||
+ if (!shouldIgnoreHTML) {
|
||||
+ const htmlString = dataTransfer.getData('text/html');
|
||||
+ if (htmlString) {
|
||||
+ try {
|
||||
+ const parser = new DOMParser();
|
||||
+ const dom = parser.parseFromString(trustHTML(htmlString), 'text/html');
|
||||
+ const nodes = $generateNodesFromDOM(editor, dom);
|
||||
+ return $insertGeneratedNodes(editor, nodes, selection);
|
||||
+ } catch (_unused2) {
|
||||
+ // Fail silently.
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/LexicalClipboard.prod.js b/LexicalClipboard.prod.js
|
||||
index da19707c8c6cfebbfbf4eab94eb4427e81015e01..afe044183dfe347f4da04277e1dd484ad11052fe 100644
|
||||
--- a/LexicalClipboard.prod.js
|
||||
+++ b/LexicalClipboard.prod.js
|
||||
@@ -6,15 +6,15 @@
|
||||
*
|
||||
*/
|
||||
|
||||
-'use strict';var e=require("@lexical/html"),m=require("@lexical/selection"),n=require("@lexical/utils"),p=require("lexical"),t;function u(a){let b=new URLSearchParams;b.append("code",a);for(let c=1;c<arguments.length;c++)b.append("v",arguments[c]);throw Error(`Minified Lexical error #${a}; visit https://lexical.dev/docs/error?${b} for the full message or `+"use the non-minified dev environment for full errors and additional helpful warnings.");}
|
||||
-t=u&&u.__esModule&&Object.prototype.hasOwnProperty.call(u,"default")?u["default"]:u;function v(a,b=p.$getSelection()){null==b&&t(166);return p.$isRangeSelection(b)&&b.isCollapsed()||0===b.getNodes().length?"":e.$generateHtmlFromNodes(a,b)}function w(a,b=p.$getSelection()){null==b&&t(166);return p.$isRangeSelection(b)&&b.isCollapsed()||0===b.getNodes().length?null:JSON.stringify(x(a,b))}
|
||||
+'use strict';var f=require("@lexical/html"),m=require("@lexical/selection"),n=require("@lexical/utils"),p=require("lexical"),t;function u(a){let b=new URLSearchParams;b.append("code",a);for(let c=1;c<arguments.length;c++)b.append("v",arguments[c]);throw Error(`Minified Lexical error #${a}; visit https://lexical.dev/docs/error?${b} for the full message or `+"use the non-minified dev environment for full errors and additional helpful warnings.");}
|
||||
+t=u&&u.__esModule&&Object.prototype.hasOwnProperty.call(u,"default")?u["default"]:u;function v(a,b=p.$getSelection()){null==b&&t(166);return p.$isRangeSelection(b)&&b.isCollapsed()||0===b.getNodes().length?"":f.$generateHtmlFromNodes(a,b)}function w(a,b=p.$getSelection()){null==b&&t(166);return p.$isRangeSelection(b)&&b.isCollapsed()||0===b.getNodes().length?null:JSON.stringify(x(a,b))}
|
||||
function y(a){return window.trustedTypes&&window.trustedTypes.createPolicy?window.trustedTypes.createPolicy("lexical",{createHTML:b=>b}).createHTML(a):a}function z(a,b,c){a.dispatchCommand(p.SELECTION_INSERT_CLIPBOARD_NODES_COMMAND,{nodes:b,selection:c})||c.insertNodes(b)}
|
||||
-function A(a,b,c,d=[]){let f=null!==b?c.isSelected(b):!0,k=p.$isElementNode(c)&&c.excludeFromCopy("html");var g=c;if(null!==b){var h=p.$cloneWithProperties(c);g=h=p.$isTextNode(h)&&null!==b?m.$sliceSelectedTextNodeContent(b,h):h}let q=p.$isElementNode(g)?g.getChildren():[];var l=g;h=l.exportJSON();var r=l.constructor;h.type!==r.getType()&&t(58,r.name);p.$isElementNode(l)&&(Array.isArray(h.children)||t(59,r.name));p.$isTextNode(g)&&(g=g.__text,0<g.length?h.text=g:f=!1);for(g=0;g<q.length;g++)l=q[g],
|
||||
-r=A(a,b,l,h.children),!f&&p.$isElementNode(c)&&r&&c.extractWithChild(l,b,"clone")&&(f=!0);if(f&&!k)d.push(h);else if(Array.isArray(h.children))for(a=0;a<h.children.length;a++)d.push(h.children[a]);return f}function x(a,b){let c=[],d=p.$getRoot().getChildren();for(let f=0;f<d.length;f++)A(a,b,d[f],c);return{namespace:a._config.namespace,nodes:c}}function B(a){let b=[];for(let c=0;c<a.length;c++){let d=p.$parseSerializedNode(a[c]);p.$isTextNode(d)&&m.$addNodeStyle(d);b.push(d)}return b}let C=null;
|
||||
+function A(a,b,c,d=[]){let h=null!==b?c.isSelected(b):!0,k=p.$isElementNode(c)&&c.excludeFromCopy("html");var e=c;if(null!==b){var g=p.$cloneWithProperties(c);e=g=p.$isTextNode(g)&&null!==b?m.$sliceSelectedTextNodeContent(b,g):g}let q=p.$isElementNode(e)?e.getChildren():[];var l=e;g=l.exportJSON();var r=l.constructor;g.type!==r.getType()&&t(58,r.name);p.$isElementNode(l)&&(Array.isArray(g.children)||t(59,r.name));p.$isTextNode(e)&&(e=e.__text,0<e.length?g.text=e:h=!1);for(e=0;e<q.length;e++)l=q[e],
|
||||
+r=A(a,b,l,g.children),!h&&p.$isElementNode(c)&&r&&c.extractWithChild(l,b,"clone")&&(h=!0);if(h&&!k)d.push(g);else if(Array.isArray(g.children))for(a=0;a<g.children.length;a++)d.push(g.children[a]);return h}function x(a,b){let c=[],d=p.$getRoot().getChildren();for(let h=0;h<d.length;h++)A(a,b,d[h],c);return{namespace:a._config.namespace,nodes:c}}function B(a){let b=[];for(let c=0;c<a.length;c++){let d=p.$parseSerializedNode(a[c]);p.$isTextNode(d)&&m.$addNodeStyle(d);b.push(d)}return b}let C=null;
|
||||
function D(a,b,c){if(void 0===c){var d=p.getDOMSelection(a._window);if(!d)return!1;c=d.anchorNode;d=d.focusNode;if(null!==c&&null!==d&&!p.isSelectionWithinEditor(a,c,d))return!1;a=p.$getSelection();if(null===a)return!1;c=E(a)}b.preventDefault();b=b.clipboardData;if(null===b)return!1;F(b,c);return!0}let G=[["text/html",v],["application/x-lexical-editor",w]];
|
||||
-function E(a=p.$getSelection()){let b={"text/plain":a?a.getTextContent():""};if(a){let c=p.$getEditor();for(let [d,f]of G){let k=f(c,a);null!==k&&(b[d]=k)}}return b}function F(a,b){for(let c in b){let d=b[c];void 0!==d&&a.setData(c,d)}}exports.$generateJSONFromSelectedNodes=x;exports.$generateNodesFromSerializedNodes=B;exports.$getClipboardDataFromSelection=E;exports.$getHtmlContent=v;exports.$getLexicalContent=w;
|
||||
+function E(a=p.$getSelection()){let b={"text/plain":a?a.getTextContent():""};if(a){let c=p.$getEditor();for(let [d,h]of G){let k=h(c,a);null!==k&&(b[d]=k)}}return b}function F(a,b){for(let c in b){let d=b[c];void 0!==d&&a.setData(c,d)}}exports.$generateJSONFromSelectedNodes=x;exports.$generateNodesFromSerializedNodes=B;exports.$getClipboardDataFromSelection=E;exports.$getHtmlContent=v;exports.$getLexicalContent=w;
|
||||
exports.$insertDataTransferForPlainText=function(a,b){a=a.getData("text/plain")||a.getData("text/uri-list");null!=a&&b.insertRawText(a)};
|
||||
-exports.$insertDataTransferForRichText=function(a,b,c){var d=a.getData("application/x-lexical-editor");if(d)try{let k=JSON.parse(d);if(k.namespace===c._config.namespace&&Array.isArray(k.nodes)){let g=B(k.nodes);return z(c,g,b)}}catch(k){}if(d=a.getData("text/html"))try{var f=(new DOMParser).parseFromString(y(d),"text/html");let k=e.$generateNodesFromDOM(c,f);return z(c,k,b)}catch(k){}a=a.getData("text/plain")||a.getData("text/uri-list");if(null!=a)if(p.$isRangeSelection(b))for(b=a.split(/(\r?\n|\t)/),
|
||||
-""===b[b.length-1]&&b.pop(),a=0;a<b.length;a++)c=p.$getSelection(),p.$isRangeSelection(c)&&(f=b[a],"\n"===f||"\r\n"===f?c.insertParagraph():"\t"===f?c.insertNodes([p.$createTabNode()]):c.insertText(f));else b.insertRawText(a)};exports.$insertGeneratedNodes=z;
|
||||
-exports.copyToClipboard=async function(a,b,c){if(null!==C)return!1;if(null!==b)return new Promise(h=>{a.update(()=>{h(D(a,b,c))})});var d=a.getRootElement();let f=null==a._window?window.document:a._window.document,k=p.getDOMSelection(a._window);if(null===d||null===k)return!1;let g=f.createElement("span");g.style.cssText="position: fixed; top: -1000px;";g.append(f.createTextNode("#"));d.append(g);d=new Range;d.setStart(g,0);d.setEnd(g,1);k.removeAllRanges();k.addRange(d);return new Promise(h=>{let q=
|
||||
-a.registerCommand(p.COPY_COMMAND,l=>{n.objectKlassEquals(l,ClipboardEvent)&&(q(),null!==C&&(window.clearTimeout(C),C=null),h(D(a,l,c)));return!0},p.COMMAND_PRIORITY_CRITICAL);C=window.setTimeout(()=>{q();C=null;h(!1)},50);f.execCommand("copy");g.remove()})};exports.setLexicalClipboardDataTransfer=F
|
||||
+exports.$insertDataTransferForRichText=function(a,b,c,d){let h=a.getData("application/x-lexical-editor");if(h)try{let e=JSON.parse(h);if(e.namespace===c._config.namespace&&Array.isArray(e.nodes)){let g=B(e.nodes);return z(c,g,b)}}catch(e){}if(!d||"insertReplacementText"!==d.inputType||!a.types.includes("text/plain"))if(d=a.getData("text/html"))try{var k=(new DOMParser).parseFromString(y(d),"text/html");let e=f.$generateNodesFromDOM(c,k);return z(c,e,b)}catch(e){}a=a.getData("text/plain")||a.getData("text/uri-list");
|
||||
+if(null!=a)if(p.$isRangeSelection(b))for(b=a.split(/(\r?\n|\t)/),""===b[b.length-1]&&b.pop(),a=0;a<b.length;a++)c=p.$getSelection(),p.$isRangeSelection(c)&&(k=b[a],"\n"===k||"\r\n"===k?c.insertParagraph():"\t"===k?c.insertNodes([p.$createTabNode()]):c.insertText(k));else b.insertRawText(a)};exports.$insertGeneratedNodes=z;
|
||||
+exports.copyToClipboard=async function(a,b,c){if(null!==C)return!1;if(null!==b)return new Promise(g=>{a.update(()=>{g(D(a,b,c))})});var d=a.getRootElement();let h=null==a._window?window.document:a._window.document,k=p.getDOMSelection(a._window);if(null===d||null===k)return!1;let e=h.createElement("span");e.style.cssText="position: fixed; top: -1000px;";e.append(h.createTextNode("#"));d.append(e);d=new Range;d.setStart(e,0);d.setEnd(e,1);k.removeAllRanges();k.addRange(d);return new Promise(g=>{let q=
|
||||
+a.registerCommand(p.COPY_COMMAND,l=>{n.objectKlassEquals(l,ClipboardEvent)&&(q(),null!==C&&(window.clearTimeout(C),C=null),g(D(a,l,c)));return!0},p.COMMAND_PRIORITY_CRITICAL);C=window.setTimeout(()=>{q();C=null;g(!1)},50);h.execCommand("copy");e.remove()})};exports.setLexicalClipboardDataTransfer=F
|
||||
diff --git a/LexicalClipboard.prod.mjs b/LexicalClipboard.prod.mjs
|
||||
index 0a2b0694926fa9838a417295956bc832a02d5499..68090dd340db822053b4e3ceda8f68e4413c8908 100644
|
||||
--- a/LexicalClipboard.prod.mjs
|
||||
+++ b/LexicalClipboard.prod.mjs
|
||||
@@ -6,4 +6,4 @@
|
||||
*
|
||||
*/
|
||||
|
||||
-import{$generateHtmlFromNodes as t,$generateNodesFromDOM as e}from"@lexical/html";import{$addNodeStyle as n,$sliceSelectedTextNodeContent as o}from"@lexical/selection";import{objectKlassEquals as r}from"@lexical/utils";import{$isRangeSelection as l,$getSelection as i,$createTabNode as s,SELECTION_INSERT_CLIPBOARD_NODES_COMMAND as c,$getRoot as a,$parseSerializedNode as u,$isTextNode as d,getDOMSelection as f,COPY_COMMAND as p,COMMAND_PRIORITY_CRITICAL as m,isSelectionWithinEditor as h,$getEditor as g,$isElementNode as x,$cloneWithProperties as w}from"lexical";function y(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var T=y((function(t){const e=new URLSearchParams;e.append("code",t);for(let t=1;t<arguments.length;t++)e.append("v",arguments[t]);throw Error(`Minified Lexical error #${t}; visit https://lexical.dev/docs/error?${e} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`)}));function v(e,n=i()){return null==n&&T(166),l(n)&&n.isCollapsed()||0===n.getNodes().length?"":t(e,n)}function C(t,e=i()){return null==e&&T(166),l(e)&&e.isCollapsed()||0===e.getNodes().length?null:JSON.stringify(A(t,e))}function D(t,e){const n=t.getData("text/plain")||t.getData("text/uri-list");null!=n&&e.insertRawText(n)}function N(t,n,o){const r=t.getData("application/x-lexical-editor");if(r)try{const t=JSON.parse(r);if(t.namespace===o._config.namespace&&Array.isArray(t.nodes)){return _(o,R(t.nodes),n)}}catch(t){}const c=t.getData("text/html");if(c)try{const t=(new DOMParser).parseFromString(function(t){if(window.trustedTypes&&window.trustedTypes.createPolicy){return window.trustedTypes.createPolicy("lexical",{createHTML:t=>t}).createHTML(t)}return t}(c),"text/html");return _(o,e(o,t),n)}catch(t){}const a=t.getData("text/plain")||t.getData("text/uri-list");if(null!=a)if(l(n)){const t=a.split(/(\r?\n|\t)/);""===t[t.length-1]&&t.pop();for(let e=0;e<t.length;e++){const n=i();if(l(n)){const o=t[e];"\n"===o||"\r\n"===o?n.insertParagraph():"\t"===o?n.insertNodes([s()]):n.insertText(o)}}}else n.insertRawText(a)}function _(t,e,n){t.dispatchCommand(c,{nodes:e,selection:n})||n.insertNodes(e)}function P(t,e,n,r=[]){let l=null===e||n.isSelected(e);const i=x(n)&&n.excludeFromCopy("html");let s=n;if(null!==e){let t=w(n);t=d(t)&&null!==e?o(e,t):t,s=t}const c=x(s)?s.getChildren():[],a=function(t){const e=t.exportJSON(),n=t.constructor;if(e.type!==n.getType()&&T(58,n.name),x(t)){const t=e.children;Array.isArray(t)||T(59,n.name)}return e}(s);if(d(s)){const t=s.__text;t.length>0?a.text=t:l=!1}for(let o=0;o<c.length;o++){const r=c[o],i=P(t,e,r,a.children);!l&&x(n)&&i&&n.extractWithChild(r,e,"clone")&&(l=!0)}if(l&&!i)r.push(a);else if(Array.isArray(a.children))for(let t=0;t<a.children.length;t++){const e=a.children[t];r.push(e)}return l}function A(t,e){const n=[],o=a().getChildren();for(let r=0;r<o.length;r++){P(t,e,o[r],n)}return{namespace:t._config.namespace,nodes:n}}function R(t){const e=[];for(let o=0;o<t.length;o++){const r=t[o],l=u(r);d(l)&&n(l),e.push(l)}return e}let S=null;async function O(t,e,n){if(null!==S)return!1;if(null!==e)return new Promise(((o,r)=>{t.update((()=>{o(E(t,e,n))}))}));const o=t.getRootElement(),l=null==t._window?window.document:t._window.document,i=f(t._window);if(null===o||null===i)return!1;const s=l.createElement("span");s.style.cssText="position: fixed; top: -1000px;",s.append(l.createTextNode("#")),o.append(s);const c=new Range;return c.setStart(s,0),c.setEnd(s,1),i.removeAllRanges(),i.addRange(c),new Promise(((e,o)=>{const i=t.registerCommand(p,(o=>(r(o,ClipboardEvent)&&(i(),null!==S&&(window.clearTimeout(S),S=null),e(E(t,o,n))),!0)),m);S=window.setTimeout((()=>{i(),S=null,e(!1)}),50),l.execCommand("copy"),s.remove()}))}function E(t,e,n){if(void 0===n){const e=f(t._window);if(!e)return!1;const o=e.anchorNode,r=e.focusNode;if(null!==o&&null!==r&&!h(t,o,r))return!1;const l=i();if(null===l)return!1;n=L(l)}e.preventDefault();const o=e.clipboardData;return null!==o&&(b(o,n),!0)}const M=[["text/html",v],["application/x-lexical-editor",C]];function L(t=i()){const e={"text/plain":t?t.getTextContent():""};if(t){const n=g();for(const[o,r]of M){const l=r(n,t);null!==l&&(e[o]=l)}}return e}function b(t,e){for(const n in e){const o=e[n];void 0!==o&&t.setData(n,o)}}export{A as $generateJSONFromSelectedNodes,R as $generateNodesFromSerializedNodes,L as $getClipboardDataFromSelection,v as $getHtmlContent,C as $getLexicalContent,D as $insertDataTransferForPlainText,N as $insertDataTransferForRichText,_ as $insertGeneratedNodes,O as copyToClipboard,b as setLexicalClipboardDataTransfer};
|
||||
+import{$generateHtmlFromNodes as t,$generateNodesFromDOM as e}from"@lexical/html";import{$addNodeStyle as n,$sliceSelectedTextNodeContent as o}from"@lexical/selection";import{objectKlassEquals as r}from"@lexical/utils";import{$isRangeSelection as l,$getSelection as i,$createTabNode as s,SELECTION_INSERT_CLIPBOARD_NODES_COMMAND as c,$getRoot as a,$parseSerializedNode as u,$isTextNode as d,getDOMSelection as f,COPY_COMMAND as p,COMMAND_PRIORITY_CRITICAL as m,isSelectionWithinEditor as h,$getEditor as x,$isElementNode as g,$cloneWithProperties as w}from"lexical";function y(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var T=y((function(t){const e=new URLSearchParams;e.append("code",t);for(let t=1;t<arguments.length;t++)e.append("v",arguments[t]);throw Error(`Minified Lexical error #${t}; visit https://lexical.dev/docs/error?${e} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`)}));function v(e,n=i()){return null==n&&T(166),l(n)&&n.isCollapsed()||0===n.getNodes().length?"":t(e,n)}function C(t,e=i()){return null==e&&T(166),l(e)&&e.isCollapsed()||0===e.getNodes().length?null:JSON.stringify(R(t,e))}function D(t,e){const n=t.getData("text/plain")||t.getData("text/uri-list");null!=n&&e.insertRawText(n)}function N(t,n,o,r){const c=t.getData("application/x-lexical-editor");if(c)try{const t=JSON.parse(c);if(t.namespace===o._config.namespace&&Array.isArray(t.nodes)){return _(o,A(t.nodes),n)}}catch(t){}if(!(r&&"insertReplacementText"===r.inputType&&t.types.includes("text/plain"))){const r=t.getData("text/html");if(r)try{const t=(new DOMParser).parseFromString(function(t){if(window.trustedTypes&&window.trustedTypes.createPolicy){return window.trustedTypes.createPolicy("lexical",{createHTML:t=>t}).createHTML(t)}return t}(r),"text/html");return _(o,e(o,t),n)}catch(t){}}const a=t.getData("text/plain")||t.getData("text/uri-list");if(null!=a)if(l(n)){const t=a.split(/(\r?\n|\t)/);""===t[t.length-1]&&t.pop();for(let e=0;e<t.length;e++){const n=i();if(l(n)){const o=t[e];"\n"===o||"\r\n"===o?n.insertParagraph():"\t"===o?n.insertNodes([s()]):n.insertText(o)}}}else n.insertRawText(a)}function _(t,e,n){t.dispatchCommand(c,{nodes:e,selection:n})||n.insertNodes(e)}function P(t,e,n,r=[]){let l=null===e||n.isSelected(e);const i=g(n)&&n.excludeFromCopy("html");let s=n;if(null!==e){let t=w(n);t=d(t)&&null!==e?o(e,t):t,s=t}const c=g(s)?s.getChildren():[],a=function(t){const e=t.exportJSON(),n=t.constructor;if(e.type!==n.getType()&&T(58,n.name),g(t)){const t=e.children;Array.isArray(t)||T(59,n.name)}return e}(s);if(d(s)){const t=s.__text;t.length>0?a.text=t:l=!1}for(let o=0;o<c.length;o++){const r=c[o],i=P(t,e,r,a.children);!l&&g(n)&&i&&n.extractWithChild(r,e,"clone")&&(l=!0)}if(l&&!i)r.push(a);else if(Array.isArray(a.children))for(let t=0;t<a.children.length;t++){const e=a.children[t];r.push(e)}return l}function R(t,e){const n=[],o=a().getChildren();for(let r=0;r<o.length;r++){P(t,e,o[r],n)}return{namespace:t._config.namespace,nodes:n}}function A(t){const e=[];for(let o=0;o<t.length;o++){const r=t[o],l=u(r);d(l)&&n(l),e.push(l)}return e}let S=null;async function O(t,e,n){if(null!==S)return!1;if(null!==e)return new Promise(((o,r)=>{t.update((()=>{o(E(t,e,n))}))}));const o=t.getRootElement(),l=null==t._window?window.document:t._window.document,i=f(t._window);if(null===o||null===i)return!1;const s=l.createElement("span");s.style.cssText="position: fixed; top: -1000px;",s.append(l.createTextNode("#")),o.append(s);const c=new Range;return c.setStart(s,0),c.setEnd(s,1),i.removeAllRanges(),i.addRange(c),new Promise(((e,o)=>{const i=t.registerCommand(p,(o=>(r(o,ClipboardEvent)&&(i(),null!==S&&(window.clearTimeout(S),S=null),e(E(t,o,n))),!0)),m);S=window.setTimeout((()=>{i(),S=null,e(!1)}),50),l.execCommand("copy"),s.remove()}))}function E(t,e,n){if(void 0===n){const e=f(t._window);if(!e)return!1;const o=e.anchorNode,r=e.focusNode;if(null!==o&&null!==r&&!h(t,o,r))return!1;const l=i();if(null===l)return!1;n=L(l)}e.preventDefault();const o=e.clipboardData;return null!==o&&(b(o,n),!0)}const M=[["text/html",v],["application/x-lexical-editor",C]];function L(t=i()){const e={"text/plain":t?t.getTextContent():""};if(t){const n=x();for(const[o,r]of M){const l=r(n,t);null!==l&&(e[o]=l)}}return e}function b(t,e){for(const n in e){const o=e[n];void 0!==o&&t.setData(n,o)}}export{R as $generateJSONFromSelectedNodes,A as $generateNodesFromSerializedNodes,L as $getClipboardDataFromSelection,v as $getHtmlContent,C as $getLexicalContent,D as $insertDataTransferForPlainText,N as $insertDataTransferForRichText,_ as $insertGeneratedNodes,O as copyToClipboard,b as setLexicalClipboardDataTransfer};
|
||||
diff --git a/clipboard.d.ts b/clipboard.d.ts
|
||||
index 33ee79d61150403f45566839251c5c2950fba8e0..b7a27d5f4700814f55bfc988eead2709e8f2a040 100644
|
||||
--- a/clipboard.d.ts
|
||||
+++ b/clipboard.d.ts
|
||||
@@ -51,7 +51,7 @@ export declare function $insertDataTransferForPlainText(dataTransfer: DataTransf
|
||||
* @param selection the selection to use as the insertion point for the content in the DataTransfer object
|
||||
* @param editor the LexicalEditor the content is being inserted into.
|
||||
*/
|
||||
-export declare function $insertDataTransferForRichText(dataTransfer: DataTransfer, selection: BaseSelection, editor: LexicalEditor): void;
|
||||
+export declare function $insertDataTransferForRichText(dataTransfer: DataTransfer, selection: BaseSelection, editor: LexicalEditor, event?: InputEvent): void;
|
||||
/**
|
||||
* Inserts Lexical nodes into the editor using different strategies depending on
|
||||
* some simple selection-based heuristics. If you're looking for a generic way to
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
49
.yarn/patches/@lexical-rich-text-npm-0.22.0-1c32cc4b16.patch
Normal file
49
.yarn/patches/@lexical-rich-text-npm-0.22.0-1c32cc4b16.patch
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -44,9 +44,8 @@
|
|||
"@types/react-native-vector-icons/@types/react": "17.0.2",
|
||||
"@types/react-native/@types/react": "17.0.2",
|
||||
"@types/hoist-non-react-statics/@types/react": "17.0.2",
|
||||
"@lexical/clipboard@0.16.0": "patch:@lexical/clipboard@npm:0.16.0#.yarn/patches/@lexical-clipboard-npm-0.16.0-3053c4af9c.patch",
|
||||
"@lexical/rich-text@0.16.0": "patch:@lexical/rich-text@npm:0.16.0#.yarn/patches/@lexical-rich-text-npm-0.16.0-f484a17832.patch",
|
||||
"@lexical/list@0.16.0": "patch:@lexical/list@npm:0.16.0#.yarn/patches/@lexical-list-npm-0.16.0-8f91da4ad5.patch"
|
||||
"@lexical/clipboard@0.22.0": "patch:@lexical/clipboard@npm:0.22.0#.yarn/patches/@lexical-clipboard-npm-0.22.0-e950aa6a7f.patch",
|
||||
"@lexical/rich-text@0.22.0": "patch:@lexical/rich-text@npm:0.22.0#.yarn/patches/@lexical-rich-text-npm-0.22.0-1c32cc4b16.patch"
|
||||
},
|
||||
"dependencies": {
|
||||
"@standardnotes/snjs": "workspace:*"
|
||||
|
|
|
|||
|
|
@ -1800,10 +1800,10 @@ EXTERNAL SOURCES:
|
|||
|
||||
SPEC CHECKSUMS:
|
||||
boost: 4cb898d0bf20404aab1850c656dcea009429d6c1
|
||||
DoubleConversion: 5189b271737e1565bdce30deb4a08d647e3f5f54
|
||||
DoubleConversion: 76ab83afb40bddeeee456813d9c04f67f78771b5
|
||||
FBLazyVector: 7b438dceb9f904bd85ca3c31d64cce32a035472b
|
||||
fmt: 4c2741a687cc09f0634a2e2c72a838b99f1ff120
|
||||
glog: 04b94705f318337d7ead9e6d17c019bd9b1f6b1b
|
||||
glog: 69ef571f3de08433d766d614c73a9838a06bf7eb
|
||||
hermes-engine: 8d2103d6c0176779aea4e25df6bb1410f9946680
|
||||
MMKV: 817ba1eea17421547e01e087285606eb270a8dcb
|
||||
MMKVCore: af055b00e27d88cd92fad301c5fecd1ff9b26dd9
|
||||
|
|
|
|||
|
|
@ -107,17 +107,17 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@ariakit/react": "^0.3.9",
|
||||
"@lexical/clipboard": "0.16.0",
|
||||
"@lexical/headless": "0.16.0",
|
||||
"@lexical/link": "0.16.0",
|
||||
"@lexical/list": "0.16.0",
|
||||
"@lexical/react": "0.16.0",
|
||||
"@lexical/rich-text": "0.16.0",
|
||||
"@lexical/utils": "0.16.0",
|
||||
"@lexical/clipboard": "0.22.0",
|
||||
"@lexical/headless": "0.22.0",
|
||||
"@lexical/link": "0.22.0",
|
||||
"@lexical/list": "0.22.0",
|
||||
"@lexical/react": "0.22.0",
|
||||
"@lexical/rich-text": "0.22.0",
|
||||
"@lexical/utils": "0.22.0",
|
||||
"@radix-ui/react-slot": "^1.0.1",
|
||||
"@react-pdf/renderer": "^3.3.2",
|
||||
"comlink": "^4.4.1",
|
||||
"fast-diff": "^1.3.0",
|
||||
"lexical": "0.16.0"
|
||||
"lexical": "0.22.0"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
import { $createParagraphNode, $getRoot, $insertNodes, $nodesOfType, LexicalNode } from 'lexical'
|
||||
import { $createParagraphNode, $getRoot, $insertNodes, LexicalNode } from 'lexical'
|
||||
import { $generateNodesFromDOM } from '@lexical/html'
|
||||
import { createHeadlessEditor } from '@lexical/headless'
|
||||
import { BlockEditorNodes } from '../SuperEditor/Lexical/Nodes/AllNodes'
|
||||
import BlocksEditorTheme from '../SuperEditor/Lexical/Theme/Theme'
|
||||
import { ClipPayload } from '@standardnotes/clipper/src/types/message'
|
||||
import { LinkNode } from '@lexical/link'
|
||||
import { $isLinkNode } from '@lexical/link'
|
||||
import { $dfs } from '@lexical/utils'
|
||||
|
||||
const AbsoluteLinkRegExp = new RegExp('^(?:[a-z+]+:)?//', 'i')
|
||||
|
||||
|
|
@ -66,15 +67,18 @@ export const getSuperJSONFromClipPayload = async (clipPayload: ClipPayload) => {
|
|||
|
||||
await new Promise<void>((resolve) => {
|
||||
editor.update(() => {
|
||||
$nodesOfType(LinkNode).forEach((linkNode) => {
|
||||
const url = linkNode.getURL()
|
||||
for (const { node } of $dfs()) {
|
||||
if (!$isLinkNode(node)) {
|
||||
continue
|
||||
}
|
||||
const url = node.getURL()
|
||||
const isAbsoluteLink = AbsoluteLinkRegExp.test(url)
|
||||
|
||||
if (!isAbsoluteLink) {
|
||||
const fixedURL = new URL(url, clipURL)
|
||||
linkNode.setURL(fixedURL.toString())
|
||||
node.setURL(fixedURL.toString())
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
resolve()
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { DecoratorBlockNode, SerializedDecoratorBlockNode } from '@lexical/react/LexicalDecoratorBlockNode'
|
||||
import { parseAndCreateZippableFileName } from '@standardnotes/utils'
|
||||
import { DOMExportOutput, Spread } from 'lexical'
|
||||
import { DOMExportOutput, ElementFormatType, NodeKey, Spread } from 'lexical'
|
||||
|
||||
type SerializedFileExportNode = Spread<
|
||||
{
|
||||
|
|
@ -20,14 +20,14 @@ export class FileExportNode extends DecoratorBlockNode {
|
|||
return 'file-export'
|
||||
}
|
||||
|
||||
constructor(name: string, mimeType: string) {
|
||||
super()
|
||||
constructor(name: string, mimeType: string, format?: ElementFormatType, key?: NodeKey) {
|
||||
super(format, key)
|
||||
this.__name = name
|
||||
this.__mimeType = mimeType
|
||||
}
|
||||
|
||||
static clone(node: FileExportNode): FileExportNode {
|
||||
return new FileExportNode(node.__name, node.__mimeType)
|
||||
return new FileExportNode(node.__name, node.__mimeType, node.__format, node.__key)
|
||||
}
|
||||
|
||||
static importJSON(serializedNode: SerializedFileExportNode): FileExportNode {
|
||||
|
|
|
|||
|
|
@ -127,6 +127,11 @@ export class TweetNode extends DecoratorBlockNode {
|
|||
return 'tweet'
|
||||
}
|
||||
|
||||
constructor(id: string, format?: ElementFormatType, key?: NodeKey) {
|
||||
super(format, key)
|
||||
this.__id = id
|
||||
}
|
||||
|
||||
static override clone(node: TweetNode): TweetNode {
|
||||
return new TweetNode(node.__id, node.__format, node.__key)
|
||||
}
|
||||
|
|
@ -168,11 +173,6 @@ export class TweetNode extends DecoratorBlockNode {
|
|||
return { element }
|
||||
}
|
||||
|
||||
constructor(id: string, format?: ElementFormatType, key?: NodeKey) {
|
||||
super(format, key)
|
||||
this.__id = id
|
||||
}
|
||||
|
||||
getId(): string {
|
||||
return this.__id
|
||||
}
|
||||
|
|
|
|||
|
|
@ -72,6 +72,11 @@ export class YouTubeNode extends DecoratorBlockNode {
|
|||
return 'youtube'
|
||||
}
|
||||
|
||||
constructor(id: string, format?: ElementFormatType, key?: NodeKey) {
|
||||
super(format, key)
|
||||
this.__id = id
|
||||
}
|
||||
|
||||
static clone(node: YouTubeNode): YouTubeNode {
|
||||
return new YouTubeNode(node.__id, node.__format, node.__key)
|
||||
}
|
||||
|
|
@ -121,11 +126,6 @@ export class YouTubeNode extends DecoratorBlockNode {
|
|||
}
|
||||
}
|
||||
|
||||
constructor(id: string, format?: ElementFormatType, key?: NodeKey) {
|
||||
super(format, key)
|
||||
this.__id = id
|
||||
}
|
||||
|
||||
updateDOM(): false {
|
||||
return false
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,12 +7,9 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* Taken from https://github.com/facebook/lexical/blob/main/packages/lexical-markdown/src/MarkdownExport.ts
|
||||
* but modified using changes from https://github.com/facebook/lexical/pull/4957 to make nested elements work
|
||||
* better when exporting to markdown.
|
||||
*/
|
||||
* Taken from https://github.com/facebook/lexical/blob/main/packages/lexical-markdown/src/MarkdownExport.ts but modified using changes from https://github.com/facebook/lexical/pull/4957 to make nested elements work better when exporting to markdown.
|
||||
* */
|
||||
|
||||
import type { ElementTransformer, TextFormatTransformer, TextMatchTransformer, Transformer } from '@lexical/markdown'
|
||||
import {
|
||||
ElementNode,
|
||||
LexicalNode,
|
||||
|
|
@ -24,10 +21,27 @@ import {
|
|||
$isLineBreakNode,
|
||||
$isTextNode,
|
||||
} from 'lexical'
|
||||
import { TRANSFORMERS, transformersByType } from './MarkdownImportExportUtils'
|
||||
|
||||
export function createMarkdownExport(transformers: Array<Transformer>): (node?: ElementNode) => string {
|
||||
import {
|
||||
ElementTransformer,
|
||||
MultilineElementTransformer,
|
||||
TextFormatTransformer,
|
||||
TextMatchTransformer,
|
||||
Transformer,
|
||||
} from '@lexical/markdown'
|
||||
|
||||
import { isEmptyParagraph, TRANSFORMERS, transformersByType } from './MarkdownImportExportUtils'
|
||||
|
||||
/**
|
||||
* Renders string from markdown. The selection is moved to the start after the operation.
|
||||
*/
|
||||
function createMarkdownExport(
|
||||
transformers: Array<Transformer>,
|
||||
shouldPreserveNewLines: boolean = false,
|
||||
): (node?: ElementNode) => string {
|
||||
const byType = transformersByType(transformers)
|
||||
const elementTransformers = [...byType.multilineElement, ...byType.element]
|
||||
const isNewlineDelimited = !shouldPreserveNewLines
|
||||
|
||||
// Export only uses text formats that are responsible for single format
|
||||
// e.g. it will filter out *** (bold, italic) and instead use separate ** and *
|
||||
|
|
@ -37,25 +51,35 @@ export function createMarkdownExport(transformers: Array<Transformer>): (node?:
|
|||
const output = []
|
||||
const children = (node || $getRoot()).getChildren()
|
||||
|
||||
for (const child of children) {
|
||||
const result = exportTopLevelElements(child, byType.element, textFormatTransformers, byType.textMatch)
|
||||
for (let i = 0; i < children.length; i++) {
|
||||
const child = children[i]
|
||||
const result = exportTopLevelElements(child, elementTransformers, textFormatTransformers, byType.textMatch)
|
||||
|
||||
if (result != null) {
|
||||
output.push(result)
|
||||
output.push(
|
||||
// separate consecutive group of texts with a line break: eg. ["hello", "world"] -> ["hello", "/nworld"]
|
||||
isNewlineDelimited && i > 0 && !isEmptyParagraph(child) && !isEmptyParagraph(children[i - 1])
|
||||
? '\n'.concat(result)
|
||||
: result,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return output.join('\n\n')
|
||||
// Ensure consecutive groups of texts are at least \n\n apart while each empty paragraph render as a newline.
|
||||
// Eg. ["hello", "", "", "hi", "\nworld"] -> "hello\n\n\nhi\n\nworld"
|
||||
return output.join('\n')
|
||||
}
|
||||
}
|
||||
|
||||
function exportTopLevelElements(
|
||||
node: LexicalNode,
|
||||
elementTransformers: Array<ElementTransformer>,
|
||||
elementTransformers: Array<ElementTransformer | MultilineElementTransformer>,
|
||||
textTransformersIndex: Array<TextFormatTransformer>,
|
||||
textMatchTransformers: Array<TextMatchTransformer>,
|
||||
): string | null {
|
||||
for (const transformer of elementTransformers) {
|
||||
if (!transformer.export) {
|
||||
continue
|
||||
}
|
||||
const result = transformer.export(node, (_node) =>
|
||||
exportChildren(_node, elementTransformers, textTransformersIndex, textMatchTransformers),
|
||||
)
|
||||
|
|
@ -76,23 +100,33 @@ function exportTopLevelElements(
|
|||
|
||||
function exportChildren(
|
||||
node: ElementNode,
|
||||
elementTransformers: Array<ElementTransformer>,
|
||||
elementTransformers: Array<ElementTransformer | MultilineElementTransformer>,
|
||||
textTransformersIndex: Array<TextFormatTransformer>,
|
||||
textMatchTransformers: Array<TextMatchTransformer>,
|
||||
): string {
|
||||
const output = []
|
||||
const children = node.getChildren()
|
||||
const childrenLength = children.length
|
||||
// keep track of unclosed tags from the very beginning
|
||||
const unclosedTags: { format: TextFormatType; tag: string }[] = []
|
||||
|
||||
mainLoop: for (let childIndex = 0; childIndex < childrenLength; childIndex++) {
|
||||
const child = children[childIndex]
|
||||
const isLastChild = childIndex === childrenLength - 1
|
||||
|
||||
mainLoop: for (const child of children) {
|
||||
if ($isElementNode(child)) {
|
||||
for (const transformer of elementTransformers) {
|
||||
if (!transformer.export) {
|
||||
continue
|
||||
}
|
||||
|
||||
const result = transformer.export(child, (_node) =>
|
||||
exportChildren(_node, elementTransformers, textTransformersIndex, textMatchTransformers),
|
||||
)
|
||||
|
||||
if (result != null) {
|
||||
output.push(result)
|
||||
if (children.indexOf(child) !== children.length - 1) {
|
||||
if (!isLastChild) {
|
||||
output.push('\n')
|
||||
}
|
||||
continue mainLoop
|
||||
|
|
@ -101,10 +135,14 @@ function exportChildren(
|
|||
}
|
||||
|
||||
for (const transformer of textMatchTransformers) {
|
||||
if (!transformer.export) {
|
||||
continue
|
||||
}
|
||||
|
||||
const result = transformer.export(
|
||||
child,
|
||||
(parentNode) => exportChildren(parentNode, elementTransformers, textTransformersIndex, textMatchTransformers),
|
||||
(textNode, textContent) => exportTextFormat(textNode, textContent, textTransformersIndex),
|
||||
(textNode, textContent) => exportTextFormat(textNode, textContent, textTransformersIndex, unclosedTags),
|
||||
)
|
||||
|
||||
if (result != null) {
|
||||
|
|
@ -116,9 +154,15 @@ function exportChildren(
|
|||
if ($isLineBreakNode(child)) {
|
||||
output.push('\n')
|
||||
} else if ($isTextNode(child)) {
|
||||
output.push(exportTextFormat(child, child.getTextContent(), textTransformersIndex))
|
||||
output.push(exportTextFormat(child, child.getTextContent(), textTransformersIndex, unclosedTags))
|
||||
} else if ($isElementNode(child)) {
|
||||
output.push(exportChildren(child, elementTransformers, textTransformersIndex, textMatchTransformers), '\n')
|
||||
// empty paragraph returns ""
|
||||
output.push(exportChildren(child, elementTransformers, textTransformersIndex, textMatchTransformers))
|
||||
// Don't insert linebreak after last child
|
||||
if (!isLastChild) {
|
||||
// Insert two line breaks to create a space between two paragraphs or other elements, as required by Markdown syntax.
|
||||
output.push('\n', '\n')
|
||||
}
|
||||
} else if ($isDecoratorNode(child)) {
|
||||
output.push(child.getTextContent())
|
||||
}
|
||||
|
|
@ -127,13 +171,26 @@ function exportChildren(
|
|||
return output.join('')
|
||||
}
|
||||
|
||||
function exportTextFormat(node: TextNode, textContent: string, textTransformers: Array<TextFormatTransformer>): string {
|
||||
function exportTextFormat(
|
||||
node: TextNode,
|
||||
textContent: string,
|
||||
textTransformers: Array<TextFormatTransformer>,
|
||||
// unclosed tags include the markdown tags that haven't been closed yet, and their associated formats
|
||||
unclosedTags: Array<{ format: TextFormatType; tag: string }>,
|
||||
): string {
|
||||
// This function handles the case of a string looking like this: " foo "
|
||||
// Where it would be invalid markdown to generate: "** foo **"
|
||||
// We instead want to trim the whitespace out, apply formatting, and then
|
||||
// bring the whitespace back. So our returned string looks like this: " **foo** "
|
||||
const frozenString = textContent.trim()
|
||||
let output = frozenString
|
||||
// the opening tags to be added to the result
|
||||
let openingTags = ''
|
||||
// the closing tags to be added to the result
|
||||
let closingTags = ''
|
||||
|
||||
const prevNode = getTextSibling(node, true)
|
||||
const nextNode = getTextSibling(node, false)
|
||||
|
||||
const applied = new Set()
|
||||
|
||||
|
|
@ -141,27 +198,39 @@ function exportTextFormat(node: TextNode, textContent: string, textTransformers:
|
|||
const format = transformer.format[0]
|
||||
const tag = transformer.tag
|
||||
|
||||
// dedup applied formats
|
||||
if (hasFormat(node, format) && !applied.has(format)) {
|
||||
// Multiple tags might be used for the same format (*, _)
|
||||
applied.add(format)
|
||||
// Prevent adding opening tag is already opened by the previous sibling
|
||||
const previousNode = getTextSibling(node, true)
|
||||
|
||||
if (!hasFormat(previousNode, format)) {
|
||||
output = tag + output
|
||||
}
|
||||
|
||||
// Prevent adding closing tag if next sibling will do it
|
||||
const nextNode = getTextSibling(node, false)
|
||||
|
||||
if (!hasFormat(nextNode, format)) {
|
||||
output += tag
|
||||
// append the tag to openningTags, if it's not applied to the previous nodes,
|
||||
// or the nodes before that (which would result in an unclosed tag)
|
||||
if (!hasFormat(prevNode, format) || !unclosedTags.find((element) => element.tag === tag)) {
|
||||
unclosedTags.push({ format, tag })
|
||||
openingTags += tag
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// close any tags in the same order they were applied, if necessary
|
||||
for (let i = 0; i < unclosedTags.length; i++) {
|
||||
// prevent adding closing tag if next sibling will do it
|
||||
if (hasFormat(nextNode, unclosedTags[i].format)) {
|
||||
continue
|
||||
}
|
||||
|
||||
while (unclosedTags.length > i) {
|
||||
const unclosedTag = unclosedTags.pop()
|
||||
if (unclosedTag && typeof unclosedTag.tag === 'string') {
|
||||
closingTags += unclosedTag.tag
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
output = openingTags + output + closingTags
|
||||
// Replace trimmed version of textContent ensuring surrounding whitespace is not modified
|
||||
return textContent.replace(frozenString, output)
|
||||
return textContent.replace(frozenString, () => output)
|
||||
}
|
||||
|
||||
// Get next or previous text sibling a text node, including cases
|
||||
|
|
@ -208,7 +277,11 @@ function hasFormat(node: LexicalNode | null | undefined, format: TextFormatType)
|
|||
return $isTextNode(node) && node.hasFormat(format)
|
||||
}
|
||||
|
||||
export function $convertToMarkdownString(transformers: Array<Transformer> = TRANSFORMERS, node?: ElementNode): string {
|
||||
const exportMarkdown = createMarkdownExport(transformers)
|
||||
export function $convertToMarkdownString(
|
||||
transformers: Array<Transformer> = TRANSFORMERS,
|
||||
node?: ElementNode,
|
||||
shouldPreserveNewLines: boolean = false,
|
||||
): string {
|
||||
const exportMarkdown = createMarkdownExport(transformers, shouldPreserveNewLines)
|
||||
return exportMarkdown(node)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,368 +0,0 @@
|
|||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Taken from https://github.com/facebook/lexical/blob/main/packages/lexical-markdown/src/MarkdownImport.ts
|
||||
* but modified to allow keeping new lines when importing markdown.
|
||||
*/
|
||||
|
||||
import { CodeNode, $createCodeNode } from '@lexical/code'
|
||||
import { ElementTransformer, TextFormatTransformer, TextMatchTransformer, Transformer } from '@lexical/markdown'
|
||||
|
||||
import { $isListItemNode, $isListNode, ListItemNode } from '@lexical/list'
|
||||
import { $isQuoteNode } from '@lexical/rich-text'
|
||||
import { $findMatchingParent } from '@lexical/utils'
|
||||
import {
|
||||
LexicalNode,
|
||||
TextNode,
|
||||
$createLineBreakNode,
|
||||
$createParagraphNode,
|
||||
$createTextNode,
|
||||
$getRoot,
|
||||
$getSelection,
|
||||
$isParagraphNode,
|
||||
$isTextNode,
|
||||
ElementNode,
|
||||
} from 'lexical'
|
||||
import { IS_APPLE_WEBKIT, IS_IOS, IS_SAFARI } from '../Shared/environment'
|
||||
import { TRANSFORMERS, transformersByType } from './MarkdownImportExportUtils'
|
||||
|
||||
const PUNCTUATION_OR_SPACE = /[!-/:-@[-`{-~\s]/
|
||||
|
||||
const MARKDOWN_EMPTY_LINE_REG_EXP = /^\s{0,3}$/
|
||||
const CODE_BLOCK_REG_EXP = /^```(\w{1,10})?\s?$/
|
||||
type TextFormatTransformersIndex = Readonly<{
|
||||
fullMatchRegExpByTag: Readonly<Record<string, RegExp>>
|
||||
openTagsRegExp: RegExp
|
||||
transformersByTag: Readonly<Record<string, TextFormatTransformer>>
|
||||
}>
|
||||
|
||||
function createMarkdownImport(
|
||||
transformers: Array<Transformer>,
|
||||
): (markdownString: string, node?: ElementNode, keepNewLines?: boolean) => void {
|
||||
const byType = transformersByType(transformers)
|
||||
const textFormatTransformersIndex = createTextFormatTransformersIndex(byType.textFormat)
|
||||
|
||||
return (markdownString, node, keepNewLines = false) => {
|
||||
const lines = markdownString.split('\n')
|
||||
const linesLength = lines.length
|
||||
const root = node || $getRoot()
|
||||
root.clear()
|
||||
|
||||
for (let i = 0; i < linesLength; i++) {
|
||||
const lineText = lines[i]
|
||||
// Codeblocks are processed first as anything inside such block
|
||||
// is ignored for further processing
|
||||
// TODO:
|
||||
// Abstract it to be dynamic as other transformers (add multiline match option)
|
||||
const [codeBlockNode, shiftedIndex] = importCodeBlock(lines, i, root)
|
||||
|
||||
if (codeBlockNode != null) {
|
||||
i = shiftedIndex
|
||||
continue
|
||||
}
|
||||
|
||||
importBlocks(lineText, root, byType.element, textFormatTransformersIndex, byType.textMatch)
|
||||
}
|
||||
|
||||
if (!keepNewLines) {
|
||||
// Removing empty paragraphs as md does not really
|
||||
// allow empty lines and uses them as dilimiter
|
||||
const children = root.getChildren()
|
||||
for (const child of children) {
|
||||
if (isEmptyParagraph(child)) {
|
||||
child.remove()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($getSelection() !== null) {
|
||||
root.selectEnd()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function isEmptyParagraph(node: LexicalNode): boolean {
|
||||
if (!$isParagraphNode(node)) {
|
||||
return false
|
||||
}
|
||||
|
||||
const firstChild = node.getFirstChild()
|
||||
return (
|
||||
firstChild == null ||
|
||||
(node.getChildrenSize() === 1 &&
|
||||
$isTextNode(firstChild) &&
|
||||
MARKDOWN_EMPTY_LINE_REG_EXP.test(firstChild.getTextContent()))
|
||||
)
|
||||
}
|
||||
|
||||
function importBlocks(
|
||||
lineText: string,
|
||||
rootNode: ElementNode,
|
||||
elementTransformers: Array<ElementTransformer>,
|
||||
textFormatTransformersIndex: TextFormatTransformersIndex,
|
||||
textMatchTransformers: Array<TextMatchTransformer>,
|
||||
) {
|
||||
const lineTextTrimmed = lineText.trim()
|
||||
const textNode = $createTextNode(lineTextTrimmed)
|
||||
const elementNode = $createParagraphNode()
|
||||
elementNode.append(textNode)
|
||||
rootNode.append(elementNode)
|
||||
|
||||
for (const { regExp, replace } of elementTransformers) {
|
||||
const match = lineText.match(regExp)
|
||||
|
||||
if (match) {
|
||||
textNode.setTextContent(lineText.slice(match[0].length))
|
||||
replace(elementNode, [textNode], match, true)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
importTextFormatTransformers(textNode, textFormatTransformersIndex, textMatchTransformers)
|
||||
|
||||
// If no transformer found and we left with original paragraph node
|
||||
// can check if its content can be appended to the previous node
|
||||
// if it's a paragraph, quote or list
|
||||
if (elementNode.isAttached() && lineTextTrimmed.length > 0) {
|
||||
const previousNode = elementNode.getPreviousSibling()
|
||||
if ($isParagraphNode(previousNode) || $isQuoteNode(previousNode) || $isListNode(previousNode)) {
|
||||
let targetNode: typeof previousNode | ListItemNode | null = previousNode
|
||||
|
||||
if ($isListNode(previousNode)) {
|
||||
const lastDescendant = previousNode.getLastDescendant()
|
||||
if (lastDescendant == null) {
|
||||
targetNode = null
|
||||
} else {
|
||||
targetNode = $findMatchingParent(lastDescendant, $isListItemNode)
|
||||
}
|
||||
}
|
||||
|
||||
if (targetNode != null && targetNode.getTextContentSize() > 0) {
|
||||
targetNode.splice(targetNode.getChildrenSize(), 0, [$createLineBreakNode(), ...elementNode.getChildren()])
|
||||
elementNode.remove()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function importCodeBlock(
|
||||
lines: Array<string>,
|
||||
startLineIndex: number,
|
||||
rootNode: ElementNode,
|
||||
): [CodeNode | null, number] {
|
||||
const openMatch = lines[startLineIndex].match(CODE_BLOCK_REG_EXP)
|
||||
|
||||
if (openMatch) {
|
||||
let endLineIndex = startLineIndex
|
||||
const linesLength = lines.length
|
||||
|
||||
while (++endLineIndex < linesLength) {
|
||||
const closeMatch = lines[endLineIndex].match(CODE_BLOCK_REG_EXP)
|
||||
|
||||
if (closeMatch) {
|
||||
const codeBlockNode = $createCodeNode(openMatch[1])
|
||||
const textNode = $createTextNode(lines.slice(startLineIndex + 1, endLineIndex).join('\n'))
|
||||
codeBlockNode.append(textNode)
|
||||
rootNode.append(codeBlockNode)
|
||||
return [codeBlockNode, endLineIndex]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return [null, startLineIndex]
|
||||
}
|
||||
|
||||
// Processing text content and replaces text format tags.
|
||||
// It takes outermost tag match and its content, creates text node with
|
||||
// format based on tag and then recursively executed over node's content
|
||||
//
|
||||
// E.g. for "*Hello **world**!*" string it will create text node with
|
||||
// "Hello **world**!" content and italic format and run recursively over
|
||||
// its content to transform "**world**" part
|
||||
function importTextFormatTransformers(
|
||||
textNode: TextNode,
|
||||
textFormatTransformersIndex: TextFormatTransformersIndex,
|
||||
textMatchTransformers: Array<TextMatchTransformer>,
|
||||
) {
|
||||
const textContent = textNode.getTextContent()
|
||||
const match = findOutermostMatch(textContent, textFormatTransformersIndex)
|
||||
|
||||
if (!match) {
|
||||
// Once text format processing is done run text match transformers, as it
|
||||
// only can span within single text node (unline formats that can cover multiple nodes)
|
||||
importTextMatchTransformers(textNode, textMatchTransformers)
|
||||
return
|
||||
}
|
||||
|
||||
let currentNode, remainderNode, leadingNode
|
||||
|
||||
// If matching full content there's no need to run splitText and can reuse existing textNode
|
||||
// to update its content and apply format. E.g. for **_Hello_** string after applying bold
|
||||
// format (**) it will reuse the same text node to apply italic (_)
|
||||
if (match[0] === textContent) {
|
||||
currentNode = textNode
|
||||
} else {
|
||||
const startIndex = match.index || 0
|
||||
const endIndex = startIndex + match[0].length
|
||||
|
||||
if (startIndex === 0) {
|
||||
;[currentNode, remainderNode] = textNode.splitText(endIndex)
|
||||
} else {
|
||||
;[leadingNode, currentNode, remainderNode] = textNode.splitText(startIndex, endIndex)
|
||||
}
|
||||
}
|
||||
|
||||
currentNode.setTextContent(match[2])
|
||||
const transformer = textFormatTransformersIndex.transformersByTag[match[1]]
|
||||
|
||||
if (transformer) {
|
||||
for (const format of transformer.format) {
|
||||
if (!currentNode.hasFormat(format)) {
|
||||
currentNode.toggleFormat(format)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Recursively run over inner text if it's not inline code
|
||||
if (!currentNode.hasFormat('code')) {
|
||||
importTextFormatTransformers(currentNode, textFormatTransformersIndex, textMatchTransformers)
|
||||
}
|
||||
|
||||
// Run over leading/remaining text if any
|
||||
if (leadingNode) {
|
||||
importTextFormatTransformers(leadingNode, textFormatTransformersIndex, textMatchTransformers)
|
||||
}
|
||||
|
||||
if (remainderNode) {
|
||||
importTextFormatTransformers(remainderNode, textFormatTransformersIndex, textMatchTransformers)
|
||||
}
|
||||
}
|
||||
|
||||
function importTextMatchTransformers(textNode_: TextNode, textMatchTransformers: Array<TextMatchTransformer>) {
|
||||
let textNode = textNode_
|
||||
|
||||
mainLoop: while (textNode) {
|
||||
for (const transformer of textMatchTransformers) {
|
||||
const match = textNode.getTextContent().match(transformer.importRegExp)
|
||||
|
||||
if (!match) {
|
||||
continue
|
||||
}
|
||||
|
||||
const startIndex = match.index || 0
|
||||
const endIndex = startIndex + match[0].length
|
||||
let replaceNode, newTextNode
|
||||
|
||||
if (startIndex === 0) {
|
||||
;[replaceNode, textNode] = textNode.splitText(endIndex)
|
||||
} else {
|
||||
;[, replaceNode, newTextNode] = textNode.splitText(startIndex, endIndex)
|
||||
}
|
||||
if (newTextNode) {
|
||||
importTextMatchTransformers(newTextNode, textMatchTransformers)
|
||||
}
|
||||
transformer.replace(replaceNode, match)
|
||||
continue mainLoop
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Finds first "<tag>content<tag>" match that is not nested into another tag
|
||||
function findOutermostMatch(
|
||||
textContent: string,
|
||||
textTransformersIndex: TextFormatTransformersIndex,
|
||||
): RegExpMatchArray | null {
|
||||
const openTagsMatch = textContent.match(textTransformersIndex.openTagsRegExp)
|
||||
|
||||
if (openTagsMatch == null) {
|
||||
return null
|
||||
}
|
||||
|
||||
for (const match of openTagsMatch) {
|
||||
// Open tags reg exp might capture leading space so removing it
|
||||
// before using match to find transformer
|
||||
const tag = match.replace(/^\s/, '')
|
||||
const fullMatchRegExp = textTransformersIndex.fullMatchRegExpByTag[tag]
|
||||
if (fullMatchRegExp == null) {
|
||||
continue
|
||||
}
|
||||
|
||||
const fullMatch = textContent.match(fullMatchRegExp)
|
||||
const transformer = textTransformersIndex.transformersByTag[tag]
|
||||
if (fullMatch != null && transformer != null) {
|
||||
if (transformer.intraword !== false) {
|
||||
return fullMatch
|
||||
}
|
||||
|
||||
// For non-intraword transformers checking if it's within a word
|
||||
// or surrounded with space/punctuation/newline
|
||||
const { index = 0 } = fullMatch
|
||||
const beforeChar = textContent[index - 1]
|
||||
const afterChar = textContent[index + fullMatch[0].length]
|
||||
|
||||
if (
|
||||
(!beforeChar || PUNCTUATION_OR_SPACE.test(beforeChar)) &&
|
||||
(!afterChar || PUNCTUATION_OR_SPACE.test(afterChar))
|
||||
) {
|
||||
return fullMatch
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
function createTextFormatTransformersIndex(
|
||||
textTransformers: Array<TextFormatTransformer>,
|
||||
): TextFormatTransformersIndex {
|
||||
const transformersByTag: Record<string, TextFormatTransformer> = {}
|
||||
const fullMatchRegExpByTag: Record<string, RegExp> = {}
|
||||
const openTagsRegExp = []
|
||||
const escapeRegExp = '(?<![\\\\])'
|
||||
|
||||
for (const transformer of textTransformers) {
|
||||
const { tag } = transformer
|
||||
transformersByTag[tag] = transformer
|
||||
const tagRegExp = tag.replace(/(\*|\^|\+)/g, '\\$1')
|
||||
openTagsRegExp.push(tagRegExp)
|
||||
|
||||
if (IS_SAFARI || IS_IOS || IS_APPLE_WEBKIT) {
|
||||
fullMatchRegExpByTag[tag] = new RegExp(
|
||||
`(${tagRegExp})(?![${tagRegExp}\\s])(.*?[^${tagRegExp}\\s])${tagRegExp}(?!${tagRegExp})`,
|
||||
)
|
||||
} else {
|
||||
fullMatchRegExpByTag[tag] = new RegExp(
|
||||
`(?<![\\\\${tagRegExp}])(${tagRegExp})((\\\\${tagRegExp})?.*?[^${tagRegExp}\\s](\\\\${tagRegExp})?)((?<!\\\\)|(?<=\\\\\\\\))(${tagRegExp})(?![\\\\${tagRegExp}])`,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
// Reg exp to find open tag + content + close tag
|
||||
fullMatchRegExpByTag,
|
||||
// Reg exp to find opening tags
|
||||
openTagsRegExp: new RegExp(
|
||||
(IS_SAFARI || IS_IOS || IS_APPLE_WEBKIT ? '' : `${escapeRegExp}`) + '(' + openTagsRegExp.join('|') + ')',
|
||||
'g',
|
||||
),
|
||||
transformersByTag,
|
||||
}
|
||||
}
|
||||
|
||||
export function $convertFromMarkdownString(
|
||||
markdown: string,
|
||||
transformers: Array<Transformer> = TRANSFORMERS,
|
||||
node?: ElementNode,
|
||||
keepNewLines = false,
|
||||
): void {
|
||||
const importMarkdown = createMarkdownImport(transformers)
|
||||
return importMarkdown(markdown, node, keepNewLines)
|
||||
}
|
||||
|
|
@ -6,7 +6,10 @@ import {
|
|||
ELEMENT_TRANSFORMERS,
|
||||
TEXT_FORMAT_TRANSFORMERS,
|
||||
TEXT_MATCH_TRANSFORMERS,
|
||||
MultilineElementTransformer,
|
||||
MULTILINE_ELEMENT_TRANSFORMERS,
|
||||
} from '@lexical/markdown'
|
||||
import { LexicalNode, $isParagraphNode, $isTextNode } from 'lexical'
|
||||
|
||||
function indexBy<T>(list: Array<T>, callback: (arg0: T) => string): Readonly<Record<string, Array<T>>> {
|
||||
const index: Record<string, Array<T>> = {}
|
||||
|
|
@ -26,6 +29,7 @@ function indexBy<T>(list: Array<T>, callback: (arg0: T) => string): Readonly<Rec
|
|||
|
||||
export function transformersByType(transformers: Array<Transformer>): Readonly<{
|
||||
element: Array<ElementTransformer>
|
||||
multilineElement: Array<MultilineElementTransformer>
|
||||
textFormat: Array<TextFormatTransformer>
|
||||
textMatch: Array<TextMatchTransformer>
|
||||
}> {
|
||||
|
|
@ -33,13 +37,31 @@ export function transformersByType(transformers: Array<Transformer>): Readonly<{
|
|||
|
||||
return {
|
||||
element: (byType.element || []) as Array<ElementTransformer>,
|
||||
multilineElement: (byType['multiline-element'] || []) as Array<MultilineElementTransformer>,
|
||||
textFormat: (byType['text-format'] || []) as Array<TextFormatTransformer>,
|
||||
textMatch: (byType['text-match'] || []) as Array<TextMatchTransformer>,
|
||||
}
|
||||
}
|
||||
|
||||
const MARKDOWN_EMPTY_LINE_REG_EXP = /^\s{0,3}$/
|
||||
|
||||
export function isEmptyParagraph(node: LexicalNode): boolean {
|
||||
if (!$isParagraphNode(node)) {
|
||||
return false
|
||||
}
|
||||
|
||||
const firstChild = node.getFirstChild()
|
||||
return (
|
||||
firstChild == null ||
|
||||
(node.getChildrenSize() === 1 &&
|
||||
$isTextNode(firstChild) &&
|
||||
MARKDOWN_EMPTY_LINE_REG_EXP.test(firstChild.getTextContent()))
|
||||
)
|
||||
}
|
||||
|
||||
export const TRANSFORMERS: Array<Transformer> = [
|
||||
...ELEMENT_TRANSFORMERS,
|
||||
...MULTILINE_ELEMENT_TRANSFORMERS,
|
||||
...TEXT_FORMAT_TRANSFORMERS,
|
||||
...TEXT_MATCH_TRANSFORMERS,
|
||||
]
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import {
|
|||
TextMatchTransformer,
|
||||
$convertToMarkdownString,
|
||||
$convertFromMarkdownString,
|
||||
MULTILINE_ELEMENT_TRANSFORMERS,
|
||||
} from '@lexical/markdown'
|
||||
import {
|
||||
$createTableCellNode,
|
||||
|
|
@ -247,6 +248,7 @@ export const MarkdownTransformers = [
|
|||
IMAGE,
|
||||
INLINE_FILE,
|
||||
...ELEMENT_TRANSFORMERS,
|
||||
...MULTILINE_ELEMENT_TRANSFORMERS,
|
||||
...TEXT_FORMAT_TRANSFORMERS,
|
||||
...TEXT_MATCH_TRANSFORMERS,
|
||||
HorizontalRule,
|
||||
|
|
|
|||
|
|
@ -44,14 +44,14 @@ export class CollapsibleContainerNode extends ElementNode {
|
|||
this.__open = open ?? false
|
||||
}
|
||||
|
||||
static override getType(): string {
|
||||
return 'collapsible-container'
|
||||
}
|
||||
|
||||
static override clone(node: CollapsibleContainerNode): CollapsibleContainerNode {
|
||||
return new CollapsibleContainerNode(node.__open, node.__key)
|
||||
}
|
||||
|
||||
static override getType(): string {
|
||||
return 'collapsible-container'
|
||||
}
|
||||
|
||||
override createDOM(_: EditorConfig, editor: LexicalEditor): HTMLElement {
|
||||
const dom = document.createElement('details')
|
||||
dom.classList.add('Collapsible__container')
|
||||
|
|
|
|||
|
|
@ -13,6 +13,12 @@ export class FileNode extends DecoratorBlockNode implements ItemNodeInterface {
|
|||
return 'snfile'
|
||||
}
|
||||
|
||||
constructor(id: string, format?: ElementFormatType, key?: NodeKey, zoomLevel?: number) {
|
||||
super(format, key)
|
||||
this.__id = id
|
||||
this.__zoomLevel = zoomLevel || 100
|
||||
}
|
||||
|
||||
static clone(node: FileNode): FileNode {
|
||||
return new FileNode(node.__id, node.__format, node.__key, node.__zoomLevel)
|
||||
}
|
||||
|
|
@ -56,12 +62,6 @@ export class FileNode extends DecoratorBlockNode implements ItemNodeInterface {
|
|||
return { element }
|
||||
}
|
||||
|
||||
constructor(id: string, format?: ElementFormatType, key?: NodeKey, zoomLevel?: number) {
|
||||
super(format, key)
|
||||
this.__id = id
|
||||
this.__zoomLevel = zoomLevel || 100
|
||||
}
|
||||
|
||||
getId(): string {
|
||||
return this.__id
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import { handleEditorChange } from '../../Utils'
|
|||
import { SuperNotePreviewCharLimit } from '../../SuperEditor'
|
||||
import { $generateNodesFromDOM } from '@lexical/html'
|
||||
import { MarkdownTransformers } from '../../MarkdownTransformers'
|
||||
import { $convertFromMarkdownString } from '../../Lexical/Utils/MarkdownImport'
|
||||
import { $convertFromMarkdownString } from '@lexical/markdown'
|
||||
|
||||
/** Note that markdown conversion does not insert new lines. See: https://github.com/facebook/lexical/issues/2815 */
|
||||
export default function ImportPlugin({
|
||||
|
|
|
|||
|
|
@ -1,5 +1,14 @@
|
|||
import { DecoratorBlockNode, SerializedDecoratorBlockNode } from '@lexical/react/LexicalDecoratorBlockNode'
|
||||
import { DOMConversionMap, DOMExportOutput, EditorConfig, LexicalEditor, LexicalNode, Spread } from 'lexical'
|
||||
import {
|
||||
DOMConversionMap,
|
||||
DOMExportOutput,
|
||||
EditorConfig,
|
||||
ElementFormatType,
|
||||
LexicalEditor,
|
||||
LexicalNode,
|
||||
NodeKey,
|
||||
Spread,
|
||||
} from 'lexical'
|
||||
import InlineFileComponent from './InlineFileComponent'
|
||||
|
||||
type SerializedInlineFileNode = Spread<
|
||||
|
|
@ -22,15 +31,15 @@ export class InlineFileNode extends DecoratorBlockNode {
|
|||
return 'inline-file'
|
||||
}
|
||||
|
||||
constructor(src: string, mimeType: string, fileName: string | undefined) {
|
||||
super()
|
||||
constructor(src: string, mimeType: string, fileName: string | undefined, format?: ElementFormatType, key?: NodeKey) {
|
||||
super(format, key)
|
||||
this.__src = src
|
||||
this.__mimeType = mimeType
|
||||
this.__fileName = fileName
|
||||
}
|
||||
|
||||
static clone(node: InlineFileNode): InlineFileNode {
|
||||
return new InlineFileNode(node.__src, node.__mimeType, node.__fileName)
|
||||
return new InlineFileNode(node.__src, node.__mimeType, node.__fileName, node.__format, node.__key)
|
||||
}
|
||||
|
||||
static importJSON(serializedNode: SerializedInlineFileNode): InlineFileNode {
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'
|
||||
import { useEffect } from 'react'
|
||||
import { $createCodeNode } from '@lexical/code'
|
||||
import { $createTextNode, $getRoot, $nodesOfType, ParagraphNode } from 'lexical'
|
||||
import { $convertToMarkdownString } from '@lexical/markdown'
|
||||
import { $createTextNode, $getRoot, $isParagraphNode } from 'lexical'
|
||||
import { MarkdownTransformers } from '../../MarkdownTransformers'
|
||||
import { $dfs } from '@lexical/utils'
|
||||
import { $convertToMarkdownString } from '../../Lexical/Utils/MarkdownExport'
|
||||
|
||||
type Props = {
|
||||
onMarkdown: (markdown: string) => void
|
||||
|
|
@ -15,10 +16,12 @@ export default function MarkdownPreviewPlugin({ onMarkdown }: Props): JSX.Elemen
|
|||
useEffect(() => {
|
||||
editor.update(() => {
|
||||
const root = $getRoot()
|
||||
const paragraphs = $nodesOfType(ParagraphNode)
|
||||
for (const paragraph of paragraphs) {
|
||||
if (paragraph.isEmpty()) {
|
||||
paragraph.remove()
|
||||
for (const { node } of $dfs()) {
|
||||
if (!$isParagraphNode(node)) {
|
||||
continue
|
||||
}
|
||||
if (node.isEmpty()) {
|
||||
node.remove()
|
||||
}
|
||||
}
|
||||
const markdown = $convertToMarkdownString(MarkdownTransformers)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,14 @@
|
|||
import { DecoratorBlockNode, SerializedDecoratorBlockNode } from '@lexical/react/LexicalDecoratorBlockNode'
|
||||
import { DOMConversionMap, DOMExportOutput, EditorConfig, LexicalEditor, LexicalNode, Spread } from 'lexical'
|
||||
import {
|
||||
DOMConversionMap,
|
||||
DOMExportOutput,
|
||||
EditorConfig,
|
||||
ElementFormatType,
|
||||
LexicalEditor,
|
||||
LexicalNode,
|
||||
NodeKey,
|
||||
Spread,
|
||||
} from 'lexical'
|
||||
import RemoteImageComponent from './RemoteImageComponent'
|
||||
|
||||
type SerializedRemoteImageNode = Spread<
|
||||
|
|
@ -20,14 +29,14 @@ export class RemoteImageNode extends DecoratorBlockNode {
|
|||
return 'unencrypted-image'
|
||||
}
|
||||
|
||||
constructor(src: string, alt?: string) {
|
||||
super()
|
||||
constructor(src: string, alt?: string, format?: ElementFormatType, key?: NodeKey) {
|
||||
super(format, key)
|
||||
this.__src = src
|
||||
this.__alt = alt
|
||||
}
|
||||
|
||||
static clone(node: RemoteImageNode): RemoteImageNode {
|
||||
return new RemoteImageNode(node.__src, node.__alt)
|
||||
return new RemoteImageNode(node.__src, node.__alt, node.__format, node.__key)
|
||||
}
|
||||
|
||||
static importJSON(serializedNode: SerializedRemoteImageNode): RemoteImageNode {
|
||||
|
|
|
|||
|
|
@ -89,9 +89,10 @@ export const SearchPlugin = () => {
|
|||
|
||||
const handleSearch = useCallback(
|
||||
(query: string, isCaseSensitive: boolean) => {
|
||||
document.querySelectorAll('.search-highlight').forEach((element) => {
|
||||
const currentHighlights = document.querySelectorAll('.search-highlight')
|
||||
for (const element of currentHighlights) {
|
||||
element.remove()
|
||||
})
|
||||
}
|
||||
|
||||
if (!query) {
|
||||
dispatch({ type: 'clear-results' })
|
||||
|
|
@ -109,7 +110,7 @@ export const SearchPlugin = () => {
|
|||
|
||||
const results: SuperSearchResult[] = []
|
||||
|
||||
textNodes.forEach((node) => {
|
||||
for (const node of textNodes) {
|
||||
const text = node.textContent || ''
|
||||
|
||||
const indices: number[] = []
|
||||
|
|
@ -122,7 +123,7 @@ export const SearchPlugin = () => {
|
|||
indices.push(index)
|
||||
}
|
||||
|
||||
indices.forEach((index) => {
|
||||
for (const index of indices) {
|
||||
const startIndex = index
|
||||
const endIndex = startIndex + query.length
|
||||
|
||||
|
|
@ -131,8 +132,8 @@ export const SearchPlugin = () => {
|
|||
startIndex,
|
||||
endIndex,
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
dispatch({
|
||||
type: 'set-results',
|
||||
|
|
@ -205,7 +206,10 @@ export const SearchPlugin = () => {
|
|||
}
|
||||
replaceResult(result, true)
|
||||
} else if (type === 'all') {
|
||||
resultsRef.current.forEach((result) => replaceResult(result))
|
||||
const results = resultsRef.current
|
||||
for (const result of results) {
|
||||
replaceResult(result)
|
||||
}
|
||||
}
|
||||
|
||||
void handleSearch(queryRef.current, isCaseSensitiveRef.current)
|
||||
|
|
@ -214,9 +218,10 @@ export const SearchPlugin = () => {
|
|||
}, [addReplaceEventListener, currentResultIndexRef, editor, handleSearch, isCaseSensitiveRef, queryRef, resultsRef])
|
||||
|
||||
useEffect(() => {
|
||||
document.querySelectorAll('.search-highlight').forEach((element) => {
|
||||
const currentHighlights = document.querySelectorAll('.search-highlight')
|
||||
for (const element of currentHighlights) {
|
||||
element.remove()
|
||||
})
|
||||
}
|
||||
if (currentResultIndex === -1) {
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -190,7 +190,7 @@ function TableActionMenu({ onClose, tableCellNode: _tableCellNode, cellMerge }:
|
|||
|
||||
const tableSelection = getTableObserverFromTableElement(tableElement)
|
||||
if (tableSelection !== null) {
|
||||
tableSelection.clearHighlight()
|
||||
tableSelection.$clearHighlight()
|
||||
}
|
||||
|
||||
tableNode.markDirty()
|
||||
|
|
|
|||
|
|
@ -1,24 +1,17 @@
|
|||
import { createHeadlessEditor } from '@lexical/headless'
|
||||
import { FileItem, PrefKey, PrefValue, SuperConverterServiceInterface } from '@standardnotes/snjs'
|
||||
import {
|
||||
$createParagraphNode,
|
||||
$getRoot,
|
||||
$insertNodes,
|
||||
$nodesOfType,
|
||||
LexicalEditor,
|
||||
LexicalNode,
|
||||
ParagraphNode,
|
||||
} from 'lexical'
|
||||
import { $createParagraphNode, $getRoot, $insertNodes, $isParagraphNode, LexicalEditor, LexicalNode } from 'lexical'
|
||||
import BlocksEditorTheme from '../Lexical/Theme/Theme'
|
||||
import { BlockEditorNodes, SuperExportNodes } from '../Lexical/Nodes/AllNodes'
|
||||
import { MarkdownTransformers } from '../MarkdownTransformers'
|
||||
import { $generateHtmlFromNodes, $generateNodesFromDOM } from '@lexical/html'
|
||||
import { FileNode } from '../Plugins/EncryptedFilePlugin/Nodes/FileNode'
|
||||
import { $createFileExportNode } from '../Lexical/Nodes/FileExportNode'
|
||||
import { $createInlineFileNode } from '../Plugins/InlineFilePlugin/InlineFileNode'
|
||||
import { $convertFromMarkdownString } from '../Lexical/Utils/MarkdownImport'
|
||||
import { $convertFromMarkdownString } from '@lexical/markdown'
|
||||
import { $convertToMarkdownString } from '../Lexical/Utils/MarkdownExport'
|
||||
import { parseFileName } from '@standardnotes/utils'
|
||||
import { $dfs } from '@lexical/utils'
|
||||
import { $isFileNode } from '../Plugins/EncryptedFilePlugin/Nodes/FileUtils'
|
||||
|
||||
export class HeadlessSuperConverter implements SuperConverterServiceInterface {
|
||||
private importEditor: LexicalEditor
|
||||
|
|
@ -80,103 +73,103 @@ export class HeadlessSuperConverter implements SuperConverterServiceInterface {
|
|||
let content: string | undefined
|
||||
|
||||
await new Promise<void>((resolve) => {
|
||||
this.exportEditor.update(
|
||||
() => {
|
||||
if (embedBehavior === 'reference') {
|
||||
resolve()
|
||||
return
|
||||
}
|
||||
if (!getFileItem) {
|
||||
resolve()
|
||||
return
|
||||
}
|
||||
const fileNodes = $nodesOfType(FileNode)
|
||||
const filenameCounts: Record<string, number> = {}
|
||||
Promise.all(
|
||||
fileNodes.map(async (fileNode) => {
|
||||
const fileItem = getFileItem(fileNode.getId())
|
||||
if (!fileItem) {
|
||||
const handleFileNodes = () => {
|
||||
if (embedBehavior === 'reference') {
|
||||
resolve()
|
||||
return
|
||||
}
|
||||
if (!getFileItem) {
|
||||
resolve()
|
||||
return
|
||||
}
|
||||
const filenameCounts: Record<string, number> = {}
|
||||
Promise.all(
|
||||
$dfs().map(async ({ node: fileNode }) => {
|
||||
if (!$isFileNode(fileNode)) {
|
||||
return
|
||||
}
|
||||
const fileItem = getFileItem(fileNode.getId())
|
||||
if (!fileItem) {
|
||||
return
|
||||
}
|
||||
const canInlineFileType = toFormat === 'pdf' ? fileItem.mimeType.startsWith('image/') : true
|
||||
if (embedBehavior === 'inline' && getFileBase64 && canInlineFileType) {
|
||||
const fileBase64 = await getFileBase64(fileNode.getId())
|
||||
if (!fileBase64) {
|
||||
return
|
||||
}
|
||||
const canInlineFileType = toFormat === 'pdf' ? fileItem.mimeType.startsWith('image/') : true
|
||||
if (embedBehavior === 'inline' && getFileBase64 && canInlineFileType) {
|
||||
const fileBase64 = await getFileBase64(fileNode.getId())
|
||||
if (!fileBase64) {
|
||||
return
|
||||
}
|
||||
this.exportEditor.update(
|
||||
() => {
|
||||
const inlineFileNode = $createInlineFileNode(fileBase64, fileItem.mimeType, fileItem.name)
|
||||
fileNode.replace(inlineFileNode)
|
||||
},
|
||||
{ discrete: true },
|
||||
)
|
||||
} else {
|
||||
this.exportEditor.update(
|
||||
() => {
|
||||
filenameCounts[fileItem.name] =
|
||||
filenameCounts[fileItem.name] == undefined ? 0 : filenameCounts[fileItem.name] + 1
|
||||
this.exportEditor.update(
|
||||
() => {
|
||||
const inlineFileNode = $createInlineFileNode(fileBase64, fileItem.mimeType, fileItem.name)
|
||||
fileNode.replace(inlineFileNode)
|
||||
},
|
||||
{ discrete: true },
|
||||
)
|
||||
} else {
|
||||
this.exportEditor.update(
|
||||
() => {
|
||||
filenameCounts[fileItem.name] =
|
||||
filenameCounts[fileItem.name] == undefined ? 0 : filenameCounts[fileItem.name] + 1
|
||||
|
||||
let name = fileItem.name
|
||||
let name = fileItem.name
|
||||
|
||||
if (filenameCounts[name] > 0) {
|
||||
const { name: _name, ext } = parseFileName(name)
|
||||
name = `${_name}-${fileItem.uuid}.${ext}`
|
||||
}
|
||||
if (filenameCounts[name] > 0) {
|
||||
const { name: _name, ext } = parseFileName(name)
|
||||
name = `${_name}-${fileItem.uuid}.${ext}`
|
||||
}
|
||||
|
||||
const fileExportNode = $createFileExportNode(name, fileItem.mimeType)
|
||||
fileNode.replace(fileExportNode)
|
||||
},
|
||||
{ discrete: true },
|
||||
)
|
||||
}
|
||||
}),
|
||||
)
|
||||
.then(() => resolve())
|
||||
.catch(console.error)
|
||||
},
|
||||
{ discrete: true },
|
||||
)
|
||||
const fileExportNode = $createFileExportNode(name, fileItem.mimeType)
|
||||
fileNode.replace(fileExportNode)
|
||||
},
|
||||
{ discrete: true },
|
||||
)
|
||||
}
|
||||
}),
|
||||
)
|
||||
.then(() => resolve())
|
||||
.catch(console.error)
|
||||
}
|
||||
this.exportEditor.update(handleFileNodes, { discrete: true })
|
||||
})
|
||||
|
||||
await new Promise<void>((resolve) => {
|
||||
this.exportEditor.update(
|
||||
() => {
|
||||
switch (toFormat) {
|
||||
case 'txt':
|
||||
case 'md': {
|
||||
const paragraphs = $nodesOfType(ParagraphNode)
|
||||
for (const paragraph of paragraphs) {
|
||||
if (paragraph.isEmpty()) {
|
||||
paragraph.remove()
|
||||
}
|
||||
const convertToFormat = () => {
|
||||
switch (toFormat) {
|
||||
case 'txt':
|
||||
case 'md': {
|
||||
for (const { node: paragraph } of $dfs()) {
|
||||
if (!$isParagraphNode(paragraph)) {
|
||||
continue
|
||||
}
|
||||
if (paragraph.isEmpty()) {
|
||||
paragraph.remove()
|
||||
}
|
||||
content = $convertToMarkdownString(MarkdownTransformers)
|
||||
resolve()
|
||||
break
|
||||
}
|
||||
case 'html':
|
||||
content = $generateHtmlFromNodes(this.exportEditor)
|
||||
resolve()
|
||||
break
|
||||
case 'pdf': {
|
||||
void import('../Lexical/Utils/PDFExport/PDFExport').then(({ $generatePDFFromNodes }): void => {
|
||||
void $generatePDFFromNodes(this.exportEditor, config?.pdf?.pageSize || 'A4').then((pdf) => {
|
||||
content = pdf
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
break
|
||||
}
|
||||
case 'json':
|
||||
default:
|
||||
content = superString
|
||||
resolve()
|
||||
break
|
||||
content = $convertToMarkdownString(MarkdownTransformers)
|
||||
resolve()
|
||||
break
|
||||
}
|
||||
},
|
||||
{ discrete: true },
|
||||
)
|
||||
case 'html':
|
||||
content = $generateHtmlFromNodes(this.exportEditor)
|
||||
resolve()
|
||||
break
|
||||
case 'pdf': {
|
||||
void import('../Lexical/Utils/PDFExport/PDFExport').then(({ $generatePDFFromNodes }): void => {
|
||||
void $generatePDFFromNodes(this.exportEditor, config?.pdf?.pageSize || 'A4').then((pdf) => {
|
||||
content = pdf
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
break
|
||||
}
|
||||
case 'json':
|
||||
default:
|
||||
content = superString
|
||||
resolve()
|
||||
break
|
||||
}
|
||||
}
|
||||
this.exportEditor.update(convertToFormat, { discrete: true })
|
||||
})
|
||||
|
||||
if (typeof content !== 'string') {
|
||||
|
|
@ -288,14 +281,16 @@ export class HeadlessSuperConverter implements SuperConverterServiceInterface {
|
|||
const ids: string[] = []
|
||||
|
||||
this.exportEditor.getEditorState().read(() => {
|
||||
const fileNodes = $nodesOfType(FileNode)
|
||||
fileNodes.forEach((fileNode) => {
|
||||
for (const { node: fileNode } of $dfs()) {
|
||||
if (!$isFileNode(fileNode)) {
|
||||
continue
|
||||
}
|
||||
const nodeId = fileNode.getId()
|
||||
if (ids.includes(nodeId)) {
|
||||
return
|
||||
continue
|
||||
}
|
||||
ids.push(nodeId)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
return ids
|
||||
|
|
|
|||
394
yarn.lock
394
yarn.lock
|
|
@ -4278,298 +4278,290 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@lexical/clipboard@npm:0.16.0":
|
||||
version: 0.16.0
|
||||
resolution: "@lexical/clipboard@npm:0.16.0"
|
||||
"@lexical/clipboard@npm:0.22.0":
|
||||
version: 0.22.0
|
||||
resolution: "@lexical/clipboard@npm:0.22.0"
|
||||
dependencies:
|
||||
"@lexical/html": 0.16.0
|
||||
"@lexical/list": 0.16.0
|
||||
"@lexical/selection": 0.16.0
|
||||
"@lexical/utils": 0.16.0
|
||||
lexical: 0.16.0
|
||||
checksum: 8fe5cf11a1ad84d4da39205610cb2969046455a0dc0b33d4de748abc9fe9904c2381ce85c495f2b9c85233548d7223270eec030619f3455bb911d6767a3516f2
|
||||
"@lexical/html": 0.22.0
|
||||
"@lexical/list": 0.22.0
|
||||
"@lexical/selection": 0.22.0
|
||||
"@lexical/utils": 0.22.0
|
||||
lexical: 0.22.0
|
||||
checksum: c6869ec54c6972185806ab40b35a089cbb54585ccd13f38e0e56cdac1783b0615f2482adf15505279b0b0f2276a2a1fa432673983c7f9a5ed3274d4e8588939c
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@lexical/clipboard@patch:@lexical/clipboard@npm:0.16.0#.yarn/patches/@lexical-clipboard-npm-0.16.0-3053c4af9c.patch::locator=%40standardnotes%2Fapp-monorepo%40workspace%3A.":
|
||||
version: 0.16.0
|
||||
resolution: "@lexical/clipboard@patch:@lexical/clipboard@npm%3A0.16.0#.yarn/patches/@lexical-clipboard-npm-0.16.0-3053c4af9c.patch::version=0.16.0&hash=ef7a9a&locator=%40standardnotes%2Fapp-monorepo%40workspace%3A."
|
||||
"@lexical/clipboard@patch:@lexical/clipboard@npm:0.22.0#.yarn/patches/@lexical-clipboard-npm-0.22.0-e950aa6a7f.patch::locator=%40standardnotes%2Fapp-monorepo%40workspace%3A.":
|
||||
version: 0.22.0
|
||||
resolution: "@lexical/clipboard@patch:@lexical/clipboard@npm%3A0.22.0#.yarn/patches/@lexical-clipboard-npm-0.22.0-e950aa6a7f.patch::version=0.22.0&hash=30572a&locator=%40standardnotes%2Fapp-monorepo%40workspace%3A."
|
||||
dependencies:
|
||||
"@lexical/html": 0.16.0
|
||||
"@lexical/list": 0.16.0
|
||||
"@lexical/selection": 0.16.0
|
||||
"@lexical/utils": 0.16.0
|
||||
lexical: 0.16.0
|
||||
checksum: 4bfeeaef9a31d15bfa35bc58d4508ec19eeb3a8c68f88a5d1eb69bcba007fca934c0cd278d3b10adf754b0b9370a0aa16e48d31f26fa3a7d7a95bfa736f0417c
|
||||
"@lexical/html": 0.22.0
|
||||
"@lexical/list": 0.22.0
|
||||
"@lexical/selection": 0.22.0
|
||||
"@lexical/utils": 0.22.0
|
||||
lexical: 0.22.0
|
||||
checksum: 8972b49800b7491072680ed597a81b934b388f97570b8239f14dabfbafd6f4e46feeb68e279a9e8c5075e955310b6dac480bb1c8f2f2e1d98f900705cd8b1168
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@lexical/code@npm:0.16.0":
|
||||
version: 0.16.0
|
||||
resolution: "@lexical/code@npm:0.16.0"
|
||||
"@lexical/code@npm:0.22.0":
|
||||
version: 0.22.0
|
||||
resolution: "@lexical/code@npm:0.22.0"
|
||||
dependencies:
|
||||
"@lexical/utils": 0.16.0
|
||||
lexical: 0.16.0
|
||||
"@lexical/utils": 0.22.0
|
||||
lexical: 0.22.0
|
||||
prismjs: ^1.27.0
|
||||
checksum: 4f6283beca15df5b9520f2245803f7e34fc4297fbaafd790371d44a590a8ba33107515f63a8db281191280d85b170c7eca3fc151eec5929b3b5a212cc5255ecf
|
||||
checksum: 6e7ff958d5dbbe02e8ca998d5601aea545fe18a509368170002fb0906a020d2d1d93fffaa6442ee742c78350eb74419a09521084e10859e801de95bb2cd8cada
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@lexical/devtools-core@npm:0.16.0":
|
||||
version: 0.16.0
|
||||
resolution: "@lexical/devtools-core@npm:0.16.0"
|
||||
"@lexical/devtools-core@npm:0.22.0":
|
||||
version: 0.22.0
|
||||
resolution: "@lexical/devtools-core@npm:0.22.0"
|
||||
dependencies:
|
||||
"@lexical/html": 0.16.0
|
||||
"@lexical/link": 0.16.0
|
||||
"@lexical/mark": 0.16.0
|
||||
"@lexical/table": 0.16.0
|
||||
"@lexical/utils": 0.16.0
|
||||
lexical: 0.16.0
|
||||
"@lexical/html": 0.22.0
|
||||
"@lexical/link": 0.22.0
|
||||
"@lexical/mark": 0.22.0
|
||||
"@lexical/table": 0.22.0
|
||||
"@lexical/utils": 0.22.0
|
||||
lexical: 0.22.0
|
||||
peerDependencies:
|
||||
react: ">=17.x"
|
||||
react-dom: ">=17.x"
|
||||
checksum: c6ba99da01c2bef29537e0c3f39f0e6c91a6c091239b96048ae9cba5d9911edac9906f053430e17599608d9d01721efbeca00471dfb8ce7878492f767105e056
|
||||
checksum: e8c75cd1fb5854e51d6565ff46cd4c1118991d0b069e7d3f3a9cc59a997a9495947bef2b77752ff0a63799fdc5bc28a02d168ff4cef92ac697089746859bb2af
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@lexical/dragon@npm:0.16.0":
|
||||
version: 0.16.0
|
||||
resolution: "@lexical/dragon@npm:0.16.0"
|
||||
"@lexical/dragon@npm:0.22.0":
|
||||
version: 0.22.0
|
||||
resolution: "@lexical/dragon@npm:0.22.0"
|
||||
dependencies:
|
||||
lexical: 0.16.0
|
||||
checksum: 8f6fa617559bdf204da8509d545e34f78d19c8268a8335bf7e62621f053f88e328521879cf60e8e6eab85d7580681b09ed90dc77a6088aaac32d0f62f860f1dd
|
||||
lexical: 0.22.0
|
||||
checksum: ba9b4143b7b01a3cc938c673c32ec2dfc944dc529fd204cbf63f4376b2b6d8481270ae72a7c241cbe3b9488e0af67f8c7017873723f903a0ddd5e14967cbe12b
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@lexical/hashtag@npm:0.16.0":
|
||||
version: 0.16.0
|
||||
resolution: "@lexical/hashtag@npm:0.16.0"
|
||||
"@lexical/hashtag@npm:0.22.0":
|
||||
version: 0.22.0
|
||||
resolution: "@lexical/hashtag@npm:0.22.0"
|
||||
dependencies:
|
||||
"@lexical/utils": 0.16.0
|
||||
lexical: 0.16.0
|
||||
checksum: a569b35a89708d6291c072ac91dbf69b759383862633fc1d8f2322ebdec9b4200f8f5a3c30f46f58963c80290ba3182da8d44d468f352760b85e00e760db2753
|
||||
"@lexical/utils": 0.22.0
|
||||
lexical: 0.22.0
|
||||
checksum: 368cf96b0851ed47359228ab5b363d62d705c226e3ce67e65cc94e446d6ddd50d4a27634f164fb171f09fb30461c5b015d5f602894ebe712bed0802ea6bd8473
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@lexical/headless@npm:0.16.0":
|
||||
version: 0.16.0
|
||||
resolution: "@lexical/headless@npm:0.16.0"
|
||||
"@lexical/headless@npm:0.22.0":
|
||||
version: 0.22.0
|
||||
resolution: "@lexical/headless@npm:0.22.0"
|
||||
dependencies:
|
||||
lexical: 0.16.0
|
||||
checksum: 6a03375495e839965b52d2d5980ffd821dd9f72acfb8793df74db2fed424cb9e9cd787d76684112651efdaa9c1af6feae4674dbb79b67edcd7b37331f67880b1
|
||||
lexical: 0.22.0
|
||||
checksum: dedc45cec5e1bd6249c3debded120d0c9b09c924dc0e6625d2d6d9e1ce08625722510f0beb8380ce8bb96f3006510375450e88a80fbc366c45ad6df6e660f4ff
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@lexical/history@npm:0.16.0":
|
||||
version: 0.16.0
|
||||
resolution: "@lexical/history@npm:0.16.0"
|
||||
"@lexical/history@npm:0.22.0":
|
||||
version: 0.22.0
|
||||
resolution: "@lexical/history@npm:0.22.0"
|
||||
dependencies:
|
||||
"@lexical/utils": 0.16.0
|
||||
lexical: 0.16.0
|
||||
checksum: a26311ddcc2a283eb069abd4fc6963d3401b57e618bfdb061a7f36b376a04af32223b3d63575185cf7e38de34416efe4e184979f42a4a71395ffad54e5337cf0
|
||||
"@lexical/utils": 0.22.0
|
||||
lexical: 0.22.0
|
||||
checksum: 8eb683a5bbe6ab1c5936be81d480a1519c7c2b0931b1957e71a1b873655155967635b18fc26f8a6228b0c8e0dc7c0c4b7e3e91bce064d003d9609350916bfed8
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@lexical/html@npm:0.16.0":
|
||||
version: 0.16.0
|
||||
resolution: "@lexical/html@npm:0.16.0"
|
||||
"@lexical/html@npm:0.22.0":
|
||||
version: 0.22.0
|
||||
resolution: "@lexical/html@npm:0.22.0"
|
||||
dependencies:
|
||||
"@lexical/selection": 0.16.0
|
||||
"@lexical/utils": 0.16.0
|
||||
lexical: 0.16.0
|
||||
checksum: 3b3ffa982318a46bfa189805352dda6e3139b10c2b9e4242efce98037bbb26eeb7656bd169b5e2666503cd91cdf93ac7e154f10905eb9cffa4a092b11e0811d9
|
||||
"@lexical/selection": 0.22.0
|
||||
"@lexical/utils": 0.22.0
|
||||
lexical: 0.22.0
|
||||
checksum: 14e32af4fbe3ee06cb48587ba6302e451360f6d3dbacef191032d80464727593d7fe98a44875809666ba8cd169c73241cd841326cf54edef235ddb24515d7ef0
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@lexical/link@npm:0.16.0":
|
||||
version: 0.16.0
|
||||
resolution: "@lexical/link@npm:0.16.0"
|
||||
"@lexical/link@npm:0.22.0":
|
||||
version: 0.22.0
|
||||
resolution: "@lexical/link@npm:0.22.0"
|
||||
dependencies:
|
||||
"@lexical/utils": 0.16.0
|
||||
lexical: 0.16.0
|
||||
checksum: 2b2900001a97bf22550f0141dea358bbb7fe1b59bffe7506afd5e834ec722371de4d62b9e9899a4a960d3d85369bfe3faf5ba79367640b9e45b7bcff46bf1409
|
||||
"@lexical/utils": 0.22.0
|
||||
lexical: 0.22.0
|
||||
checksum: f36c3d3a7e05308f02b402a4645bf00ffe8f61223c7a8f8e59c61ee8fabdbf77aac95d7a6e04c68490aa5b701a620fa89cd323a135963f85f5d82a5e6417efae
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@lexical/list@npm:0.16.0":
|
||||
version: 0.16.0
|
||||
resolution: "@lexical/list@npm:0.16.0"
|
||||
"@lexical/list@npm:0.22.0":
|
||||
version: 0.22.0
|
||||
resolution: "@lexical/list@npm:0.22.0"
|
||||
dependencies:
|
||||
"@lexical/utils": 0.16.0
|
||||
lexical: 0.16.0
|
||||
checksum: f60fd40d03b276624b67371498f42cd70fb8ad6971d0c3e396681e8f3c2fc2d9678472912363388c4b7913c93bc526f2400b925dbc3cfcdb61aea06a0af53a0b
|
||||
"@lexical/utils": 0.22.0
|
||||
lexical: 0.22.0
|
||||
checksum: 7ee86ccc5686a23c365b38c3df3e6c1da560dfc6d7e4ad66e06d9e1b759b68276e1b24bb0f94906462e20d7778a55897909030ff35f03836e178b8ce68d70c1e
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@lexical/list@patch:@lexical/list@npm:0.16.0#.yarn/patches/@lexical-list-npm-0.16.0-8f91da4ad5.patch::locator=%40standardnotes%2Fapp-monorepo%40workspace%3A.":
|
||||
version: 0.16.0
|
||||
resolution: "@lexical/list@patch:@lexical/list@npm%3A0.16.0#.yarn/patches/@lexical-list-npm-0.16.0-8f91da4ad5.patch::version=0.16.0&hash=6af727&locator=%40standardnotes%2Fapp-monorepo%40workspace%3A."
|
||||
"@lexical/mark@npm:0.22.0":
|
||||
version: 0.22.0
|
||||
resolution: "@lexical/mark@npm:0.22.0"
|
||||
dependencies:
|
||||
"@lexical/utils": 0.16.0
|
||||
lexical: 0.16.0
|
||||
checksum: bb546181595b39180ce4b733f36ea34adf1b6f89cdee1ffd74b4ece4b299e9ef51a0b269e8eb90dcbff10b78f2f3ddd333d611a7c91defe218f2b717cf9ca93b
|
||||
"@lexical/utils": 0.22.0
|
||||
lexical: 0.22.0
|
||||
checksum: c3cf36c47b03944d90f67d4ced88f4e6702c629647e4e0ba70ee5fbcbd3fab424b7602f55b63c37bafdcc146fcaf2186348ed6fa08ef586ad6ce5d6320ba66a9
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@lexical/mark@npm:0.16.0":
|
||||
version: 0.16.0
|
||||
resolution: "@lexical/mark@npm:0.16.0"
|
||||
"@lexical/markdown@npm:0.22.0":
|
||||
version: 0.22.0
|
||||
resolution: "@lexical/markdown@npm:0.22.0"
|
||||
dependencies:
|
||||
"@lexical/utils": 0.16.0
|
||||
lexical: 0.16.0
|
||||
checksum: 08067e266d0518bce4aa402e73dc066a6be3af138a4cee76f2255725b2032248bdc4ebd98a85b19923c441853cfde154f12e3b87eae8ae203bca30f0e4d49700
|
||||
"@lexical/code": 0.22.0
|
||||
"@lexical/link": 0.22.0
|
||||
"@lexical/list": 0.22.0
|
||||
"@lexical/rich-text": 0.22.0
|
||||
"@lexical/text": 0.22.0
|
||||
"@lexical/utils": 0.22.0
|
||||
lexical: 0.22.0
|
||||
checksum: 0e2c371ead6434be1bc62eda95fe19a15a638382c659921f83bc41f5f2229de3f74982cc9ab1a9e7bcd5831fcd273d262f9d94d094300a4901ed48205f4dfafe
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@lexical/markdown@npm:0.16.0":
|
||||
version: 0.16.0
|
||||
resolution: "@lexical/markdown@npm:0.16.0"
|
||||
"@lexical/offset@npm:0.22.0":
|
||||
version: 0.22.0
|
||||
resolution: "@lexical/offset@npm:0.22.0"
|
||||
dependencies:
|
||||
"@lexical/code": 0.16.0
|
||||
"@lexical/link": 0.16.0
|
||||
"@lexical/list": 0.16.0
|
||||
"@lexical/rich-text": 0.16.0
|
||||
"@lexical/text": 0.16.0
|
||||
"@lexical/utils": 0.16.0
|
||||
lexical: 0.16.0
|
||||
checksum: 2d061e4a3b0f8eee0c7975cfff8043601a435aece33c06c0e717a639cf680fa68e3727b95247468cb55d81e1d8970ee8ea8b9348d8bef755b968dc306be19792
|
||||
lexical: 0.22.0
|
||||
checksum: 9172370f74f8c9f444a3bba778975de340b61d232d2736a392e2fa4506953819e9131f6369c4a03afe2f913a288fffca8267e09a0943521b57e7e6ddeefe4d63
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@lexical/offset@npm:0.16.0":
|
||||
version: 0.16.0
|
||||
resolution: "@lexical/offset@npm:0.16.0"
|
||||
"@lexical/overflow@npm:0.22.0":
|
||||
version: 0.22.0
|
||||
resolution: "@lexical/overflow@npm:0.22.0"
|
||||
dependencies:
|
||||
lexical: 0.16.0
|
||||
checksum: c6c581be2f084d20aa2b1ef7b0d3deaac9b4550792f9278a35427d493d35d68aaf7ec2eb4357b5defa61c50001928c74199d7867a94670cda648944451bfbfbf
|
||||
lexical: 0.22.0
|
||||
checksum: 9b486682927089e61de4243f7097da8f6c7f7cbf57e1c1da666b10e417c54a444459bc8daaca5b885c24d4cb427eb9ff1554606b01299c2bf645bf5a560b32f1
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@lexical/overflow@npm:0.16.0":
|
||||
version: 0.16.0
|
||||
resolution: "@lexical/overflow@npm:0.16.0"
|
||||
"@lexical/plain-text@npm:0.22.0":
|
||||
version: 0.22.0
|
||||
resolution: "@lexical/plain-text@npm:0.22.0"
|
||||
dependencies:
|
||||
lexical: 0.16.0
|
||||
checksum: 9b659e40537ffd09ab3f8a6ba7e61eb7adddaefb0dd4922d7cb912e2d94c606960a5d8e7737267fc36e95792526cb9b158f3605bedcdade0ce1594895ee0304b
|
||||
"@lexical/clipboard": 0.22.0
|
||||
"@lexical/selection": 0.22.0
|
||||
"@lexical/utils": 0.22.0
|
||||
lexical: 0.22.0
|
||||
checksum: 1093ebfc11f13b0767dab3c1e29c55fbaae6b1ff1979d5c66b0e07f8589a2ba602b5c40633575d90152031623dc3cf66a12c5915e6606974b925389e9cedc02b
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@lexical/plain-text@npm:0.16.0":
|
||||
version: 0.16.0
|
||||
resolution: "@lexical/plain-text@npm:0.16.0"
|
||||
"@lexical/react@npm:0.22.0":
|
||||
version: 0.22.0
|
||||
resolution: "@lexical/react@npm:0.22.0"
|
||||
dependencies:
|
||||
"@lexical/clipboard": 0.16.0
|
||||
"@lexical/selection": 0.16.0
|
||||
"@lexical/utils": 0.16.0
|
||||
lexical: 0.16.0
|
||||
checksum: 026a745849ed6cc6fe7b68cc1982f1be32fbe56c63a5afd27383f786482438cb38ab7b06d3e2cb8dfd0c689ea92d12ba6be62a453ea52c068e5df57c7489d453
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@lexical/react@npm:0.16.0":
|
||||
version: 0.16.0
|
||||
resolution: "@lexical/react@npm:0.16.0"
|
||||
dependencies:
|
||||
"@lexical/clipboard": 0.16.0
|
||||
"@lexical/code": 0.16.0
|
||||
"@lexical/devtools-core": 0.16.0
|
||||
"@lexical/dragon": 0.16.0
|
||||
"@lexical/hashtag": 0.16.0
|
||||
"@lexical/history": 0.16.0
|
||||
"@lexical/link": 0.16.0
|
||||
"@lexical/list": 0.16.0
|
||||
"@lexical/mark": 0.16.0
|
||||
"@lexical/markdown": 0.16.0
|
||||
"@lexical/overflow": 0.16.0
|
||||
"@lexical/plain-text": 0.16.0
|
||||
"@lexical/rich-text": 0.16.0
|
||||
"@lexical/selection": 0.16.0
|
||||
"@lexical/table": 0.16.0
|
||||
"@lexical/text": 0.16.0
|
||||
"@lexical/utils": 0.16.0
|
||||
"@lexical/yjs": 0.16.0
|
||||
lexical: 0.16.0
|
||||
"@lexical/clipboard": 0.22.0
|
||||
"@lexical/code": 0.22.0
|
||||
"@lexical/devtools-core": 0.22.0
|
||||
"@lexical/dragon": 0.22.0
|
||||
"@lexical/hashtag": 0.22.0
|
||||
"@lexical/history": 0.22.0
|
||||
"@lexical/link": 0.22.0
|
||||
"@lexical/list": 0.22.0
|
||||
"@lexical/mark": 0.22.0
|
||||
"@lexical/markdown": 0.22.0
|
||||
"@lexical/overflow": 0.22.0
|
||||
"@lexical/plain-text": 0.22.0
|
||||
"@lexical/rich-text": 0.22.0
|
||||
"@lexical/selection": 0.22.0
|
||||
"@lexical/table": 0.22.0
|
||||
"@lexical/text": 0.22.0
|
||||
"@lexical/utils": 0.22.0
|
||||
"@lexical/yjs": 0.22.0
|
||||
lexical: 0.22.0
|
||||
react-error-boundary: ^3.1.4
|
||||
peerDependencies:
|
||||
react: ">=17.x"
|
||||
react-dom: ">=17.x"
|
||||
checksum: a58988010f1ae2182b0779280e92086bfe9c36f15baf96d069b1c81da48595579afaf01bbf69ecb3a10fdad01a32eda134bfe5efde31e545711c68516a088018
|
||||
checksum: 6d4f56be0bac9f7dd31b9855cab97b4b24bb93a5d998e6065ab6d0bc987fde42d674fc608547e47c108ef31250c7c77a703943560dd5d980629604a582d019b1
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@lexical/rich-text@npm:0.16.0":
|
||||
version: 0.16.0
|
||||
resolution: "@lexical/rich-text@npm:0.16.0"
|
||||
"@lexical/rich-text@npm:0.22.0":
|
||||
version: 0.22.0
|
||||
resolution: "@lexical/rich-text@npm:0.22.0"
|
||||
dependencies:
|
||||
"@lexical/clipboard": 0.16.0
|
||||
"@lexical/selection": 0.16.0
|
||||
"@lexical/utils": 0.16.0
|
||||
lexical: 0.16.0
|
||||
checksum: 00318a6a7813406e7f1c3fe7509c622ecaeb336c4b3c8bfef428cc7aa4dd5a8af4d2110e4884b6880ea28663b97ab0e8a9b3e9282de3fc7aa4aba910d215431e
|
||||
"@lexical/clipboard": 0.22.0
|
||||
"@lexical/selection": 0.22.0
|
||||
"@lexical/utils": 0.22.0
|
||||
lexical: 0.22.0
|
||||
checksum: f7c7153b16406c41a4b770a11c6abb48eb919edb2e7cec36ffcebee4889e70110a0a03ee545572c96bf5f4dc1be233572fb4c2e0336016031460d203b486fa27
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@lexical/rich-text@patch:@lexical/rich-text@npm:0.16.0#.yarn/patches/@lexical-rich-text-npm-0.16.0-f484a17832.patch::locator=%40standardnotes%2Fapp-monorepo%40workspace%3A.":
|
||||
version: 0.16.0
|
||||
resolution: "@lexical/rich-text@patch:@lexical/rich-text@npm%3A0.16.0#.yarn/patches/@lexical-rich-text-npm-0.16.0-f484a17832.patch::version=0.16.0&hash=24f58c&locator=%40standardnotes%2Fapp-monorepo%40workspace%3A."
|
||||
"@lexical/rich-text@patch:@lexical/rich-text@npm:0.22.0#.yarn/patches/@lexical-rich-text-npm-0.22.0-1c32cc4b16.patch::locator=%40standardnotes%2Fapp-monorepo%40workspace%3A.":
|
||||
version: 0.22.0
|
||||
resolution: "@lexical/rich-text@patch:@lexical/rich-text@npm%3A0.22.0#.yarn/patches/@lexical-rich-text-npm-0.22.0-1c32cc4b16.patch::version=0.22.0&hash=d9e598&locator=%40standardnotes%2Fapp-monorepo%40workspace%3A."
|
||||
dependencies:
|
||||
"@lexical/clipboard": 0.16.0
|
||||
"@lexical/selection": 0.16.0
|
||||
"@lexical/utils": 0.16.0
|
||||
lexical: 0.16.0
|
||||
checksum: fb69c079641d385e4aa5f6568769051837fbd7dac9db264d10dcb95326bd79f94379cda43e157d53d7a01849722bd3ad82f15c7cff5f2fa365d203f41f5ad159
|
||||
"@lexical/clipboard": 0.22.0
|
||||
"@lexical/selection": 0.22.0
|
||||
"@lexical/utils": 0.22.0
|
||||
lexical: 0.22.0
|
||||
checksum: c6523beac513a4a654329813056e5e45a4ec089dcd7ba3767fcf7a8b6dab778725fdd1da1dc171929d15ca5afd7e57e4c36667df7b28e9cd1836c973dee5bb08
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@lexical/selection@npm:0.16.0":
|
||||
version: 0.16.0
|
||||
resolution: "@lexical/selection@npm:0.16.0"
|
||||
"@lexical/selection@npm:0.22.0":
|
||||
version: 0.22.0
|
||||
resolution: "@lexical/selection@npm:0.22.0"
|
||||
dependencies:
|
||||
lexical: 0.16.0
|
||||
checksum: fd4832f3b01018b4025706ea86ada3e3dd5a70e2b73722d993fb7e272c3fa2a339e22c914f5fb1836ae077a56daefc6b16dfa77477c56648135ef6ea5ba53f05
|
||||
lexical: 0.22.0
|
||||
checksum: 5c3f80944e8b55b911ddb08af3ff3529b0ce1708f9b86ba8a276ad248c61eea5df767e66c624efbab696941622e1114016fab06931f5f9340d2818fb93ed2d6f
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@lexical/table@npm:0.16.0":
|
||||
version: 0.16.0
|
||||
resolution: "@lexical/table@npm:0.16.0"
|
||||
"@lexical/table@npm:0.22.0":
|
||||
version: 0.22.0
|
||||
resolution: "@lexical/table@npm:0.22.0"
|
||||
dependencies:
|
||||
"@lexical/utils": 0.16.0
|
||||
lexical: 0.16.0
|
||||
checksum: 484b6c53dd62aa679f71c9f2b602463de8cf64974a4c6c7052798f1f995b2b8805f2da7a34895fcc73fdaa9938f7a3785ca92a954ba9d79c0c126c496551ad40
|
||||
"@lexical/clipboard": 0.22.0
|
||||
"@lexical/utils": 0.22.0
|
||||
lexical: 0.22.0
|
||||
checksum: 6a8e3564ef7431fd0928ac85fc0e2fb517c1d12a2464ed99a2738241aca53bd904bcf9d04ad434b6c9f0d086c5735173cd3ae4a7d25d3635c547d56a9b65dee6
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@lexical/text@npm:0.16.0":
|
||||
version: 0.16.0
|
||||
resolution: "@lexical/text@npm:0.16.0"
|
||||
"@lexical/text@npm:0.22.0":
|
||||
version: 0.22.0
|
||||
resolution: "@lexical/text@npm:0.22.0"
|
||||
dependencies:
|
||||
lexical: 0.16.0
|
||||
checksum: 60eadf8d4c037af3a53dfb8c1168949529e02d1a7aaf31876eb9f0a790c4bc9b0c46747535fc03974c6a637e9a6dd0026d556bb0f61e918ad72e811987d08b65
|
||||
lexical: 0.22.0
|
||||
checksum: 82857b6c3b6cc4f2ad2264f9c3e87656f94bfaf4f879d538dd09ef1b7bb4eaade9b61001cf94618617baa7aebc14cdce00ce5d4687e2732171c3c33032e245eb
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@lexical/utils@npm:0.16.0":
|
||||
version: 0.16.0
|
||||
resolution: "@lexical/utils@npm:0.16.0"
|
||||
"@lexical/utils@npm:0.22.0":
|
||||
version: 0.22.0
|
||||
resolution: "@lexical/utils@npm:0.22.0"
|
||||
dependencies:
|
||||
"@lexical/list": 0.16.0
|
||||
"@lexical/selection": 0.16.0
|
||||
"@lexical/table": 0.16.0
|
||||
lexical: 0.16.0
|
||||
checksum: b6696b83b9ef7027cd7b117c25e6d6e30266f73b892e72e9718e02190b925c050f51b83aae25782c7abc950b6ef31d89e3c09ae3e37cae82274fcd42c5a60958
|
||||
"@lexical/list": 0.22.0
|
||||
"@lexical/selection": 0.22.0
|
||||
"@lexical/table": 0.22.0
|
||||
lexical: 0.22.0
|
||||
checksum: 45e1e60f89e9dab45401db97ae1885260dad4436fefa1a2e752b7c3c1394322c3d28916c278e18c911a284676ab5cf850efb5cad2aa874281ee87a1ba31c409d
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@lexical/yjs@npm:0.16.0":
|
||||
version: 0.16.0
|
||||
resolution: "@lexical/yjs@npm:0.16.0"
|
||||
"@lexical/yjs@npm:0.22.0":
|
||||
version: 0.22.0
|
||||
resolution: "@lexical/yjs@npm:0.22.0"
|
||||
dependencies:
|
||||
"@lexical/offset": 0.16.0
|
||||
lexical: 0.16.0
|
||||
"@lexical/offset": 0.22.0
|
||||
"@lexical/selection": 0.22.0
|
||||
lexical: 0.22.0
|
||||
peerDependencies:
|
||||
yjs: ">=13.5.22"
|
||||
checksum: 906056977928fa605593ee9fb323e37905960f97b7ef59ae20065f7644b51db72ddb8ef8ae1020c0a0b9bec9c2b18ed276c32ee5f4aabe4bc811cb8be102e9ac
|
||||
checksum: 3ffe2fa446e542fd0af085ccbf015769ac65831977e3b3cbe3a37700442a7a042242d9cd2f27f078a4eaf09e76448c129a68aa05cc2b6808a813e0dee6b8de02
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
|
@ -8338,13 +8330,13 @@ __metadata:
|
|||
"@babel/plugin-transform-react-jsx": ^7.19.0
|
||||
"@babel/preset-env": "*"
|
||||
"@babel/preset-typescript": ^7.21.5
|
||||
"@lexical/clipboard": 0.16.0
|
||||
"@lexical/headless": 0.16.0
|
||||
"@lexical/link": 0.16.0
|
||||
"@lexical/list": 0.16.0
|
||||
"@lexical/react": 0.16.0
|
||||
"@lexical/rich-text": 0.16.0
|
||||
"@lexical/utils": 0.16.0
|
||||
"@lexical/clipboard": 0.22.0
|
||||
"@lexical/headless": 0.22.0
|
||||
"@lexical/link": 0.22.0
|
||||
"@lexical/list": 0.22.0
|
||||
"@lexical/react": 0.22.0
|
||||
"@lexical/rich-text": 0.22.0
|
||||
"@lexical/utils": 0.22.0
|
||||
"@pmmmwh/react-refresh-webpack-plugin": ^0.5.10
|
||||
"@radix-ui/react-slot": ^1.0.1
|
||||
"@react-pdf/renderer": ^3.3.2
|
||||
|
|
@ -8396,7 +8388,7 @@ __metadata:
|
|||
identity-obj-proxy: ^3.0.0
|
||||
jest: ^29.3.1
|
||||
jest-environment-jsdom: ^29.3.1
|
||||
lexical: 0.16.0
|
||||
lexical: 0.22.0
|
||||
lint-staged: ">=13"
|
||||
mini-css-extract-plugin: ^2.7.2
|
||||
minimatch: ^5.1.1
|
||||
|
|
@ -19442,10 +19434,10 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"lexical@npm:0.16.0":
|
||||
version: 0.16.0
|
||||
resolution: "lexical@npm:0.16.0"
|
||||
checksum: ef43cf65dd30e044f7bbab1e56078b8ebee70a4182e517d1379c190d90174c04550c86921780360ad154fc78ce11cdd859bb0b8824971d072a38e0833166fe18
|
||||
"lexical@npm:0.22.0":
|
||||
version: 0.22.0
|
||||
resolution: "lexical@npm:0.22.0"
|
||||
checksum: 54153b6d31b007f45181317c6d18117c107dae90493f02f06b82c28488f266329431878c2ffe1af2df2638d3de363f5020d7a5019436531b220c3e1dea608938
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue