slate-angular 19.1.0 → 19.1.2

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.
@@ -1,5 +1,5 @@
1
1
  import { Editor, Range, Element, Transforms, Text as Text$1, Node, Path } from 'slate';
2
- import { EDITOR_TO_ELEMENT, NODE_TO_ELEMENT, DOMEditor, normalizeDOMPoint, isDOMSelection, IS_CHROME as IS_CHROME$1, hasShadowRoot, isDOMElement, NODE_TO_PARENT, NODE_TO_INDEX, isDOMNode, IS_FOCUSED, withDOM, NODE_TO_KEY, ELEMENT_TO_NODE, getDefaultView, EDITOR_TO_WINDOW, IS_READ_ONLY, EDITOR_TO_ON_CHANGE, TRIPLE_CLICK, isPlainTextOnlyPaste } from 'slate-dom';
2
+ import { EDITOR_TO_ELEMENT, NODE_TO_ELEMENT, DOMEditor, normalizeDOMPoint, isDOMSelection, IS_CHROME as IS_CHROME$1, hasShadowRoot, isDOMElement, NODE_TO_PARENT, NODE_TO_INDEX, IS_FOCUSED, isDOMNode, withDOM, NODE_TO_KEY, ELEMENT_TO_NODE, getDefaultView, EDITOR_TO_WINDOW, IS_READ_ONLY, EDITOR_TO_ON_CHANGE, TRIPLE_CLICK, isPlainTextOnlyPaste } from 'slate-dom';
3
3
  import { isKeyHotkey } from 'is-hotkey';
4
4
  import * as i0 from '@angular/core';
5
5
  import { TemplateRef, ViewChild, ChangeDetectionStrategy, Component, InjectionToken, ComponentRef, IterableDiffers, inject, ElementRef, ChangeDetectorRef, Input, Directive, HostBinding, ViewContainerRef, forwardRef, Inject, NgModule } from '@angular/core';
@@ -353,53 +353,6 @@ const CustomDOMEditor = {
353
353
  }
354
354
  };
355
355
 
