@codemirror/view 0.19.43 → 0.19.46
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 +30 -0
- package/dist/index.cjs +150 -41
- package/dist/index.d.ts +9 -1
- package/dist/index.js +150 -41
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,33 @@
|
|
|
1
|
+
## 0.19.46 (2022-03-03)
|
|
2
|
+
|
|
3
|
+
### Bug fixes
|
|
4
|
+
|
|
5
|
+
Fix a bug where block widgets on the edges of viewports could cause the positioning of content to misalign with the gutter and height computations.
|
|
6
|
+
|
|
7
|
+
Improve cursor height next to widgets.
|
|
8
|
+
|
|
9
|
+
Fix a bug where mapping positions to screen coordinates could return incorred coordinates during composition.
|
|
10
|
+
|
|
11
|
+
## 0.19.45 (2022-02-23)
|
|
12
|
+
|
|
13
|
+
### Bug fixes
|
|
14
|
+
|
|
15
|
+
Fix an issue where the library failed to call `WidgetType.destroy` on the old widget when replacing a widget with a different widget of the same type.
|
|
16
|
+
|
|
17
|
+
Fix an issue where the editor would compute DOM positions inside composition contexts incorrectly in some cases, causing the selection to be put in the wrong place and needlessly interrupting compositions.
|
|
18
|
+
|
|
19
|
+
Fix leaking of resize event handlers.
|
|
20
|
+
|
|
21
|
+
## 0.19.44 (2022-02-17)
|
|
22
|
+
|
|
23
|
+
### Bug fixes
|
|
24
|
+
|
|
25
|
+
Fix a crash that occasionally occurred when drag-selecting in a way that scrolled the editor.
|
|
26
|
+
|
|
27
|
+
### New features
|
|
28
|
+
|
|
29
|
+
The new `EditorView.compositionStarted` property indicates whether a composition is starting.
|
|
30
|
+
|
|
1
31
|
## 0.19.43 (2022-02-16)
|
|
2
32
|
|
|
3
33
|
### Bug fixes
|
package/dist/index.cjs
CHANGED
|
@@ -22,7 +22,7 @@ function getSelection(root) {
|
|
|
22
22
|
return target.getSelection();
|
|
23
23
|
}
|
|
24
24
|
function contains(dom, node) {
|
|
25
|
-
return node ? dom.contains(node.nodeType != 1 ? node.parentNode : node) : false;
|
|
25
|
+
return node ? dom == node || dom.contains(node.nodeType != 1 ? node.parentNode : node) : false;
|
|
26
26
|
}
|
|
27
27
|
function deepActiveElement() {
|
|
28
28
|
let elt = document.activeElement;
|
|
@@ -781,6 +781,7 @@ class WidgetView extends ContentView {
|
|
|
781
781
|
this.widget = widget;
|
|
782
782
|
this.length = length;
|
|
783
783
|
this.side = side;
|
|
784
|
+
this.prevWidget = null;
|
|
784
785
|
}
|
|
785
786
|
static create(widget, length, side) {
|
|
786
787
|
return new (widget.customView || WidgetView)(widget, length, side);
|
|
@@ -792,6 +793,9 @@ class WidgetView extends ContentView {
|
|
|
792
793
|
}
|
|
793
794
|
sync() {
|
|
794
795
|
if (!this.dom || !this.widget.updateDOM(this.dom)) {
|
|
796
|
+
if (this.dom && this.prevWidget)
|
|
797
|
+
this.prevWidget.destroy(this.dom);
|
|
798
|
+
this.prevWidget = null;
|
|
795
799
|
this.setDOM(this.widget.toDOM(this.editorView));
|
|
796
800
|
this.dom.contentEditable = "false";
|
|
797
801
|
}
|
|
@@ -809,6 +813,8 @@ class WidgetView extends ContentView {
|
|
|
809
813
|
if (this.widget.constructor == other.widget.constructor) {
|
|
810
814
|
if (!this.widget.eq(other.widget))
|
|
811
815
|
this.markDirty(true);
|
|
816
|
+
if (this.dom && !this.prevWidget)
|
|
817
|
+
this.prevWidget = this.widget;
|
|
812
818
|
this.widget = other.widget;
|
|
813
819
|
return true;
|
|
814
820
|
}
|
|
@@ -849,16 +855,69 @@ class WidgetView extends ContentView {
|
|
|
849
855
|
}
|
|
850
856
|
}
|
|
851
857
|
class CompositionView extends WidgetView {
|
|
852
|
-
domAtPos(pos) {
|
|
858
|
+
domAtPos(pos) {
|
|
859
|
+
let { topView, text } = this.widget;
|
|
860
|
+
if (!topView)
|
|
861
|
+
return new DOMPos(text, Math.min(pos, text.nodeValue.length));
|
|
862
|
+
return scanCompositionTree(pos, 0, topView, text, (v, p) => v.domAtPos(p), p => new DOMPos(text, Math.min(p, text.nodeValue.length)));
|
|
863
|
+
}
|
|
853
864
|
sync() { this.setDOM(this.widget.toDOM()); }
|
|
854
865
|
localPosFromDOM(node, offset) {
|
|
855
|
-
|
|
866
|
+
let { topView, text } = this.widget;
|
|
867
|
+
if (!topView)
|
|
868
|
+
return Math.min(offset, this.length);
|
|
869
|
+
return posFromDOMInCompositionTree(node, offset, topView, text);
|
|
856
870
|
}
|
|
857
871
|
ignoreMutation() { return false; }
|
|
858
872
|
get overrideDOMText() { return null; }
|
|
859
|
-
coordsAt(pos, side) {
|
|
873
|
+
coordsAt(pos, side) {
|
|
874
|
+
let { topView, text } = this.widget;
|
|
875
|
+
if (!topView)
|
|
876
|
+
return textCoords(text, pos, side);
|
|
877
|
+
return scanCompositionTree(pos, side, topView, text, (v, pos, side) => v.coordsAt(pos, side), (pos, side) => textCoords(text, pos, side));
|
|
878
|
+
}
|
|
879
|
+
destroy() {
|
|
880
|
+
var _a;
|
|
881
|
+
super.destroy();
|
|
882
|
+
(_a = this.widget.topView) === null || _a === void 0 ? void 0 : _a.destroy();
|
|
883
|
+
}
|
|
860
884
|
get isEditable() { return true; }
|
|
861
885
|
}
|
|
886
|
+
// Uses the old structure of a chunk of content view frozen for
|
|
887
|
+
// composition to try and find a reasonable DOM location for the given
|
|
888
|
+
// offset.
|
|
889
|
+
function scanCompositionTree(pos, side, view, text, enterView, fromText) {
|
|
890
|
+
if (view instanceof MarkView) {
|
|
891
|
+
for (let child of view.children) {
|
|
892
|
+
let hasComp = contains(child.dom, text);
|
|
893
|
+
let len = hasComp ? text.nodeValue.length : child.length;
|
|
894
|
+
if (pos < len || pos == len && child.getSide() <= 0)
|
|
895
|
+
return hasComp ? scanCompositionTree(pos, side, child, text, enterView, fromText) : enterView(child, pos, side);
|
|
896
|
+
pos -= len;
|
|
897
|
+
}
|
|
898
|
+
return enterView(view, view.length, -1);
|
|
899
|
+
}
|
|
900
|
+
else if (view.dom == text) {
|
|
901
|
+
return fromText(pos, side);
|
|
902
|
+
}
|
|
903
|
+
else {
|
|
904
|
+
return enterView(view, pos, side);
|
|
905
|
+
}
|
|
906
|
+
}
|
|
907
|
+
function posFromDOMInCompositionTree(node, offset, view, text) {
|
|
908
|
+
if (view instanceof MarkView) {
|
|
909
|
+
for (let child of view.children) {
|
|
910
|
+
let pos = 0, hasComp = contains(child.dom, text);
|
|
911
|
+
if (contains(child.dom, node))
|
|
912
|
+
return pos + (hasComp ? posFromDOMInCompositionTree(node, offset, child, text) : child.localPosFromDOM(node, offset));
|
|
913
|
+
pos += hasComp ? text.nodeValue.length : child.length;
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
else if (view.dom == text) {
|
|
917
|
+
return Math.min(offset, text.nodeValue.length);
|
|
918
|
+
}
|
|
919
|
+
return view.localPosFromDOM(node, offset);
|
|
920
|
+
}
|
|
862
921
|
// These are drawn around uneditable widgets to avoid a number of
|
|
863
922
|
// browser bugs that show up when the cursor is directly next to
|
|
864
923
|
// uneditable inline content.
|
|
@@ -885,13 +944,43 @@ class WidgetBufferView extends ContentView {
|
|
|
885
944
|
localPosFromDOM() { return 0; }
|
|
886
945
|
domBoundsAround() { return null; }
|
|
887
946
|
coordsAt(pos) {
|
|
888
|
-
|
|
947
|
+
let imgRect = this.dom.getBoundingClientRect();
|
|
948
|
+
// Since the <img> height doesn't correspond to text height, try
|
|
949
|
+
// to borrow the height from some sibling node.
|
|
950
|
+
let siblingRect = inlineSiblingRect(this, this.side > 0 ? -1 : 1);
|
|
951
|
+
return siblingRect && siblingRect.top < imgRect.bottom && siblingRect.bottom > imgRect.top
|
|
952
|
+
? { left: imgRect.left, right: imgRect.right, top: siblingRect.top, bottom: siblingRect.bottom } : imgRect;
|
|
889
953
|
}
|
|
890
954
|
get overrideDOMText() {
|
|
891
955
|
return text.Text.empty;
|
|
892
956
|
}
|
|
893
957
|
}
|
|
894
958
|
TextView.prototype.children = WidgetView.prototype.children = WidgetBufferView.prototype.children = noChildren;
|
|
959
|
+
function inlineSiblingRect(view, side) {
|
|
960
|
+
let parent = view.parent, index = parent ? parent.children.indexOf(view) : -1;
|
|
961
|
+
while (parent && index >= 0) {
|
|
962
|
+
if (side < 0 ? index > 0 : index < parent.children.length) {
|
|
963
|
+
let next = parent.children[index + side];
|
|
964
|
+
if (next instanceof TextView) {
|
|
965
|
+
let nextRect = next.coordsAt(side < 0 ? next.length : 0, side);
|
|
966
|
+
if (nextRect)
|
|
967
|
+
return nextRect;
|
|
968
|
+
}
|
|
969
|
+
index += side;
|
|
970
|
+
}
|
|
971
|
+
else if (parent instanceof MarkView && parent.parent) {
|
|
972
|
+
index = parent.parent.children.indexOf(parent) + (side < 0 ? 0 : 1);
|
|
973
|
+
parent = parent.parent;
|
|
974
|
+
}
|
|
975
|
+
else {
|
|
976
|
+
let last = parent.dom.lastChild;
|
|
977
|
+
if (last && last.nodeName == "BR")
|
|
978
|
+
return last.getClientRects()[0];
|
|
979
|
+
break;
|
|
980
|
+
}
|
|
981
|
+
}
|
|
982
|
+
return undefined;
|
|
983
|
+
}
|
|
895
984
|
function inlineDOMAtPos(dom, children, pos) {
|
|
896
985
|
let i = 0;
|
|
897
986
|
for (let off = 0; i < children.length; i++) {
|
|
@@ -935,7 +1024,7 @@ function coordsInChildren(view, pos, side) {
|
|
|
935
1024
|
continue;
|
|
936
1025
|
flatten = side = -child.getSide();
|
|
937
1026
|
}
|
|
938
|
-
let rect = child.coordsAt(pos - off, side);
|
|
1027
|
+
let rect = child.coordsAt(Math.max(0, pos - off), side);
|
|
939
1028
|
return flatten && rect ? flattenRect(rect, side < 0) : rect;
|
|
940
1029
|
}
|
|
941
1030
|
off = end;
|
|
@@ -1117,7 +1206,7 @@ class Decoration extends rangeset.RangeValue {
|
|
|
1117
1206
|
*/
|
|
1118
1207
|
static widget(spec) {
|
|
1119
1208
|
let side = spec.side || 0, block = !!spec.block;
|
|
1120
|
-
side += block ? (side > 0 ?
|
|
1209
|
+
side += block ? (side > 0 ? 400000000 /* BlockAfter */ : -500000000 /* BlockBefore */) : (side > 0 ? 100000000 /* InlineAfter */ : -100000000 /* InlineBefore */);
|
|
1121
1210
|
return new PointDecoration(spec, side, side, block, spec.widget || null, false);
|
|
1122
1211
|
}
|
|
1123
1212
|
/**
|
|
@@ -1125,10 +1214,16 @@ class Decoration extends rangeset.RangeValue {
|
|
|
1125
1214
|
a widget, or simply hides it.
|
|
1126
1215
|
*/
|
|
1127
1216
|
static replace(spec) {
|
|
1128
|
-
let block = !!spec.block;
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1217
|
+
let block = !!spec.block, startSide, endSide;
|
|
1218
|
+
if (spec.isBlockGap) {
|
|
1219
|
+
startSide = -400000000 /* GapStart */;
|
|
1220
|
+
endSide = 300000000 /* GapEnd */;
|
|
1221
|
+
}
|
|
1222
|
+
else {
|
|
1223
|
+
let { start, end } = getInclusive(spec, block);
|
|
1224
|
+
startSide = (start ? (block ? -300000000 /* BlockIncStart */ : -1 /* InlineIncStart */) : 500000000 /* NonIncStart */) - 1;
|
|
1225
|
+
endSide = (end ? (block ? 200000000 /* BlockIncEnd */ : 1 /* InlineIncEnd */) : -600000000 /* NonIncEnd */) + 1;
|
|
1226
|
+
}
|
|
1132
1227
|
return new PointDecoration(spec, startSide, endSide, block, spec.widget || null, true);
|
|
1133
1228
|
}
|
|
1134
1229
|
/**
|
|
@@ -1158,7 +1253,7 @@ Decoration.none = rangeset.RangeSet.empty;
|
|
|
1158
1253
|
class MarkDecoration extends Decoration {
|
|
1159
1254
|
constructor(spec) {
|
|
1160
1255
|
let { start, end } = getInclusive(spec);
|
|
1161
|
-
super(start ? -1 /* InlineIncStart */ :
|
|
1256
|
+
super(start ? -1 /* InlineIncStart */ : 500000000 /* NonIncStart */, end ? 1 /* InlineIncEnd */ : -600000000 /* NonIncEnd */, null, spec);
|
|
1162
1257
|
this.tagName = spec.tagName || "span";
|
|
1163
1258
|
this.class = spec.class || "";
|
|
1164
1259
|
this.attrs = spec.attributes || null;
|
|
@@ -1388,6 +1483,7 @@ class BlockWidgetView extends ContentView {
|
|
|
1388
1483
|
this.length = length;
|
|
1389
1484
|
this.type = type;
|
|
1390
1485
|
this.breakAfter = 0;
|
|
1486
|
+
this.prevWidget = null;
|
|
1391
1487
|
}
|
|
1392
1488
|
merge(from, to, source, _takeDeco, openStart, openEnd) {
|
|
1393
1489
|
if (source && (!(source instanceof BlockWidgetView) || !this.widget.compare(source.widget) ||
|
|
@@ -1409,6 +1505,9 @@ class BlockWidgetView extends ContentView {
|
|
|
1409
1505
|
get children() { return noChildren; }
|
|
1410
1506
|
sync() {
|
|
1411
1507
|
if (!this.dom || !this.widget.updateDOM(this.dom)) {
|
|
1508
|
+
if (this.dom && this.prevWidget)
|
|
1509
|
+
this.prevWidget.destroy(this.dom);
|
|
1510
|
+
this.prevWidget = null;
|
|
1412
1511
|
this.setDOM(this.widget.toDOM(this.editorView));
|
|
1413
1512
|
this.dom.contentEditable = "false";
|
|
1414
1513
|
}
|
|
@@ -1422,6 +1521,8 @@ class BlockWidgetView extends ContentView {
|
|
|
1422
1521
|
other.widget.constructor == this.widget.constructor) {
|
|
1423
1522
|
if (!other.widget.eq(this.widget))
|
|
1424
1523
|
this.markDirty(true);
|
|
1524
|
+
if (this.dom && !this.prevWidget)
|
|
1525
|
+
this.prevWidget = this.widget;
|
|
1425
1526
|
this.widget = other.widget;
|
|
1426
1527
|
this.length = other.length;
|
|
1427
1528
|
this.breakAfter = other.breakAfter;
|
|
@@ -2731,7 +2832,12 @@ class DocView extends ContentView {
|
|
|
2731
2832
|
let end = next ? next.from - 1 : this.length;
|
|
2732
2833
|
if (end > pos) {
|
|
2733
2834
|
let height = vs.lineBlockAt(end).bottom - vs.lineBlockAt(pos).top;
|
|
2734
|
-
deco.push(Decoration.replace({
|
|
2835
|
+
deco.push(Decoration.replace({
|
|
2836
|
+
widget: new BlockGapWidget(height),
|
|
2837
|
+
block: true,
|
|
2838
|
+
inclusive: true,
|
|
2839
|
+
isBlockGap: true,
|
|
2840
|
+
}).range(pos, end));
|
|
2735
2841
|
}
|
|
2736
2842
|
if (!next)
|
|
2737
2843
|
break;
|
|
@@ -2850,13 +2956,19 @@ function computeCompositionDeco(view, changes) {
|
|
|
2850
2956
|
else if (state.doc.sliceString(newFrom, newTo, LineBreakPlaceholder) != text) {
|
|
2851
2957
|
return Decoration.none;
|
|
2852
2958
|
}
|
|
2853
|
-
|
|
2959
|
+
let topView = ContentView.get(node);
|
|
2960
|
+
if (topView instanceof CompositionView)
|
|
2961
|
+
topView = topView.widget.topView;
|
|
2962
|
+
else if (topView)
|
|
2963
|
+
topView.parent = null;
|
|
2964
|
+
return Decoration.set(Decoration.replace({ widget: new CompositionWidget(node, textNode, topView) }).range(newFrom, newTo));
|
|
2854
2965
|
}
|
|
2855
2966
|
class CompositionWidget extends WidgetType {
|
|
2856
|
-
constructor(top, text) {
|
|
2967
|
+
constructor(top, text, topView) {
|
|
2857
2968
|
super();
|
|
2858
2969
|
this.top = top;
|
|
2859
2970
|
this.text = text;
|
|
2971
|
+
this.topView = topView;
|
|
2860
2972
|
}
|
|
2861
2973
|
eq(other) { return this.top == other.top && this.text == other.text; }
|
|
2862
2974
|
toDOM() { return this.top; }
|
|
@@ -5197,8 +5309,9 @@ const baseTheme = buildTheme("." + baseThemeID, {
|
|
|
5197
5309
|
verticalAlign: "bottom"
|
|
5198
5310
|
},
|
|
5199
5311
|
".cm-widgetBuffer": {
|
|
5200
|
-
verticalAlign: "text-
|
|
5312
|
+
verticalAlign: "text-top",
|
|
5201
5313
|
height: "1em",
|
|
5314
|
+
display: "inline"
|
|
5202
5315
|
},
|
|
5203
5316
|
".cm-placeholder": {
|
|
5204
5317
|
color: "#888",
|
|
@@ -5307,19 +5420,16 @@ class DOMObserver {
|
|
|
5307
5420
|
this.flushSoon();
|
|
5308
5421
|
};
|
|
5309
5422
|
this.onSelectionChange = this.onSelectionChange.bind(this);
|
|
5423
|
+
window.addEventListener("resize", this.onResize = this.onResize.bind(this));
|
|
5310
5424
|
if (typeof ResizeObserver == "function") {
|
|
5311
5425
|
this.resize = new ResizeObserver(() => {
|
|
5312
|
-
if (this.view.docView.lastUpdate < Date.now() - 75
|
|
5313
|
-
this.
|
|
5314
|
-
this.resizeTimeout = -1;
|
|
5315
|
-
this.view.requestMeasure();
|
|
5316
|
-
}, 50);
|
|
5426
|
+
if (this.view.docView.lastUpdate < Date.now() - 75)
|
|
5427
|
+
this.onResize();
|
|
5317
5428
|
});
|
|
5318
5429
|
this.resize.observe(view.scrollDOM);
|
|
5319
5430
|
}
|
|
5320
5431
|
this.start();
|
|
5321
|
-
this.onScroll = this.onScroll.bind(this);
|
|
5322
|
-
window.addEventListener("scroll", this.onScroll);
|
|
5432
|
+
window.addEventListener("scroll", this.onScroll = this.onScroll.bind(this));
|
|
5323
5433
|
if (typeof IntersectionObserver == "function") {
|
|
5324
5434
|
this.intersection = new IntersectionObserver(entries => {
|
|
5325
5435
|
if (this.parentCheck < 0)
|
|
@@ -5345,6 +5455,13 @@ class DOMObserver {
|
|
|
5345
5455
|
this.flush(false);
|
|
5346
5456
|
this.onScrollChanged(e);
|
|
5347
5457
|
}
|
|
5458
|
+
onResize() {
|
|
5459
|
+
if (this.resizeTimeout < 0)
|
|
5460
|
+
this.resizeTimeout = setTimeout(() => {
|
|
5461
|
+
this.resizeTimeout = -1;
|
|
5462
|
+
this.view.requestMeasure();
|
|
5463
|
+
}, 50);
|
|
5464
|
+
}
|
|
5348
5465
|
updateGaps(gaps) {
|
|
5349
5466
|
if (this.gapIntersection && (gaps.length != this.gaps.length || this.gaps.some((g, i) => g != gaps[i]))) {
|
|
5350
5467
|
this.gapIntersection.disconnect();
|
|
@@ -5561,6 +5678,7 @@ class DOMObserver {
|
|
|
5561
5678
|
for (let dom of this.scrollTargets)
|
|
5562
5679
|
dom.removeEventListener("scroll", this.onScroll);
|
|
5563
5680
|
window.removeEventListener("scroll", this.onScroll);
|
|
5681
|
+
window.removeEventListener("resize", this.onResize);
|
|
5564
5682
|
this.dom.ownerDocument.removeEventListener("selectionchange", this.onSelectionChange);
|
|
5565
5683
|
clearTimeout(this.parentCheck);
|
|
5566
5684
|
clearTimeout(this.resizeTimeout);
|
|
@@ -5880,7 +5998,6 @@ class EditorView {
|
|
|
5880
5998
|
this.mountStyles();
|
|
5881
5999
|
this.updateAttrs();
|
|
5882
6000
|
this.updateState = 0 /* Idle */;
|
|
5883
|
-
ensureGlobalHandler();
|
|
5884
6001
|
this.requestMeasure();
|
|
5885
6002
|
if (config.parent)
|
|
5886
6003
|
config.parent.appendChild(this.dom);
|
|
@@ -5913,9 +6030,17 @@ class EditorView {
|
|
|
5913
6030
|
get inView() { return this.viewState.inView; }
|
|
5914
6031
|
/**
|
|
5915
6032
|
Indicates whether the user is currently composing text via
|
|
5916
|
-
[IME](https://en.wikipedia.org/wiki/Input_method)
|
|
6033
|
+
[IME](https://en.wikipedia.org/wiki/Input_method), and at least
|
|
6034
|
+
one change has been made in the current composition.
|
|
5917
6035
|
*/
|
|
5918
6036
|
get composing() { return this.inputState.composing > 0; }
|
|
6037
|
+
/**
|
|
6038
|
+
Indicates whether the user is currently in composing state. Note
|
|
6039
|
+
that on some platforms, like Android, this will be the case a
|
|
6040
|
+
lot, since just putting the cursor on a word starts a
|
|
6041
|
+
composition there.
|
|
6042
|
+
*/
|
|
6043
|
+
get compositionStarted() { return this.inputState.composing >= 0; }
|
|
5919
6044
|
dispatch(...input) {
|
|
5920
6045
|
this._dispatch(input.length == 1 && input[0] instanceof state.Transaction ? input[0]
|
|
5921
6046
|
: this.state.update(...input));
|
|
@@ -6709,22 +6834,6 @@ const MaxBidiLine = 4096;
|
|
|
6709
6834
|
function ensureTop(given, view) {
|
|
6710
6835
|
return (given == null ? view.contentDOM.getBoundingClientRect().top : given) + view.viewState.paddingTop;
|
|
6711
6836
|
}
|
|
6712
|
-
let resizeDebounce = -1;
|
|
6713
|
-
function ensureGlobalHandler() {
|
|
6714
|
-
window.addEventListener("resize", () => {
|
|
6715
|
-
if (resizeDebounce == -1)
|
|
6716
|
-
resizeDebounce = setTimeout(handleResize, 50);
|
|
6717
|
-
});
|
|
6718
|
-
}
|
|
6719
|
-
function handleResize() {
|
|
6720
|
-
resizeDebounce = -1;
|
|
6721
|
-
let found = document.querySelectorAll(".cm-content");
|
|
6722
|
-
for (let i = 0; i < found.length; i++) {
|
|
6723
|
-
let docView = ContentView.get(found[i]);
|
|
6724
|
-
if (docView)
|
|
6725
|
-
docView.editorView.requestMeasure();
|
|
6726
|
-
}
|
|
6727
|
-
}
|
|
6728
6837
|
const BadMeasure = {};
|
|
6729
6838
|
class CachedOrder {
|
|
6730
6839
|
constructor(from, to, dir, order) {
|
package/dist/index.d.ts
CHANGED
|
@@ -676,9 +676,17 @@ declare class EditorView {
|
|
|
676
676
|
get inView(): boolean;
|
|
677
677
|
/**
|
|
678
678
|
Indicates whether the user is currently composing text via
|
|
679
|
-
[IME](https://en.wikipedia.org/wiki/Input_method)
|
|
679
|
+
[IME](https://en.wikipedia.org/wiki/Input_method), and at least
|
|
680
|
+
one change has been made in the current composition.
|
|
680
681
|
*/
|
|
681
682
|
get composing(): boolean;
|
|
683
|
+
/**
|
|
684
|
+
Indicates whether the user is currently in composing state. Note
|
|
685
|
+
that on some platforms, like Android, this will be the case a
|
|
686
|
+
lot, since just putting the cursor on a word starts a
|
|
687
|
+
composition there.
|
|
688
|
+
*/
|
|
689
|
+
get compositionStarted(): boolean;
|
|
682
690
|
private _dispatch;
|
|
683
691
|
/**
|
|
684
692
|
The document or shadow root that the view lives in.
|
package/dist/index.js
CHANGED
|
@@ -19,7 +19,7 @@ function getSelection(root) {
|
|
|
19
19
|
return target.getSelection();
|
|
20
20
|
}
|
|
21
21
|
function contains(dom, node) {
|
|
22
|
-
return node ? dom.contains(node.nodeType != 1 ? node.parentNode : node) : false;
|
|
22
|
+
return node ? dom == node || dom.contains(node.nodeType != 1 ? node.parentNode : node) : false;
|
|
23
23
|
}
|
|
24
24
|
function deepActiveElement() {
|
|
25
25
|
let elt = document.activeElement;
|
|
@@ -778,6 +778,7 @@ class WidgetView extends ContentView {
|
|
|
778
778
|
this.widget = widget;
|
|
779
779
|
this.length = length;
|
|
780
780
|
this.side = side;
|
|
781
|
+
this.prevWidget = null;
|
|
781
782
|
}
|
|
782
783
|
static create(widget, length, side) {
|
|
783
784
|
return new (widget.customView || WidgetView)(widget, length, side);
|
|
@@ -789,6 +790,9 @@ class WidgetView extends ContentView {
|
|
|
789
790
|
}
|
|
790
791
|
sync() {
|
|
791
792
|
if (!this.dom || !this.widget.updateDOM(this.dom)) {
|
|
793
|
+
if (this.dom && this.prevWidget)
|
|
794
|
+
this.prevWidget.destroy(this.dom);
|
|
795
|
+
this.prevWidget = null;
|
|
792
796
|
this.setDOM(this.widget.toDOM(this.editorView));
|
|
793
797
|
this.dom.contentEditable = "false";
|
|
794
798
|
}
|
|
@@ -806,6 +810,8 @@ class WidgetView extends ContentView {
|
|
|
806
810
|
if (this.widget.constructor == other.widget.constructor) {
|
|
807
811
|
if (!this.widget.eq(other.widget))
|
|
808
812
|
this.markDirty(true);
|
|
813
|
+
if (this.dom && !this.prevWidget)
|
|
814
|
+
this.prevWidget = this.widget;
|
|
809
815
|
this.widget = other.widget;
|
|
810
816
|
return true;
|
|
811
817
|
}
|
|
@@ -846,16 +852,69 @@ class WidgetView extends ContentView {
|
|
|
846
852
|
}
|
|
847
853
|
}
|
|
848
854
|
class CompositionView extends WidgetView {
|
|
849
|
-
domAtPos(pos) {
|
|
855
|
+
domAtPos(pos) {
|
|
856
|
+
let { topView, text } = this.widget;
|
|
857
|
+
if (!topView)
|
|
858
|
+
return new DOMPos(text, Math.min(pos, text.nodeValue.length));
|
|
859
|
+
return scanCompositionTree(pos, 0, topView, text, (v, p) => v.domAtPos(p), p => new DOMPos(text, Math.min(p, text.nodeValue.length)));
|
|
860
|
+
}
|
|
850
861
|
sync() { this.setDOM(this.widget.toDOM()); }
|
|
851
862
|
localPosFromDOM(node, offset) {
|
|
852
|
-
|
|
863
|
+
let { topView, text } = this.widget;
|
|
864
|
+
if (!topView)
|
|
865
|
+
return Math.min(offset, this.length);
|
|
866
|
+
return posFromDOMInCompositionTree(node, offset, topView, text);
|
|
853
867
|
}
|
|
854
868
|
ignoreMutation() { return false; }
|
|
855
869
|
get overrideDOMText() { return null; }
|
|
856
|
-
coordsAt(pos, side) {
|
|
870
|
+
coordsAt(pos, side) {
|
|
871
|
+
let { topView, text } = this.widget;
|
|
872
|
+
if (!topView)
|
|
873
|
+
return textCoords(text, pos, side);
|
|
874
|
+
return scanCompositionTree(pos, side, topView, text, (v, pos, side) => v.coordsAt(pos, side), (pos, side) => textCoords(text, pos, side));
|
|
875
|
+
}
|
|
876
|
+
destroy() {
|
|
877
|
+
var _a;
|
|
878
|
+
super.destroy();
|
|
879
|
+
(_a = this.widget.topView) === null || _a === void 0 ? void 0 : _a.destroy();
|
|
880
|
+
}
|
|
857
881
|
get isEditable() { return true; }
|
|
858
882
|
}
|
|
883
|
+
// Uses the old structure of a chunk of content view frozen for
|
|
884
|
+
// composition to try and find a reasonable DOM location for the given
|
|
885
|
+
// offset.
|
|
886
|
+
function scanCompositionTree(pos, side, view, text, enterView, fromText) {
|
|
887
|
+
if (view instanceof MarkView) {
|
|
888
|
+
for (let child of view.children) {
|
|
889
|
+
let hasComp = contains(child.dom, text);
|
|
890
|
+
let len = hasComp ? text.nodeValue.length : child.length;
|
|
891
|
+
if (pos < len || pos == len && child.getSide() <= 0)
|
|
892
|
+
return hasComp ? scanCompositionTree(pos, side, child, text, enterView, fromText) : enterView(child, pos, side);
|
|
893
|
+
pos -= len;
|
|
894
|
+
}
|
|
895
|
+
return enterView(view, view.length, -1);
|
|
896
|
+
}
|
|
897
|
+
else if (view.dom == text) {
|
|
898
|
+
return fromText(pos, side);
|
|
899
|
+
}
|
|
900
|
+
else {
|
|
901
|
+
return enterView(view, pos, side);
|
|
902
|
+
}
|
|
903
|
+
}
|
|
904
|
+
function posFromDOMInCompositionTree(node, offset, view, text) {
|
|
905
|
+
if (view instanceof MarkView) {
|
|
906
|
+
for (let child of view.children) {
|
|
907
|
+
let pos = 0, hasComp = contains(child.dom, text);
|
|
908
|
+
if (contains(child.dom, node))
|
|
909
|
+
return pos + (hasComp ? posFromDOMInCompositionTree(node, offset, child, text) : child.localPosFromDOM(node, offset));
|
|
910
|
+
pos += hasComp ? text.nodeValue.length : child.length;
|
|
911
|
+
}
|
|
912
|
+
}
|
|
913
|
+
else if (view.dom == text) {
|
|
914
|
+
return Math.min(offset, text.nodeValue.length);
|
|
915
|
+
}
|
|
916
|
+
return view.localPosFromDOM(node, offset);
|
|
917
|
+
}
|
|
859
918
|
// These are drawn around uneditable widgets to avoid a number of
|
|
860
919
|
// browser bugs that show up when the cursor is directly next to
|
|
861
920
|
// uneditable inline content.
|
|
@@ -882,13 +941,43 @@ class WidgetBufferView extends ContentView {
|
|
|
882
941
|
localPosFromDOM() { return 0; }
|
|
883
942
|
domBoundsAround() { return null; }
|
|
884
943
|
coordsAt(pos) {
|
|
885
|
-
|
|
944
|
+
let imgRect = this.dom.getBoundingClientRect();
|
|
945
|
+
// Since the <img> height doesn't correspond to text height, try
|
|
946
|
+
// to borrow the height from some sibling node.
|
|
947
|
+
let siblingRect = inlineSiblingRect(this, this.side > 0 ? -1 : 1);
|
|
948
|
+
return siblingRect && siblingRect.top < imgRect.bottom && siblingRect.bottom > imgRect.top
|
|
949
|
+
? { left: imgRect.left, right: imgRect.right, top: siblingRect.top, bottom: siblingRect.bottom } : imgRect;
|
|
886
950
|
}
|
|
887
951
|
get overrideDOMText() {
|
|
888
952
|
return Text.empty;
|
|
889
953
|
}
|
|
890
954
|
}
|
|
891
955
|
TextView.prototype.children = WidgetView.prototype.children = WidgetBufferView.prototype.children = noChildren;
|
|
956
|
+
function inlineSiblingRect(view, side) {
|
|
957
|
+
let parent = view.parent, index = parent ? parent.children.indexOf(view) : -1;
|
|
958
|
+
while (parent && index >= 0) {
|
|
959
|
+
if (side < 0 ? index > 0 : index < parent.children.length) {
|
|
960
|
+
let next = parent.children[index + side];
|
|
961
|
+
if (next instanceof TextView) {
|
|
962
|
+
let nextRect = next.coordsAt(side < 0 ? next.length : 0, side);
|
|
963
|
+
if (nextRect)
|
|
964
|
+
return nextRect;
|
|
965
|
+
}
|
|
966
|
+
index += side;
|
|
967
|
+
}
|
|
968
|
+
else if (parent instanceof MarkView && parent.parent) {
|
|
969
|
+
index = parent.parent.children.indexOf(parent) + (side < 0 ? 0 : 1);
|
|
970
|
+
parent = parent.parent;
|
|
971
|
+
}
|
|
972
|
+
else {
|
|
973
|
+
let last = parent.dom.lastChild;
|
|
974
|
+
if (last && last.nodeName == "BR")
|
|
975
|
+
return last.getClientRects()[0];
|
|
976
|
+
break;
|
|
977
|
+
}
|
|
978
|
+
}
|
|
979
|
+
return undefined;
|
|
980
|
+
}
|
|
892
981
|
function inlineDOMAtPos(dom, children, pos) {
|
|
893
982
|
let i = 0;
|
|
894
983
|
for (let off = 0; i < children.length; i++) {
|
|
@@ -932,7 +1021,7 @@ function coordsInChildren(view, pos, side) {
|
|
|
932
1021
|
continue;
|
|
933
1022
|
flatten = side = -child.getSide();
|
|
934
1023
|
}
|
|
935
|
-
let rect = child.coordsAt(pos - off, side);
|
|
1024
|
+
let rect = child.coordsAt(Math.max(0, pos - off), side);
|
|
936
1025
|
return flatten && rect ? flattenRect(rect, side < 0) : rect;
|
|
937
1026
|
}
|
|
938
1027
|
off = end;
|
|
@@ -1113,7 +1202,7 @@ class Decoration extends RangeValue {
|
|
|
1113
1202
|
*/
|
|
1114
1203
|
static widget(spec) {
|
|
1115
1204
|
let side = spec.side || 0, block = !!spec.block;
|
|
1116
|
-
side += block ? (side > 0 ?
|
|
1205
|
+
side += block ? (side > 0 ? 400000000 /* BlockAfter */ : -500000000 /* BlockBefore */) : (side > 0 ? 100000000 /* InlineAfter */ : -100000000 /* InlineBefore */);
|
|
1117
1206
|
return new PointDecoration(spec, side, side, block, spec.widget || null, false);
|
|
1118
1207
|
}
|
|
1119
1208
|
/**
|
|
@@ -1121,10 +1210,16 @@ class Decoration extends RangeValue {
|
|
|
1121
1210
|
a widget, or simply hides it.
|
|
1122
1211
|
*/
|
|
1123
1212
|
static replace(spec) {
|
|
1124
|
-
let block = !!spec.block;
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1213
|
+
let block = !!spec.block, startSide, endSide;
|
|
1214
|
+
if (spec.isBlockGap) {
|
|
1215
|
+
startSide = -400000000 /* GapStart */;
|
|
1216
|
+
endSide = 300000000 /* GapEnd */;
|
|
1217
|
+
}
|
|
1218
|
+
else {
|
|
1219
|
+
let { start, end } = getInclusive(spec, block);
|
|
1220
|
+
startSide = (start ? (block ? -300000000 /* BlockIncStart */ : -1 /* InlineIncStart */) : 500000000 /* NonIncStart */) - 1;
|
|
1221
|
+
endSide = (end ? (block ? 200000000 /* BlockIncEnd */ : 1 /* InlineIncEnd */) : -600000000 /* NonIncEnd */) + 1;
|
|
1222
|
+
}
|
|
1128
1223
|
return new PointDecoration(spec, startSide, endSide, block, spec.widget || null, true);
|
|
1129
1224
|
}
|
|
1130
1225
|
/**
|
|
@@ -1154,7 +1249,7 @@ Decoration.none = RangeSet.empty;
|
|
|
1154
1249
|
class MarkDecoration extends Decoration {
|
|
1155
1250
|
constructor(spec) {
|
|
1156
1251
|
let { start, end } = getInclusive(spec);
|
|
1157
|
-
super(start ? -1 /* InlineIncStart */ :
|
|
1252
|
+
super(start ? -1 /* InlineIncStart */ : 500000000 /* NonIncStart */, end ? 1 /* InlineIncEnd */ : -600000000 /* NonIncEnd */, null, spec);
|
|
1158
1253
|
this.tagName = spec.tagName || "span";
|
|
1159
1254
|
this.class = spec.class || "";
|
|
1160
1255
|
this.attrs = spec.attributes || null;
|
|
@@ -1384,6 +1479,7 @@ class BlockWidgetView extends ContentView {
|
|
|
1384
1479
|
this.length = length;
|
|
1385
1480
|
this.type = type;
|
|
1386
1481
|
this.breakAfter = 0;
|
|
1482
|
+
this.prevWidget = null;
|
|
1387
1483
|
}
|
|
1388
1484
|
merge(from, to, source, _takeDeco, openStart, openEnd) {
|
|
1389
1485
|
if (source && (!(source instanceof BlockWidgetView) || !this.widget.compare(source.widget) ||
|
|
@@ -1405,6 +1501,9 @@ class BlockWidgetView extends ContentView {
|
|
|
1405
1501
|
get children() { return noChildren; }
|
|
1406
1502
|
sync() {
|
|
1407
1503
|
if (!this.dom || !this.widget.updateDOM(this.dom)) {
|
|
1504
|
+
if (this.dom && this.prevWidget)
|
|
1505
|
+
this.prevWidget.destroy(this.dom);
|
|
1506
|
+
this.prevWidget = null;
|
|
1408
1507
|
this.setDOM(this.widget.toDOM(this.editorView));
|
|
1409
1508
|
this.dom.contentEditable = "false";
|
|
1410
1509
|
}
|
|
@@ -1418,6 +1517,8 @@ class BlockWidgetView extends ContentView {
|
|
|
1418
1517
|
other.widget.constructor == this.widget.constructor) {
|
|
1419
1518
|
if (!other.widget.eq(this.widget))
|
|
1420
1519
|
this.markDirty(true);
|
|
1520
|
+
if (this.dom && !this.prevWidget)
|
|
1521
|
+
this.prevWidget = this.widget;
|
|
1421
1522
|
this.widget = other.widget;
|
|
1422
1523
|
this.length = other.length;
|
|
1423
1524
|
this.breakAfter = other.breakAfter;
|
|
@@ -2726,7 +2827,12 @@ class DocView extends ContentView {
|
|
|
2726
2827
|
let end = next ? next.from - 1 : this.length;
|
|
2727
2828
|
if (end > pos) {
|
|
2728
2829
|
let height = vs.lineBlockAt(end).bottom - vs.lineBlockAt(pos).top;
|
|
2729
|
-
deco.push(Decoration.replace({
|
|
2830
|
+
deco.push(Decoration.replace({
|
|
2831
|
+
widget: new BlockGapWidget(height),
|
|
2832
|
+
block: true,
|
|
2833
|
+
inclusive: true,
|
|
2834
|
+
isBlockGap: true,
|
|
2835
|
+
}).range(pos, end));
|
|
2730
2836
|
}
|
|
2731
2837
|
if (!next)
|
|
2732
2838
|
break;
|
|
@@ -2845,13 +2951,19 @@ function computeCompositionDeco(view, changes) {
|
|
|
2845
2951
|
else if (state.doc.sliceString(newFrom, newTo, LineBreakPlaceholder) != text) {
|
|
2846
2952
|
return Decoration.none;
|
|
2847
2953
|
}
|
|
2848
|
-
|
|
2954
|
+
let topView = ContentView.get(node);
|
|
2955
|
+
if (topView instanceof CompositionView)
|
|
2956
|
+
topView = topView.widget.topView;
|
|
2957
|
+
else if (topView)
|
|
2958
|
+
topView.parent = null;
|
|
2959
|
+
return Decoration.set(Decoration.replace({ widget: new CompositionWidget(node, textNode, topView) }).range(newFrom, newTo));
|
|
2849
2960
|
}
|
|
2850
2961
|
class CompositionWidget extends WidgetType {
|
|
2851
|
-
constructor(top, text) {
|
|
2962
|
+
constructor(top, text, topView) {
|
|
2852
2963
|
super();
|
|
2853
2964
|
this.top = top;
|
|
2854
2965
|
this.text = text;
|
|
2966
|
+
this.topView = topView;
|
|
2855
2967
|
}
|
|
2856
2968
|
eq(other) { return this.top == other.top && this.text == other.text; }
|
|
2857
2969
|
toDOM() { return this.top; }
|
|
@@ -5191,8 +5303,9 @@ const baseTheme = /*@__PURE__*/buildTheme("." + baseThemeID, {
|
|
|
5191
5303
|
verticalAlign: "bottom"
|
|
5192
5304
|
},
|
|
5193
5305
|
".cm-widgetBuffer": {
|
|
5194
|
-
verticalAlign: "text-
|
|
5306
|
+
verticalAlign: "text-top",
|
|
5195
5307
|
height: "1em",
|
|
5308
|
+
display: "inline"
|
|
5196
5309
|
},
|
|
5197
5310
|
".cm-placeholder": {
|
|
5198
5311
|
color: "#888",
|
|
@@ -5301,19 +5414,16 @@ class DOMObserver {
|
|
|
5301
5414
|
this.flushSoon();
|
|
5302
5415
|
};
|
|
5303
5416
|
this.onSelectionChange = this.onSelectionChange.bind(this);
|
|
5417
|
+
window.addEventListener("resize", this.onResize = this.onResize.bind(this));
|
|
5304
5418
|
if (typeof ResizeObserver == "function") {
|
|
5305
5419
|
this.resize = new ResizeObserver(() => {
|
|
5306
|
-
if (this.view.docView.lastUpdate < Date.now() - 75
|
|
5307
|
-
this.
|
|
5308
|
-
this.resizeTimeout = -1;
|
|
5309
|
-
this.view.requestMeasure();
|
|
5310
|
-
}, 50);
|
|
5420
|
+
if (this.view.docView.lastUpdate < Date.now() - 75)
|
|
5421
|
+
this.onResize();
|
|
5311
5422
|
});
|
|
5312
5423
|
this.resize.observe(view.scrollDOM);
|
|
5313
5424
|
}
|
|
5314
5425
|
this.start();
|
|
5315
|
-
this.onScroll = this.onScroll.bind(this);
|
|
5316
|
-
window.addEventListener("scroll", this.onScroll);
|
|
5426
|
+
window.addEventListener("scroll", this.onScroll = this.onScroll.bind(this));
|
|
5317
5427
|
if (typeof IntersectionObserver == "function") {
|
|
5318
5428
|
this.intersection = new IntersectionObserver(entries => {
|
|
5319
5429
|
if (this.parentCheck < 0)
|
|
@@ -5339,6 +5449,13 @@ class DOMObserver {
|
|
|
5339
5449
|
this.flush(false);
|
|
5340
5450
|
this.onScrollChanged(e);
|
|
5341
5451
|
}
|
|
5452
|
+
onResize() {
|
|
5453
|
+
if (this.resizeTimeout < 0)
|
|
5454
|
+
this.resizeTimeout = setTimeout(() => {
|
|
5455
|
+
this.resizeTimeout = -1;
|
|
5456
|
+
this.view.requestMeasure();
|
|
5457
|
+
}, 50);
|
|
5458
|
+
}
|
|
5342
5459
|
updateGaps(gaps) {
|
|
5343
5460
|
if (this.gapIntersection && (gaps.length != this.gaps.length || this.gaps.some((g, i) => g != gaps[i]))) {
|
|
5344
5461
|
this.gapIntersection.disconnect();
|
|
@@ -5555,6 +5672,7 @@ class DOMObserver {
|
|
|
5555
5672
|
for (let dom of this.scrollTargets)
|
|
5556
5673
|
dom.removeEventListener("scroll", this.onScroll);
|
|
5557
5674
|
window.removeEventListener("scroll", this.onScroll);
|
|
5675
|
+
window.removeEventListener("resize", this.onResize);
|
|
5558
5676
|
this.dom.ownerDocument.removeEventListener("selectionchange", this.onSelectionChange);
|
|
5559
5677
|
clearTimeout(this.parentCheck);
|
|
5560
5678
|
clearTimeout(this.resizeTimeout);
|
|
@@ -5874,7 +5992,6 @@ class EditorView {
|
|
|
5874
5992
|
this.mountStyles();
|
|
5875
5993
|
this.updateAttrs();
|
|
5876
5994
|
this.updateState = 0 /* Idle */;
|
|
5877
|
-
ensureGlobalHandler();
|
|
5878
5995
|
this.requestMeasure();
|
|
5879
5996
|
if (config.parent)
|
|
5880
5997
|
config.parent.appendChild(this.dom);
|
|
@@ -5907,9 +6024,17 @@ class EditorView {
|
|
|
5907
6024
|
get inView() { return this.viewState.inView; }
|
|
5908
6025
|
/**
|
|
5909
6026
|
Indicates whether the user is currently composing text via
|
|
5910
|
-
[IME](https://en.wikipedia.org/wiki/Input_method)
|
|
6027
|
+
[IME](https://en.wikipedia.org/wiki/Input_method), and at least
|
|
6028
|
+
one change has been made in the current composition.
|
|
5911
6029
|
*/
|
|
5912
6030
|
get composing() { return this.inputState.composing > 0; }
|
|
6031
|
+
/**
|
|
6032
|
+
Indicates whether the user is currently in composing state. Note
|
|
6033
|
+
that on some platforms, like Android, this will be the case a
|
|
6034
|
+
lot, since just putting the cursor on a word starts a
|
|
6035
|
+
composition there.
|
|
6036
|
+
*/
|
|
6037
|
+
get compositionStarted() { return this.inputState.composing >= 0; }
|
|
5913
6038
|
dispatch(...input) {
|
|
5914
6039
|
this._dispatch(input.length == 1 && input[0] instanceof Transaction ? input[0]
|
|
5915
6040
|
: this.state.update(...input));
|
|
@@ -6703,22 +6828,6 @@ const MaxBidiLine = 4096;
|
|
|
6703
6828
|
function ensureTop(given, view) {
|
|
6704
6829
|
return (given == null ? view.contentDOM.getBoundingClientRect().top : given) + view.viewState.paddingTop;
|
|
6705
6830
|
}
|
|
6706
|
-
let resizeDebounce = -1;
|
|
6707
|
-
function ensureGlobalHandler() {
|
|
6708
|
-
window.addEventListener("resize", () => {
|
|
6709
|
-
if (resizeDebounce == -1)
|
|
6710
|
-
resizeDebounce = setTimeout(handleResize, 50);
|
|
6711
|
-
});
|
|
6712
|
-
}
|
|
6713
|
-
function handleResize() {
|
|
6714
|
-
resizeDebounce = -1;
|
|
6715
|
-
let found = document.querySelectorAll(".cm-content");
|
|
6716
|
-
for (let i = 0; i < found.length; i++) {
|
|
6717
|
-
let docView = ContentView.get(found[i]);
|
|
6718
|
-
if (docView)
|
|
6719
|
-
docView.editorView.requestMeasure();
|
|
6720
|
-
}
|
|
6721
|
-
}
|
|
6722
6831
|
const BadMeasure = {};
|
|
6723
6832
|
class CachedOrder {
|
|
6724
6833
|
constructor(from, to, dir, order) {
|