@lexical/rich-text 0.12.2 → 0.12.3

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