356
- const SlateFragmentAttributeKey = 'data-slate-angular-fragment';
357
- /**
358
- * Get x-slate-fragment attribute from data-slate-angular-fragment
359
- */
360
- const catchSlateFragment = /data-slate-angular-fragment="(.+?)"/m;
361
- const getSlateFragmentAttribute = (htmlData) => {
362
- const [, fragment] = htmlData.match(catchSlateFragment) || [];
363
- return fragment;
364
- };
365
- /**
366
- * Check if a DOM node is an element node.
367
- */
368
- const isDOMText = (value) => {
369
- return isDOMNode(value) && value.nodeType === 3;
370
- };
371
- /**
372
- * Get a plaintext representation of the content of a node, accounting for block
373
- * elements which get a newline appended.
374
- *
375
- * The domNode must be attached to the DOM.
376
- */
377
- const getPlainText = (domNode) => {
378
- let text = '';
379
- if (isDOMText(domNode) && domNode.nodeValue) {
380
- return domNode.nodeValue;
381
- }
382
- if (isDOMElement(domNode)) {
383
- for (const childNode of Array.from(domNode.childNodes)) {
384
- text += getPlainText(childNode);
385
- }
386
- const display = getComputedStyle(domNode).getPropertyValue('display');
387
- if (display === 'block' || display === 'list' || domNode.tagName === 'BR') {
388
- text += '\n';
389
- }
390
- }
391
- return text;
392
- };
393
- /**
394
- * Get the dom selection from Shadow Root if possible, otherwise from the document
395
- */
396
- const getSelection = (root) => {
397
- if (root.getSelection != null) {
398
- return root.getSelection();
399
- }
400
- return document.getSelection();
401
- };
402
-
403
356
  const AngularEditor = {
404
357
  ...CustomDOMEditor,
405
358
  /**
@@ -463,23 +416,12 @@ const AngularEditor = {
463
416
  if (!EDITOR_TO_ELEMENT.get(editor)) {
464
417
  return;
465
418
  }
419
+ IS_FOCUSED.set(editor, true);
466
420
  const el = DOMEditor.toDOMNode(editor, editor);
467
421
  const root = DOMEditor.findDocumentOrShadowRoot(editor);
468
422
  if (root.activeElement !== el) {
469
- // Ensure that the DOM selection state is set to the editor's selection
470
- if (editor.selection && root instanceof Document) {
471
- const domSelection = getSelection(root);
472
- const domRange = DOMEditor.toDOMRange(editor, editor.selection);
473
- domSelection?.removeAllRanges();
474
- domSelection?.addRange(domRange);
475
- }
476
- // Create a new selection in the top of the document if missing
477
- if (!editor.selection) {
478
- Transforms.select(editor, Editor.start(editor, []));
479
- }
480
423
  // IS_FOCUSED should be set before calling el.focus() to ensure that
481
424
  // FocusedContext is updated to the correct value
482
- IS_FOCUSED.set(editor, true);
483
425
  el.focus({ preventScroll: true });
484
426
  }
485
427
  }
@@ -827,6 +769,53 @@ const getNavigatorClipboard = async () => {
827
769
  return clipboardData;
828
770
  };
829
771
 
772
+ const SlateFragmentAttributeKey = 'data-slate-angular-fragment';
773
+ /**
774
+ * Get x-slate-fragment attribute from data-slate-angular-fragment
775
+ */
776
+ const catchSlateFragment = /data-slate-angular-fragment="(.+?)"/m;
777
+ const getSlateFragmentAttribute = (htmlData) => {
778
+ const [, fragment] = htmlData.match(catchSlateFragment) || [];
779
+ return fragment;
780
+ };
781
+ /**
782
+ * Check if a DOM node is an element node.
783
+ */
784
+ const isDOMText = (value) => {
785
+ return isDOMNode(value) && value.nodeType === 3;
786
+ };
787
+ /**
788
+ * Get a plaintext representation of the content of a node, accounting for block
789
+ * elements which get a newline appended.
790
+ *
791
+ * The domNode must be attached to the DOM.
792
+ */
793
+ const getPlainText = (domNode) => {
794
+ let text = '';
795
+ if (isDOMText(domNode) && domNode.nodeValue) {
796
+ return domNode.nodeValue;
797
+ }
798
+ if (isDOMElement(domNode)) {
799
+ for (const childNode of Array.from(domNode.childNodes)) {
800
+ text += getPlainText(childNode);
801
+ }
802
+ const display = getComputedStyle(domNode).getPropertyValue('display');
803
+ if (display === 'block' || display === 'list' || domNode.tagName === 'BR') {
804
+ text += '\n';
805
+ }
806
+ }
807
+ return text;
808
+ };
809
+ /**
810
+ * Get the dom selection from Shadow Root if possible, otherwise from the document
811
+ */
812
+ const getSelection = (root) => {
813
+ if (root.getSelection != null) {
814
+ return root.getSelection();
815
+ }
816
+ return document.getSelection();
817
+ };
818
+
830
819
  const buildHTMLText = (wrapper, attach, data) => {
831
820
  const stringObj = JSON.stringify(data);
832
821
  const encoded = window.btoa(encodeURIComponent(stringObj));
@@ -3863,6 +3852,17 @@ const defaultScrollSelectionIntoView = (editor, domRange) => {
3863
3852
  // so enabled only if the selection has been collapsed.
3864
3853
  if (domRange.getBoundingClientRect && (!editor.selection || (editor.selection && Range.isCollapsed(editor.selection)))) {
3865
3854
  const leafEl = domRange.startContainer.parentElement;
3855
+ // COMPAT: In Chrome, domRange.getBoundingClientRect() can return zero dimensions for valid ranges (e.g. line breaks).
3856
+ // When this happens, do not scroll like most editors do.
3857
+ const domRect = domRange.getBoundingClientRect();
3858
+ const isZeroDimensionRect = domRect.width === 0 && domRect.height === 0 && domRect.x === 0 && domRect.y === 0;
3859
+ if (isZeroDimensionRect) {
3860
+ const leafRect = leafEl.getBoundingClientRect();
3861
+ const leafHasDimensions = leafRect.width > 0 || leafRect.height > 0;
3862
+ if (leafHasDimensions) {
3863
+ return;
3864
+ }
3865
+ }
3866
3866
  leafEl.getBoundingClientRect = domRange.getBoundingClientRect.bind(domRange);
3867
3867
  scrollIntoView(leafEl, {
3868
3868
  scrollMode: 'if-needed'