@bigbinary/neeto-editor 1.47.104 → 1.47.105

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.
@@ -5,7 +5,7 @@ var _toConsumableArray = require('@babel/runtime/helpers/toConsumableArray');
5
5
  var _slicedToArray = require('@babel/runtime/helpers/slicedToArray');
6
6
  var _objectWithoutProperties = require('@babel/runtime/helpers/objectWithoutProperties');
7
7
  var React = require('react');
8
- var Menu$4 = require('./chunk-2w0QpL4j.cjs.js');
8
+ var Menu$4 = require('./chunk-C3rn62sV.cjs.js');
9
9
  var classnames = require('classnames');
10
10
  var constants = require('./chunk-2HrSPdAV.cjs.js');
11
11
  var neetoCist = require('@bigbinary/neeto-cist');
@@ -10,7 +10,7 @@ var Editor = require('./Editor.cjs.js');
10
10
  var jsxRuntime = require('react/jsx-runtime');
11
11
  require('@babel/runtime/helpers/toConsumableArray');
12
12
  require('@babel/runtime/helpers/slicedToArray');
13
- require('./chunk-2w0QpL4j.cjs.js');
13
+ require('./chunk-C3rn62sV.cjs.js');
14
14
  require('./chunk-vQvjPR2x.cjs.js');
15
15
  require('i18next');
16
16
  require('@bigbinary/neeto-icons/TextH1');
@@ -5,7 +5,7 @@ require('@babel/runtime/helpers/toConsumableArray');
5
5
  require('@babel/runtime/helpers/slicedToArray');
6
6
  require('react');
7
7
  require('ramda');
8
- var Menu = require('./chunk-2w0QpL4j.cjs.js');
8
+ var Menu = require('./chunk-C3rn62sV.cjs.js');
9
9
  require('./chunk-BGy3NmZC.cjs.js');
10
10
  require('react/jsx-runtime');
11
11
  require('./chunk-vQvjPR2x.cjs.js');
