@codemirror/view 6.9.3 → 6.9.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +32 -0
- package/dist/index.cjs +147 -55
- package/dist/index.js +147 -55
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,35 @@
|
|
|
1
|
+
## 6.9.5 (2023-04-17)
|
|
2
|
+
|
|
3
|
+
### Bug fixes
|
|
4
|
+
|
|
5
|
+
Avoid disrupting the composition in specific cases where Safari invasively changes the DOM structure in the middle of a composition.
|
|
6
|
+
|
|
7
|
+
Fix a bug that prevented `destroy` being called on hover tooltips.
|
|
8
|
+
|
|
9
|
+
Fix a bug where the editor could take focus when content changes required it to restore the DOM selection.
|
|
10
|
+
|
|
11
|
+
Fix height layout corruption caused by a division by zero.
|
|
12
|
+
|
|
13
|
+
Make sure styles targeting the editor's focus status are specific enough to not cause them to apply to editors nested inside another focused editor. This will require themes to adjust their selection background styles to match the new specificity.
|
|
14
|
+
|
|
15
|
+
## 6.9.4 (2023-04-11)
|
|
16
|
+
|
|
17
|
+
### Bug fixes
|
|
18
|
+
|
|
19
|
+
Make the editor scroll while dragging a selection near its sides, even if the cursor isn't outside the scrollable element.
|
|
20
|
+
|
|
21
|
+
Fix a bug that interrupted composition after widgets in some circumstances on Firefox.
|
|
22
|
+
|
|
23
|
+
Make sure the last change in a composition has its user event set to `input.type.compose`, even if the `compositionend` event fires before the changes are applied.
|
|
24
|
+
|
|
25
|
+
Make it possible to remove additional selection ranges by clicking on them with ctrl/cmd held, even if they aren't cursors.
|
|
26
|
+
|
|
27
|
+
Keep widget buffers between widgets and compositions, since removing them confuses IME on macOS Firefox.
|
|
28
|
+
|
|
29
|
+
Fix a bug where, for DOM changes that put the selection in the middle of the changed range, the editor incorrectly set its selection state.
|
|
30
|
+
|
|
31
|
+
Fix a bug where `coordsAtPos` could return a coordinates before the line break when querying a line-wrapped position with a positive `side`.
|
|
32
|
+
|
|
1
33
|
## 6.9.3 (2023-03-21)
|
|
2
34
|
|
|
3
35
|
### Bug fixes
|
package/dist/index.cjs
CHANGED
|
@@ -520,6 +520,7 @@ class ContentView {
|
|
|
520
520
|
static get(node) { return node.cmView; }
|
|
521
521
|
get isEditable() { return true; }
|
|
522
522
|
get isWidget() { return false; }
|
|
523
|
+
get isHidden() { return false; }
|
|
523
524
|
merge(from, to, source, hasStart, openStart, openEnd) {
|
|
524
525
|
return false;
|
|
525
526
|
}
|
|
@@ -857,7 +858,7 @@ class WidgetView extends ContentView {
|
|
|
857
858
|
become(other) {
|
|
858
859
|
if (other.length == this.length && other instanceof WidgetView && other.side == this.side) {
|
|
859
860
|
if (this.widget.constructor == other.widget.constructor) {
|
|
860
|
-
if (!this.widget.
|
|
861
|
+
if (!this.widget.compare(other.widget))
|
|
861
862
|
this.markDirty(true);
|
|
862
863
|
if (this.dom && !this.prevWidget)
|
|
863
864
|
this.prevWidget = this.widget;
|
|
@@ -879,7 +880,9 @@ class WidgetView extends ContentView {
|
|
|
879
880
|
return text ? text.slice(start, start + this.length) : state.Text.empty;
|
|
880
881
|
}
|
|
881
882
|
domAtPos(pos) {
|
|
882
|
-
return pos == 0
|
|
883
|
+
return (this.length ? pos == 0 : this.side > 0)
|
|
884
|
+
? DOMPos.before(this.dom)
|
|
885
|
+
: DOMPos.after(this.dom, pos == this.length);
|
|
883
886
|
}
|
|
884
887
|
domBoundsAround() { return null; }
|
|
885
888
|
coordsAt(pos, side) {
|
|
@@ -895,6 +898,7 @@ class WidgetView extends ContentView {
|
|
|
895
898
|
}
|
|
896
899
|
get isEditable() { return false; }
|
|
897
900
|
get isWidget() { return true; }
|
|
901
|
+
get isHidden() { return this.widget.isHidden; }
|
|
898
902
|
destroy() {
|
|
899
903
|
super.destroy();
|
|
900
904
|
if (this.dom)
|
|
@@ -906,14 +910,14 @@ class CompositionView extends WidgetView {
|
|
|
906
910
|
let { topView, text } = this.widget;
|
|
907
911
|
if (!topView)
|
|
908
912
|
return new DOMPos(text, Math.min(pos, text.nodeValue.length));
|
|
909
|
-
return scanCompositionTree(pos, 0, topView, text, (v, p) => v.domAtPos(p), p => new DOMPos(text, Math.min(p, text.nodeValue.length)));
|
|
913
|
+
return scanCompositionTree(pos, 0, topView, text, this.length - topView.length, (v, p) => v.domAtPos(p), (text, p) => new DOMPos(text, Math.min(p, text.nodeValue.length)));
|
|
910
914
|
}
|
|
911
915
|
sync() { this.setDOM(this.widget.toDOM()); }
|
|
912
916
|
localPosFromDOM(node, offset) {
|
|
913
917
|
let { topView, text } = this.widget;
|
|
914
918
|
if (!topView)
|
|
915
919
|
return Math.min(offset, this.length);
|
|
916
|
-
return posFromDOMInCompositionTree(node, offset, topView, text);
|
|
920
|
+
return posFromDOMInCompositionTree(node, offset, topView, text, this.length - topView.length);
|
|
917
921
|
}
|
|
918
922
|
ignoreMutation() { return false; }
|
|
919
923
|
get overrideDOMText() { return null; }
|
|
@@ -921,7 +925,7 @@ class CompositionView extends WidgetView {
|
|
|
921
925
|
let { topView, text } = this.widget;
|
|
922
926
|
if (!topView)
|
|
923
927
|
return textCoords(text, pos, side);
|
|
924
|
-
return scanCompositionTree(pos, side, topView, text, (v, pos, side) => v.coordsAt(pos, side), (pos, side) => textCoords(text, pos, side));
|
|
928
|
+
return scanCompositionTree(pos, side, topView, text, this.length - topView.length, (v, pos, side) => v.coordsAt(pos, side), (text, pos, side) => textCoords(text, pos, side));
|
|
925
929
|
}
|
|
926
930
|
destroy() {
|
|
927
931
|
var _a;
|
|
@@ -934,35 +938,68 @@ class CompositionView extends WidgetView {
|
|
|
934
938
|
// Uses the old structure of a chunk of content view frozen for
|
|
935
939
|
// composition to try and find a reasonable DOM location for the given
|
|
936
940
|
// offset.
|
|
937
|
-
function scanCompositionTree(pos, side, view, text, enterView, fromText) {
|
|
941
|
+
function scanCompositionTree(pos, side, view, text, dLen, enterView, fromText) {
|
|
938
942
|
if (view instanceof MarkView) {
|
|
939
943
|
for (let child = view.dom.firstChild; child; child = child.nextSibling) {
|
|
940
944
|
let desc = ContentView.get(child);
|
|
941
|
-
if (!desc)
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
945
|
+
if (!desc) {
|
|
946
|
+
let inner = scanCompositionNode(pos, side, child, fromText);
|
|
947
|
+
if (typeof inner != "number")
|
|
948
|
+
return inner;
|
|
949
|
+
pos = inner;
|
|
950
|
+
}
|
|
951
|
+
else {
|
|
952
|
+
let hasComp = contains(child, text);
|
|
953
|
+
let len = desc.length + (hasComp ? dLen : 0);
|
|
954
|
+
if (pos < len || pos == len && desc.getSide() <= 0)
|
|
955
|
+
return hasComp ? scanCompositionTree(pos, side, desc, text, dLen, enterView, fromText) : enterView(desc, pos, side);
|
|
956
|
+
pos -= len;
|
|
957
|
+
}
|
|
948
958
|
}
|
|
949
959
|
return enterView(view, view.length, -1);
|
|
950
960
|
}
|
|
951
961
|
else if (view.dom == text) {
|
|
952
|
-
return fromText(pos, side);
|
|
962
|
+
return fromText(text, pos, side);
|
|
953
963
|
}
|
|
954
964
|
else {
|
|
955
965
|
return enterView(view, pos, side);
|
|
956
966
|
}
|
|
957
967
|
}
|
|
958
|
-
function
|
|
968
|
+
function scanCompositionNode(pos, side, node, fromText) {
|
|
969
|
+
if (node.nodeType == 3) {
|
|
970
|
+
let len = node.nodeValue.length;
|
|
971
|
+
if (pos <= len)
|
|
972
|
+
return fromText(node, pos, side);
|
|
973
|
+
pos -= len;
|
|
974
|
+
}
|
|
975
|
+
else if (node.nodeType == 1 && node.contentEditable != "false") {
|
|
976
|
+
for (let child = node.firstChild; child; child = child.nextSibling) {
|
|
977
|
+
let inner = scanCompositionNode(pos, side, child, fromText);
|
|
978
|
+
if (typeof inner != "number")
|
|
979
|
+
return inner;
|
|
980
|
+
pos = inner;
|
|
981
|
+
}
|
|
982
|
+
}
|
|
983
|
+
return pos;
|
|
984
|
+
}
|
|
985
|
+
function posFromDOMInCompositionTree(node, offset, view, text, dLen) {
|
|
959
986
|
if (view instanceof MarkView) {
|
|
960
987
|
let pos = 0;
|
|
961
|
-
for (let child
|
|
962
|
-
let
|
|
963
|
-
if (
|
|
964
|
-
|
|
965
|
-
|
|
988
|
+
for (let child = view.dom.firstChild; child; child = child.nextSibling) {
|
|
989
|
+
let childView = ContentView.get(child);
|
|
990
|
+
if (childView) {
|
|
991
|
+
let hasComp = contains(child, text);
|
|
992
|
+
if (contains(child, node))
|
|
993
|
+
return pos + (hasComp ? posFromDOMInCompositionTree(node, offset, childView, text, dLen)
|
|
994
|
+
: childView.localPosFromDOM(node, offset));
|
|
995
|
+
pos += childView.length + (hasComp ? dLen : 0);
|
|
996
|
+
}
|
|
997
|
+
else {
|
|
998
|
+
let inner = posFromDOMInOpaqueNode(node, offset, child);
|
|
999
|
+
if (inner.result != null)
|
|
1000
|
+
return pos + inner.result;
|
|
1001
|
+
pos += inner.size;
|
|
1002
|
+
}
|
|
966
1003
|
}
|
|
967
1004
|
}
|
|
968
1005
|
else if (view.dom == text) {
|
|
@@ -970,6 +1007,27 @@ function posFromDOMInCompositionTree(node, offset, view, text) {
|
|
|
970
1007
|
}
|
|
971
1008
|
return view.localPosFromDOM(node, offset);
|
|
972
1009
|
}
|
|
1010
|
+
function posFromDOMInOpaqueNode(node, offset, target) {
|
|
1011
|
+
if (target.nodeType == 3) {
|
|
1012
|
+
return node == target ? { result: offset } : { size: target.nodeValue.length };
|
|
1013
|
+
}
|
|
1014
|
+
else if (target.nodeType == 1 && target.contentEditable != "false") {
|
|
1015
|
+
let pos = 0;
|
|
1016
|
+
for (let child = target.firstChild, i = 0;; child = child.nextSibling, i++) {
|
|
1017
|
+
if (node == target && i == offset)
|
|
1018
|
+
return { result: pos };
|
|
1019
|
+
if (!child)
|
|
1020
|
+
return { size: pos };
|
|
1021
|
+
let inner = posFromDOMInOpaqueNode(node, offset, child);
|
|
1022
|
+
if (inner.result != null)
|
|
1023
|
+
return { result: offset + inner.result };
|
|
1024
|
+
pos += inner.size;
|
|
1025
|
+
}
|
|
1026
|
+
}
|
|
1027
|
+
else {
|
|
1028
|
+
return target.contains(node) ? { result: 0 } : { size: 0 };
|
|
1029
|
+
}
|
|
1030
|
+
}
|
|
973
1031
|
// These are drawn around uneditable widgets to avoid a number of
|
|
974
1032
|
// browser bugs that show up when the cursor is directly next to
|
|
975
1033
|
// uneditable inline content.
|
|
@@ -1007,6 +1065,7 @@ class WidgetBufferView extends ContentView {
|
|
|
1007
1065
|
get overrideDOMText() {
|
|
1008
1066
|
return state.Text.empty;
|
|
1009
1067
|
}
|
|
1068
|
+
get isHidden() { return true; }
|
|
1010
1069
|
}
|
|
1011
1070
|
TextView.prototype.children = WidgetView.prototype.children = WidgetBufferView.prototype.children = noChildren;
|
|
1012
1071
|
function inlineSiblingRect(view, side) {
|
|
@@ -1080,7 +1139,8 @@ function coordsInChildren(view, pos, side) {
|
|
|
1080
1139
|
if (child.children.length) {
|
|
1081
1140
|
scan(child, pos - off);
|
|
1082
1141
|
}
|
|
1083
|
-
else if (!after
|
|
1142
|
+
else if ((!after || after instanceof WidgetBufferView && side > 0) &&
|
|
1143
|
+
(end > pos || off == end && child.getSide() > 0)) {
|
|
1084
1144
|
after = child;
|
|
1085
1145
|
afterPos = pos - off;
|
|
1086
1146
|
}
|
|
@@ -1194,6 +1254,10 @@ class WidgetType {
|
|
|
1194
1254
|
*/
|
|
1195
1255
|
get customView() { return null; }
|
|
1196
1256
|
/**
|
|
1257
|
+
@internal
|
|
1258
|
+
*/
|
|
1259
|
+
get isHidden() { return false; }
|
|
1260
|
+
/**
|
|
1197
1261
|
This is called when the an instance of the widget is removed
|
|
1198
1262
|
from the editor view.
|
|
1199
1263
|
*/
|
|
@@ -1605,7 +1669,7 @@ class BlockWidgetView extends ContentView {
|
|
|
1605
1669
|
become(other) {
|
|
1606
1670
|
if (other instanceof BlockWidgetView && other.type == this.type &&
|
|
1607
1671
|
other.widget.constructor == this.widget.constructor) {
|
|
1608
|
-
if (!other.widget.
|
|
1672
|
+
if (!other.widget.compare(this.widget))
|
|
1609
1673
|
this.markDirty(true);
|
|
1610
1674
|
if (this.dom && !this.prevWidget)
|
|
1611
1675
|
this.prevWidget = this.widget;
|
|
@@ -1736,10 +1800,11 @@ class ContentBuilder {
|
|
|
1736
1800
|
}
|
|
1737
1801
|
else {
|
|
1738
1802
|
let view = WidgetView.create(deco.widget || new NullWidget("span"), len, len ? 0 : deco.startSide);
|
|
1739
|
-
let cursorBefore = this.atCursorPos && !view.isEditable && openStart <= active.length &&
|
|
1803
|
+
let cursorBefore = this.atCursorPos && !view.isEditable && openStart <= active.length &&
|
|
1804
|
+
(from < to || deco.startSide > 0);
|
|
1740
1805
|
let cursorAfter = !view.isEditable && (from < to || openStart > active.length || deco.startSide <= 0);
|
|
1741
1806
|
let line = this.getLine();
|
|
1742
|
-
if (this.pendingBuffer == 2 /* Buf.IfCursor */ && !cursorBefore)
|
|
1807
|
+
if (this.pendingBuffer == 2 /* Buf.IfCursor */ && !cursorBefore && !view.isEditable)
|
|
1743
1808
|
this.pendingBuffer = 0 /* Buf.No */;
|
|
1744
1809
|
this.flushBuffer(active);
|
|
1745
1810
|
if (cursorBefore) {
|
|
@@ -1793,6 +1858,7 @@ class NullWidget extends WidgetType {
|
|
|
1793
1858
|
eq(other) { return other.tag == this.tag; }
|
|
1794
1859
|
toDOM() { return document.createElement(this.tag); }
|
|
1795
1860
|
updateDOM(elt) { return elt.nodeName.toLowerCase() == this.tag; }
|
|
1861
|
+
get isHidden() { return true; }
|
|
1796
1862
|
}
|
|
1797
1863
|
|
|
1798
1864
|
const clickAddsSelectionRange = state.Facet.define();
|
|
@@ -2636,7 +2702,10 @@ class DocView extends ContentView {
|
|
|
2636
2702
|
updateSelection(mustRead = false, fromPointer = false) {
|
|
2637
2703
|
if (mustRead || !this.view.observer.selectionRange.focusNode)
|
|
2638
2704
|
this.view.observer.readSelectionRange();
|
|
2639
|
-
|
|
2705
|
+
let activeElt = this.view.root.activeElement, focused = activeElt == this.dom;
|
|
2706
|
+
let selectionNotFocus = !focused &&
|
|
2707
|
+
hasSelection(this.dom, this.view.observer.selectionRange) && !(activeElt && this.dom.contains(activeElt));
|
|
2708
|
+
if (!(focused || fromPointer || selectionNotFocus))
|
|
2640
2709
|
return;
|
|
2641
2710
|
let force = this.forceSelection;
|
|
2642
2711
|
this.forceSelection = false;
|
|
@@ -2646,7 +2715,7 @@ class DocView extends ContentView {
|
|
|
2646
2715
|
let head = main.empty ? anchor : this.domAtPos(main.head);
|
|
2647
2716
|
// Always reset on Firefox when next to an uneditable node to
|
|
2648
2717
|
// avoid invisible cursor bugs (#111)
|
|
2649
|
-
if (browser.gecko && main.empty && betweenUneditable(anchor)) {
|
|
2718
|
+
if (browser.gecko && main.empty && !this.compositionDeco.size && betweenUneditable(anchor)) {
|
|
2650
2719
|
let dummy = document.createTextNode("");
|
|
2651
2720
|
this.view.observer.ignore(() => anchor.node.insertBefore(dummy, anchor.node.childNodes[anchor.offset] || null));
|
|
2652
2721
|
anchor = head = new DOMPos(dummy, 0);
|
|
@@ -2706,6 +2775,11 @@ class DocView extends ContentView {
|
|
|
2706
2775
|
rawSel.removeAllRanges();
|
|
2707
2776
|
rawSel.addRange(range);
|
|
2708
2777
|
}
|
|
2778
|
+
if (selectionNotFocus && this.view.root.activeElement == this.dom) {
|
|
2779
|
+
this.dom.blur();
|
|
2780
|
+
if (activeElt)
|
|
2781
|
+
activeElt.focus();
|
|
2782
|
+
}
|
|
2709
2783
|
});
|
|
2710
2784
|
this.view.observer.setSelectionRange(anchor, head);
|
|
2711
2785
|
}
|
|
@@ -2739,11 +2813,6 @@ class DocView extends ContentView {
|
|
|
2739
2813
|
if (view.docView.posFromDOM(newRange.anchorNode, newRange.anchorOffset) != cursor.from)
|
|
2740
2814
|
sel.collapse(anchorNode, anchorOffset);
|
|
2741
2815
|
}
|
|
2742
|
-
mayControlSelection() {
|
|
2743
|
-
let active = this.view.root.activeElement;
|
|
2744
|
-
return active == this.dom ||
|
|
2745
|
-
hasSelection(this.dom, this.view.observer.selectionRange) && !(active && this.dom.contains(active));
|
|
2746
|
-
}
|
|
2747
2816
|
nearest(dom) {
|
|
2748
2817
|
for (let cur = dom; cur;) {
|
|
2749
2818
|
let domView = ContentView.get(cur);
|
|
@@ -3440,7 +3509,15 @@ class InputState {
|
|
|
3440
3509
|
// first, false means first has already been marked for this
|
|
3441
3510
|
// composition)
|
|
3442
3511
|
this.compositionFirstChange = null;
|
|
3512
|
+
// End time of the previous composition
|
|
3443
3513
|
this.compositionEndedAt = 0;
|
|
3514
|
+
// Used in a kludge to detect when an Enter keypress should be
|
|
3515
|
+
// considered part of the composition on Safari, which fires events
|
|
3516
|
+
// in the wrong order
|
|
3517
|
+
this.compositionPendingKey = false;
|
|
3518
|
+
// Used to categorize changes as part of a composition, even when
|
|
3519
|
+
// the mutation events fire shortly after the compositionend event
|
|
3520
|
+
this.compositionPendingChange = false;
|
|
3444
3521
|
this.mouseSelection = null;
|
|
3445
3522
|
let handleEvent = (handler, event) => {
|
|
3446
3523
|
if (this.ignoreDuringComposition(event))
|
|
@@ -3597,8 +3674,8 @@ class InputState {
|
|
|
3597
3674
|
// compositionend and keydown events are sometimes emitted in the
|
|
3598
3675
|
// wrong order. The key event should still be ignored, even when
|
|
3599
3676
|
// it happens after the compositionend event.
|
|
3600
|
-
if (browser.safari && !browser.ios && Date.now() - this.compositionEndedAt < 100) {
|
|
3601
|
-
this.
|
|
3677
|
+
if (browser.safari && !browser.ios && this.compositionPendingKey && Date.now() - this.compositionEndedAt < 100) {
|
|
3678
|
+
this.compositionPendingKey = false;
|
|
3602
3679
|
return true;
|
|
3603
3680
|
}
|
|
3604
3681
|
return false;
|
|
@@ -3630,8 +3707,9 @@ const PendingKeys = [
|
|
|
3630
3707
|
const EmacsyPendingKeys = "dthko";
|
|
3631
3708
|
// Key codes for modifier keys
|
|
3632
3709
|
const modifierCodes = [16, 17, 18, 20, 91, 92, 224, 225];
|
|
3710
|
+
const dragScrollMargin = 6;
|
|
3633
3711
|
function dragScrollSpeed(dist) {
|
|
3634
|
-
return dist * 0.7 + 8;
|
|
3712
|
+
return Math.max(0, dist) * 0.7 + 8;
|
|
3635
3713
|
}
|
|
3636
3714
|
class MouseSelection {
|
|
3637
3715
|
constructor(view, startEvent, style, mustSelect) {
|
|
@@ -3668,13 +3746,13 @@ class MouseSelection {
|
|
|
3668
3746
|
let sx = 0, sy = 0;
|
|
3669
3747
|
let rect = ((_a = this.scrollParent) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect())
|
|
3670
3748
|
|| { left: 0, top: 0, right: this.view.win.innerWidth, bottom: this.view.win.innerHeight };
|
|
3671
|
-
if (event.clientX <= rect.left)
|
|
3749
|
+
if (event.clientX <= rect.left + dragScrollMargin)
|
|
3672
3750
|
sx = -dragScrollSpeed(rect.left - event.clientX);
|
|
3673
|
-
else if (event.clientX >= rect.right)
|
|
3751
|
+
else if (event.clientX >= rect.right - dragScrollMargin)
|
|
3674
3752
|
sx = dragScrollSpeed(event.clientX - rect.right);
|
|
3675
|
-
if (event.clientY <= rect.top)
|
|
3753
|
+
if (event.clientY <= rect.top + dragScrollMargin)
|
|
3676
3754
|
sy = -dragScrollSpeed(rect.top - event.clientY);
|
|
3677
|
-
else if (event.clientY >= rect.bottom)
|
|
3755
|
+
else if (event.clientY >= rect.bottom - dragScrollMargin)
|
|
3678
3756
|
sy = dragScrollSpeed(event.clientY - rect.bottom);
|
|
3679
3757
|
this.setScrollSpeed(sx, sy);
|
|
3680
3758
|
}
|
|
@@ -3921,7 +3999,7 @@ function basicMouseSelection(view, event) {
|
|
|
3921
3999
|
}
|
|
3922
4000
|
},
|
|
3923
4001
|
get(event, extend, multiple) {
|
|
3924
|
-
let cur = queryPos(view, event);
|
|
4002
|
+
let cur = queryPos(view, event), removed;
|
|
3925
4003
|
let range = rangeForClick(view, cur.pos, cur.bias, type);
|
|
3926
4004
|
if (start.pos != cur.pos && !extend) {
|
|
3927
4005
|
let startRange = rangeForClick(view, start.pos, start.bias, type);
|
|
@@ -3930,8 +4008,8 @@ function basicMouseSelection(view, event) {
|
|
|
3930
4008
|
}
|
|
3931
4009
|
if (extend)
|
|
3932
4010
|
return startSel.replaceRange(startSel.main.extend(range.from, range.to));
|
|
3933
|
-
else if (multiple && startSel.ranges.length > 1 &&
|
|
3934
|
-
return
|
|
4011
|
+
else if (multiple && type == 1 && startSel.ranges.length > 1 && (removed = removeRangeAround(startSel, cur.pos)))
|
|
4012
|
+
return removed;
|
|
3935
4013
|
else if (multiple)
|
|
3936
4014
|
return startSel.addRange(range);
|
|
3937
4015
|
else
|
|
@@ -3939,11 +4017,13 @@ function basicMouseSelection(view, event) {
|
|
|
3939
4017
|
}
|
|
3940
4018
|
};
|
|
3941
4019
|
}
|
|
3942
|
-
function
|
|
3943
|
-
for (let i = 0
|
|
3944
|
-
|
|
4020
|
+
function removeRangeAround(sel, pos) {
|
|
4021
|
+
for (let i = 0; i < sel.ranges.length; i++) {
|
|
4022
|
+
let { from, to } = sel.ranges[i];
|
|
4023
|
+
if (from <= pos && to >= pos)
|
|
3945
4024
|
return state.EditorSelection.create(sel.ranges.slice(0, i).concat(sel.ranges.slice(i + 1)), sel.mainIndex == i ? 0 : sel.mainIndex - (sel.mainIndex > i ? 1 : 0));
|
|
3946
4025
|
}
|
|
4026
|
+
return null;
|
|
3947
4027
|
}
|
|
3948
4028
|
handlers.dragstart = (view, event) => {
|
|
3949
4029
|
let { selection: { main } } = view.state;
|
|
@@ -4120,6 +4200,8 @@ handlers.compositionstart = handlers.compositionupdate = view => {
|
|
|
4120
4200
|
handlers.compositionend = view => {
|
|
4121
4201
|
view.inputState.composing = -1;
|
|
4122
4202
|
view.inputState.compositionEndedAt = Date.now();
|
|
4203
|
+
view.inputState.compositionPendingKey = true;
|
|
4204
|
+
view.inputState.compositionPendingChange = view.observer.pendingRecords().length > 0;
|
|
4123
4205
|
view.inputState.compositionFirstChange = null;
|
|
4124
4206
|
if (browser.chrome && browser.android)
|
|
4125
4207
|
view.observer.flushSoon();
|
|
@@ -4467,7 +4549,8 @@ class HeightMapGap extends HeightMap {
|
|
|
4467
4549
|
if (oracle.lineWrapping) {
|
|
4468
4550
|
let totalPerLine = Math.min(this.height, oracle.lineHeight * lines);
|
|
4469
4551
|
perLine = totalPerLine / lines;
|
|
4470
|
-
|
|
4552
|
+
if (this.length > lines + 1)
|
|
4553
|
+
perChar = (this.height - totalPerLine) / (this.length - lines - 1);
|
|
4471
4554
|
}
|
|
4472
4555
|
else {
|
|
4473
4556
|
perLine = this.height / lines;
|
|
@@ -5483,16 +5566,16 @@ const baseTheme$1 = buildTheme("." + baseThemeID, {
|
|
|
5483
5566
|
"&dark .cm-selectionBackground": {
|
|
5484
5567
|
background: "#222"
|
|
5485
5568
|
},
|
|
5486
|
-
"&light.cm-focused .cm-selectionBackground": {
|
|
5569
|
+
"&light.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground": {
|
|
5487
5570
|
background: "#d7d4f0"
|
|
5488
5571
|
},
|
|
5489
|
-
"&dark.cm-focused .cm-selectionBackground": {
|
|
5572
|
+
"&dark.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground": {
|
|
5490
5573
|
background: "#233"
|
|
5491
5574
|
},
|
|
5492
5575
|
".cm-cursorLayer": {
|
|
5493
5576
|
pointerEvents: "none"
|
|
5494
5577
|
},
|
|
5495
|
-
"&.cm-focused .cm-cursorLayer": {
|
|
5578
|
+
"&.cm-focused > .cm-scroller > .cm-cursorLayer": {
|
|
5496
5579
|
animation: "steps(1) cm-blink 1.2s infinite"
|
|
5497
5580
|
},
|
|
5498
5581
|
// Two animations defined so that we can switch between them to
|
|
@@ -5514,7 +5597,7 @@ const baseTheme$1 = buildTheme("." + baseThemeID, {
|
|
|
5514
5597
|
".cm-dropCursor": {
|
|
5515
5598
|
position: "absolute"
|
|
5516
5599
|
},
|
|
5517
|
-
"&.cm-focused .cm-cursor": {
|
|
5600
|
+
"&.cm-focused > .cm-scroller > .cm-cursorLayer .cm-cursor": {
|
|
5518
5601
|
display: "block"
|
|
5519
5602
|
},
|
|
5520
5603
|
"&light .cm-activeLine": { backgroundColor: "#cceeff44" },
|
|
@@ -5775,8 +5858,7 @@ function applyDOMChange(view, domChange) {
|
|
|
5775
5858
|
}
|
|
5776
5859
|
else {
|
|
5777
5860
|
let changes = startState.changes(change);
|
|
5778
|
-
let mainSel = newSel &&
|
|
5779
|
-
? newSel.main : undefined;
|
|
5861
|
+
let mainSel = newSel && newSel.main.to <= changes.newLength ? newSel.main : undefined;
|
|
5780
5862
|
// Try to apply a composition change to all cursors
|
|
5781
5863
|
if (startState.selection.ranges.length > 1 && view.inputState.composing >= 0 &&
|
|
5782
5864
|
change.to <= sel.to && change.to >= sel.to - 10) {
|
|
@@ -5810,7 +5892,9 @@ function applyDOMChange(view, domChange) {
|
|
|
5810
5892
|
}
|
|
5811
5893
|
}
|
|
5812
5894
|
let userEvent = "input.type";
|
|
5813
|
-
if (view.composing
|
|
5895
|
+
if (view.composing ||
|
|
5896
|
+
view.inputState.compositionPendingChange && view.inputState.compositionEndedAt > Date.now() - 50) {
|
|
5897
|
+
view.inputState.compositionPendingChange = false;
|
|
5814
5898
|
userEvent += ".compose";
|
|
5815
5899
|
if (view.inputState.compositionFirstChange) {
|
|
5816
5900
|
userEvent += ".start";
|
|
@@ -6186,10 +6270,13 @@ class DOMObserver {
|
|
|
6186
6270
|
}
|
|
6187
6271
|
this.flush();
|
|
6188
6272
|
}
|
|
6189
|
-
|
|
6190
|
-
let records = this.queue;
|
|
6273
|
+
pendingRecords() {
|
|
6191
6274
|
for (let mut of this.observer.takeRecords())
|
|
6192
|
-
|
|
6275
|
+
this.queue.push(mut);
|
|
6276
|
+
return this.queue;
|
|
6277
|
+
}
|
|
6278
|
+
processRecords() {
|
|
6279
|
+
let records = this.pendingRecords();
|
|
6193
6280
|
if (records.length)
|
|
6194
6281
|
this.queue = [];
|
|
6195
6282
|
let from = -1, to = -1, typeOver = false;
|
|
@@ -8782,6 +8869,11 @@ class HoverTooltipHost {
|
|
|
8782
8869
|
update(update) {
|
|
8783
8870
|
this.manager.update(update);
|
|
8784
8871
|
}
|
|
8872
|
+
destroy() {
|
|
8873
|
+
var _a;
|
|
8874
|
+
for (let t of this.manager.tooltipViews)
|
|
8875
|
+
(_a = t.destroy) === null || _a === void 0 ? void 0 : _a.call(t);
|
|
8876
|
+
}
|
|
8785
8877
|
}
|
|
8786
8878
|
const showHoverTooltipHost = showTooltip.compute([showHoverTooltip], state => {
|
|
8787
8879
|
let tooltips = state.facet(showHoverTooltip).filter(t => t);
|
package/dist/index.js
CHANGED
|
@@ -516,6 +516,7 @@ class ContentView {
|
|
|
516
516
|
static get(node) { return node.cmView; }
|
|
517
517
|
get isEditable() { return true; }
|
|
518
518
|
get isWidget() { return false; }
|
|
519
|
+
get isHidden() { return false; }
|
|
519
520
|
merge(from, to, source, hasStart, openStart, openEnd) {
|
|
520
521
|
return false;
|
|
521
522
|
}
|
|
@@ -853,7 +854,7 @@ class WidgetView extends ContentView {
|
|
|
853
854
|
become(other) {
|
|
854
855
|
if (other.length == this.length && other instanceof WidgetView && other.side == this.side) {
|
|
855
856
|
if (this.widget.constructor == other.widget.constructor) {
|
|
856
|
-
if (!this.widget.
|
|
857
|
+
if (!this.widget.compare(other.widget))
|
|
857
858
|
this.markDirty(true);
|
|
858
859
|
if (this.dom && !this.prevWidget)
|
|
859
860
|
this.prevWidget = this.widget;
|
|
@@ -875,7 +876,9 @@ class WidgetView extends ContentView {
|
|
|
875
876
|
return text ? text.slice(start, start + this.length) : Text.empty;
|
|
876
877
|
}
|
|
877
878
|
domAtPos(pos) {
|
|
878
|
-
return pos == 0
|
|
879
|
+
return (this.length ? pos == 0 : this.side > 0)
|
|
880
|
+
? DOMPos.before(this.dom)
|
|
881
|
+
: DOMPos.after(this.dom, pos == this.length);
|
|
879
882
|
}
|
|
880
883
|
domBoundsAround() { return null; }
|
|
881
884
|
coordsAt(pos, side) {
|
|
@@ -891,6 +894,7 @@ class WidgetView extends ContentView {
|
|
|
891
894
|
}
|
|
892
895
|
get isEditable() { return false; }
|
|
893
896
|
get isWidget() { return true; }
|
|
897
|
+
get isHidden() { return this.widget.isHidden; }
|
|
894
898
|
destroy() {
|
|
895
899
|
super.destroy();
|
|
896
900
|
if (this.dom)
|
|
@@ -902,14 +906,14 @@ class CompositionView extends WidgetView {
|
|
|
902
906
|
let { topView, text } = this.widget;
|
|
903
907
|
if (!topView)
|
|
904
908
|
return new DOMPos(text, Math.min(pos, text.nodeValue.length));
|
|
905
|
-
return scanCompositionTree(pos, 0, topView, text, (v, p) => v.domAtPos(p), p => new DOMPos(text, Math.min(p, text.nodeValue.length)));
|
|
909
|
+
return scanCompositionTree(pos, 0, topView, text, this.length - topView.length, (v, p) => v.domAtPos(p), (text, p) => new DOMPos(text, Math.min(p, text.nodeValue.length)));
|
|
906
910
|
}
|
|
907
911
|
sync() { this.setDOM(this.widget.toDOM()); }
|
|
908
912
|
localPosFromDOM(node, offset) {
|
|
909
913
|
let { topView, text } = this.widget;
|
|
910
914
|
if (!topView)
|
|
911
915
|
return Math.min(offset, this.length);
|
|
912
|
-
return posFromDOMInCompositionTree(node, offset, topView, text);
|
|
916
|
+
return posFromDOMInCompositionTree(node, offset, topView, text, this.length - topView.length);
|
|
913
917
|
}
|
|
914
918
|
ignoreMutation() { return false; }
|
|
915
919
|
get overrideDOMText() { return null; }
|
|
@@ -917,7 +921,7 @@ class CompositionView extends WidgetView {
|
|
|
917
921
|
let { topView, text } = this.widget;
|
|
918
922
|
if (!topView)
|
|
919
923
|
return textCoords(text, pos, side);
|
|
920
|
-
return scanCompositionTree(pos, side, topView, text, (v, pos, side) => v.coordsAt(pos, side), (pos, side) => textCoords(text, pos, side));
|
|
924
|
+
return scanCompositionTree(pos, side, topView, text, this.length - topView.length, (v, pos, side) => v.coordsAt(pos, side), (text, pos, side) => textCoords(text, pos, side));
|
|
921
925
|
}
|
|
922
926
|
destroy() {
|
|
923
927
|
var _a;
|
|
@@ -930,35 +934,68 @@ class CompositionView extends WidgetView {
|
|
|
930
934
|
// Uses the old structure of a chunk of content view frozen for
|
|
931
935
|
// composition to try and find a reasonable DOM location for the given
|
|
932
936
|
// offset.
|
|
933
|
-
function scanCompositionTree(pos, side, view, text, enterView, fromText) {
|
|
937
|
+
function scanCompositionTree(pos, side, view, text, dLen, enterView, fromText) {
|
|
934
938
|
if (view instanceof MarkView) {
|
|
935
939
|
for (let child = view.dom.firstChild; child; child = child.nextSibling) {
|
|
936
940
|
let desc = ContentView.get(child);
|
|
937
|
-
if (!desc)
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
941
|
+
if (!desc) {
|
|
942
|
+
let inner = scanCompositionNode(pos, side, child, fromText);
|
|
943
|
+
if (typeof inner != "number")
|
|
944
|
+
return inner;
|
|
945
|
+
pos = inner;
|
|
946
|
+
}
|
|
947
|
+
else {
|
|
948
|
+
let hasComp = contains(child, text);
|
|
949
|
+
let len = desc.length + (hasComp ? dLen : 0);
|
|
950
|
+
if (pos < len || pos == len && desc.getSide() <= 0)
|
|
951
|
+
return hasComp ? scanCompositionTree(pos, side, desc, text, dLen, enterView, fromText) : enterView(desc, pos, side);
|
|
952
|
+
pos -= len;
|
|
953
|
+
}
|
|
944
954
|
}
|
|
945
955
|
return enterView(view, view.length, -1);
|
|
946
956
|
}
|
|
947
957
|
else if (view.dom == text) {
|
|
948
|
-
return fromText(pos, side);
|
|
958
|
+
return fromText(text, pos, side);
|
|
949
959
|
}
|
|
950
960
|
else {
|
|
951
961
|
return enterView(view, pos, side);
|
|
952
962
|
}
|
|
953
963
|
}
|
|
954
|
-
function
|
|
964
|
+
function scanCompositionNode(pos, side, node, fromText) {
|
|
965
|
+
if (node.nodeType == 3) {
|
|
966
|
+
let len = node.nodeValue.length;
|
|
967
|
+
if (pos <= len)
|
|
968
|
+
return fromText(node, pos, side);
|
|
969
|
+
pos -= len;
|
|
970
|
+
}
|
|
971
|
+
else if (node.nodeType == 1 && node.contentEditable != "false") {
|
|
972
|
+
for (let child = node.firstChild; child; child = child.nextSibling) {
|
|
973
|
+
let inner = scanCompositionNode(pos, side, child, fromText);
|
|
974
|
+
if (typeof inner != "number")
|
|
975
|
+
return inner;
|
|
976
|
+
pos = inner;
|
|
977
|
+
}
|
|
978
|
+
}
|
|
979
|
+
return pos;
|
|
980
|
+
}
|
|
981
|
+
function posFromDOMInCompositionTree(node, offset, view, text, dLen) {
|
|
955
982
|
if (view instanceof MarkView) {
|
|
956
983
|
let pos = 0;
|
|
957
|
-
for (let child
|
|
958
|
-
let
|
|
959
|
-
if (
|
|
960
|
-
|
|
961
|
-
|
|
984
|
+
for (let child = view.dom.firstChild; child; child = child.nextSibling) {
|
|
985
|
+
let childView = ContentView.get(child);
|
|
986
|
+
if (childView) {
|
|
987
|
+
let hasComp = contains(child, text);
|
|
988
|
+
if (contains(child, node))
|
|
989
|
+
return pos + (hasComp ? posFromDOMInCompositionTree(node, offset, childView, text, dLen)
|
|
990
|
+
: childView.localPosFromDOM(node, offset));
|
|
991
|
+
pos += childView.length + (hasComp ? dLen : 0);
|
|
992
|
+
}
|
|
993
|
+
else {
|
|
994
|
+
let inner = posFromDOMInOpaqueNode(node, offset, child);
|
|
995
|
+
if (inner.result != null)
|
|
996
|
+
return pos + inner.result;
|
|
997
|
+
pos += inner.size;
|
|
998
|
+
}
|
|
962
999
|
}
|
|
963
1000
|
}
|
|
964
1001
|
else if (view.dom == text) {
|
|
@@ -966,6 +1003,27 @@ function posFromDOMInCompositionTree(node, offset, view, text) {
|
|
|
966
1003
|
}
|
|
967
1004
|
return view.localPosFromDOM(node, offset);
|
|
968
1005
|
}
|
|
1006
|
+
function posFromDOMInOpaqueNode(node, offset, target) {
|
|
1007
|
+
if (target.nodeType == 3) {
|
|
1008
|
+
return node == target ? { result: offset } : { size: target.nodeValue.length };
|
|
1009
|
+
}
|
|
1010
|
+
else if (target.nodeType == 1 && target.contentEditable != "false") {
|
|
1011
|
+
let pos = 0;
|
|
1012
|
+
for (let child = target.firstChild, i = 0;; child = child.nextSibling, i++) {
|
|
1013
|
+
if (node == target && i == offset)
|
|
1014
|
+
return { result: pos };
|
|
1015
|
+
if (!child)
|
|
1016
|
+
return { size: pos };
|
|
1017
|
+
let inner = posFromDOMInOpaqueNode(node, offset, child);
|
|
1018
|
+
if (inner.result != null)
|
|
1019
|
+
return { result: offset + inner.result };
|
|
1020
|
+
pos += inner.size;
|
|
1021
|
+
}
|
|
1022
|
+
}
|
|
1023
|
+
else {
|
|
1024
|
+
return target.contains(node) ? { result: 0 } : { size: 0 };
|
|
1025
|
+
}
|
|
1026
|
+
}
|
|
969
1027
|
// These are drawn around uneditable widgets to avoid a number of
|
|
970
1028
|
// browser bugs that show up when the cursor is directly next to
|
|
971
1029
|
// uneditable inline content.
|
|
@@ -1003,6 +1061,7 @@ class WidgetBufferView extends ContentView {
|
|
|
1003
1061
|
get overrideDOMText() {
|
|
1004
1062
|
return Text.empty;
|
|
1005
1063
|
}
|
|
1064
|
+
get isHidden() { return true; }
|
|
1006
1065
|
}
|
|
1007
1066
|
TextView.prototype.children = WidgetView.prototype.children = WidgetBufferView.prototype.children = noChildren;
|
|
1008
1067
|
function inlineSiblingRect(view, side) {
|
|
@@ -1076,7 +1135,8 @@ function coordsInChildren(view, pos, side) {
|
|
|
1076
1135
|
if (child.children.length) {
|
|
1077
1136
|
scan(child, pos - off);
|
|
1078
1137
|
}
|
|
1079
|
-
else if (!after
|
|
1138
|
+
else if ((!after || after instanceof WidgetBufferView && side > 0) &&
|
|
1139
|
+
(end > pos || off == end && child.getSide() > 0)) {
|
|
1080
1140
|
after = child;
|
|
1081
1141
|
afterPos = pos - off;
|
|
1082
1142
|
}
|
|
@@ -1190,6 +1250,10 @@ class WidgetType {
|
|
|
1190
1250
|
*/
|
|
1191
1251
|
get customView() { return null; }
|
|
1192
1252
|
/**
|
|
1253
|
+
@internal
|
|
1254
|
+
*/
|
|
1255
|
+
get isHidden() { return false; }
|
|
1256
|
+
/**
|
|
1193
1257
|
This is called when the an instance of the widget is removed
|
|
1194
1258
|
from the editor view.
|
|
1195
1259
|
*/
|
|
@@ -1600,7 +1664,7 @@ class BlockWidgetView extends ContentView {
|
|
|
1600
1664
|
become(other) {
|
|
1601
1665
|
if (other instanceof BlockWidgetView && other.type == this.type &&
|
|
1602
1666
|
other.widget.constructor == this.widget.constructor) {
|
|
1603
|
-
if (!other.widget.
|
|
1667
|
+
if (!other.widget.compare(this.widget))
|
|
1604
1668
|
this.markDirty(true);
|
|
1605
1669
|
if (this.dom && !this.prevWidget)
|
|
1606
1670
|
this.prevWidget = this.widget;
|
|
@@ -1731,10 +1795,11 @@ class ContentBuilder {
|
|
|
1731
1795
|
}
|
|
1732
1796
|
else {
|
|
1733
1797
|
let view = WidgetView.create(deco.widget || new NullWidget("span"), len, len ? 0 : deco.startSide);
|
|
1734
|
-
let cursorBefore = this.atCursorPos && !view.isEditable && openStart <= active.length &&
|
|
1798
|
+
let cursorBefore = this.atCursorPos && !view.isEditable && openStart <= active.length &&
|
|
1799
|
+
(from < to || deco.startSide > 0);
|
|
1735
1800
|
let cursorAfter = !view.isEditable && (from < to || openStart > active.length || deco.startSide <= 0);
|
|
1736
1801
|
let line = this.getLine();
|
|
1737
|
-
if (this.pendingBuffer == 2 /* Buf.IfCursor */ && !cursorBefore)
|
|
1802
|
+
if (this.pendingBuffer == 2 /* Buf.IfCursor */ && !cursorBefore && !view.isEditable)
|
|
1738
1803
|
this.pendingBuffer = 0 /* Buf.No */;
|
|
1739
1804
|
this.flushBuffer(active);
|
|
1740
1805
|
if (cursorBefore) {
|
|
@@ -1788,6 +1853,7 @@ class NullWidget extends WidgetType {
|
|
|
1788
1853
|
eq(other) { return other.tag == this.tag; }
|
|
1789
1854
|
toDOM() { return document.createElement(this.tag); }
|
|
1790
1855
|
updateDOM(elt) { return elt.nodeName.toLowerCase() == this.tag; }
|
|
1856
|
+
get isHidden() { return true; }
|
|
1791
1857
|
}
|
|
1792
1858
|
|
|
1793
1859
|
const clickAddsSelectionRange = /*@__PURE__*/Facet.define();
|
|
@@ -2630,7 +2696,10 @@ class DocView extends ContentView {
|
|
|
2630
2696
|
updateSelection(mustRead = false, fromPointer = false) {
|
|
2631
2697
|
if (mustRead || !this.view.observer.selectionRange.focusNode)
|
|
2632
2698
|
this.view.observer.readSelectionRange();
|
|
2633
|
-
|
|
2699
|
+
let activeElt = this.view.root.activeElement, focused = activeElt == this.dom;
|
|
2700
|
+
let selectionNotFocus = !focused &&
|
|
2701
|
+
hasSelection(this.dom, this.view.observer.selectionRange) && !(activeElt && this.dom.contains(activeElt));
|
|
2702
|
+
if (!(focused || fromPointer || selectionNotFocus))
|
|
2634
2703
|
return;
|
|
2635
2704
|
let force = this.forceSelection;
|
|
2636
2705
|
this.forceSelection = false;
|
|
@@ -2640,7 +2709,7 @@ class DocView extends ContentView {
|
|
|
2640
2709
|
let head = main.empty ? anchor : this.domAtPos(main.head);
|
|
2641
2710
|
// Always reset on Firefox when next to an uneditable node to
|
|
2642
2711
|
// avoid invisible cursor bugs (#111)
|
|
2643
|
-
if (browser.gecko && main.empty && betweenUneditable(anchor)) {
|
|
2712
|
+
if (browser.gecko && main.empty && !this.compositionDeco.size && betweenUneditable(anchor)) {
|
|
2644
2713
|
let dummy = document.createTextNode("");
|
|
2645
2714
|
this.view.observer.ignore(() => anchor.node.insertBefore(dummy, anchor.node.childNodes[anchor.offset] || null));
|
|
2646
2715
|
anchor = head = new DOMPos(dummy, 0);
|
|
@@ -2700,6 +2769,11 @@ class DocView extends ContentView {
|
|
|
2700
2769
|
rawSel.removeAllRanges();
|
|
2701
2770
|
rawSel.addRange(range);
|
|
2702
2771
|
}
|
|
2772
|
+
if (selectionNotFocus && this.view.root.activeElement == this.dom) {
|
|
2773
|
+
this.dom.blur();
|
|
2774
|
+
if (activeElt)
|
|
2775
|
+
activeElt.focus();
|
|
2776
|
+
}
|
|
2703
2777
|
});
|
|
2704
2778
|
this.view.observer.setSelectionRange(anchor, head);
|
|
2705
2779
|
}
|
|
@@ -2733,11 +2807,6 @@ class DocView extends ContentView {
|
|
|
2733
2807
|
if (view.docView.posFromDOM(newRange.anchorNode, newRange.anchorOffset) != cursor.from)
|
|
2734
2808
|
sel.collapse(anchorNode, anchorOffset);
|
|
2735
2809
|
}
|
|
2736
|
-
mayControlSelection() {
|
|
2737
|
-
let active = this.view.root.activeElement;
|
|
2738
|
-
return active == this.dom ||
|
|
2739
|
-
hasSelection(this.dom, this.view.observer.selectionRange) && !(active && this.dom.contains(active));
|
|
2740
|
-
}
|
|
2741
2810
|
nearest(dom) {
|
|
2742
2811
|
for (let cur = dom; cur;) {
|
|
2743
2812
|
let domView = ContentView.get(cur);
|
|
@@ -3434,7 +3503,15 @@ class InputState {
|
|
|
3434
3503
|
// first, false means first has already been marked for this
|
|
3435
3504
|
// composition)
|
|
3436
3505
|
this.compositionFirstChange = null;
|
|
3506
|
+
// End time of the previous composition
|
|
3437
3507
|
this.compositionEndedAt = 0;
|
|
3508
|
+
// Used in a kludge to detect when an Enter keypress should be
|
|
3509
|
+
// considered part of the composition on Safari, which fires events
|
|
3510
|
+
// in the wrong order
|
|
3511
|
+
this.compositionPendingKey = false;
|
|
3512
|
+
// Used to categorize changes as part of a composition, even when
|
|
3513
|
+
// the mutation events fire shortly after the compositionend event
|
|
3514
|
+
this.compositionPendingChange = false;
|
|
3438
3515
|
this.mouseSelection = null;
|
|
3439
3516
|
let handleEvent = (handler, event) => {
|
|
3440
3517
|
if (this.ignoreDuringComposition(event))
|
|
@@ -3591,8 +3668,8 @@ class InputState {
|
|
|
3591
3668
|
// compositionend and keydown events are sometimes emitted in the
|
|
3592
3669
|
// wrong order. The key event should still be ignored, even when
|
|
3593
3670
|
// it happens after the compositionend event.
|
|
3594
|
-
if (browser.safari && !browser.ios && Date.now() - this.compositionEndedAt < 100) {
|
|
3595
|
-
this.
|
|
3671
|
+
if (browser.safari && !browser.ios && this.compositionPendingKey && Date.now() - this.compositionEndedAt < 100) {
|
|
3672
|
+
this.compositionPendingKey = false;
|
|
3596
3673
|
return true;
|
|
3597
3674
|
}
|
|
3598
3675
|
return false;
|
|
@@ -3624,8 +3701,9 @@ const PendingKeys = [
|
|
|
3624
3701
|
const EmacsyPendingKeys = "dthko";
|
|
3625
3702
|
// Key codes for modifier keys
|
|
3626
3703
|
const modifierCodes = [16, 17, 18, 20, 91, 92, 224, 225];
|
|
3704
|
+
const dragScrollMargin = 6;
|
|
3627
3705
|
function dragScrollSpeed(dist) {
|
|
3628
|
-
return dist * 0.7 + 8;
|
|
3706
|
+
return Math.max(0, dist) * 0.7 + 8;
|
|
3629
3707
|
}
|
|
3630
3708
|
class MouseSelection {
|
|
3631
3709
|
constructor(view, startEvent, style, mustSelect) {
|
|
@@ -3662,13 +3740,13 @@ class MouseSelection {
|
|
|
3662
3740
|
let sx = 0, sy = 0;
|
|
3663
3741
|
let rect = ((_a = this.scrollParent) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect())
|
|
3664
3742
|
|| { left: 0, top: 0, right: this.view.win.innerWidth, bottom: this.view.win.innerHeight };
|
|
3665
|
-
if (event.clientX <= rect.left)
|
|
3743
|
+
if (event.clientX <= rect.left + dragScrollMargin)
|
|
3666
3744
|
sx = -dragScrollSpeed(rect.left - event.clientX);
|
|
3667
|
-
else if (event.clientX >= rect.right)
|
|
3745
|
+
else if (event.clientX >= rect.right - dragScrollMargin)
|
|
3668
3746
|
sx = dragScrollSpeed(event.clientX - rect.right);
|
|
3669
|
-
if (event.clientY <= rect.top)
|
|
3747
|
+
if (event.clientY <= rect.top + dragScrollMargin)
|
|
3670
3748
|
sy = -dragScrollSpeed(rect.top - event.clientY);
|
|
3671
|
-
else if (event.clientY >= rect.bottom)
|
|
3749
|
+
else if (event.clientY >= rect.bottom - dragScrollMargin)
|
|
3672
3750
|
sy = dragScrollSpeed(event.clientY - rect.bottom);
|
|
3673
3751
|
this.setScrollSpeed(sx, sy);
|
|
3674
3752
|
}
|
|
@@ -3915,7 +3993,7 @@ function basicMouseSelection(view, event) {
|
|
|
3915
3993
|
}
|
|
3916
3994
|
},
|
|
3917
3995
|
get(event, extend, multiple) {
|
|
3918
|
-
let cur = queryPos(view, event);
|
|
3996
|
+
let cur = queryPos(view, event), removed;
|
|
3919
3997
|
let range = rangeForClick(view, cur.pos, cur.bias, type);
|
|
3920
3998
|
if (start.pos != cur.pos && !extend) {
|
|
3921
3999
|
let startRange = rangeForClick(view, start.pos, start.bias, type);
|
|
@@ -3924,8 +4002,8 @@ function basicMouseSelection(view, event) {
|
|
|
3924
4002
|
}
|
|
3925
4003
|
if (extend)
|
|
3926
4004
|
return startSel.replaceRange(startSel.main.extend(range.from, range.to));
|
|
3927
|
-
else if (multiple && startSel.ranges.length > 1 &&
|
|
3928
|
-
return
|
|
4005
|
+
else if (multiple && type == 1 && startSel.ranges.length > 1 && (removed = removeRangeAround(startSel, cur.pos)))
|
|
4006
|
+
return removed;
|
|
3929
4007
|
else if (multiple)
|
|
3930
4008
|
return startSel.addRange(range);
|
|
3931
4009
|
else
|
|
@@ -3933,11 +4011,13 @@ function basicMouseSelection(view, event) {
|
|
|
3933
4011
|
}
|
|
3934
4012
|
};
|
|
3935
4013
|
}
|
|
3936
|
-
function
|
|
3937
|
-
for (let i = 0
|
|
3938
|
-
|
|
4014
|
+
function removeRangeAround(sel, pos) {
|
|
4015
|
+
for (let i = 0; i < sel.ranges.length; i++) {
|
|
4016
|
+
let { from, to } = sel.ranges[i];
|
|
4017
|
+
if (from <= pos && to >= pos)
|
|
3939
4018
|
return EditorSelection.create(sel.ranges.slice(0, i).concat(sel.ranges.slice(i + 1)), sel.mainIndex == i ? 0 : sel.mainIndex - (sel.mainIndex > i ? 1 : 0));
|
|
3940
4019
|
}
|
|
4020
|
+
return null;
|
|
3941
4021
|
}
|
|
3942
4022
|
handlers.dragstart = (view, event) => {
|
|
3943
4023
|
let { selection: { main } } = view.state;
|
|
@@ -4114,6 +4194,8 @@ handlers.compositionstart = handlers.compositionupdate = view => {
|
|
|
4114
4194
|
handlers.compositionend = view => {
|
|
4115
4195
|
view.inputState.composing = -1;
|
|
4116
4196
|
view.inputState.compositionEndedAt = Date.now();
|
|
4197
|
+
view.inputState.compositionPendingKey = true;
|
|
4198
|
+
view.inputState.compositionPendingChange = view.observer.pendingRecords().length > 0;
|
|
4117
4199
|
view.inputState.compositionFirstChange = null;
|
|
4118
4200
|
if (browser.chrome && browser.android)
|
|
4119
4201
|
view.observer.flushSoon();
|
|
@@ -4460,7 +4542,8 @@ class HeightMapGap extends HeightMap {
|
|
|
4460
4542
|
if (oracle.lineWrapping) {
|
|
4461
4543
|
let totalPerLine = Math.min(this.height, oracle.lineHeight * lines);
|
|
4462
4544
|
perLine = totalPerLine / lines;
|
|
4463
|
-
|
|
4545
|
+
if (this.length > lines + 1)
|
|
4546
|
+
perChar = (this.height - totalPerLine) / (this.length - lines - 1);
|
|
4464
4547
|
}
|
|
4465
4548
|
else {
|
|
4466
4549
|
perLine = this.height / lines;
|
|
@@ -5476,16 +5559,16 @@ const baseTheme$1 = /*@__PURE__*/buildTheme("." + baseThemeID, {
|
|
|
5476
5559
|
"&dark .cm-selectionBackground": {
|
|
5477
5560
|
background: "#222"
|
|
5478
5561
|
},
|
|
5479
|
-
"&light.cm-focused .cm-selectionBackground": {
|
|
5562
|
+
"&light.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground": {
|
|
5480
5563
|
background: "#d7d4f0"
|
|
5481
5564
|
},
|
|
5482
|
-
"&dark.cm-focused .cm-selectionBackground": {
|
|
5565
|
+
"&dark.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground": {
|
|
5483
5566
|
background: "#233"
|
|
5484
5567
|
},
|
|
5485
5568
|
".cm-cursorLayer": {
|
|
5486
5569
|
pointerEvents: "none"
|
|
5487
5570
|
},
|
|
5488
|
-
"&.cm-focused .cm-cursorLayer": {
|
|
5571
|
+
"&.cm-focused > .cm-scroller > .cm-cursorLayer": {
|
|
5489
5572
|
animation: "steps(1) cm-blink 1.2s infinite"
|
|
5490
5573
|
},
|
|
5491
5574
|
// Two animations defined so that we can switch between them to
|
|
@@ -5507,7 +5590,7 @@ const baseTheme$1 = /*@__PURE__*/buildTheme("." + baseThemeID, {
|
|
|
5507
5590
|
".cm-dropCursor": {
|
|
5508
5591
|
position: "absolute"
|
|
5509
5592
|
},
|
|
5510
|
-
"&.cm-focused .cm-cursor": {
|
|
5593
|
+
"&.cm-focused > .cm-scroller > .cm-cursorLayer .cm-cursor": {
|
|
5511
5594
|
display: "block"
|
|
5512
5595
|
},
|
|
5513
5596
|
"&light .cm-activeLine": { backgroundColor: "#cceeff44" },
|
|
@@ -5768,8 +5851,7 @@ function applyDOMChange(view, domChange) {
|
|
|
5768
5851
|
}
|
|
5769
5852
|
else {
|
|
5770
5853
|
let changes = startState.changes(change);
|
|
5771
|
-
let mainSel = newSel &&
|
|
5772
|
-
? newSel.main : undefined;
|
|
5854
|
+
let mainSel = newSel && newSel.main.to <= changes.newLength ? newSel.main : undefined;
|
|
5773
5855
|
// Try to apply a composition change to all cursors
|
|
5774
5856
|
if (startState.selection.ranges.length > 1 && view.inputState.composing >= 0 &&
|
|
5775
5857
|
change.to <= sel.to && change.to >= sel.to - 10) {
|
|
@@ -5803,7 +5885,9 @@ function applyDOMChange(view, domChange) {
|
|
|
5803
5885
|
}
|
|
5804
5886
|
}
|
|
5805
5887
|
let userEvent = "input.type";
|
|
5806
|
-
if (view.composing
|
|
5888
|
+
if (view.composing ||
|
|
5889
|
+
view.inputState.compositionPendingChange && view.inputState.compositionEndedAt > Date.now() - 50) {
|
|
5890
|
+
view.inputState.compositionPendingChange = false;
|
|
5807
5891
|
userEvent += ".compose";
|
|
5808
5892
|
if (view.inputState.compositionFirstChange) {
|
|
5809
5893
|
userEvent += ".start";
|
|
@@ -6179,10 +6263,13 @@ class DOMObserver {
|
|
|
6179
6263
|
}
|
|
6180
6264
|
this.flush();
|
|
6181
6265
|
}
|
|
6182
|
-
|
|
6183
|
-
let records = this.queue;
|
|
6266
|
+
pendingRecords() {
|
|
6184
6267
|
for (let mut of this.observer.takeRecords())
|
|
6185
|
-
|
|
6268
|
+
this.queue.push(mut);
|
|
6269
|
+
return this.queue;
|
|
6270
|
+
}
|
|
6271
|
+
processRecords() {
|
|
6272
|
+
let records = this.pendingRecords();
|
|
6186
6273
|
if (records.length)
|
|
6187
6274
|
this.queue = [];
|
|
6188
6275
|
let from = -1, to = -1, typeOver = false;
|
|
@@ -8775,6 +8862,11 @@ class HoverTooltipHost {
|
|
|
8775
8862
|
update(update) {
|
|
8776
8863
|
this.manager.update(update);
|
|
8777
8864
|
}
|
|
8865
|
+
destroy() {
|
|
8866
|
+
var _a;
|
|
8867
|
+
for (let t of this.manager.tooltipViews)
|
|
8868
|
+
(_a = t.destroy) === null || _a === void 0 ? void 0 : _a.call(t);
|
|
8869
|
+
}
|
|
8778
8870
|
}
|
|
8779
8871
|
const showHoverTooltipHost = /*@__PURE__*/showTooltip.compute([showHoverTooltip], state => {
|
|
8780
8872
|
let tooltips = state.facet(showHoverTooltip).filter(t => t);
|