@lexical/react 0.1.8 → 0.1.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/DEPRECATED_useLexical.dev.js +3 -38
- package/DEPRECATED_useLexical.prod.js +1 -2
- package/DEPRECATED_useLexicalAutoFormatter.dev.js +202 -74
- package/DEPRECATED_useLexicalAutoFormatter.prod.js +21 -16
- package/DEPRECATED_useLexicalCanShowPlaceholder.prod.js +1 -1
- package/DEPRECATED_useLexicalCharacterLimit.dev.js +23 -21
- package/DEPRECATED_useLexicalCharacterLimit.prod.js +8 -8
- package/DEPRECATED_useLexicalDecorators.prod.js +1 -1
- package/DEPRECATED_useLexicalEditor.dev.js +1 -25
- package/DEPRECATED_useLexicalEditor.prod.js +1 -1
- package/DEPRECATED_useLexicalEditorEvents.prod.js +1 -1
- package/DEPRECATED_useLexicalHistory.dev.js +18 -15
- package/DEPRECATED_useLexicalHistory.prod.js +7 -7
- package/DEPRECATED_useLexicalList.dev.js +6 -0
- package/DEPRECATED_useLexicalList.prod.js +1 -1
- package/DEPRECATED_useLexicalPlainText.dev.js +79 -70
- package/DEPRECATED_useLexicalPlainText.prod.js +15 -16
- package/DEPRECATED_useLexicalRichText.dev.js +124 -250
- package/DEPRECATED_useLexicalRichText.prod.js +25 -29
- package/LexicalAutoFormatterPlugin.dev.js +202 -74
- package/LexicalAutoFormatterPlugin.js.flow +10 -0
- package/LexicalAutoFormatterPlugin.prod.js +21 -17
- package/LexicalAutoLinkPlugin.js.flow +23 -0
- package/LexicalAutoLinkPlugin.prod.js +4 -4
- package/LexicalCharacterLimitPlugin.dev.js +23 -21
- package/LexicalCharacterLimitPlugin.js.flow +12 -0
- package/LexicalCharacterLimitPlugin.prod.js +9 -8
- package/LexicalClearEditorPlugin.dev.js +52 -0
- package/LexicalClearEditorPlugin.js +9 -0
- package/LexicalClearEditorPlugin.js.flow +14 -0
- package/LexicalClearEditorPlugin.prod.js +7 -0
- package/LexicalCollaborationPlugin.dev.js +31 -36
- package/LexicalCollaborationPlugin.js.flow +55 -0
- package/LexicalCollaborationPlugin.prod.js +7 -8
- package/LexicalComposer.dev.js +8 -6
- package/LexicalComposer.js.flow +23 -0
- package/LexicalComposer.prod.js +3 -3
- package/LexicalComposerContext.js.flow +27 -0
- package/LexicalComposerContext.prod.js +1 -1
- package/LexicalContentEditable.dev.js +14 -8
- package/LexicalContentEditable.js.flow +35 -0
- package/LexicalContentEditable.prod.js +3 -3
- package/LexicalHashtagPlugin.js.flow +20 -0
- package/LexicalHashtagPlugin.prod.js +1 -1
- package/LexicalHistoryPlugin.dev.js +18 -15
- package/LexicalHistoryPlugin.js.flow +34 -0
- package/LexicalHistoryPlugin.prod.js +7 -7
- package/LexicalHorizontalRuleNode.dev.js +66 -0
- package/LexicalHorizontalRuleNode.js +9 -0
- package/LexicalHorizontalRuleNode.js.flow +25 -0
- package/LexicalHorizontalRuleNode.prod.js +8 -0
- package/LexicalLinkPlugin.dev.js +0 -1
- package/LexicalLinkPlugin.js.flow +10 -0
- package/LexicalLinkPlugin.prod.js +3 -3
- package/LexicalListPlugin.dev.js +6 -0
- package/LexicalListPlugin.js.flow +10 -0
- package/LexicalListPlugin.prod.js +2 -2
- package/LexicalNestedComposer.js.flow +21 -0
- package/LexicalNestedComposer.prod.js +1 -1
- package/LexicalOnChangePlugin.js.flow +14 -0
- package/LexicalOnChangePlugin.prod.js +1 -1
- package/LexicalPlainTextPlugin.dev.js +72 -44
- package/LexicalPlainTextPlugin.js.flow +18 -0
- package/LexicalPlainTextPlugin.prod.js +12 -11
- package/LexicalRichTextPlugin.dev.js +115 -222
- package/LexicalRichTextPlugin.js.flow +18 -0
- package/LexicalRichTextPlugin.prod.js +21 -25
- package/LexicalTablePlugin.dev.js +43 -39
- package/LexicalTablePlugin.js.flow +10 -0
- package/LexicalTablePlugin.prod.js +4 -3
- package/LexicalTreeView.dev.js +10 -2
- package/LexicalTreeView.js.flow +19 -0
- package/LexicalTreeView.prod.js +9 -8
- package/README.md +0 -1
- package/package.json +5 -4
- package/useLexicalDecoratorMap.js.flow +16 -0
- package/useLexicalDecoratorMap.prod.js +1 -1
- package/useLexicalIsTextContentEmpty.js.flow +15 -0
- package/useLexicalIsTextContentEmpty.prod.js +1 -1
- package/useLexicalNodeSelection.dev.js +70 -0
- package/useLexicalNodeSelection.js +9 -0
- package/useLexicalNodeSelection.js.flow +14 -0
- package/useLexicalNodeSelection.prod.js +8 -0
- package/withSubscriptions.js.flow +13 -0
- package/withSubscriptions.prod.js +1 -1
- package/LexicalBootstrapPlugin.dev.js +0 -124
- package/LexicalBootstrapPlugin.js +0 -9
- package/LexicalBootstrapPlugin.prod.js +0 -8
- package/LexicalHorizontalRulePlugin.dev.js +0 -51
- package/LexicalHorizontalRulePlugin.js +0 -9
- package/LexicalHorizontalRulePlugin.prod.js +0 -7
|
@@ -10,10 +10,6 @@ var LexicalComposerContext = require('@lexical/react/LexicalComposerContext');
|
|
|
10
10
|
var React = require('react');
|
|
11
11
|
var lexical = require('lexical');
|
|
12
12
|
var reactDom = require('react-dom');
|
|
13
|
-
var list = require('@lexical/list');
|
|
14
|
-
var CodeNode = require('lexical/CodeNode');
|
|
15
|
-
var HeadingNode = require('lexical/HeadingNode');
|
|
16
|
-
var LinkNode = require('lexical/LinkNode');
|
|
17
13
|
|
|
18
14
|
/**
|
|
19
15
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
@@ -261,6 +257,12 @@ function $copyLeafNodeBranchToRoot(leaf, startingOffset, isLeftSide, range, node
|
|
|
261
257
|
}
|
|
262
258
|
|
|
263
259
|
function $cloneContents(selection) {
|
|
260
|
+
if (!lexical.$isRangeSelection(selection)) {
|
|
261
|
+
{
|
|
262
|
+
throw Error(`TODO`);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
264
266
|
const anchor = selection.anchor;
|
|
265
267
|
const focus = selection.focus;
|
|
266
268
|
const anchorOffset = anchor.getCharacterOffset();
|
|
@@ -298,7 +300,7 @@ function $cloneContents(selection) {
|
|
|
298
300
|
const firstNode = nodes[0];
|
|
299
301
|
const firstNodeParent = firstNode.getParent();
|
|
300
302
|
|
|
301
|
-
if (firstNodeParent !== null && !firstNodeParent.canBeEmpty()) {
|
|
303
|
+
if (firstNodeParent !== null && (!firstNodeParent.canBeEmpty() || lexical.$isRootNode(firstNodeParent))) {
|
|
302
304
|
const parentChildren = firstNodeParent.__children;
|
|
303
305
|
const parentChildrenLength = parentChildren.length;
|
|
304
306
|
|
|
@@ -354,7 +356,7 @@ function $moveCaretSelection(selection, isHoldingShift, isBackward, granularity)
|
|
|
354
356
|
}
|
|
355
357
|
function $isParentElementRTL(selection) {
|
|
356
358
|
const anchorNode = selection.anchor.getNode();
|
|
357
|
-
const parent = anchorNode.getParentOrThrow();
|
|
359
|
+
const parent = lexical.$isRootNode(anchorNode) ? anchorNode : anchorNode.getParentOrThrow();
|
|
358
360
|
return parent.getDirection() === 'rtl';
|
|
359
361
|
}
|
|
360
362
|
function $moveCharacter(selection, isHoldingShift, isBackward) {
|
|
@@ -370,195 +372,6 @@ function $moveCharacter(selection, isHoldingShift, isBackward) {
|
|
|
370
372
|
*
|
|
371
373
|
*
|
|
372
374
|
*/
|
|
373
|
-
function getPossibleDecoratorNode(focus, isBackward) {
|
|
374
|
-
const focusOffset = focus.offset;
|
|
375
|
-
|
|
376
|
-
if (focus.type === 'element') {
|
|
377
|
-
const block = focus.getNode();
|
|
378
|
-
return block.getChildAtIndex(isBackward ? focusOffset - 1 : focusOffset);
|
|
379
|
-
} else {
|
|
380
|
-
const focusNode = focus.getNode();
|
|
381
|
-
|
|
382
|
-
if (isBackward && focusOffset === 0 || !isBackward && focusOffset === focusNode.getTextContentSize()) {
|
|
383
|
-
return isBackward ? focusNode.getPreviousSibling() : focusNode.getNextSibling();
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
return null;
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
/**
|
|
391
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
392
|
-
*
|
|
393
|
-
* This source code is licensed under the MIT license found in the
|
|
394
|
-
* LICENSE file in the root directory of this source tree.
|
|
395
|
-
*
|
|
396
|
-
*
|
|
397
|
-
*/
|
|
398
|
-
|
|
399
|
-
const isCodeElement = div => {
|
|
400
|
-
return div.style.fontFamily.match('monospace') !== null;
|
|
401
|
-
};
|
|
402
|
-
|
|
403
|
-
const DOM_NODE_NAME_TO_LEXICAL_NODE = {
|
|
404
|
-
'#text': domNode => ({
|
|
405
|
-
node: lexical.$createTextNode(domNode.textContent)
|
|
406
|
-
}),
|
|
407
|
-
a: domNode => {
|
|
408
|
-
let node;
|
|
409
|
-
|
|
410
|
-
if (domNode instanceof HTMLAnchorElement) {
|
|
411
|
-
node = LinkNode.$createLinkNode(domNode.href);
|
|
412
|
-
} else {
|
|
413
|
-
node = lexical.$createTextNode(domNode.textContent);
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
return {
|
|
417
|
-
node
|
|
418
|
-
};
|
|
419
|
-
},
|
|
420
|
-
b: domNode => {
|
|
421
|
-
// $FlowFixMe[incompatible-type] domNode is a <b> since we matched it by nodeName
|
|
422
|
-
const b = domNode; // Google Docs wraps all copied HTML in a <b> with font-weight normal
|
|
423
|
-
|
|
424
|
-
const hasNormalFontWeight = b.style.fontWeight === 'normal';
|
|
425
|
-
return {
|
|
426
|
-
forChild: lexicalNode => {
|
|
427
|
-
if (lexical.$isTextNode(lexicalNode) && !hasNormalFontWeight) {
|
|
428
|
-
lexicalNode.toggleFormat('bold');
|
|
429
|
-
}
|
|
430
|
-
},
|
|
431
|
-
node: null
|
|
432
|
-
};
|
|
433
|
-
},
|
|
434
|
-
br: () => ({
|
|
435
|
-
node: lexical.$createLineBreakNode()
|
|
436
|
-
}),
|
|
437
|
-
div: domNode => {
|
|
438
|
-
// $FlowFixMe[incompatible-type] domNode is a <div> since we matched it by nodeName
|
|
439
|
-
const div = domNode;
|
|
440
|
-
return {
|
|
441
|
-
after: childLexicalNodes => {
|
|
442
|
-
const domParent = domNode.parentNode;
|
|
443
|
-
|
|
444
|
-
if (domParent != null && domNode !== domParent.lastChild) {
|
|
445
|
-
childLexicalNodes.push(lexical.$createLineBreakNode());
|
|
446
|
-
}
|
|
447
|
-
|
|
448
|
-
return childLexicalNodes;
|
|
449
|
-
},
|
|
450
|
-
node: isCodeElement(div) ? CodeNode.$createCodeNode() : null
|
|
451
|
-
};
|
|
452
|
-
},
|
|
453
|
-
em: domNode => {
|
|
454
|
-
return {
|
|
455
|
-
forChild: lexicalNode => {
|
|
456
|
-
if (lexical.$isTextNode(lexicalNode)) {
|
|
457
|
-
lexicalNode.toggleFormat('italic');
|
|
458
|
-
}
|
|
459
|
-
},
|
|
460
|
-
node: null
|
|
461
|
-
};
|
|
462
|
-
},
|
|
463
|
-
h1: () => ({
|
|
464
|
-
node: HeadingNode.$createHeadingNode('h1')
|
|
465
|
-
}),
|
|
466
|
-
h2: () => ({
|
|
467
|
-
node: HeadingNode.$createHeadingNode('h2')
|
|
468
|
-
}),
|
|
469
|
-
h3: () => ({
|
|
470
|
-
node: HeadingNode.$createHeadingNode('h3')
|
|
471
|
-
}),
|
|
472
|
-
h4: () => ({
|
|
473
|
-
node: HeadingNode.$createHeadingNode('h4')
|
|
474
|
-
}),
|
|
475
|
-
h5: () => ({
|
|
476
|
-
node: HeadingNode.$createHeadingNode('h5')
|
|
477
|
-
}),
|
|
478
|
-
i: domNode => {
|
|
479
|
-
return {
|
|
480
|
-
forChild: lexicalNode => {
|
|
481
|
-
if (lexical.$isTextNode(lexicalNode)) {
|
|
482
|
-
lexicalNode.toggleFormat('italic');
|
|
483
|
-
}
|
|
484
|
-
},
|
|
485
|
-
node: null
|
|
486
|
-
};
|
|
487
|
-
},
|
|
488
|
-
li: () => ({
|
|
489
|
-
node: list.$createListItemNode()
|
|
490
|
-
}),
|
|
491
|
-
ol: () => ({
|
|
492
|
-
node: list.$createListNode('ol')
|
|
493
|
-
}),
|
|
494
|
-
p: () => ({
|
|
495
|
-
node: lexical.$createParagraphNode()
|
|
496
|
-
}),
|
|
497
|
-
pre: domNode => ({
|
|
498
|
-
node: CodeNode.$createCodeNode()
|
|
499
|
-
}),
|
|
500
|
-
span: domNode => {
|
|
501
|
-
// $FlowFixMe[incompatible-type] domNode is a <span> since we matched it by nodeName
|
|
502
|
-
const span = domNode; // Google Docs uses span tags + font-weight for bold text
|
|
503
|
-
|
|
504
|
-
const hasBoldFontWeight = span.style.fontWeight === '700';
|
|
505
|
-
return {
|
|
506
|
-
forChild: lexicalNode => {
|
|
507
|
-
if (lexical.$isTextNode(lexicalNode) && hasBoldFontWeight) {
|
|
508
|
-
lexicalNode.toggleFormat('bold');
|
|
509
|
-
}
|
|
510
|
-
},
|
|
511
|
-
node: null
|
|
512
|
-
};
|
|
513
|
-
},
|
|
514
|
-
strong: domNode => {
|
|
515
|
-
return {
|
|
516
|
-
forChild: lexicalNode => {
|
|
517
|
-
if (lexical.$isTextNode(lexicalNode)) {
|
|
518
|
-
lexicalNode.toggleFormat('bold');
|
|
519
|
-
}
|
|
520
|
-
},
|
|
521
|
-
node: null
|
|
522
|
-
};
|
|
523
|
-
},
|
|
524
|
-
table: domNode => {
|
|
525
|
-
// $FlowFixMe[incompatible-type] domNode is a <table> since we matched it by nodeName
|
|
526
|
-
const table = domNode;
|
|
527
|
-
const isGitHubCodeTable = table.classList.contains('js-file-line-container');
|
|
528
|
-
return {
|
|
529
|
-
node: isGitHubCodeTable ? CodeNode.$createCodeNode() : null
|
|
530
|
-
};
|
|
531
|
-
},
|
|
532
|
-
td: domNode => {
|
|
533
|
-
// $FlowFixMe[incompatible-type] domNode is a <table> since we matched it by nodeName
|
|
534
|
-
const cell = domNode;
|
|
535
|
-
const isGitHubCodeCell = cell.classList.contains('js-file-line');
|
|
536
|
-
return {
|
|
537
|
-
after: childLexicalNodes => {
|
|
538
|
-
if (isGitHubCodeCell && cell.parentNode && cell.parentNode.nextSibling) {
|
|
539
|
-
// Append newline between code lines
|
|
540
|
-
childLexicalNodes.push(lexical.$createLineBreakNode());
|
|
541
|
-
}
|
|
542
|
-
|
|
543
|
-
return childLexicalNodes;
|
|
544
|
-
},
|
|
545
|
-
node: null
|
|
546
|
-
};
|
|
547
|
-
},
|
|
548
|
-
u: domNode => {
|
|
549
|
-
return {
|
|
550
|
-
forChild: lexicalNode => {
|
|
551
|
-
if (lexical.$isTextNode(lexicalNode)) {
|
|
552
|
-
lexicalNode.toggleFormat('underline');
|
|
553
|
-
}
|
|
554
|
-
},
|
|
555
|
-
node: null
|
|
556
|
-
};
|
|
557
|
-
},
|
|
558
|
-
ul: () => ({
|
|
559
|
-
node: list.$createListNode('ul')
|
|
560
|
-
})
|
|
561
|
-
};
|
|
562
375
|
|
|
563
376
|
function $generateNodes(nodeRange) {
|
|
564
377
|
const {
|
|
@@ -581,12 +394,34 @@ function $generateNodes(nodeRange) {
|
|
|
581
394
|
return nodes;
|
|
582
395
|
}
|
|
583
396
|
|
|
584
|
-
function
|
|
397
|
+
function getConversionFunction(domNode, editor) {
|
|
398
|
+
const {
|
|
399
|
+
nodeName
|
|
400
|
+
} = domNode;
|
|
401
|
+
|
|
402
|
+
const cachedConversions = editor._htmlConversions.get(nodeName.toLowerCase());
|
|
403
|
+
|
|
404
|
+
let currentConversion = null;
|
|
405
|
+
|
|
406
|
+
if (cachedConversions !== undefined) {
|
|
407
|
+
cachedConversions.forEach(cachedConversion => {
|
|
408
|
+
const domConversion = cachedConversion(domNode);
|
|
409
|
+
|
|
410
|
+
if (domConversion !== null) {
|
|
411
|
+
if (currentConversion === null || currentConversion.priority < domConversion.priority) {
|
|
412
|
+
currentConversion = domConversion;
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
});
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
return currentConversion !== null ? currentConversion.conversion : null;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
function $createNodesFromDOM(node, editor, forChildMap = new Map()) {
|
|
585
422
|
let lexicalNodes = [];
|
|
586
423
|
let currentLexicalNode = null;
|
|
587
|
-
const
|
|
588
|
-
const customHtmlTransforms = editor._config.htmlTransforms || {};
|
|
589
|
-
const transformFunction = customHtmlTransforms[nodeName] || conversionMap[nodeName];
|
|
424
|
+
const transformFunction = getConversionFunction(node, editor);
|
|
590
425
|
const transformOutput = transformFunction ? transformFunction(node) : null;
|
|
591
426
|
let postTransform = null;
|
|
592
427
|
|
|
@@ -604,7 +439,7 @@ function $createNodesFromDOM(node, conversionMap, editor, forChildMap = new Map(
|
|
|
604
439
|
}
|
|
605
440
|
|
|
606
441
|
if (transformOutput.forChild != null) {
|
|
607
|
-
forChildMap.set(nodeName, transformOutput.forChild);
|
|
442
|
+
forChildMap.set(node.nodeName, transformOutput.forChild);
|
|
608
443
|
}
|
|
609
444
|
} // If the DOM node doesn't have a transformer, we don't know what
|
|
610
445
|
// to do with it but we still need to process any childNodes.
|
|
@@ -614,7 +449,7 @@ function $createNodesFromDOM(node, conversionMap, editor, forChildMap = new Map(
|
|
|
614
449
|
let childLexicalNodes = [];
|
|
615
450
|
|
|
616
451
|
for (let i = 0; i < children.length; i++) {
|
|
617
|
-
childLexicalNodes.push(...$createNodesFromDOM(children[i],
|
|
452
|
+
childLexicalNodes.push(...$createNodesFromDOM(children[i], editor, forChildMap));
|
|
618
453
|
}
|
|
619
454
|
|
|
620
455
|
if (postTransform != null) {
|
|
@@ -636,13 +471,13 @@ function $createNodesFromDOM(node, conversionMap, editor, forChildMap = new Map(
|
|
|
636
471
|
return lexicalNodes;
|
|
637
472
|
}
|
|
638
473
|
|
|
639
|
-
function $generateNodesFromDOM(dom,
|
|
474
|
+
function $generateNodesFromDOM(dom, editor) {
|
|
640
475
|
let lexicalNodes = [];
|
|
641
476
|
const elements = dom.body ? Array.from(dom.body.childNodes) : [];
|
|
642
477
|
const elementsLength = elements.length;
|
|
643
478
|
|
|
644
479
|
for (let i = 0; i < elementsLength; i++) {
|
|
645
|
-
const lexicalNode = $createNodesFromDOM(elements[i],
|
|
480
|
+
const lexicalNode = $createNodesFromDOM(elements[i], editor);
|
|
646
481
|
|
|
647
482
|
if (lexicalNode !== null) {
|
|
648
483
|
lexicalNodes = lexicalNodes.concat(lexicalNode);
|
|
@@ -677,7 +512,7 @@ function $insertDataTransferForRichText(dataTransfer, selection, editor) {
|
|
|
677
512
|
if (htmlString) {
|
|
678
513
|
const parser = new DOMParser();
|
|
679
514
|
const dom = parser.parseFromString(htmlString, textHtmlMimeType);
|
|
680
|
-
const nodes = $generateNodesFromDOM(dom,
|
|
515
|
+
const nodes = $generateNodesFromDOM(dom, editor); // Wrap text and inline nodes in paragraph nodes so we have all blocks at the top-level
|
|
681
516
|
|
|
682
517
|
const topLevelBlocks = [];
|
|
683
518
|
let currentBlock = null;
|
|
@@ -714,17 +549,16 @@ function $insertDataTransferForPlainText(dataTransfer, selection) {
|
|
|
714
549
|
}
|
|
715
550
|
}
|
|
716
551
|
function $shouldOverrideDefaultCharacterSelection(selection, isBackward) {
|
|
717
|
-
const
|
|
718
|
-
return lexical.$isDecoratorNode(
|
|
552
|
+
const possibleNode = lexical.$getDecoratorNode(selection.focus, isBackward);
|
|
553
|
+
return lexical.$isDecoratorNode(possibleNode) && !possibleNode.isIsolated();
|
|
719
554
|
}
|
|
720
555
|
function onPasteForRichText(event, editor) {
|
|
721
556
|
event.preventDefault();
|
|
722
557
|
editor.update(() => {
|
|
723
|
-
lexical.$log('onPasteForRichText');
|
|
724
558
|
const selection = lexical.$getSelection();
|
|
725
559
|
const clipboardData = event.clipboardData;
|
|
726
560
|
|
|
727
|
-
if (clipboardData != null && selection
|
|
561
|
+
if (clipboardData != null && lexical.$isRangeSelection(selection)) {
|
|
728
562
|
$insertDataTransferForRichText(clipboardData, selection, editor);
|
|
729
563
|
}
|
|
730
564
|
});
|
|
@@ -732,10 +566,9 @@ function onPasteForRichText(event, editor) {
|
|
|
732
566
|
function onCutForRichText(event, editor) {
|
|
733
567
|
onCopyForRichText(event, editor);
|
|
734
568
|
editor.update(() => {
|
|
735
|
-
lexical.$log('onCutForRichText');
|
|
736
569
|
const selection = lexical.$getSelection();
|
|
737
570
|
|
|
738
|
-
if (selection
|
|
571
|
+
if (lexical.$isRangeSelection(selection)) {
|
|
739
572
|
selection.removeText();
|
|
740
573
|
}
|
|
741
574
|
});
|
|
@@ -743,7 +576,6 @@ function onCutForRichText(event, editor) {
|
|
|
743
576
|
function onCopyForRichText(event, editor) {
|
|
744
577
|
event.preventDefault();
|
|
745
578
|
editor.update(() => {
|
|
746
|
-
lexical.$log('onCopyForRichText');
|
|
747
579
|
const clipboardData = event.clipboardData;
|
|
748
580
|
const selection = lexical.$getSelection();
|
|
749
581
|
|
|
@@ -775,6 +607,62 @@ function onCopyForRichText(event, editor) {
|
|
|
775
607
|
});
|
|
776
608
|
}
|
|
777
609
|
|
|
610
|
+
/**
|
|
611
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
612
|
+
*
|
|
613
|
+
* This source code is licensed under the MIT license found in the
|
|
614
|
+
* LICENSE file in the root directory of this source tree.
|
|
615
|
+
*
|
|
616
|
+
*
|
|
617
|
+
*/
|
|
618
|
+
// Convoluted logic to make this work with Flow. Order matters.
|
|
619
|
+
const options = {
|
|
620
|
+
tag: 'history-merge'
|
|
621
|
+
};
|
|
622
|
+
const setEditorOptions = options;
|
|
623
|
+
const updateOptions = options;
|
|
624
|
+
function initializeEditor(editor, initialEditorState) {
|
|
625
|
+
if (initialEditorState === null) {
|
|
626
|
+
return;
|
|
627
|
+
} else if (initialEditorState === undefined) {
|
|
628
|
+
editor.update(() => {
|
|
629
|
+
const root = lexical.$getRoot();
|
|
630
|
+
const firstChild = root.getFirstChild();
|
|
631
|
+
|
|
632
|
+
if (firstChild === null) {
|
|
633
|
+
const paragraph = lexical.$createParagraphNode();
|
|
634
|
+
root.append(paragraph);
|
|
635
|
+
const activeElement = document.activeElement;
|
|
636
|
+
|
|
637
|
+
if (lexical.$getSelection() !== null || activeElement !== null && activeElement === editor.getRootElement()) {
|
|
638
|
+
paragraph.select();
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
}, updateOptions);
|
|
642
|
+
} else if (initialEditorState !== null) {
|
|
643
|
+
switch (typeof initialEditorState) {
|
|
644
|
+
case 'string':
|
|
645
|
+
{
|
|
646
|
+
const parsedEditorState = editor.parseEditorState(initialEditorState);
|
|
647
|
+
editor.setEditorState(parsedEditorState, setEditorOptions);
|
|
648
|
+
break;
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
case 'object':
|
|
652
|
+
{
|
|
653
|
+
editor.setEditorState(initialEditorState, setEditorOptions);
|
|
654
|
+
break;
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
case 'function':
|
|
658
|
+
{
|
|
659
|
+
editor.update(initialEditorState, updateOptions);
|
|
660
|
+
break;
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
|
|
778
666
|
/**
|
|
779
667
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
780
668
|
*
|
|
@@ -812,10 +700,9 @@ function useLexicalDragonSupport(editor) {
|
|
|
812
700
|
if (args) {
|
|
813
701
|
const [elementStart, elementLength, text, selStart, selLength, formatCommand] = args; // TODO: we should probably handle formatCommand somehow?
|
|
814
702
|
editor.update(() => {
|
|
815
|
-
lexical.$log('useLexicalDragonSupport');
|
|
816
703
|
const selection = lexical.$getSelection();
|
|
817
704
|
|
|
818
|
-
if (selection
|
|
705
|
+
if (lexical.$isRangeSelection(selection)) {
|
|
819
706
|
const anchor = selection.anchor;
|
|
820
707
|
let anchorNode = anchor.getNode();
|
|
821
708
|
let setSelStart = 0;
|
|
@@ -872,13 +759,17 @@ function useLexicalDragonSupport(editor) {
|
|
|
872
759
|
*
|
|
873
760
|
*
|
|
874
761
|
*/
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
useLayoutEffect(() => {
|
|
762
|
+
function useRichTextSetup(editor, initialEditorState) {
|
|
763
|
+
React.useLayoutEffect(() => {
|
|
878
764
|
const removeListener = editor.addListener('command', (type, payload) => {
|
|
879
765
|
const selection = lexical.$getSelection();
|
|
880
766
|
|
|
881
|
-
if (
|
|
767
|
+
if (type === 'click' && lexical.$isNodeSelection(selection)) {
|
|
768
|
+
selection.clear();
|
|
769
|
+
return true;
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
if (!lexical.$isRangeSelection(selection)) {
|
|
882
773
|
return false;
|
|
883
774
|
}
|
|
884
775
|
|
|
@@ -1107,9 +998,10 @@ function useRichTextSetup(editor) {
|
|
|
1107
998
|
}
|
|
1108
999
|
|
|
1109
1000
|
return false;
|
|
1110
|
-
},
|
|
1111
|
-
editor
|
|
1112
|
-
return removeListener;
|
|
1001
|
+
}, 0);
|
|
1002
|
+
initializeEditor(editor, initialEditorState);
|
|
1003
|
+
return removeListener; // We only do this for init
|
|
1004
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1113
1005
|
}, [editor]);
|
|
1114
1006
|
useLexicalDragonSupport(editor);
|
|
1115
1007
|
}
|
|
@@ -1124,11 +1016,12 @@ function useRichTextSetup(editor) {
|
|
|
1124
1016
|
*/
|
|
1125
1017
|
function RichTextPlugin({
|
|
1126
1018
|
contentEditable,
|
|
1127
|
-
placeholder
|
|
1019
|
+
placeholder,
|
|
1020
|
+
initialEditorState
|
|
1128
1021
|
}) {
|
|
1129
1022
|
const [editor] = LexicalComposerContext.useLexicalComposerContext();
|
|
1130
1023
|
const showPlaceholder = useLexicalCanShowPlaceholder(editor);
|
|
1131
|
-
useRichTextSetup(editor);
|
|
1024
|
+
useRichTextSetup(editor, initialEditorState);
|
|
1132
1025
|
const decorators = useDecorators(editor);
|
|
1133
1026
|
return /*#__PURE__*/React.createElement(React.Fragment, null, contentEditable, showPlaceholder && placeholder, decorators);
|
|
1134
1027
|
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
* @flow strict
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type {EditorState} from 'lexical';
|
|
11
|
+
|
|
12
|
+
type InitialEditorStateType = null | string | EditorState | (() => void);
|
|
13
|
+
|
|
14
|
+
declare export default function RichTextPlugin({
|
|
15
|
+
contentEditable: React$Node,
|
|
16
|
+
initialEditorState?: InitialEditorStateType,
|
|
17
|
+
placeholder: React$Node,
|
|
18
|
+
}): React$Node;
|
|
@@ -4,28 +4,24 @@
|
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
|
-
|
|
8
|
-
function
|
|
9
|
-
function
|
|
10
|
-
function
|
|
11
|
-
function
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
(
|
|
16
|
-
{
|
|
17
|
-
function
|
|
18
|
-
|
|
19
|
-
c)
|
|
20
|
-
function
|
|
21
|
-
function
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
d.anchor.getNode(),(x.$isElementNode(d)?d:d.getParentOrThrow()).setFormat(b),!0;case "insertLineBreak":return d.insertLineBreak(b),!0;case "insertParagraph":return d.insertParagraph(),!0;case "indentContent":return d=d.anchor,d="element"===d.type?d.getNode():d.getNode().getParentOrThrow(),d.canInsertTab()?a.execCommand("insertText","\t"):10!==d.getIndent()&&d.setIndent(d.getIndent()+1),!0;case "outdentContent":return d=d.anchor,b=d.getNode(),c="element"===d.type?d.getNode():d.getNode().getParentOrThrow(),
|
|
29
|
-
c.canInsertTab()?"\t"===b.getTextContent()[d.offset-1]&&a.execCommand("deleteCharacter",!0):0!==c.getIndent()&&c.setIndent(c.getIndent()-1),!0;case "keyArrowLeft":c=b.shiftKey;if(P(d,!0))return b.preventDefault(),b=c,c="rtl"===d.anchor.getNode().getParentOrThrow().getDirection(),d.modify(b?"extend":"move",!c,"character"),!0;break;case "keyArrowRight":c=b.shiftKey;if(P(d,!1))return b.preventDefault(),b=c,c="rtl"===d.anchor.getNode().getParentOrThrow().getDirection(),d.modify(b?"extend":"move",c,"character"),
|
|
30
|
-
!0;break;case "keyBackspace":return b.preventDefault(),{anchor:b}=d,d.isCollapsed()&&0===b.offset&&0<("element"===b.type?b.getNode():b.getNode().getParentOrThrow()).getIndent()?a.execCommand("outdentContent"):a.execCommand("deleteCharacter",!0);case "keyDelete":return b.preventDefault(),a.execCommand("deleteCharacter",!1);case "keyEnter":return b.preventDefault(),b.shiftKey?a.execCommand("insertLineBreak"):a.execCommand("insertParagraph");case "keyTab":return b.preventDefault(),a.execCommand(b.shiftKey?
|
|
31
|
-
"outdentContent":"indentContent");case "keyEscape":return a.blur(),!0;case "copy":return S(b,a),!0;case "cut":return R(b,a),!0;case "paste":return Q(b,a),!0;case "drop":case "dragstart":return b.preventDefault(),!0}return!1},0);a.execCommand("bootstrapEditor");return e},[a]);U(a)}module.exports=function({contentEditable:a,placeholder:e}){var [c]=g.useLexicalComposerContext();const b=I(c);V(c);c=J(c);return v.createElement(v.Fragment,null,a,b&&e,c)};
|
|
7
|
+
var g=require("@lexical/react/LexicalComposerContext"),u=require("react"),y=require("lexical"),z=require("react-dom");function A(a,e=!0){if(a)return!1;a=y.$getRoot().getTextContent();e&&(a=a.trim());return""===a}
|
|
8
|
+
function B(a){if(!A(a,!1))return!1;a=y.$getRoot().getChildren();const e=a.length;if(1<e)return!1;for(let c=0;c<e;c++){var f=a[c];if(y.$isElementNode(f)){if("paragraph"!==f.__type||0!==f.__indent)return!1;f=f.getChildren();const d=f.length;for(let b=0;b<d;b++)if(!y.$isTextNode(f[c]))return!1}}return!0}function C(a){return()=>B(a)}var D="undefined"!==typeof window&&"undefined"!==typeof window.document&&"undefined"!==typeof window.document.createElement?u.useLayoutEffect:u.useEffect;
|
|
9
|
+
function E(a){const [e,f]=u.useState(a.getEditorState().read(C(a.isComposing())));D(()=>a.addListener("update",({editorState:c})=>{const d=a.isComposing();c=c.read(C(d));f(c)}),[a]);return e}function F(a){const [e,f]=u.useState(()=>a.getDecorators());D(()=>a.addListener("decorator",c=>{z.flushSync(()=>{f(c)})}),[a]);return u.useMemo(()=>{const c=[],d=Object.keys(e);for(let k=0;k<d.length;k++){var b=d[k];const h=e[b];b=a.getElementByKey(b);null!==b&&c.push(z.createPortal(h,b))}return c},[e,a])}
|
|
10
|
+
function G(a){a=a.getLatest();const e=a.constructor.clone(a);e.__parent=a.__parent;y.$isElementNode(a)&&y.$isElementNode(e)?(e.__children=Array.from(a.__children),e.__format=a.__format,e.__indent=a.__indent,e.__dir=a.__dir):y.$isTextNode(a)&&y.$isTextNode(e)?(e.__format=a.__format,e.__style=a.__style,e.__mode=a.__mode,e.__detail=a.__detail):y.$isDecoratorNode(a)&&y.$isDecoratorNode(e)&&(e.__state=a.__state);return e}
|
|
11
|
+
function H(a,e,f,c,d){for(var b=e;null!==a;){for(e=a.getParent();null!==e&&e.excludeFromCopy();)e=e.getParent();if(null===e)break;if(!y.$isElementNode(a)||!a.excludeFromCopy()){const k=a.getKey();let h=d.get(k);const l=void 0===h;l&&(h=G(a),d.set(k,h));!y.$isTextNode(h)||h.isSegmented()||h.isToken()?y.$isElementNode(h)&&(h.__children=h.__children.slice(f?b:0,f?void 0:b+1)):h.__text=h.__text.slice(f?b:0,f?void 0:b);if(y.$isRootNode(e)){l&&c.push(k);break}}b=d.get(e.getKey());b=y.$isElementNode(b)?
|
|
12
|
+
b.__children.indexOf(a.getKey()):a.getIndexWithinParent();a=e}}function I(a){a=a.anchor.getNode();return"rtl"===(y.$isRootNode(a)?a:a.getParentOrThrow()).getDirection()}function J(a,e){const {nodeName:f}=a;e=e._htmlConversions.get(f.toLowerCase());let c=null;void 0!==e&&e.forEach(d=>{d=d(a);null!==d&&(null===c||c.priority<d.priority)&&(c=d)});return null!==c?c.conversion:null}
|
|
13
|
+
function K(a,e,f=new Map){let c=[],d=null;var b=J(a,e),k=b?b(a):null;b=null;if(null!==k){b=k.after;d=k.node;if(null!==d){c.push(d);var h=Array.from(f.values());for(let l=0;l<h.length;l++)h[l](d)}null!=k.forChild&&f.set(a.nodeName,k.forChild)}a=a.childNodes;k=[];for(h=0;h<a.length;h++)k.push(...K(a[h],e,f));null!=b&&(k=b(k));null==d?c=c.concat(k):y.$isElementNode(d)&&d.append(...k);return c}
|
|
14
|
+
function L(a,e,f){var c=a.getData("application/x-lexical-editor");if(c){var d=f._config.namespace;try{const l=JSON.parse(c);if(l.namespace===d){const {range:t,nodeMap:m}=l.state;var b=new Map(m);c=[];for(d=0;d<t.length;d++){var k=b.get(t[d]);if(void 0!==k){var h=y.$createNodeFromParse(k,b);c.push(h)}}e.insertNodes(c);return}}catch(l){}}if(b=a.getData("text/html")){b=(new DOMParser).parseFromString(b,"text/html");a=[];b=b.body?Array.from(b.body.childNodes):[];k=b.length;for(h=0;h<k;h++)c=K(b[h],f),
|
|
15
|
+
null!==c&&(a=a.concat(c));f=a;a=[];b=null;for(k=0;k<f.length;k++)h=f[k],!y.$isElementNode(h)||h.isInline()?(null===b&&(b=y.$createParagraphNode(),a.push(b)),null!==b&&b.append(h)):(a.push(h),b=null);e.insertNodes(a)}else f=a.getData("text/plain"),null!=f&&e.insertRawText(f)}function M(a,e){a=y.$getDecoratorNode(a.focus,e);return y.$isDecoratorNode(a)&&!a.isIsolated()}
|
|
16
|
+
function N(a,e){a.preventDefault();e.update(()=>{const f=y.$getSelection(),c=a.clipboardData;null!=c&&y.$isRangeSelection(f)&&L(c,f,e)})}function O(a,e){P(a,e);e.update(()=>{const f=y.$getSelection();y.$isRangeSelection(f)&&f.removeText()})}
|
|
17
|
+
function P(a,e){a.preventDefault();e.update(()=>{const f=a.clipboardData;var c=y.$getSelection();if(null!==c&&null!=f){var d=window.getSelection();if(!d.isCollapsed){var b=d.getRangeAt(0);b&&(d=document.createElement("div"),b=b.cloneContents(),d.appendChild(b),f.setData("text/html",d.innerHTML));f.setData("text/plain",c.getTextContent());d=e._config.namespace;b=f.setData;var k=JSON,h=k.stringify;{if(!y.$isRangeSelection(c))throw Error("Minified Lexical error #68; see codes.json for the full message or use the non-minified dev environment for full errors and additional helpful warnings.");
|
|
18
|
+
var l=c.anchor,t=c.focus;var m=l.getCharacterOffset();const x=t.getCharacterOffset();var n=l.getNode(),q=t.getNode(),p=n.getParentOrThrow();if(n===q&&y.$isTextNode(n)&&(p.canBeEmpty()||1<p.getChildrenSize()))c=G(n),n=x>m,c.__text=c.__text.slice(n?m:x,n?x:m),m=c.getKey(),m={nodeMap:[[m,c]],range:[m]};else if(c=c.getNodes(),0===c.length)m={nodeMap:[],range:[]};else{n=c.length;q=c[0];p=q.getParent();if(null!==p&&(!p.canBeEmpty()||y.$isRootNode(p))){var r=p.__children;if(r.length===n){var v=!0;for(var w=
|
|
19
|
+
0;w<r.length;w++)if(r[w]!==c[w].__key){v=!1;break}v&&(n++,c.push(p))}}p=c[n-1];l=l.isBefore(t);t=new Map;r=[];H(q,l?m:x,!0,r,t);for(q=0;q<n;q++)if(v=c[q],w=v.getKey(),!(t.has(w)||y.$isElementNode(v)&&v.excludeFromCopy())){const R=G(v);y.$isRootNode(v.getParent())&&r.push(v.getKey());t.set(w,R)}H(p,l?x:m,!1,r,t);m={nodeMap:Array.from(t.entries()),range:r}}}b.call(f,"application/x-lexical-editor",h.call(k,{namespace:d,state:m}))}}})}const Q={tag:"history-merge"};
|
|
20
|
+
function S(a,e){if(null!==e)if(void 0===e)a.update(()=>{var f=y.$getRoot();if(null===f.getFirstChild()){const c=y.$createParagraphNode();f.append(c);f=document.activeElement;(null!==y.$getSelection()||null!==f&&f===a.getRootElement())&&c.select()}},Q);else if(null!==e)switch(typeof e){case "string":e=a.parseEditorState(e);a.setEditorState(e,Q);break;case "object":a.setEditorState(e,Q);break;case "function":a.update(e,Q)}}
|
|
21
|
+
function T(a){u.useEffect(()=>{const e=f=>{var c=a.getRootElement();if(document.activeElement===c&&(c=f.data,"string"===typeof c)){try{var d=JSON.parse(c)}catch(b){return}if(d&&"nuanria_messaging"===d.protocol&&"request"===d.type&&(d=d.payload)&&"makeChanges"===d.functionId&&(d=d.args)){const [b,k,h,l,t]=d;a.update(()=>{const m=y.$getSelection();if(y.$isRangeSelection(m)){var n=m.anchor;let q=n.getNode(),p=0,r=0;y.$isTextNode(q)&&0<=b&&0<=k&&(p=b,r=b+k,m.setTextNodeRange(q,p,q,r));if(p!==r||""!==
|
|
22
|
+
h)m.insertRawText(h),q=n.getNode();y.$isTextNode(q)&&(p=l,r=l+t,n=q.getTextContentSize(),p=p>n?n:p,r=r>n?n:r,m.setTextNodeRange(q,p,q,r));f.stopImmediatePropagation()}})}}};window.addEventListener("message",e,!0);return()=>{window.removeEventListener("message",e,!0)}},[a])}
|
|
23
|
+
function U(a,e){u.useLayoutEffect(()=>{const f=a.addListener("command",(c,d)=>{var b=y.$getSelection();if("click"===c&&y.$isNodeSelection(b))return b.clear(),!0;if(!y.$isRangeSelection(b))return!1;switch(c){case "deleteCharacter":return b.deleteCharacter(d),!0;case "deleteWord":return b.deleteWord(d),!0;case "deleteLine":return b.deleteLine(d),!0;case "insertText":return"string"===typeof d?b.insertText(d):(c=d.dataTransfer,null!=c?L(c,b,a):(d=d.data)&&b.insertText(d)),!0;case "removeText":return b.removeText(),
|
|
24
|
+
!0;case "formatText":return b.formatText(d),!0;case "formatElement":return b=b.anchor.getNode(),(y.$isElementNode(b)?b:b.getParentOrThrow()).setFormat(d),!0;case "insertLineBreak":return b.insertLineBreak(d),!0;case "insertParagraph":return b.insertParagraph(),!0;case "indentContent":return b=b.anchor,b="element"===b.type?b.getNode():b.getNode().getParentOrThrow(),b.canInsertTab()?a.execCommand("insertText","\t"):10!==b.getIndent()&&b.setIndent(b.getIndent()+1),!0;case "outdentContent":return b=b.anchor,
|
|
25
|
+
d=b.getNode(),c="element"===b.type?b.getNode():b.getNode().getParentOrThrow(),c.canInsertTab()?"\t"===d.getTextContent()[b.offset-1]&&a.execCommand("deleteCharacter",!0):0!==c.getIndent()&&c.setIndent(c.getIndent()-1),!0;case "keyArrowLeft":c=d.shiftKey;if(M(b,!0))return d.preventDefault(),d=c,c=I(b),b.modify(d?"extend":"move",!c,"character"),!0;break;case "keyArrowRight":c=d.shiftKey;if(M(b,!1))return d.preventDefault(),d=c,c=I(b),b.modify(d?"extend":"move",c,"character"),!0;break;case "keyBackspace":return d.preventDefault(),
|
|
26
|
+
{anchor:d}=b,b.isCollapsed()&&0===d.offset&&0<("element"===d.type?d.getNode():d.getNode().getParentOrThrow()).getIndent()?a.execCommand("outdentContent"):a.execCommand("deleteCharacter",!0);case "keyDelete":return d.preventDefault(),a.execCommand("deleteCharacter",!1);case "keyEnter":return d.preventDefault(),d.shiftKey?a.execCommand("insertLineBreak"):a.execCommand("insertParagraph");case "keyTab":return d.preventDefault(),a.execCommand(d.shiftKey?"outdentContent":"indentContent");case "keyEscape":return a.blur(),
|
|
27
|
+
!0;case "copy":return P(d,a),!0;case "cut":return O(d,a),!0;case "paste":return N(d,a),!0;case "drop":case "dragstart":return d.preventDefault(),!0}return!1},0);S(a,e);return f},[a]);T(a)}module.exports=function({contentEditable:a,placeholder:e,initialEditorState:f}){const [c]=g.useLexicalComposerContext(),d=E(c);U(c,f);f=F(c);return u.createElement(u.Fragment,null,a,d&&e,f)};
|