@@ -559,14 +559,15 @@ function posFromCaret(view, node, offset, coords) {
559
559
  let desc = view.docView.nearestDesc(cur, true);
560
560
  if (!desc)
561
561
  return null;
562
- if (desc.dom.nodeType == 1 && (desc.node.isBlock && desc.parent && !sawBlock || !desc.contentDOM)) {
562
+ if (desc.dom.nodeType == 1 && (desc.node.isBlock && desc.parent || !desc.contentDOM)) {
563
563
  let rect = desc.dom.getBoundingClientRect();
564
- if (desc.node.isBlock && desc.parent && !sawBlock) {
565
- sawBlock = true;
566
- if (rect.left > coords.left || rect.top > coords.top)
564
+ if (desc.node.isBlock && desc.parent) {
565
+ // Only apply the horizontal test to the innermost block. Vertical for any parent.
566
+ if (!sawBlock && rect.left > coords.left || rect.top > coords.top)
567
567
  outsideBlock = desc.posBefore;
568
- else if (rect.right < coords.left || rect.bottom < coords.top)
568
+ else if (!sawBlock && rect.right < coords.left || rect.bottom < coords.top)
569
569
  outsideBlock = desc.posAfter;
570
+ sawBlock = true;
570
571
  }
571
572
  if (!desc.contentDOM && outsideBlock < 0 && !desc.node.isText) {
572
573
  // If we are inside a leaf, return the side of the leaf closer to the coords
@@ -821,6 +822,8 @@ function endOfTextblockHorizontal(view, state, dir) {
821
822
  return false;
822
823
  let offset = $head.parentOffset, atStart = !offset, atEnd = offset == $head.parent.content.size;
823
824
  let sel = view.domSelection();
825
+ if (!sel)
826
+ return $head.pos == $head.start() || $head.pos == $head.end();
824
827
  // If the textblock is all LTR, or the browser doesn't support
825
828
  // Selection.modify (Edge), fall back to a primitive approach
826
829
  if (!maybeRTL.test($head.parent.textContent) || !sel.modify)
@@ -1357,7 +1360,7 @@ class MarkViewDesc extends ViewDesc {
1357
1360
  let custom = view.nodeViews[mark.type.name];
1358
1361
  let spec = custom && custom(mark, view, inline);
1359
1362
  if (!spec || !spec.dom)
1360
- spec = utils.DOMSerializer.renderSpec(document, mark.type.spec.toDOM(mark, inline));
1363
+ spec = utils.DOMSerializer.renderSpec(document, mark.type.spec.toDOM(mark, inline), null, mark.attrs);
1361
1364
  return new MarkViewDesc(parent, mark, spec.dom, spec.contentDOM || spec.dom);
1362
1365
  }
1363
1366
  parseRule() {
@@ -1429,7 +1432,8 @@ class NodeViewDesc extends ViewDesc {
1429
1432
  throw new RangeError("Text must be rendered as a DOM text node");
1430
1433
  }
1431
1434
  else if (!dom) {
1432
- ({ dom, contentDOM } = utils.DOMSerializer.renderSpec(document, node.type.spec.toDOM(node)));
1435
+ let spec = utils.DOMSerializer.renderSpec(document, node.type.spec.toDOM(node), null, node.attrs);
1436
+ ({ dom, contentDOM } = spec);
1433
1437
  }
1434
1438
  if (!contentDOM && !node.isText && dom.nodeName != "BR") { // Chrome gets confused by <br contenteditable=false>
1435
1439
  if (!dom.hasAttribute("contenteditable"))
@@ -1615,10 +1619,11 @@ class NodeViewDesc extends ViewDesc {
1615
1619
  }
1616
1620
  // Remove selected node marking from this node.
1617
1621
  deselectNode() {
1618
- if (this.nodeDOM.nodeType == 1)
1622
+ if (this.nodeDOM.nodeType == 1) {
1619
1623
  this.nodeDOM.classList.remove("ProseMirror-selectednode");
1620
- if (this.contentDOM || !this.node.type.spec.draggable)
1621
- this.dom.removeAttribute("draggable");
1624
+ if (this.contentDOM || !this.node.type.spec.draggable)
1625
+ this.dom.removeAttribute("draggable");
1626
+ }
1622
1627
  }
1623
1628
  get domAtom() { return this.node.isAtom; }
1624
1629
  }
@@ -2441,12 +2446,14 @@ function removeClassOnSelectionChange(view) {
2441
2446
  }
2442
2447
  function selectCursorWrapper(view) {
2443
2448
  let domSel = view.domSelection(), range = document.createRange();
2449
+ if (!domSel)
2450
+ return;
2444
2451
  let node = view.cursorWrapper.dom, img = node.nodeName == "IMG";
2445
2452
  if (img)
2446
- range.setEnd(node.parentNode, domIndex(node) + 1);
2453
+ range.setStart(node.parentNode, domIndex(node) + 1);
2447
2454
  else
2448
- range.setEnd(node, 0);
2449
- range.collapse(false);
2455
+ range.setStart(node, 0);
2456
+ range.collapse(true);
2450
2457
  domSel.removeAllRanges();
2451
2458
  domSel.addRange(range);
2452
2459
  // Kludge to kill 'control selection' in IE11 when selecting an
@@ -2734,6 +2741,8 @@ function setSelFocus(view, node, offset) {
2734
2741
  }
2735
2742
  }
2736
2743
  let sel = view.domSelection();
2744
+ if (!sel)
2745
+ return;
2737
2746
  if (selectionCollapsed(sel)) {
2738
2747
  let range = document.createRange();
2739
2748
  range.setEnd(node, offset);
@@ -2916,7 +2925,7 @@ function serializeForClipboard(view, slice) {
2916
2925
  firstChild.setAttribute("data-pm-slice", `${openStart} ${openEnd}${wrappers ? ` -${wrappers}` : ""} ${JSON.stringify(context)}`);
2917
2926
  let text = view.someProp("clipboardTextSerializer", f => f(slice, view)) ||
2918
2927
  slice.content.textBetween(0, slice.content.size, "\n\n");
2919
- return { dom: wrap, text };
2928
+ return { dom: wrap, text, slice };
2920
2929
  }
2921
2930
  // Read a slice of content from the clipboard (or drop data).
2922
2931
  function parseFromClipboard(view, text, html, plainText, $context) {
@@ -3300,6 +3309,8 @@ function runHandlerOnContext(view, propName, pos, inside, event) {
3300
3309
  function updateSelection(view, selection, origin) {
3301
3310
  if (!view.focused)
3302
3311
  view.focus();
3312
+ if (view.state.selection.eq(selection))
3313
+ return;
3303
3314
  let tr = view.state.tr.setSelection(selection);
3304
3315
  tr.setMeta("pointer", true);
3305
3316
  view.dispatch(tr);
@@ -3432,7 +3443,7 @@ class MouseDown {
3432
3443
  }
3433
3444
  const target = flushed ? null : event.target;
3434
3445
  const targetDesc = target ? view.docView.nearestDesc(target, true) : null;
3435
- this.target = targetDesc ? targetDesc.dom : null;
3446
+ this.target = targetDesc && targetDesc.dom.nodeType == 1 ? targetDesc.dom : null;
3436
3447
  let { selection } = view.state;
3437
3448
  if (event.button == 0 &&
3438
3449
  targetNode.type.spec.draggable && targetNode.type.spec.selectable !== false ||
@@ -3553,8 +3564,8 @@ const timeoutComposition = android ? 5000 : -1;
3553
3564
  editHandlers.compositionstart = editHandlers.compositionupdate = view => {
3554
3565
  if (!view.composing) {
3555
3566
  view.domObserver.flush();
3556
- let { state } = view, $pos = state.selection.$from;
3557
- if (state.selection.empty &&
3567
+ let { state } = view, $pos = state.selection.$to;
3568
+ if (state.selection instanceof utils.TextSelection &&
3558
3569
  (state.storedMarks ||
3559
3570
  (!$pos.textOffset && $pos.parentOffset && $pos.nodeBefore.marks.some(m => m.type.spec.inclusive === false)))) {
3560
3571
  // Need to wrap the cursor in mark nodes different from the ones in the DOM context
@@ -3563,7 +3574,7 @@ editHandlers.compositionstart = editHandlers.compositionupdate = view => {
3563
3574
  view.markCursor = null;
3564
3575
  }
3565
3576
  else {
3566
- endComposition(view);
3577
+ endComposition(view, !state.selection.empty);
3567
3578
  // In firefox, if the cursor is after but outside a marked node,
3568
3579
  // the inserted text won't inherit the marks. So this moves it
3569
3580
  // inside if necessary.
@@ -3574,7 +3585,9 @@ editHandlers.compositionstart = editHandlers.compositionupdate = view => {
3574
3585
  if (!before)
3575
3586
  break;
3576
3587
  if (before.nodeType == 3) {
3577
- view.domSelection().collapse(before, before.nodeValue.length);
3588
+ let sel = view.domSelection();
3589
+ if (sel)
3590
+ sel.collapse(before, before.nodeValue.length);
3578
3591
  break;
3579
3592
  }
3580
3593
  else {
@@ -3620,7 +3633,9 @@ function findCompositionNode(view) {
3620
3633
  let textBefore = textNodeBefore$1(sel.focusNode, sel.focusOffset);
3621
3634
  let textAfter = textNodeAfter$1(sel.focusNode, sel.focusOffset);
3622
3635
  if (textBefore && textAfter && textBefore != textAfter) {
3623
- let descAfter = textAfter.pmViewDesc;
3636
+ let descAfter = textAfter.pmViewDesc, lastChanged = view.domObserver.lastChangedTextNode;
3637
+ if (textBefore == lastChanged || textAfter == lastChanged)
3638
+ return lastChanged;
3624
3639
  if (!descAfter || !descAfter.isText(textAfter.nodeValue)) {
3625
3640
  return textAfter;
3626
3641
  }
@@ -3630,7 +3645,7 @@ function findCompositionNode(view) {
3630
3645
  return textAfter;
3631
3646
  }
3632
3647
  }
3633
- return textBefore;
3648
+ return textBefore || textAfter;
3634
3649
  }
3635
3650
  function timestampFromCustomEvent() {
3636
3651
  let event = document.createEvent("Event");
@@ -3640,15 +3655,17 @@ function timestampFromCustomEvent() {
3640
3655
  /**
3641
3656
  @internal
3642
3657
  */
3643
- function endComposition(view, forceUpdate = false) {
3658
+ function endComposition(view, restarting = false) {
3644
3659
  if (android && view.domObserver.flushingSoon >= 0)
3645
3660
  return;
3646
3661
  view.domObserver.forceFlush();
3647
3662
  clearComposition(view);
3648
- if (forceUpdate || view.docView && view.docView.dirty) {
3663
+ if (restarting || view.docView && view.docView.dirty) {
3649
3664
  let sel = selectionFromDOM(view);
3650
3665
  if (sel && !sel.eq(view.state.selection))
3651
3666
  view.dispatch(view.state.tr.setSelection(sel));
3667
+ else if ((view.markCursor || restarting) && !view.state.selection.empty)
3668
+ view.dispatch(view.state.tr.deleteSelection());
3652
3669
  else
3653
3670
  view.updateState(view.state);
3654
3671
  return true;
@@ -3787,8 +3804,11 @@ handlers.dragstart = (view, _event) => {
3787
3804
  if (desc && desc.node.type.spec.draggable && desc != view.docView)
3788
3805
  node = utils.NodeSelection.create(view.state.doc, desc.posBefore);
3789
3806
  }
3790
- let slice = (node || view.state.selection).content(), { dom, text } = serializeForClipboard(view, slice);
3791
- event.dataTransfer.clearData();
3807
+ let draggedSlice = (node || view.state.selection).content();
3808
+ let { dom, text, slice } = serializeForClipboard(view, draggedSlice);
3809
+ // Pre-120 Chrome versions clear files when calling `clearData` (#1472)
3810
+ if (!event.dataTransfer.files.length || !chrome || chrome_version > 120)
3811
+ event.dataTransfer.clearData();
3792
3812
  event.dataTransfer.setData(brokenClipboardAPI ? "Text" : "text/html", dom.innerHTML);
3793
3813
  // See https://github.com/ProseMirror/prosemirror/issues/1156
3794
3814
  event.dataTransfer.effectAllowed = "copyMove";
@@ -4631,6 +4651,7 @@ class DOMObserver {
4631
4651
  this.currentSelection = new SelectionState;
4632
4652
  this.onCharData = null;
4633
4653
  this.suppressingSelectionUpdates = false;
4654
+ this.lastChangedTextNode = null;
4634
4655
  this.observer = window.MutationObserver &&
4635
4656
  new window.MutationObserver(mutations => {
4636
4657
  for (let i = 0; i < mutations.length; i++)
@@ -4763,15 +4784,23 @@ class DOMObserver {
4763
4784
  }
4764
4785
  }
4765
4786
  }
4766
- if (gecko && added.length > 1) {
4787
+ if (gecko && added.length) {
4767
4788
  let brs = added.filter(n => n.nodeName == "BR");
4768
4789
  if (brs.length == 2) {
4769
- let a = brs[0], b = brs[1];
4790
+ let [a, b] = brs;
4770
4791
  if (a.parentNode && a.parentNode.parentNode == b.parentNode)
4771
4792
  b.remove();
4772
4793
  else
4773
4794
  a.remove();
4774
4795
  }
4796
+ else {
4797
+ let { focusNode } = this.currentSelection;
4798
+ for (let br of brs) {
4799
+ let parent = br.parentNode;
4800
+ if (parent && parent.nodeName == "LI" && (!focusNode || blockParent(view, focusNode) != parent))
4801
+ br.remove();
4802
+ }
4803
+ }
4775
4804
  }
4776
4805
  let readSel = null;
4777
4806
  // If it looks like the browser has reset the selection to the
@@ -4812,8 +4841,12 @@ class DOMObserver {
4812
4841
  if (!desc || desc.ignoreMutation(mut))
4813
4842
  return null;
4814
4843
  if (mut.type == "childList") {
4815
- for (let i = 0; i < mut.addedNodes.length; i++)
4816
- added.push(mut.addedNodes[i]);
4844
+ for (let i = 0; i < mut.addedNodes.length; i++) {
4845
+ let node = mut.addedNodes[i];
4846
+ added.push(node);
4847
+ if (node.nodeType == 3)
4848
+ this.lastChangedTextNode = node;
4849
+ }
4817
4850
  if (desc.contentDOM && desc.contentDOM != desc.dom && !desc.contentDOM.contains(mut.target))
4818
4851
  return { from: desc.posBefore, to: desc.posAfter };
4819
4852
  let prev = mut.previousSibling, next = mut.nextSibling;
@@ -4840,6 +4873,7 @@ class DOMObserver {
4840
4873
  return { from: desc.posAtStart - desc.border, to: desc.posAtEnd + desc.border };
4841
4874
  }
4842
4875
  else { // "characterData"
4876
+ this.lastChangedTextNode = mut.target;
4843
4877
  return {
4844
4878
  from: desc.posAtStart,
4845
4879
  to: desc.posAtEnd,
@@ -4901,6 +4935,14 @@ function safariShadowSelectionRange(view, selection) {
4901
4935
  view.dom.removeEventListener("beforeinput", read, true);
4902
4936
  return found ? rangeToSelectionRange(view, found) : null;
4903
4937
  }
4938
+ function blockParent(view, node) {
4939
+ for (let p = node.parentNode; p && p != view.dom; p = p.parentNode) {
4940
+ let desc = view.docView.nearestDesc(p, true);
4941
+ if (desc && desc.node.isBlock)
4942
+ return p;
4943
+ }
4944
+ return null;
4945
+ }
4904
4946
 
4905
4947
  // Note that all referencing and parsing is done with the
4906
4948
  // start-of-operation selection and document, since that's the one
@@ -5765,6 +5807,8 @@ class EditorView {
5765
5807
  */
5766
5808
  domSelectionRange() {
5767
5809
  let sel = this.domSelection();
5810
+ if (!sel)
5811
+ return { focusNode: null, focusOffset: 0, anchorNode: null, anchorOffset: 0 };
5768
5812
  return safari && this.root.nodeType === 11 &&
5769
5813
  deepActiveElement(this.dom.ownerDocument) == this.dom && safariShadowSelectionRange(this, sel) || sel;
5770
5814
  }
@@ -5802,7 +5846,7 @@ function updateCursorWrapper(view) {
5802
5846
  dom.className = "ProseMirror-separator";
5803
5847
  dom.setAttribute("mark-placeholder", "true");
5804
5848
  dom.setAttribute("alt", "");
5805
- view.cursorWrapper = { dom, deco: Decoration.widget(view.state.selection.head, dom, { raw: true, marks: view.markCursor }) };
5849
+ view.cursorWrapper = { dom, deco: Decoration.widget(view.state.selection.from, dom, { raw: true, marks: view.markCursor }) };
5806
5850
  }
5807
5851
  else {
5808
5852
  view.cursorWrapper = null;
@@ -19035,4 +19079,4 @@ exports.useEditor = useEditor;
19035
19079
  exports.useEditorState = useEditorState$1;
19036
19080
  exports.validateUrl = validateUrl;
19037
19081
  exports.wrappingInputRule = wrappingInputRule;
19038
- //# sourceMappingURL=chunk-2w0QpL4j.cjs.js.map
19082
+ //# sourceMappingURL=chunk-C3rn62sV.cjs.js.map