@lexical/rich-text 0.8.1 → 0.9.1

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.
@@ -18,24 +18,26 @@ var lexical = require('lexical');
18
18
  * LICENSE file in the root directory of this source tree.
19
19
  *
20
20
  */
21
-
22
21
  function caretFromPoint(x, y) {
23
22
  if (typeof document.caretRangeFromPoint !== 'undefined') {
24
23
  const range = document.caretRangeFromPoint(x, y);
24
+
25
25
  if (range === null) {
26
26
  return null;
27
27
  }
28
+
28
29
  return {
29
30
  node: range.startContainer,
30
31
  offset: range.startOffset
31
- };
32
- // @ts-ignore
32
+ }; // @ts-ignore
33
33
  } else if (document.caretPositionFromPoint !== 'undefined') {
34
34
  // @ts-ignore FF - no types
35
35
  const range = document.caretPositionFromPoint(x, y);
36
+
36
37
  if (range === null) {
37
38
  return null;
38
39
  }
40
+
39
41
  return {
40
42
  node: range.offsetNode,
41
43
  offset: range.offset
@@ -53,7 +55,6 @@ function caretFromPoint(x, y) {
53
55
  * LICENSE file in the root directory of this source tree.
54
56
  *
55
57
  */
56
-
57
58
  const CAN_USE_DOM = typeof window !== 'undefined' && typeof window.document !== 'undefined' && typeof window.document.createElement !== 'undefined';
58
59
 
59
60
  /**
@@ -68,39 +69,41 @@ CAN_USE_DOM && /Mac|iPod|iPhone|iPad/.test(navigator.platform);
68
69
  CAN_USE_DOM && /^(?!.*Seamonkey)(?=.*Firefox).*/i.test(navigator.userAgent);
69
70
  const CAN_USE_BEFORE_INPUT = CAN_USE_DOM && 'InputEvent' in window && !documentMode ? 'getTargetRanges' in new window.InputEvent('input') : false;
70
71
  const IS_SAFARI = CAN_USE_DOM && /Version\/[\d.]+.*Safari/.test(navigator.userAgent);
71
- const IS_IOS = CAN_USE_DOM && /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
72
-
73
- // Keep these in case we need to use them in the future.
72
+ const IS_IOS = CAN_USE_DOM && /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream; // Keep these in case we need to use them in the future.
74
73
  // export const IS_WINDOWS: boolean = CAN_USE_DOM && /Win/.test(navigator.platform);
75
- const IS_CHROME = CAN_USE_DOM && /^(?=.*Chrome).*/i.test(navigator.userAgent);
76
- // export const canUseTextInputEvent: boolean = CAN_USE_DOM && 'TextEvent' in window && !documentMode;
74
+
75
+ const IS_CHROME = CAN_USE_DOM && /^(?=.*Chrome).*/i.test(navigator.userAgent); // export const canUseTextInputEvent: boolean = CAN_USE_DOM && 'TextEvent' in window && !documentMode;
77
76
 
78
77
  const IS_APPLE_WEBKIT = CAN_USE_DOM && /AppleWebKit\/[\d.]+/.test(navigator.userAgent) && !IS_CHROME;
79
78
 
80
79
  /** @module @lexical/rich-text */
81
80
  const DRAG_DROP_PASTE = lexical.createCommand('DRAG_DROP_PASTE_FILE');
81
+
82
82
  /** @noInheritDoc */
83
83
  class QuoteNode extends lexical.ElementNode {
84
84
  static getType() {
85
85
  return 'quote';
86
86
  }
87
+
87
88
  static clone(node) {
88
89
  return new QuoteNode(node.__key);
89
90
  }
91
+
90
92
  constructor(key) {
91
93
  super(key);
92
- }
94
+ } // View
93
95
 
94
- // View
95
96
 
96
97
  createDOM(config) {
97
98
  const element = document.createElement('blockquote');
98
99
  utils.addClassNamesToElement(element, config.theme.quote);
99
100
  return element;
100
101
  }
102
+
101
103
  updateDOM(prevNode, dom) {
102
104
  return false;
103
105
  }
106
+
104
107
  static importDOM() {
105
108
  return {
106
109
  blockquote: node => ({
@@ -109,6 +112,7 @@ class QuoteNode extends lexical.ElementNode {
109
112
  })
110
113
  };
111
114
  }
115
+
112
116
  static importJSON(serializedNode) {
113
117
  const node = $createQuoteNode();
114
118
  node.setFormat(serializedNode.format);
@@ -116,14 +120,13 @@ class QuoteNode extends lexical.ElementNode {
116
120
  node.setDirection(serializedNode.direction);
117
121
  return node;
118
122
  }
123
+
119
124
  exportJSON() {
120
- return {
121
- ...super.exportJSON(),
125
+ return { ...super.exportJSON(),
122
126
  type: 'quote'
123
127
  };
124
- }
128
+ } // Mutation
125
129
 
126
- // Mutation
127
130
 
128
131
  insertNewAfter(_, restoreSelection) {
129
132
  const newBlock = lexical.$createParagraphNode();
@@ -132,6 +135,7 @@ class QuoteNode extends lexical.ElementNode {
132
135
  this.insertAfter(newBlock, restoreSelection);
133
136
  return newBlock;
134
137
  }
138
+
135
139
  collapseAtStart() {
136
140
  const paragraph = lexical.$createParagraphNode();
137
141
  const children = this.getChildren();
@@ -139,6 +143,7 @@ class QuoteNode extends lexical.ElementNode {
139
143
  this.replace(paragraph);
140
144
  return true;
141
145
  }
146
+
142
147
  }
143
148
  function $createQuoteNode() {
144
149
  return lexical.$applyNodeReplacement(new QuoteNode());
@@ -146,40 +151,46 @@ function $createQuoteNode() {
146
151
  function $isQuoteNode(node) {
147
152
  return node instanceof QuoteNode;
148
153
  }
154
+
149
155
  /** @noInheritDoc */
150
156
  class HeadingNode extends lexical.ElementNode {
151
157
  /** @internal */
152
-
153
158
  static getType() {
154
159
  return 'heading';
155
160
  }
161
+
156
162
  static clone(node) {
157
163
  return new HeadingNode(node.__tag, node.__key);
158
164
  }
165
+
159
166
  constructor(tag, key) {
160
167
  super(key);
161
168
  this.__tag = tag;
162
169
  }
170
+
163
171
  getTag() {
164
172
  return this.__tag;
165
- }
173
+ } // View
166
174
 
167
- // View
168
175
 
169
176
  createDOM(config) {
170
177
  const tag = this.__tag;
171
178
  const element = document.createElement(tag);
172
179
  const theme = config.theme;
173
180
  const classNames = theme.heading;
181
+
174
182
  if (classNames !== undefined) {
175
183
  const className = classNames[tag];
176
184
  utils.addClassNamesToElement(element, className);
177
185
  }
186
+
178
187
  return element;
179
188
  }
189
+
180
190
  updateDOM(prevNode, dom) {
181
191
  return false;
182
192
  }
193
+
183
194
  static importDOM() {
184
195
  return {
185
196
  h1: node => ({
@@ -210,6 +221,7 @@ class HeadingNode extends lexical.ElementNode {
210
221
  // domNode is a <p> since we matched it by nodeName
211
222
  const paragraph = node;
212
223
  const firstChild = paragraph.firstChild;
224
+
213
225
  if (firstChild !== null && isGoogleDocsTitle(firstChild)) {
214
226
  return {
215
227
  conversion: () => ({
@@ -218,6 +230,7 @@ class HeadingNode extends lexical.ElementNode {
218
230
  priority: 3
219
231
  };
220
232
  }
233
+
221
234
  return null;
222
235
  },
223
236
  span: node => {
@@ -231,10 +244,12 @@ class HeadingNode extends lexical.ElementNode {
231
244
  priority: 3
232
245
  };
233
246
  }
247
+
234
248
  return null;
235
249
  }
236
250
  };
237
251
  }
252
+
238
253
  static importJSON(serializedNode) {
239
254
  const node = $createHeadingNode(serializedNode.tag);
240
255
  node.setFormat(serializedNode.format);
@@ -242,16 +257,16 @@ class HeadingNode extends lexical.ElementNode {
242
257
  node.setDirection(serializedNode.direction);
243
258
  return node;
244
259
  }
260
+
245
261
  exportJSON() {
246
- return {
247
- ...super.exportJSON(),
262
+ return { ...super.exportJSON(),
248
263
  tag: this.getTag(),
249
264
  type: 'heading',
250
265
  version: 1
251
266
  };
252
- }
267
+ } // Mutation
268
+
253
269
 
254
- // Mutation
255
270
  insertNewAfter(selection, restoreSelection = true) {
256
271
  const anchorOffet = selection ? selection.anchor.offset : 0;
257
272
  const newElement = anchorOffet > 0 && anchorOffet < this.getTextContentSize() ? $createHeadingNode(this.getTag()) : lexical.$createParagraphNode();
@@ -260,6 +275,7 @@ class HeadingNode extends lexical.ElementNode {
260
275
  this.insertAfter(newElement, restoreSelection);
261
276
  return newElement;
262
277
  }
278
+
263
279
  collapseAtStart() {
264
280
  const newElement = !this.isEmpty() ? $createHeadingNode(this.getTag()) : lexical.$createParagraphNode();
265
281
  const children = this.getChildren();
@@ -267,43 +283,54 @@ class HeadingNode extends lexical.ElementNode {
267
283
  this.replace(newElement);
268
284
  return true;
269
285
  }
286
+
270
287
  extractWithChild() {
271
288
  return true;
272
289
  }
290
+
273
291
  }
292
+
274
293
  function isGoogleDocsTitle(domNode) {
275
294
  if (domNode.nodeName.toLowerCase() === 'span') {
276
295
  return domNode.style.fontSize === '26pt';
277
296
  }
297
+
278
298
  return false;
279
299
  }
300
+
280
301
  function convertHeadingElement(domNode) {
281
302
  const nodeName = domNode.nodeName.toLowerCase();
282
303
  let node = null;
304
+
283
305
  if (nodeName === 'h1' || nodeName === 'h2' || nodeName === 'h3' || nodeName === 'h4' || nodeName === 'h5' || nodeName === 'h6') {
284
306
  node = $createHeadingNode(nodeName);
285
307
  }
308
+
286
309
  return {
287
310
  node
288
311
  };
289
312
  }
313
+
290
314
  function convertBlockquoteElement() {
291
315
  const node = $createQuoteNode();
292
316
  return {
293
317
  node
294
318
  };
295
319
  }
320
+
296
321
  function $createHeadingNode(headingTag) {
297
322
  return lexical.$applyNodeReplacement(new HeadingNode(headingTag));
298
323
  }
299
324
  function $isHeadingNode(node) {
300
325
  return node instanceof HeadingNode;
301
326
  }
327
+
302
328
  function onPasteForRichText(event, editor) {
303
329
  event.preventDefault();
304
330
  editor.update(() => {
305
331
  const selection = lexical.$getSelection();
306
332
  const clipboardData = event instanceof InputEvent || event instanceof KeyboardEvent ? null : event.clipboardData;
333
+
307
334
  if (clipboardData != null && (lexical.$isRangeSelection(selection) || lexical.DEPRECATED_$isGridSelection(selection))) {
308
335
  clipboard.$insertDataTransferForRichText(clipboardData, selection, editor);
309
336
  }
@@ -311,51 +338,63 @@ function onPasteForRichText(event, editor) {
311
338
  tag: 'paste'
312
339
  });
313
340
  }
341
+
314
342
  async function onCutForRichText(event, editor) {
315
- await clipboard.copyToClipboard__EXPERIMENTAL(editor, event instanceof ClipboardEvent ? event : null);
343
+ await clipboard.copyToClipboard(editor, event instanceof ClipboardEvent ? event : null);
316
344
  editor.update(() => {
317
345
  const selection = lexical.$getSelection();
346
+
318
347
  if (lexical.$isRangeSelection(selection)) {
319
348
  selection.removeText();
320
349
  } else if (lexical.$isNodeSelection(selection)) {
321
350
  selection.getNodes().forEach(node => node.remove());
322
351
  }
323
352
  });
324
- }
325
-
326
- // Clipboard may contain files that we aren't allowed to read. While the event is arguably useless,
353
+ } // Clipboard may contain files that we aren't allowed to read. While the event is arguably useless,
327
354
  // in certain ocassions, we want to know whether it was a file transfer, as opposed to text. We
328
355
  // control this with the first boolean flag.
356
+
357
+
329
358
  function eventFiles(event) {
330
359
  let dataTransfer = null;
360
+
331
361
  if (event instanceof DragEvent) {
332
362
  dataTransfer = event.dataTransfer;
333
363
  } else if (event instanceof ClipboardEvent) {
334
364
  dataTransfer = event.clipboardData;
335
365
  }
366
+
336
367
  if (dataTransfer === null) {
337
368
  return [false, [], false];
338
369
  }
370
+
339
371
  const types = dataTransfer.types;
340
372
  const hasFiles = types.includes('Files');
341
373
  const hasContent = types.includes('text/html') || types.includes('text/plain');
342
374
  return [hasFiles, Array.from(dataTransfer.files), hasContent];
343
375
  }
376
+
344
377
  function handleIndentAndOutdent(insertTab, indentOrOutdent) {
345
378
  const selection = lexical.$getSelection();
379
+
346
380
  if (!lexical.$isRangeSelection(selection)) {
347
381
  return;
348
382
  }
383
+
349
384
  const alreadyHandled = new Set();
350
385
  const nodes = selection.getNodes();
386
+
351
387
  for (let i = 0; i < nodes.length; i++) {
352
388
  const node = nodes[i];
353
389
  const key = node.getKey();
390
+
354
391
  if (alreadyHandled.has(key)) {
355
392
  continue;
356
393
  }
394
+
357
395
  const parentBlock = utils.$getNearestBlockElementAncestorOrThrow(node);
358
396
  const parentKey = parentBlock.getKey();
397
+
359
398
  if (parentBlock.canInsertTab()) {
360
399
  insertTab(node);
361
400
  alreadyHandled.add(key);
@@ -365,45 +404,57 @@ function handleIndentAndOutdent(insertTab, indentOrOutdent) {
365
404
  }
366
405
  }
367
406
  }
407
+
368
408
  function $isTargetWithinDecorator(target) {
369
409
  const node = lexical.$getNearestNodeFromDOMNode(target);
370
410
  return lexical.$isDecoratorNode(node);
371
411
  }
412
+
372
413
  function $isSelectionAtEndOfRoot(selection) {
373
414
  const focus = selection.focus;
374
415
  return focus.key === 'root' && focus.offset === lexical.$getRoot().getChildrenSize();
375
416
  }
417
+
376
418
  function registerRichText(editor) {
377
419
  const removeListener = utils.mergeRegister(editor.registerCommand(lexical.CLICK_COMMAND, payload => {
378
420
  const selection = lexical.$getSelection();
421
+
379
422
  if (lexical.$isNodeSelection(selection)) {
380
423
  selection.clear();
381
424
  return true;
382
425
  }
426
+
383
427
  return false;
384
428
  }, 0), editor.registerCommand(lexical.DELETE_CHARACTER_COMMAND, isBackward => {
385
429
  const selection = lexical.$getSelection();
430
+
386
431
  if (!lexical.$isRangeSelection(selection)) {
387
432
  return false;
388
433
  }
434
+
389
435
  selection.deleteCharacter(isBackward);
390
436
  return true;
391
437
  }, lexical.COMMAND_PRIORITY_EDITOR), editor.registerCommand(lexical.DELETE_WORD_COMMAND, isBackward => {
392
438
  const selection = lexical.$getSelection();
439
+
393
440
  if (!lexical.$isRangeSelection(selection)) {
394
441
  return false;
395
442
  }
443
+
396
444
  selection.deleteWord(isBackward);
397
445
  return true;
398
446
  }, lexical.COMMAND_PRIORITY_EDITOR), editor.registerCommand(lexical.DELETE_LINE_COMMAND, isBackward => {
399
447
  const selection = lexical.$getSelection();
448
+
400
449
  if (!lexical.$isRangeSelection(selection)) {
401
450
  return false;
402
451
  }
452
+
403
453
  selection.deleteLine(isBackward);
404
454
  return true;
405
455
  }, lexical.COMMAND_PRIORITY_EDITOR), editor.registerCommand(lexical.CONTROLLED_TEXT_INSERTION_COMMAND, eventOrText => {
406
456
  const selection = lexical.$getSelection();
457
+
407
458
  if (typeof eventOrText === 'string') {
408
459
  if (lexical.$isRangeSelection(selection)) {
409
460
  selection.insertText(eventOrText);
@@ -412,55 +463,72 @@ function registerRichText(editor) {
412
463
  if (!lexical.$isRangeSelection(selection) && !lexical.DEPRECATED_$isGridSelection(selection)) {
413
464
  return false;
414
465
  }
466
+
415
467
  const dataTransfer = eventOrText.dataTransfer;
468
+
416
469
  if (dataTransfer != null) {
417
470
  clipboard.$insertDataTransferForRichText(dataTransfer, selection, editor);
418
471
  } else if (lexical.$isRangeSelection(selection)) {
419
472
  const data = eventOrText.data;
473
+
420
474
  if (data) {
421
475
  selection.insertText(data);
422
476
  }
477
+
423
478
  return true;
424
479
  }
425
480
  }
481
+
426
482
  return true;
427
483
  }, lexical.COMMAND_PRIORITY_EDITOR), editor.registerCommand(lexical.REMOVE_TEXT_COMMAND, () => {
428
484
  const selection = lexical.$getSelection();
485
+
429
486
  if (!lexical.$isRangeSelection(selection)) {
430
487
  return false;
431
488
  }
489
+
432
490
  selection.removeText();
433
491
  return true;
434
492
  }, lexical.COMMAND_PRIORITY_EDITOR), editor.registerCommand(lexical.FORMAT_TEXT_COMMAND, format => {
435
493
  const selection = lexical.$getSelection();
494
+
436
495
  if (!lexical.$isRangeSelection(selection)) {
437
496
  return false;
438
497
  }
498
+
439
499
  selection.formatText(format);
440
500
  return true;
441
501
  }, lexical.COMMAND_PRIORITY_EDITOR), editor.registerCommand(lexical.FORMAT_ELEMENT_COMMAND, format => {
442
502
  const selection = lexical.$getSelection();
503
+
443
504
  if (!lexical.$isRangeSelection(selection) && !lexical.$isNodeSelection(selection)) {
444
505
  return false;
445
506
  }
507
+
446
508
  const nodes = selection.getNodes();
509
+
447
510
  for (const node of nodes) {
448
511
  const element = utils.$getNearestBlockElementAncestorOrThrow(node);
449
512
  element.setFormat(format);
450
513
  }
514
+
451
515
  return true;
452
516
  }, lexical.COMMAND_PRIORITY_EDITOR), editor.registerCommand(lexical.INSERT_LINE_BREAK_COMMAND, selectStart => {
453
517
  const selection = lexical.$getSelection();
518
+
454
519
  if (!lexical.$isRangeSelection(selection)) {
455
520
  return false;
456
521
  }
522
+
457
523
  selection.insertLineBreak(selectStart);
458
524
  return true;
459
525
  }, lexical.COMMAND_PRIORITY_EDITOR), editor.registerCommand(lexical.INSERT_PARAGRAPH_COMMAND, () => {
460
526
  const selection = lexical.$getSelection();
527
+
461
528
  if (!lexical.$isRangeSelection(selection)) {
462
529
  return false;
463
530
  }
531
+
464
532
  selection.insertParagraph();
465
533
  return true;
466
534
  }, lexical.COMMAND_PRIORITY_EDITOR), editor.registerCommand(lexical.INDENT_CONTENT_COMMAND, () => {
@@ -468,6 +536,7 @@ function registerRichText(editor) {
468
536
  editor.dispatchCommand(lexical.CONTROLLED_TEXT_INSERTION_COMMAND, '\t');
469
537
  }, block => {
470
538
  const indent = block.getIndent();
539
+
471
540
  if (indent !== 10) {
472
541
  block.setIndent(indent + 1);
473
542
  }
@@ -478,12 +547,14 @@ function registerRichText(editor) {
478
547
  if (lexical.$isTextNode(node)) {
479
548
  const textContent = node.getTextContent();
480
549
  const character = textContent[textContent.length - 1];
550
+
481
551
  if (character === '\t') {
482
552
  editor.dispatchCommand(lexical.DELETE_CHARACTER_COMMAND, true);
483
553
  }
484
554
  }
485
555
  }, block => {
486
556
  const indent = block.getIndent();
557
+
487
558
  if (indent !== 0) {
488
559
  block.setIndent(indent - 1);
489
560
  }
@@ -491,16 +562,19 @@ function registerRichText(editor) {
491
562
  return true;
492
563
  }, lexical.COMMAND_PRIORITY_EDITOR), editor.registerCommand(lexical.KEY_ARROW_UP_COMMAND, event => {
493
564
  const selection = lexical.$getSelection();
565
+
494
566
  if (lexical.$isNodeSelection(selection) && !$isTargetWithinDecorator(event.target)) {
495
567
  // If selection is on a node, let's try and move selection
496
568
  // back to being a range selection.
497
569
  const nodes = selection.getNodes();
570
+
498
571
  if (nodes.length > 0) {
499
572
  nodes[0].selectPrevious();
500
573
  return true;
501
574
  }
502
575
  } else if (lexical.$isRangeSelection(selection)) {
503
576
  const possibleNode = lexical.$getAdjacentNode(selection.focus, true);
577
+
504
578
  if (lexical.$isDecoratorNode(possibleNode) && !possibleNode.isIsolated() && !possibleNode.isInline()) {
505
579
  possibleNode.selectPrevious();
506
580
  event.preventDefault();
@@ -511,13 +585,16 @@ function registerRichText(editor) {
511
585
  return true;
512
586
  }
513
587
  }
588
+
514
589
  return false;
515
590
  }, lexical.COMMAND_PRIORITY_EDITOR), editor.registerCommand(lexical.KEY_ARROW_DOWN_COMMAND, event => {
516
591
  const selection = lexical.$getSelection();
592
+
517
593
  if (lexical.$isNodeSelection(selection)) {
518
594
  // If selection is on a node, let's try and move selection
519
595
  // back to being a range selection.
520
596
  const nodes = selection.getNodes();
597
+
521
598
  if (nodes.length > 0) {
522
599
  nodes[0].selectNext(0, 0);
523
600
  return true;
@@ -527,93 +604,118 @@ function registerRichText(editor) {
527
604
  event.preventDefault();
528
605
  return true;
529
606
  }
607
+
530
608
  const possibleNode = lexical.$getAdjacentNode(selection.focus, false);
609
+
531
610
  if (lexical.$isDecoratorNode(possibleNode) && !possibleNode.isIsolated() && !possibleNode.isInline()) {
532
611
  possibleNode.selectNext();
533
612
  event.preventDefault();
534
613
  return true;
535
614
  }
536
615
  }
616
+
537
617
  return false;
538
618
  }, lexical.COMMAND_PRIORITY_EDITOR), editor.registerCommand(lexical.KEY_ARROW_LEFT_COMMAND, event => {
539
619
  const selection$1 = lexical.$getSelection();
620
+
540
621
  if (lexical.$isNodeSelection(selection$1)) {
541
622
  // If selection is on a node, let's try and move selection
542
623
  // back to being a range selection.
543
624
  const nodes = selection$1.getNodes();
625
+
544
626
  if (nodes.length > 0) {
545
627
  event.preventDefault();
546
628
  nodes[0].selectPrevious();
547
629
  return true;
548
630
  }
549
631
  }
632
+
550
633
  if (!lexical.$isRangeSelection(selection$1)) {
551
634
  return false;
552
635
  }
636
+
553
637
  if (selection.$shouldOverrideDefaultCharacterSelection(selection$1, true)) {
554
638
  const isHoldingShift = event.shiftKey;
555
639
  event.preventDefault();
556
640
  selection.$moveCharacter(selection$1, isHoldingShift, true);
557
641
  return true;
558
642
  }
643
+
559
644
  return false;
560
645
  }, lexical.COMMAND_PRIORITY_EDITOR), editor.registerCommand(lexical.KEY_ARROW_RIGHT_COMMAND, event => {
561
646
  const selection$1 = lexical.$getSelection();
647
+
562
648
  if (lexical.$isNodeSelection(selection$1) && !$isTargetWithinDecorator(event.target)) {
563
649
  // If selection is on a node, let's try and move selection
564
650
  // back to being a range selection.
565
651
  const nodes = selection$1.getNodes();
652
+
566
653
  if (nodes.length > 0) {
567
654
  event.preventDefault();
568
655
  nodes[0].selectNext(0, 0);
569
656
  return true;
570
657
  }
571
658
  }
659
+
572
660
  if (!lexical.$isRangeSelection(selection$1)) {
573
661
  return false;
574
662
  }
663
+
575
664
  const isHoldingShift = event.shiftKey;
665
+
576
666
  if (selection.$shouldOverrideDefaultCharacterSelection(selection$1, false)) {
577
667
  event.preventDefault();
578
668
  selection.$moveCharacter(selection$1, isHoldingShift, false);
579
669
  return true;
580
670
  }
671
+
581
672
  return false;
582
673
  }, lexical.COMMAND_PRIORITY_EDITOR), editor.registerCommand(lexical.KEY_BACKSPACE_COMMAND, event => {
583
674
  if ($isTargetWithinDecorator(event.target)) {
584
675
  return false;
585
676
  }
677
+
586
678
  const selection = lexical.$getSelection();
679
+
587
680
  if (!lexical.$isRangeSelection(selection)) {
588
681
  return false;
589
682
  }
683
+
590
684
  event.preventDefault();
591
685
  const {
592
686
  anchor
593
687
  } = selection;
594
688
  const anchorNode = anchor.getNode();
689
+
595
690
  if (selection.isCollapsed() && anchor.offset === 0 && !lexical.$isRootNode(anchorNode)) {
596
691
  const element = utils.$getNearestBlockElementAncestorOrThrow(anchorNode);
692
+
597
693
  if (element.getIndent() > 0) {
598
694
  return editor.dispatchCommand(lexical.OUTDENT_CONTENT_COMMAND, undefined);
599
695
  }
600
696
  }
697
+
601
698
  return editor.dispatchCommand(lexical.DELETE_CHARACTER_COMMAND, true);
602
699
  }, lexical.COMMAND_PRIORITY_EDITOR), editor.registerCommand(lexical.KEY_DELETE_COMMAND, event => {
603
700
  if ($isTargetWithinDecorator(event.target)) {
604
701
  return false;
605
702
  }
703
+
606
704
  const selection = lexical.$getSelection();
705
+
607
706
  if (!lexical.$isRangeSelection(selection)) {
608
707
  return false;
609
708
  }
709
+
610
710
  event.preventDefault();
611
711
  return editor.dispatchCommand(lexical.DELETE_CHARACTER_COMMAND, false);
612
712
  }, lexical.COMMAND_PRIORITY_EDITOR), editor.registerCommand(lexical.KEY_ENTER_COMMAND, event => {
613
713
  const selection = lexical.$getSelection();
714
+
614
715
  if (!lexical.$isRangeSelection(selection)) {
615
716
  return false;
616
717
  }
718
+
617
719
  if (event !== null) {
618
720
  // If we have beforeinput, then we can avoid blocking
619
721
  // the default behavior. This ensures that the iOS can
@@ -625,33 +727,42 @@ function registerRichText(editor) {
625
727
  if ((IS_IOS || IS_SAFARI || IS_APPLE_WEBKIT) && CAN_USE_BEFORE_INPUT) {
626
728
  return false;
627
729
  }
730
+
628
731
  event.preventDefault();
732
+
629
733
  if (event.shiftKey) {
630
734
  return editor.dispatchCommand(lexical.INSERT_LINE_BREAK_COMMAND, false);
631
735
  }
632
736
  }
737
+
633
738
  return editor.dispatchCommand(lexical.INSERT_PARAGRAPH_COMMAND, undefined);
634
739
  }, lexical.COMMAND_PRIORITY_EDITOR), editor.registerCommand(lexical.KEY_ESCAPE_COMMAND, () => {
635
740
  const selection = lexical.$getSelection();
741
+
636
742
  if (!lexical.$isRangeSelection(selection)) {
637
743
  return false;
638
744
  }
745
+
639
746
  editor.blur();
640
747
  return true;
641
748
  }, lexical.COMMAND_PRIORITY_EDITOR), editor.registerCommand(lexical.DROP_COMMAND, event => {
642
749
  const [, files] = eventFiles(event);
750
+
643
751
  if (files.length > 0) {
644
752
  const x = event.clientX;
645
753
  const y = event.clientY;
646
754
  const eventRange = caretFromPoint(x, y);
755
+
647
756
  if (eventRange !== null) {
648
757
  const {
649
758
  offset: domOffset,
650
759
  node: domNode
651
760
  } = eventRange;
652
761
  const node = lexical.$getNearestNodeFromDOMNode(domNode);
762
+
653
763
  if (node !== null) {
654
764
  const selection = lexical.$createRangeSelection();
765
+
655
766
  if (lexical.$isTextNode(node)) {
656
767
  selection.anchor.set(node.getKey(), domOffset, 'text');
657
768
  selection.focus.set(node.getKey(), domOffset, 'text');
@@ -661,61 +772,78 @@ function registerRichText(editor) {
661
772
  selection.anchor.set(parentKey, offset, 'element');
662
773
  selection.focus.set(parentKey, offset, 'element');
663
774
  }
775
+
664
776
  const normalizedSelection = lexical.$normalizeSelection__EXPERIMENTAL(selection);
665
777
  lexical.$setSelection(normalizedSelection);
666
778
  }
779
+
667
780
  editor.dispatchCommand(DRAG_DROP_PASTE, files);
668
781
  }
782
+
669
783
  event.preventDefault();
670
784
  return true;
671
785
  }
786
+
672
787
  const selection = lexical.$getSelection();
788
+
673
789
  if (lexical.$isRangeSelection(selection)) {
674
790
  return true;
675
791
  }
792
+
676
793
  return false;
677
794
  }, lexical.COMMAND_PRIORITY_EDITOR), editor.registerCommand(lexical.DRAGSTART_COMMAND, event => {
678
795
  const [isFileTransfer] = eventFiles(event);
679
796
  const selection = lexical.$getSelection();
797
+
680
798
  if (isFileTransfer && !lexical.$isRangeSelection(selection)) {
681
799
  return false;
682
800
  }
801
+
683
802
  return true;
684
803
  }, lexical.COMMAND_PRIORITY_EDITOR), editor.registerCommand(lexical.DRAGOVER_COMMAND, event => {
685
804
  const [isFileTransfer] = eventFiles(event);
686
805
  const selection = lexical.$getSelection();
806
+
687
807
  if (isFileTransfer && !lexical.$isRangeSelection(selection)) {
688
808
  return false;
689
809
  }
810
+
690
811
  const x = event.clientX;
691
812
  const y = event.clientY;
692
813
  const eventRange = caretFromPoint(x, y);
814
+
693
815
  if (eventRange !== null) {
694
816
  const node = lexical.$getNearestNodeFromDOMNode(eventRange.node);
817
+
695
818
  if (lexical.$isDecoratorNode(node)) {
696
819
  // Show browser caret as the user is dragging the media across the screen. Won't work
697
820
  // for DecoratorNode nor it's relevant.
698
821
  event.preventDefault();
699
822
  }
700
823
  }
824
+
701
825
  return true;
702
826
  }, lexical.COMMAND_PRIORITY_EDITOR), editor.registerCommand(lexical.COPY_COMMAND, event => {
703
- clipboard.copyToClipboard__EXPERIMENTAL(editor, event instanceof ClipboardEvent ? event : null);
827
+ clipboard.copyToClipboard(editor, event instanceof ClipboardEvent ? event : null);
704
828
  return true;
705
829
  }, lexical.COMMAND_PRIORITY_EDITOR), editor.registerCommand(lexical.CUT_COMMAND, event => {
706
830
  onCutForRichText(event, editor);
707
831
  return true;
708
832
  }, lexical.COMMAND_PRIORITY_EDITOR), editor.registerCommand(lexical.PASTE_COMMAND, event => {
709
833
  const [, files, hasTextContent] = eventFiles(event);
834
+
710
835
  if (files.length > 0 && !hasTextContent) {
711
836
  editor.dispatchCommand(DRAG_DROP_PASTE, files);
712
837
  return true;
713
838
  }
839
+
714
840
  const selection = lexical.$getSelection();
841
+
715
842
  if (lexical.$isRangeSelection(selection) || lexical.DEPRECATED_$isGridSelection(selection)) {
716
843
  onPasteForRichText(event, editor);
717
844
  return true;
718
845
  }
846
+
719
847
  return false;
720
848
  }, lexical.COMMAND_PRIORITY_EDITOR));
721
849
  return removeListener;
@@ -13,7 +13,7 @@ class D extends l.ElementNode{static getType(){return"heading"}static clone(c){r
13
13
  priority:0}),h6:()=>({conversion:E,priority:0}),p:c=>{c=c.firstChild;return null!==c&&F(c)?{conversion:()=>({node:null}),priority:3}:null},span:c=>F(c)?{conversion:()=>({node:G("h1")}),priority:3}:null}}static importJSON(c){let b=G(c.tag);b.setFormat(c.format);b.setIndent(c.indent);b.setDirection(c.direction);return b}exportJSON(){return{...super.exportJSON(),tag:this.getTag(),type:"heading",version:1}}insertNewAfter(c,b=!0){c=c?c.anchor.offset:0;c=0<c&&c<this.getTextContentSize()?G(this.getTag()):
14
14
  l.$createParagraphNode();let d=this.getDirection();c.setDirection(d);this.insertAfter(c,b);return c}collapseAtStart(){let c=this.isEmpty()?l.$createParagraphNode():G(this.getTag());this.getChildren().forEach(b=>c.append(b));this.replace(c);return!0}extractWithChild(){return!0}}function F(c){return"span"===c.nodeName.toLowerCase()?"26pt"===c.style.fontSize:!1}function E(c){c=c.nodeName.toLowerCase();let b=null;if("h1"===c||"h2"===c||"h3"===c||"h4"===c||"h5"===c||"h6"===c)b=G(c);return{node:b}}
15
15
  function A(){return{node:B()}}function G(c){return l.$applyNodeReplacement(new D(c))}function H(c,b){c.preventDefault();b.update(()=>{let d=l.$getSelection(),e=c instanceof InputEvent||c instanceof KeyboardEvent?null:c.clipboardData;null!=e&&(l.$isRangeSelection(d)||l.DEPRECATED_$isGridSelection(d))&&a.$insertDataTransferForRichText(e,d,b)},{tag:"paste"})}
16
- async function I(c,b){await a.copyToClipboard__EXPERIMENTAL(b,c instanceof ClipboardEvent?c:null);b.update(()=>{let d=l.$getSelection();l.$isRangeSelection(d)?d.removeText():l.$isNodeSelection(d)&&d.getNodes().forEach(e=>e.remove())})}function J(c){let b=null;c instanceof DragEvent?b=c.dataTransfer:c instanceof ClipboardEvent&&(b=c.clipboardData);if(null===b)return[!1,[],!1];var d=b.types;c=d.includes("Files");d=d.includes("text/html")||d.includes("text/plain");return[c,Array.from(b.files),d]}
16
+ async function I(c,b){await a.copyToClipboard(b,c instanceof ClipboardEvent?c:null);b.update(()=>{let d=l.$getSelection();l.$isRangeSelection(d)?d.removeText():l.$isNodeSelection(d)&&d.getNodes().forEach(e=>e.remove())})}function J(c){let b=null;c instanceof DragEvent?b=c.dataTransfer:c instanceof ClipboardEvent&&(b=c.clipboardData);if(null===b)return[!1,[],!1];var d=b.types;c=d.includes("Files");d=d.includes("text/html")||d.includes("text/plain");return[c,Array.from(b.files),d]}
17
17
  function K(c,b){var d=l.$getSelection();if(l.$isRangeSelection(d)){var e=new Set;d=d.getNodes();for(let f=0;f<d.length;f++){let n=d[f],v=n.getKey();if(e.has(v))continue;let h=k.$getNearestBlockElementAncestorOrThrow(n),C=h.getKey();h.canInsertTab()?(c(n),e.add(v)):h.canIndent()&&!e.has(C)&&(e.add(C),b(h))}}}function L(c){c=l.$getNearestNodeFromDOMNode(c);return l.$isDecoratorNode(c)}exports.$createHeadingNode=G;exports.$createQuoteNode=B;exports.$isHeadingNode=function(c){return c instanceof D};
18
18
  exports.$isQuoteNode=function(c){return c instanceof z};exports.DRAG_DROP_PASTE=y;exports.HeadingNode=D;exports.QuoteNode=z;exports.eventFiles=J;
19
19
  exports.registerRichText=function(c){return k.mergeRegister(c.registerCommand(l.CLICK_COMMAND,()=>{const b=l.$getSelection();return l.$isNodeSelection(b)?(b.clear(),!0):!1},0),c.registerCommand(l.DELETE_CHARACTER_COMMAND,b=>{const d=l.$getSelection();if(!l.$isRangeSelection(d))return!1;d.deleteCharacter(b);return!0},l.COMMAND_PRIORITY_EDITOR),c.registerCommand(l.DELETE_WORD_COMMAND,b=>{const d=l.$getSelection();if(!l.$isRangeSelection(d))return!1;d.deleteWord(b);return!0},l.COMMAND_PRIORITY_EDITOR),
@@ -28,5 +28,5 @@ c.registerCommand(l.KEY_BACKSPACE_COMMAND,b=>{if(L(b.target))return!1;const d=l.
28
28
  l.$getSelection();if(!l.$isRangeSelection(d))return!1;b.preventDefault();return c.dispatchCommand(l.DELETE_CHARACTER_COMMAND,!1)},l.COMMAND_PRIORITY_EDITOR),c.registerCommand(l.KEY_ENTER_COMMAND,b=>{const d=l.$getSelection();if(!l.$isRangeSelection(d))return!1;if(null!==b){if((u||t||x)&&r)return!1;b.preventDefault();if(b.shiftKey)return c.dispatchCommand(l.INSERT_LINE_BREAK_COMMAND,!1)}return c.dispatchCommand(l.INSERT_PARAGRAPH_COMMAND,void 0)},l.COMMAND_PRIORITY_EDITOR),c.registerCommand(l.KEY_ESCAPE_COMMAND,
29
29
  ()=>{const b=l.$getSelection();if(!l.$isRangeSelection(b))return!1;c.blur();return!0},l.COMMAND_PRIORITY_EDITOR),c.registerCommand(l.DROP_COMMAND,b=>{const [,d]=J(b);if(0<d.length){var e=m(b.clientX,b.clientY);if(null!==e){const {offset:n,node:v}=e;var f=l.$getNearestNodeFromDOMNode(v);if(null!==f){e=l.$createRangeSelection();if(l.$isTextNode(f))e.anchor.set(f.getKey(),n,"text"),e.focus.set(f.getKey(),n,"text");else{const h=f.getParentOrThrow().getKey();f=f.getIndexWithinParent()+1;e.anchor.set(h,
30
30
  f,"element");e.focus.set(h,f,"element")}e=l.$normalizeSelection__EXPERIMENTAL(e);l.$setSelection(e)}c.dispatchCommand(y,d)}b.preventDefault();return!0}b=l.$getSelection();return l.$isRangeSelection(b)?!0:!1},l.COMMAND_PRIORITY_EDITOR),c.registerCommand(l.DRAGSTART_COMMAND,b=>{[b]=J(b);const d=l.$getSelection();return b&&!l.$isRangeSelection(d)?!1:!0},l.COMMAND_PRIORITY_EDITOR),c.registerCommand(l.DRAGOVER_COMMAND,b=>{var [d]=J(b);const e=l.$getSelection();if(d&&!l.$isRangeSelection(e))return!1;d=
31
- m(b.clientX,b.clientY);null!==d&&(d=l.$getNearestNodeFromDOMNode(d.node),l.$isDecoratorNode(d)&&b.preventDefault());return!0},l.COMMAND_PRIORITY_EDITOR),c.registerCommand(l.COPY_COMMAND,b=>{a.copyToClipboard__EXPERIMENTAL(c,b instanceof ClipboardEvent?b:null);return!0},l.COMMAND_PRIORITY_EDITOR),c.registerCommand(l.CUT_COMMAND,b=>{I(b,c);return!0},l.COMMAND_PRIORITY_EDITOR),c.registerCommand(l.PASTE_COMMAND,b=>{const [,d,e]=J(b);if(0<d.length&&!e)return c.dispatchCommand(y,d),!0;const f=l.$getSelection();
32
- return l.$isRangeSelection(f)||l.DEPRECATED_$isGridSelection(f)?(H(b,c),!0):!1},l.COMMAND_PRIORITY_EDITOR))}
31
+ m(b.clientX,b.clientY);null!==d&&(d=l.$getNearestNodeFromDOMNode(d.node),l.$isDecoratorNode(d)&&b.preventDefault());return!0},l.COMMAND_PRIORITY_EDITOR),c.registerCommand(l.COPY_COMMAND,b=>{a.copyToClipboard(c,b instanceof ClipboardEvent?b:null);return!0},l.COMMAND_PRIORITY_EDITOR),c.registerCommand(l.CUT_COMMAND,b=>{I(b,c);return!0},l.COMMAND_PRIORITY_EDITOR),c.registerCommand(l.PASTE_COMMAND,b=>{const [,d,e]=J(b);if(0<d.length&&!e)return c.dispatchCommand(y,d),!0;const f=l.$getSelection();return l.$isRangeSelection(f)||
32
+ l.DEPRECATED_$isGridSelection(f)?(H(b,c),!0):!1},l.COMMAND_PRIORITY_EDITOR))}
package/package.json CHANGED
@@ -7,13 +7,13 @@
7
7
  "rich-text"
8
8
  ],
9
9
  "license": "MIT",
10
- "version": "0.8.1",
10
+ "version": "0.9.1",
11
11
  "main": "LexicalRichText.js",
12
12
  "peerDependencies": {
13
- "lexical": "0.8.1",
14
- "@lexical/selection": "0.8.1",
15
- "@lexical/clipboard": "0.8.1",
16
- "@lexical/utils": "0.8.1"
13
+ "lexical": "0.9.1",
14
+ "@lexical/selection": "0.9.1",
15
+ "@lexical/clipboard": "0.9.1",
16
+ "@lexical/utils": "0.9.1"
17
17
  },
18
18
  "repository": {
19
19
  "type": "git",