@codemirror/view 0.19.29 → 0.19.33
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 +50 -0
- package/dist/index.cjs +284 -125
- package/dist/index.d.ts +53 -2
- package/dist/index.js +285 -127
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { MapMode, Text as Text$1, Facet, StateEffect, ChangeSet, EditorSelection, CharCategory, EditorState, Transaction, Prec, combineConfig } from '@codemirror/state';
|
|
1
|
+
import { MapMode, Text as Text$1, Facet, StateEffect, ChangeSet, EditorSelection, CharCategory, EditorState, Transaction, Prec, combineConfig, StateField } from '@codemirror/state';
|
|
2
2
|
import { StyleModule } from 'style-mod';
|
|
3
3
|
import { RangeSet, RangeValue, RangeSetBuilder } from '@codemirror/rangeset';
|
|
4
4
|
export { Range } from '@codemirror/rangeset';
|
|
@@ -98,8 +98,7 @@ function windowRect(win) {
|
|
|
98
98
|
return { left: 0, right: win.innerWidth,
|
|
99
99
|
top: 0, bottom: win.innerHeight };
|
|
100
100
|
}
|
|
101
|
-
|
|
102
|
-
function scrollRectIntoView(dom, rect, side, center) {
|
|
101
|
+
function scrollRectIntoView(dom, rect, side, x, y, xMargin, yMargin, ltr) {
|
|
103
102
|
let doc = dom.ownerDocument, win = doc.defaultView;
|
|
104
103
|
for (let cur = dom; cur;) {
|
|
105
104
|
if (cur.nodeType == 1) { // Element
|
|
@@ -118,38 +117,42 @@ function scrollRectIntoView(dom, rect, side, center) {
|
|
|
118
117
|
top: rect.top, bottom: rect.top + cur.clientHeight };
|
|
119
118
|
}
|
|
120
119
|
let moveX = 0, moveY = 0;
|
|
121
|
-
if (
|
|
120
|
+
if (y == "nearest") {
|
|
121
|
+
if (rect.top < bounding.top) {
|
|
122
|
+
moveY = -(bounding.top - rect.top + yMargin);
|
|
123
|
+
if (side > 0 && rect.bottom > bounding.bottom + moveY)
|
|
124
|
+
moveY = rect.bottom - bounding.bottom + moveY + yMargin;
|
|
125
|
+
}
|
|
126
|
+
else if (rect.bottom > bounding.bottom) {
|
|
127
|
+
moveY = rect.bottom - bounding.bottom + yMargin;
|
|
128
|
+
if (side < 0 && (rect.top - moveY) < bounding.top)
|
|
129
|
+
moveY = -(bounding.top + moveY - rect.top + yMargin);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
122
133
|
let rectHeight = rect.bottom - rect.top, boundingHeight = bounding.bottom - bounding.top;
|
|
123
|
-
let targetTop
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
else if (side < 0)
|
|
127
|
-
targetTop = rect.top - ScrollSpace;
|
|
128
|
-
else
|
|
129
|
-
targetTop = rect.bottom + ScrollSpace - boundingHeight;
|
|
134
|
+
let targetTop = y == "center" && rectHeight <= boundingHeight ? rect.top + rectHeight / 2 - boundingHeight / 2 :
|
|
135
|
+
y == "start" || y == "center" && side < 0 ? rect.top - yMargin :
|
|
136
|
+
rect.bottom - boundingHeight + yMargin;
|
|
130
137
|
moveY = targetTop - bounding.top;
|
|
131
|
-
if (Math.abs(moveY) <= 1)
|
|
132
|
-
moveY = 0;
|
|
133
|
-
}
|
|
134
|
-
else if (rect.top < bounding.top) {
|
|
135
|
-
moveY = -(bounding.top - rect.top + ScrollSpace);
|
|
136
|
-
if (side > 0 && rect.bottom > bounding.bottom + moveY)
|
|
137
|
-
moveY = rect.bottom - bounding.bottom + moveY + ScrollSpace;
|
|
138
138
|
}
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
139
|
+
if (x == "nearest") {
|
|
140
|
+
if (rect.left < bounding.left) {
|
|
141
|
+
moveX = -(bounding.left - rect.left + xMargin);
|
|
142
|
+
if (side > 0 && rect.right > bounding.right + moveX)
|
|
143
|
+
moveX = rect.right - bounding.right + moveX + xMargin;
|
|
144
|
+
}
|
|
145
|
+
else if (rect.right > bounding.right) {
|
|
146
|
+
moveX = rect.right - bounding.right + xMargin;
|
|
147
|
+
if (side < 0 && rect.left < bounding.left + moveX)
|
|
148
|
+
moveX = -(bounding.left + moveX - rect.left + xMargin);
|
|
149
|
+
}
|
|
148
150
|
}
|
|
149
|
-
else
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
151
|
+
else {
|
|
152
|
+
let targetLeft = x == "center" ? rect.left + (rect.right - rect.left) / 2 - (bounding.right - bounding.left) / 2 :
|
|
153
|
+
(x == "start") == ltr ? rect.left - xMargin :
|
|
154
|
+
rect.right - (bounding.right - bounding.left) + xMargin;
|
|
155
|
+
moveX = targetLeft - bounding.left;
|
|
153
156
|
}
|
|
154
157
|
if (moveX || moveY) {
|
|
155
158
|
if (top) {
|
|
@@ -173,7 +176,7 @@ function scrollRectIntoView(dom, rect, side, center) {
|
|
|
173
176
|
if (top)
|
|
174
177
|
break;
|
|
175
178
|
cur = cur.assignedSlot || cur.parentNode;
|
|
176
|
-
|
|
179
|
+
x = y = "nearest";
|
|
177
180
|
}
|
|
178
181
|
else if (cur.nodeType == 11) { // A shadow root
|
|
179
182
|
cur = cur.host;
|
|
@@ -260,6 +263,10 @@ function getRoot(node) {
|
|
|
260
263
|
}
|
|
261
264
|
return null;
|
|
262
265
|
}
|
|
266
|
+
function clearAttributes(node) {
|
|
267
|
+
while (node.attributes.length)
|
|
268
|
+
node.removeAttributeNode(node.attributes[0]);
|
|
269
|
+
}
|
|
263
270
|
|
|
264
271
|
class DOMPos {
|
|
265
272
|
constructor(node, offset, precise = true) {
|
|
@@ -306,14 +313,16 @@ class ContentView {
|
|
|
306
313
|
// given position.
|
|
307
314
|
coordsAt(_pos, _side) { return null; }
|
|
308
315
|
sync(track) {
|
|
309
|
-
var _a;
|
|
310
316
|
if (this.dirty & 2 /* Node */) {
|
|
311
317
|
let parent = this.dom;
|
|
312
318
|
let pos = parent.firstChild;
|
|
313
319
|
for (let child of this.children) {
|
|
314
320
|
if (child.dirty) {
|
|
315
|
-
if (!child.dom && pos
|
|
316
|
-
|
|
321
|
+
if (!child.dom && pos) {
|
|
322
|
+
let contentView = ContentView.get(pos);
|
|
323
|
+
if (!contentView || !contentView.parent && contentView.constructor == child.constructor)
|
|
324
|
+
child.reuseDOM(pos);
|
|
325
|
+
}
|
|
317
326
|
child.sync(track);
|
|
318
327
|
child.dirty = 0 /* Not */;
|
|
319
328
|
}
|
|
@@ -341,7 +350,7 @@ class ContentView {
|
|
|
341
350
|
}
|
|
342
351
|
}
|
|
343
352
|
}
|
|
344
|
-
reuseDOM(_dom) {
|
|
353
|
+
reuseDOM(_dom) { }
|
|
345
354
|
localPosFromDOM(node, offset) {
|
|
346
355
|
let after;
|
|
347
356
|
if (node == this.dom) {
|
|
@@ -640,10 +649,8 @@ class TextView extends ContentView {
|
|
|
640
649
|
}
|
|
641
650
|
}
|
|
642
651
|
reuseDOM(dom) {
|
|
643
|
-
if (dom.nodeType
|
|
644
|
-
|
|
645
|
-
this.createDOM(dom);
|
|
646
|
-
return true;
|
|
652
|
+
if (dom.nodeType == 3)
|
|
653
|
+
this.createDOM(dom);
|
|
647
654
|
}
|
|
648
655
|
merge(from, to, source) {
|
|
649
656
|
if (source && (!(source instanceof TextView) || this.length - (to - from) + source.length > MaxJoinLen))
|
|
@@ -655,6 +662,7 @@ class TextView extends ContentView {
|
|
|
655
662
|
split(from) {
|
|
656
663
|
let result = new TextView(this.text.slice(from));
|
|
657
664
|
this.text = this.text.slice(0, from);
|
|
665
|
+
this.markDirty();
|
|
658
666
|
return result;
|
|
659
667
|
}
|
|
660
668
|
localPosFromDOM(node, offset) {
|
|
@@ -677,18 +685,26 @@ class MarkView extends ContentView {
|
|
|
677
685
|
for (let ch of children)
|
|
678
686
|
ch.setParent(this);
|
|
679
687
|
}
|
|
680
|
-
|
|
681
|
-
|
|
688
|
+
setAttrs(dom) {
|
|
689
|
+
clearAttributes(dom);
|
|
682
690
|
if (this.mark.class)
|
|
683
691
|
dom.className = this.mark.class;
|
|
684
692
|
if (this.mark.attrs)
|
|
685
693
|
for (let name in this.mark.attrs)
|
|
686
694
|
dom.setAttribute(name, this.mark.attrs[name]);
|
|
687
|
-
|
|
695
|
+
return dom;
|
|
696
|
+
}
|
|
697
|
+
reuseDOM(node) {
|
|
698
|
+
if (node.nodeName == this.mark.tagName.toUpperCase()) {
|
|
699
|
+
this.setDOM(node);
|
|
700
|
+
this.dirty |= 4 /* Attrs */ | 2 /* Node */;
|
|
701
|
+
}
|
|
688
702
|
}
|
|
689
703
|
sync(track) {
|
|
690
|
-
if (!this.dom
|
|
691
|
-
this.
|
|
704
|
+
if (!this.dom)
|
|
705
|
+
this.setDOM(this.setAttrs(document.createElement(this.mark.tagName)));
|
|
706
|
+
else if (this.dirty & 4 /* Attrs */)
|
|
707
|
+
this.setAttrs(this.dom);
|
|
692
708
|
super.sync(track);
|
|
693
709
|
}
|
|
694
710
|
merge(from, to, source, _hasStart, openStart, openEnd) {
|
|
@@ -832,8 +848,7 @@ class WidgetView extends ContentView {
|
|
|
832
848
|
}
|
|
833
849
|
class CompositionView extends WidgetView {
|
|
834
850
|
domAtPos(pos) { return new DOMPos(this.widget.text, pos); }
|
|
835
|
-
sync() {
|
|
836
|
-
this.setDOM(this.widget.toDOM()); }
|
|
851
|
+
sync() { this.setDOM(this.widget.toDOM()); }
|
|
837
852
|
localPosFromDOM(node, offset) {
|
|
838
853
|
return !offset ? 0 : node.nodeType == 3 ? Math.min(offset, this.length) : this.length;
|
|
839
854
|
}
|
|
@@ -1297,13 +1312,23 @@ class LineView extends ContentView {
|
|
|
1297
1312
|
domAtPos(pos) {
|
|
1298
1313
|
return inlineDOMAtPos(this.dom, this.children, pos);
|
|
1299
1314
|
}
|
|
1315
|
+
reuseDOM(node) {
|
|
1316
|
+
if (node.nodeName == "DIV") {
|
|
1317
|
+
this.setDOM(node);
|
|
1318
|
+
this.dirty |= 4 /* Attrs */ | 2 /* Node */;
|
|
1319
|
+
}
|
|
1320
|
+
}
|
|
1300
1321
|
sync(track) {
|
|
1301
1322
|
var _a;
|
|
1302
|
-
if (!this.dom
|
|
1323
|
+
if (!this.dom) {
|
|
1303
1324
|
this.setDOM(document.createElement("div"));
|
|
1304
1325
|
this.dom.className = "cm-line";
|
|
1305
1326
|
this.prevAttrs = this.attrs ? null : undefined;
|
|
1306
1327
|
}
|
|
1328
|
+
else if (this.dirty & 4 /* Attrs */) {
|
|
1329
|
+
clearAttributes(this.dom);
|
|
1330
|
+
this.prevAttrs = this.attrs ? null : undefined;
|
|
1331
|
+
}
|
|
1307
1332
|
if (this.prevAttrs !== undefined) {
|
|
1308
1333
|
updateAttrs(this.dom, this.prevAttrs, this.attrs);
|
|
1309
1334
|
this.dom.classList.add("cm-line");
|
|
@@ -1575,12 +1600,27 @@ const mouseSelectionStyle = /*@__PURE__*/Facet.define();
|
|
|
1575
1600
|
const exceptionSink = /*@__PURE__*/Facet.define();
|
|
1576
1601
|
const updateListener = /*@__PURE__*/Facet.define();
|
|
1577
1602
|
const inputHandler = /*@__PURE__*/Facet.define();
|
|
1603
|
+
// FIXME remove
|
|
1578
1604
|
const scrollTo = /*@__PURE__*/StateEffect.define({
|
|
1579
1605
|
map: (range, changes) => range.map(changes)
|
|
1580
1606
|
});
|
|
1607
|
+
// FIXME remove
|
|
1581
1608
|
const centerOn = /*@__PURE__*/StateEffect.define({
|
|
1582
1609
|
map: (range, changes) => range.map(changes)
|
|
1583
1610
|
});
|
|
1611
|
+
class ScrollTarget {
|
|
1612
|
+
constructor(range, y = "nearest", x = "nearest", yMargin = 5, xMargin = 5) {
|
|
1613
|
+
this.range = range;
|
|
1614
|
+
this.y = y;
|
|
1615
|
+
this.x = x;
|
|
1616
|
+
this.yMargin = yMargin;
|
|
1617
|
+
this.xMargin = xMargin;
|
|
1618
|
+
}
|
|
1619
|
+
map(changes) {
|
|
1620
|
+
return changes.empty ? this : new ScrollTarget(this.range.map(changes), this.y, this.x, this.yMargin, this.xMargin);
|
|
1621
|
+
}
|
|
1622
|
+
}
|
|
1623
|
+
const scrollIntoView = /*@__PURE__*/StateEffect.define({ map: (t, ch) => t.map(ch) });
|
|
1584
1624
|
/**
|
|
1585
1625
|
Log or report an unhandled exception in client code. Should
|
|
1586
1626
|
probably only be used by extension code that allows client code to
|
|
@@ -2393,16 +2433,6 @@ class DocView extends ContentView {
|
|
|
2393
2433
|
return true;
|
|
2394
2434
|
}
|
|
2395
2435
|
}
|
|
2396
|
-
reset(sel) {
|
|
2397
|
-
if (this.dirty) {
|
|
2398
|
-
this.view.observer.ignore(() => this.view.docView.sync());
|
|
2399
|
-
this.dirty = 0 /* Not */;
|
|
2400
|
-
this.updateSelection(true);
|
|
2401
|
-
}
|
|
2402
|
-
else {
|
|
2403
|
-
this.updateSelection();
|
|
2404
|
-
}
|
|
2405
|
-
}
|
|
2406
2436
|
// Used by update and the constructor do perform the actual DOM
|
|
2407
2437
|
// update
|
|
2408
2438
|
updateInner(changes, deco, oldLength) {
|
|
@@ -2478,7 +2508,8 @@ class DocView extends ContentView {
|
|
|
2478
2508
|
// inside an uneditable node, and not bring it back when we
|
|
2479
2509
|
// move the cursor to its proper position. This tries to
|
|
2480
2510
|
// restore the keyboard by cycling focus.
|
|
2481
|
-
if (browser.android && browser.chrome && this.dom.contains(domSel.focusNode) &&
|
|
2511
|
+
if (browser.android && browser.chrome && this.dom.contains(domSel.focusNode) &&
|
|
2512
|
+
inUneditable(domSel.focusNode, this.dom)) {
|
|
2482
2513
|
this.dom.blur();
|
|
2483
2514
|
this.dom.focus({ preventScroll: true });
|
|
2484
2515
|
}
|
|
@@ -2667,7 +2698,8 @@ class DocView extends ContentView {
|
|
|
2667
2698
|
this.view.viewState.lineGapDeco
|
|
2668
2699
|
];
|
|
2669
2700
|
}
|
|
2670
|
-
scrollIntoView(
|
|
2701
|
+
scrollIntoView(target) {
|
|
2702
|
+
let { range } = target;
|
|
2671
2703
|
let rect = this.coordsAt(range.head, range.empty ? range.assoc : range.head > range.anchor ? -1 : 1), other;
|
|
2672
2704
|
if (!rect)
|
|
2673
2705
|
return;
|
|
@@ -2687,10 +2719,11 @@ class DocView extends ContentView {
|
|
|
2687
2719
|
if (bottom != null)
|
|
2688
2720
|
mBottom = Math.max(mBottom, bottom);
|
|
2689
2721
|
}
|
|
2690
|
-
|
|
2722
|
+
let targetRect = {
|
|
2691
2723
|
left: rect.left - mLeft, top: rect.top - mTop,
|
|
2692
2724
|
right: rect.right + mRight, bottom: rect.bottom + mBottom
|
|
2693
|
-
}
|
|
2725
|
+
};
|
|
2726
|
+
scrollRectIntoView(this.view.scrollDOM, targetRect, range.head < range.anchor ? -1 : 1, target.x, target.y, target.xMargin, target.yMargin, this.view.textDirection == Direction.LTR);
|
|
2694
2727
|
}
|
|
2695
2728
|
}
|
|
2696
2729
|
function betweenUneditable(pos) {
|
|
@@ -3131,14 +3164,6 @@ class InputState {
|
|
|
3131
3164
|
constructor(view) {
|
|
3132
3165
|
this.lastKeyCode = 0;
|
|
3133
3166
|
this.lastKeyTime = 0;
|
|
3134
|
-
// On Chrome Android, backspace near widgets is just completely
|
|
3135
|
-
// broken, and there are no key events, so we need to handle the
|
|
3136
|
-
// beforeinput event. Deleting stuff will often create a flurry of
|
|
3137
|
-
// events, and interrupting it before it is done just makes
|
|
3138
|
-
// subsequent events even more broken, so again, we hold off doing
|
|
3139
|
-
// anything until the browser is finished with whatever it is trying
|
|
3140
|
-
// to do.
|
|
3141
|
-
this.pendingAndroidKey = undefined;
|
|
3142
3167
|
// On iOS, some keys need to have their default behavior happen
|
|
3143
3168
|
// (after which we retroactively handle them and reset the DOM) to
|
|
3144
3169
|
// avoid messing up the virtual keyboard state.
|
|
@@ -3207,22 +3232,15 @@ class InputState {
|
|
|
3207
3232
|
}
|
|
3208
3233
|
runCustomHandlers(type, view, event) {
|
|
3209
3234
|
for (let set of this.customHandlers) {
|
|
3210
|
-
let handler = set.handlers[type]
|
|
3235
|
+
let handler = set.handlers[type];
|
|
3211
3236
|
if (handler) {
|
|
3212
3237
|
try {
|
|
3213
|
-
|
|
3238
|
+
if (handler.call(set.plugin, event, view) || event.defaultPrevented)
|
|
3239
|
+
return true;
|
|
3214
3240
|
}
|
|
3215
3241
|
catch (e) {
|
|
3216
3242
|
logException(view.state, e);
|
|
3217
3243
|
}
|
|
3218
|
-
if (handled || event.defaultPrevented) {
|
|
3219
|
-
// Chrome for Android often applies a bunch of nonsensical
|
|
3220
|
-
// DOM changes after an enter press, even when
|
|
3221
|
-
// preventDefault-ed. This tries to ignore those.
|
|
3222
|
-
if (browser.android && type == "keydown" && event.keyCode == 13)
|
|
3223
|
-
view.observer.flushSoon();
|
|
3224
|
-
return true;
|
|
3225
|
-
}
|
|
3226
3244
|
}
|
|
3227
3245
|
}
|
|
3228
3246
|
return false;
|
|
@@ -3246,6 +3264,16 @@ class InputState {
|
|
|
3246
3264
|
this.lastKeyTime = Date.now();
|
|
3247
3265
|
if (this.screenKeyEvent(view, event))
|
|
3248
3266
|
return true;
|
|
3267
|
+
// Chrome for Android usually doesn't fire proper key events, but
|
|
3268
|
+
// occasionally does, usually surrounded by a bunch of complicated
|
|
3269
|
+
// composition changes. When an enter or backspace key event is
|
|
3270
|
+
// seen, hold off on handling DOM events for a bit, and then
|
|
3271
|
+
// dispatch it.
|
|
3272
|
+
if (browser.android && browser.chrome && !event.synthetic &&
|
|
3273
|
+
(event.keyCode == 13 || event.keyCode == 8)) {
|
|
3274
|
+
view.observer.delayAndroidKey(event.key, event.keyCode);
|
|
3275
|
+
return true;
|
|
3276
|
+
}
|
|
3249
3277
|
// Prevent the default behavior of Enter on iOS makes the
|
|
3250
3278
|
// virtual keyboard get stuck in the wrong (lowercase)
|
|
3251
3279
|
// state. So we let it go through, and then, in
|
|
@@ -3267,24 +3295,6 @@ class InputState {
|
|
|
3267
3295
|
this.pendingIOSKey = undefined;
|
|
3268
3296
|
return dispatchKey(view.contentDOM, key.key, key.keyCode);
|
|
3269
3297
|
}
|
|
3270
|
-
// This causes the DOM observer to pause for a bit, and sets an
|
|
3271
|
-
// animation frame (which seems the most reliable way to detect
|
|
3272
|
-
// 'Chrome is done flailing about messing with the DOM') to fire a
|
|
3273
|
-
// fake key event and re-sync the view again.
|
|
3274
|
-
setPendingAndroidKey(view, pending) {
|
|
3275
|
-
this.pendingAndroidKey = pending;
|
|
3276
|
-
requestAnimationFrame(() => {
|
|
3277
|
-
let key = this.pendingAndroidKey;
|
|
3278
|
-
if (!key)
|
|
3279
|
-
return;
|
|
3280
|
-
this.pendingAndroidKey = undefined;
|
|
3281
|
-
view.observer.processRecords();
|
|
3282
|
-
let startState = view.state;
|
|
3283
|
-
dispatchKey(view.contentDOM, key.key, key.keyCode);
|
|
3284
|
-
if (view.state == startState)
|
|
3285
|
-
view.docView.reset(true);
|
|
3286
|
-
});
|
|
3287
|
-
}
|
|
3288
3298
|
ignoreDuringComposition(event) {
|
|
3289
3299
|
if (!/^key/.test(event.type))
|
|
3290
3300
|
return false;
|
|
@@ -3763,12 +3773,12 @@ handlers.compositionstart = handlers.compositionupdate = view => {
|
|
|
3763
3773
|
if (view.inputState.compositionFirstChange == null)
|
|
3764
3774
|
view.inputState.compositionFirstChange = true;
|
|
3765
3775
|
if (view.inputState.composing < 0) {
|
|
3776
|
+
// FIXME possibly set a timeout to clear it again on Android
|
|
3777
|
+
view.inputState.composing = 0;
|
|
3766
3778
|
if (view.docView.compositionDeco.size) {
|
|
3767
3779
|
view.observer.flush();
|
|
3768
3780
|
forceClearComposition(view, true);
|
|
3769
3781
|
}
|
|
3770
|
-
// FIXME possibly set a timeout to clear it again on Android
|
|
3771
|
-
view.inputState.composing = 0;
|
|
3772
3782
|
}
|
|
3773
3783
|
};
|
|
3774
3784
|
handlers.compositionend = view => {
|
|
@@ -3794,7 +3804,7 @@ handlers.beforeinput = (view, event) => {
|
|
|
3794
3804
|
// seems to do nothing at all on Chrome).
|
|
3795
3805
|
let pending;
|
|
3796
3806
|
if (browser.chrome && browser.android && (pending = PendingKeys.find(key => key.inputType == event.inputType))) {
|
|
3797
|
-
view.
|
|
3807
|
+
view.observer.delayAndroidKey(pending.key, pending.keyCode);
|
|
3798
3808
|
if (pending.key == "Backspace" || pending.key == "Delete") {
|
|
3799
3809
|
let startViewHeight = ((_a = window.visualViewport) === null || _a === void 0 ? void 0 : _a.height) || 0;
|
|
3800
3810
|
setTimeout(() => {
|
|
@@ -4546,15 +4556,6 @@ class LineGapWidget extends WidgetType {
|
|
|
4546
4556
|
}
|
|
4547
4557
|
get estimatedHeight() { return this.vertical ? this.size : -1; }
|
|
4548
4558
|
}
|
|
4549
|
-
class ScrollTarget {
|
|
4550
|
-
constructor(range, center = false) {
|
|
4551
|
-
this.range = range;
|
|
4552
|
-
this.center = center;
|
|
4553
|
-
}
|
|
4554
|
-
map(changes) {
|
|
4555
|
-
return changes.empty ? this : new ScrollTarget(this.range.map(changes), this.center);
|
|
4556
|
-
}
|
|
4557
|
-
}
|
|
4558
4559
|
class ViewState {
|
|
4559
4560
|
constructor(state) {
|
|
4560
4561
|
this.state = state;
|
|
@@ -4629,9 +4630,9 @@ class ViewState {
|
|
|
4629
4630
|
let updateLines = !update.changes.empty || (update.flags & 2 /* Height */) ||
|
|
4630
4631
|
viewport.from != this.viewport.from || viewport.to != this.viewport.to;
|
|
4631
4632
|
this.viewport = viewport;
|
|
4633
|
+
this.updateForViewport();
|
|
4632
4634
|
if (updateLines)
|
|
4633
4635
|
this.updateViewportLines();
|
|
4634
|
-
this.updateForViewport();
|
|
4635
4636
|
if (this.lineGaps.length || this.viewport.to - this.viewport.from > 4000 /* DoubleMargin */)
|
|
4636
4637
|
this.updateLineGaps(this.ensureLineGaps(this.mapLineGaps(this.lineGaps, update.changes)));
|
|
4637
4638
|
update.flags |= this.computeVisibleRanges();
|
|
@@ -4663,7 +4664,12 @@ class ViewState {
|
|
|
4663
4664
|
let pixelViewport = this.printing ? { top: -1e8, bottom: 1e8, left: -1e8, right: 1e8 } : visiblePixelRange(dom, this.paddingTop);
|
|
4664
4665
|
let dTop = pixelViewport.top - this.pixelViewport.top, dBottom = pixelViewport.bottom - this.pixelViewport.bottom;
|
|
4665
4666
|
this.pixelViewport = pixelViewport;
|
|
4666
|
-
|
|
4667
|
+
let inView = this.pixelViewport.bottom > this.pixelViewport.top && this.pixelViewport.right > this.pixelViewport.left;
|
|
4668
|
+
if (inView != this.inView) {
|
|
4669
|
+
this.inView = inView;
|
|
4670
|
+
if (inView)
|
|
4671
|
+
measureContent = true;
|
|
4672
|
+
}
|
|
4667
4673
|
if (!this.inView)
|
|
4668
4674
|
return 0;
|
|
4669
4675
|
if (measureContent) {
|
|
@@ -4700,9 +4706,9 @@ class ViewState {
|
|
|
4700
4706
|
this.scrollTarget && (this.scrollTarget.range.head < this.viewport.from || this.scrollTarget.range.head > this.viewport.to);
|
|
4701
4707
|
if (viewportChange)
|
|
4702
4708
|
this.viewport = this.getViewport(bias, this.scrollTarget);
|
|
4709
|
+
this.updateForViewport();
|
|
4703
4710
|
if ((result & 2 /* Height */) || viewportChange)
|
|
4704
4711
|
this.updateViewportLines();
|
|
4705
|
-
this.updateForViewport();
|
|
4706
4712
|
if (this.lineGaps.length || this.viewport.to - this.viewport.from > 4000 /* DoubleMargin */)
|
|
4707
4713
|
this.updateLineGaps(this.ensureLineGaps(refresh ? [] : this.lineGaps));
|
|
4708
4714
|
result |= this.computeVisibleRanges();
|
|
@@ -4730,9 +4736,9 @@ class ViewState {
|
|
|
4730
4736
|
let { head } = scrollTarget.range, viewHeight = this.editorHeight;
|
|
4731
4737
|
if (head < viewport.from || head > viewport.to) {
|
|
4732
4738
|
let block = map.lineAt(head, QueryType.ByPos, doc, 0, 0), topPos;
|
|
4733
|
-
if (scrollTarget.center)
|
|
4739
|
+
if (scrollTarget.y == "center")
|
|
4734
4740
|
topPos = (block.top + block.bottom) / 2 - viewHeight / 2;
|
|
4735
|
-
else if (head < viewport.from)
|
|
4741
|
+
else if (scrollTarget.y == "start" || head < viewport.from)
|
|
4736
4742
|
topPos = block.top;
|
|
4737
4743
|
else
|
|
4738
4744
|
topPos = block.bottom - viewHeight;
|
|
@@ -5090,11 +5096,13 @@ const baseTheme = /*@__PURE__*/buildTheme("." + baseThemeID, {
|
|
|
5090
5096
|
// recomputation.
|
|
5091
5097
|
"@keyframes cm-blink": { "0%": {}, "50%": { visibility: "hidden" }, "100%": {} },
|
|
5092
5098
|
"@keyframes cm-blink2": { "0%": {}, "50%": { visibility: "hidden" }, "100%": {} },
|
|
5093
|
-
".cm-cursor": {
|
|
5099
|
+
".cm-cursor, .cm-dropCursor": {
|
|
5094
5100
|
position: "absolute",
|
|
5095
5101
|
borderLeft: "1.2px solid black",
|
|
5096
5102
|
marginLeft: "-0.6px",
|
|
5097
5103
|
pointerEvents: "none",
|
|
5104
|
+
},
|
|
5105
|
+
".cm-cursor": {
|
|
5098
5106
|
display: "none"
|
|
5099
5107
|
},
|
|
5100
5108
|
"&dark .cm-cursor": {
|
|
@@ -5182,6 +5190,7 @@ class DOMObserver {
|
|
|
5182
5190
|
this.delayedFlush = -1;
|
|
5183
5191
|
this.resizeTimeout = -1;
|
|
5184
5192
|
this.queue = [];
|
|
5193
|
+
this.delayedAndroidKey = null;
|
|
5185
5194
|
this.scrollTargets = [];
|
|
5186
5195
|
this.intersection = null;
|
|
5187
5196
|
this.resize = null;
|
|
@@ -5235,7 +5244,7 @@ class DOMObserver {
|
|
|
5235
5244
|
this.intersection = new IntersectionObserver(entries => {
|
|
5236
5245
|
if (this.parentCheck < 0)
|
|
5237
5246
|
this.parentCheck = setTimeout(this.listenForScroll.bind(this), 1000);
|
|
5238
|
-
if (entries.length > 0 && entries[entries.length - 1].intersectionRatio > 0 != this.intersecting) {
|
|
5247
|
+
if (entries.length > 0 && (entries[entries.length - 1].intersectionRatio > 0) != this.intersecting) {
|
|
5239
5248
|
this.intersecting = !this.intersecting;
|
|
5240
5249
|
if (this.intersecting != this.view.inView)
|
|
5241
5250
|
this.onScrollChanged(document.createEvent("Event"));
|
|
@@ -5265,7 +5274,7 @@ class DOMObserver {
|
|
|
5265
5274
|
}
|
|
5266
5275
|
}
|
|
5267
5276
|
onSelectionChange(event) {
|
|
5268
|
-
if (!this.readSelectionRange())
|
|
5277
|
+
if (!this.readSelectionRange() || this.delayedAndroidKey)
|
|
5269
5278
|
return;
|
|
5270
5279
|
let { view } = this, sel = this.selectionRange;
|
|
5271
5280
|
if (view.state.facet(editable) ? view.root.activeElement != this.dom : !hasSelection(view.dom, sel))
|
|
@@ -5361,6 +5370,32 @@ class DOMObserver {
|
|
|
5361
5370
|
this.queue.length = 0;
|
|
5362
5371
|
this.selectionChanged = false;
|
|
5363
5372
|
}
|
|
5373
|
+
// Chrome Android, especially in combination with GBoard, not only
|
|
5374
|
+
// doesn't reliably fire regular key events, but also often
|
|
5375
|
+
// surrounds the effect of enter or backspace with a bunch of
|
|
5376
|
+
// composition events that, when interrupted, cause text duplication
|
|
5377
|
+
// or other kinds of corruption. This hack makes the editor back off
|
|
5378
|
+
// from handling DOM changes for a moment when such a key is
|
|
5379
|
+
// detected (via beforeinput or keydown), and then dispatches the
|
|
5380
|
+
// key event, throwing away the DOM changes if it gets handled.
|
|
5381
|
+
delayAndroidKey(key, keyCode) {
|
|
5382
|
+
if (!this.delayedAndroidKey)
|
|
5383
|
+
requestAnimationFrame(() => {
|
|
5384
|
+
let key = this.delayedAndroidKey;
|
|
5385
|
+
this.delayedAndroidKey = null;
|
|
5386
|
+
let startState = this.view.state;
|
|
5387
|
+
if (dispatchKey(this.view.contentDOM, key.key, key.keyCode))
|
|
5388
|
+
this.processRecords();
|
|
5389
|
+
else
|
|
5390
|
+
this.flush();
|
|
5391
|
+
if (this.view.state == startState)
|
|
5392
|
+
this.view.update([]);
|
|
5393
|
+
});
|
|
5394
|
+
// Since backspace beforeinput is sometimes signalled spuriously,
|
|
5395
|
+
// Enter always takes precedence.
|
|
5396
|
+
if (!this.delayedAndroidKey || key == "Enter")
|
|
5397
|
+
this.delayedAndroidKey = { key, keyCode };
|
|
5398
|
+
}
|
|
5364
5399
|
flushSoon() {
|
|
5365
5400
|
if (this.delayedFlush < 0)
|
|
5366
5401
|
this.delayedFlush = window.setTimeout(() => { this.delayedFlush = -1; this.flush(); }, 20);
|
|
@@ -5397,13 +5432,13 @@ class DOMObserver {
|
|
|
5397
5432
|
}
|
|
5398
5433
|
// Apply pending changes, if any
|
|
5399
5434
|
flush(readSelection = true) {
|
|
5400
|
-
if (readSelection)
|
|
5401
|
-
this.readSelectionRange();
|
|
5402
5435
|
// Completely hold off flushing when pending keys are set—the code
|
|
5403
5436
|
// managing those will make sure processRecords is called and the
|
|
5404
5437
|
// view is resynchronized after
|
|
5405
|
-
if (this.delayedFlush >= 0 || this.
|
|
5438
|
+
if (this.delayedFlush >= 0 || this.delayedAndroidKey)
|
|
5406
5439
|
return;
|
|
5440
|
+
if (readSelection)
|
|
5441
|
+
this.readSelectionRange();
|
|
5407
5442
|
let { from, to, typeOver } = this.processRecords();
|
|
5408
5443
|
let newSel = this.selectionChanged && hasSelection(this.dom, this.selectionRange);
|
|
5409
5444
|
if (from < 0 && !newSel)
|
|
@@ -5809,7 +5844,9 @@ class EditorView {
|
|
|
5809
5844
|
if (e.is(scrollTo))
|
|
5810
5845
|
scrollTarget = new ScrollTarget(e.value);
|
|
5811
5846
|
else if (e.is(centerOn))
|
|
5812
|
-
scrollTarget = new ScrollTarget(e.value,
|
|
5847
|
+
scrollTarget = new ScrollTarget(e.value, "center");
|
|
5848
|
+
else if (e.is(scrollIntoView))
|
|
5849
|
+
scrollTarget = e.value;
|
|
5813
5850
|
}
|
|
5814
5851
|
}
|
|
5815
5852
|
this.viewState.update(update, scrollTarget);
|
|
@@ -6377,6 +6414,14 @@ class EditorView {
|
|
|
6377
6414
|
this.destroyed = true;
|
|
6378
6415
|
}
|
|
6379
6416
|
/**
|
|
6417
|
+
Returns an effect that can be
|
|
6418
|
+
[added](https://codemirror.net/6/docs/ref/#state.TransactionSpec.effects) to a transaction to
|
|
6419
|
+
cause it to scroll the given position or range into view.
|
|
6420
|
+
*/
|
|
6421
|
+
static scrollIntoView(pos, options = {}) {
|
|
6422
|
+
return scrollIntoView.of(new ScrollTarget(typeof pos == "number" ? EditorSelection.cursor(pos) : pos, options.y, options.x, options.yMargin, options.xMargin));
|
|
6423
|
+
}
|
|
6424
|
+
/**
|
|
6380
6425
|
Facet that can be used to add DOM event handlers. The value
|
|
6381
6426
|
should be an object mapping event names to handler functions. The
|
|
6382
6427
|
first such function to return true will be assumed to have handled
|
|
@@ -6430,11 +6475,15 @@ class EditorView {
|
|
|
6430
6475
|
/**
|
|
6431
6476
|
Effect that can be [added](https://codemirror.net/6/docs/ref/#state.TransactionSpec.effects) to a
|
|
6432
6477
|
transaction to make it scroll the given range into view.
|
|
6478
|
+
|
|
6479
|
+
*Deprecated*. Use [`scrollIntoView`](https://codemirror.net/6/docs/ref/#view.EditorView^scrollIntoView) instead.
|
|
6433
6480
|
*/
|
|
6434
6481
|
EditorView.scrollTo = scrollTo;
|
|
6435
6482
|
/**
|
|
6436
6483
|
Effect that makes the editor scroll the given range to the
|
|
6437
6484
|
center of the visible view.
|
|
6485
|
+
|
|
6486
|
+
*Deprecated*. Use [`scrollIntoView`](https://codemirror.net/6/docs/ref/#view.EditorView^scrollIntoView) instead.
|
|
6438
6487
|
*/
|
|
6439
6488
|
EditorView.centerOn = centerOn;
|
|
6440
6489
|
/**
|
|
@@ -6903,7 +6952,7 @@ function measureRange(view, range) {
|
|
|
6903
6952
|
let ltr = view.textDirection == Direction.LTR;
|
|
6904
6953
|
let content = view.contentDOM, contentRect = content.getBoundingClientRect(), base = getBase(view);
|
|
6905
6954
|
let lineStyle = window.getComputedStyle(content.firstChild);
|
|
6906
|
-
let leftSide = contentRect.left + parseInt(lineStyle.paddingLeft);
|
|
6955
|
+
let leftSide = contentRect.left + parseInt(lineStyle.paddingLeft) + Math.min(0, parseInt(lineStyle.textIndent));
|
|
6907
6956
|
let rightSide = contentRect.right - parseInt(lineStyle.paddingRight);
|
|
6908
6957
|
let startBlock = blockAt(view, from), endBlock = blockAt(view, to);
|
|
6909
6958
|
let visualStart = startBlock.type == BlockType.Text ? startBlock : null;
|
|
@@ -6923,7 +6972,7 @@ function measureRange(view, range) {
|
|
|
6923
6972
|
let between = [];
|
|
6924
6973
|
if ((visualStart || startBlock).to < (visualEnd || endBlock).from - 1)
|
|
6925
6974
|
between.push(piece(leftSide, top.bottom, rightSide, bottom.top));
|
|
6926
|
-
else if (top.bottom < bottom.top &&
|
|
6975
|
+
else if (top.bottom < bottom.top && view.elementAtHeight((top.bottom + bottom.top) / 2).type == BlockType.Text)
|
|
6927
6976
|
top.bottom = bottom.top = (top.bottom + bottom.top) / 2;
|
|
6928
6977
|
return pieces(top).concat(between).concat(pieces(bottom));
|
|
6929
6978
|
}
|
|
@@ -6988,6 +7037,98 @@ function measureCursor(view, cursor, primary) {
|
|
|
6988
7037
|
return new Piece(pos.left - base.left, pos.top - base.top, -1, pos.bottom - pos.top, primary ? "cm-cursor cm-cursor-primary" : "cm-cursor cm-cursor-secondary");
|
|
6989
7038
|
}
|
|
6990
7039
|
|
|
7040
|
+
const setDropCursorPos = /*@__PURE__*/StateEffect.define({
|
|
7041
|
+
map(pos, mapping) { return pos == null ? null : mapping.mapPos(pos); }
|
|
7042
|
+
});
|
|
7043
|
+
const dropCursorPos = /*@__PURE__*/StateField.define({
|
|
7044
|
+
create() { return null; },
|
|
7045
|
+
update(pos, tr) {
|
|
7046
|
+
if (pos != null)
|
|
7047
|
+
pos = tr.changes.mapPos(pos);
|
|
7048
|
+
return tr.effects.reduce((pos, e) => e.is(setDropCursorPos) ? e.value : pos, pos);
|
|
7049
|
+
}
|
|
7050
|
+
});
|
|
7051
|
+
const drawDropCursor = /*@__PURE__*/ViewPlugin.fromClass(class {
|
|
7052
|
+
constructor(view) {
|
|
7053
|
+
this.view = view;
|
|
7054
|
+
this.cursor = null;
|
|
7055
|
+
this.measureReq = { read: this.readPos.bind(this), write: this.drawCursor.bind(this) };
|
|
7056
|
+
}
|
|
7057
|
+
update(update) {
|
|
7058
|
+
var _a;
|
|
7059
|
+
let cursorPos = update.state.field(dropCursorPos);
|
|
7060
|
+
if (cursorPos == null) {
|
|
7061
|
+
if (this.cursor != null) {
|
|
7062
|
+
(_a = this.cursor) === null || _a === void 0 ? void 0 : _a.remove();
|
|
7063
|
+
this.cursor = null;
|
|
7064
|
+
}
|
|
7065
|
+
}
|
|
7066
|
+
else {
|
|
7067
|
+
if (!this.cursor) {
|
|
7068
|
+
this.cursor = this.view.scrollDOM.appendChild(document.createElement("div"));
|
|
7069
|
+
this.cursor.className = "cm-dropCursor";
|
|
7070
|
+
}
|
|
7071
|
+
if (update.startState.field(dropCursorPos) != cursorPos || update.docChanged || update.geometryChanged)
|
|
7072
|
+
this.view.requestMeasure(this.measureReq);
|
|
7073
|
+
}
|
|
7074
|
+
}
|
|
7075
|
+
readPos() {
|
|
7076
|
+
let pos = this.view.state.field(dropCursorPos);
|
|
7077
|
+
let rect = pos != null && this.view.coordsAtPos(pos);
|
|
7078
|
+
if (!rect)
|
|
7079
|
+
return null;
|
|
7080
|
+
let outer = this.view.scrollDOM.getBoundingClientRect();
|
|
7081
|
+
return {
|
|
7082
|
+
left: rect.left - outer.left + this.view.scrollDOM.scrollLeft,
|
|
7083
|
+
top: rect.top - outer.top + this.view.scrollDOM.scrollTop,
|
|
7084
|
+
height: rect.bottom - rect.top
|
|
7085
|
+
};
|
|
7086
|
+
}
|
|
7087
|
+
drawCursor(pos) {
|
|
7088
|
+
if (this.cursor) {
|
|
7089
|
+
if (pos) {
|
|
7090
|
+
this.cursor.style.left = pos.left + "px";
|
|
7091
|
+
this.cursor.style.top = pos.top + "px";
|
|
7092
|
+
this.cursor.style.height = pos.height + "px";
|
|
7093
|
+
}
|
|
7094
|
+
else {
|
|
7095
|
+
this.cursor.style.left = "-100000px";
|
|
7096
|
+
}
|
|
7097
|
+
}
|
|
7098
|
+
}
|
|
7099
|
+
destroy() {
|
|
7100
|
+
if (this.cursor)
|
|
7101
|
+
this.cursor.remove();
|
|
7102
|
+
}
|
|
7103
|
+
setDropPos(pos) {
|
|
7104
|
+
if (this.view.state.field(dropCursorPos) != pos)
|
|
7105
|
+
this.view.dispatch({ effects: setDropCursorPos.of(pos) });
|
|
7106
|
+
}
|
|
7107
|
+
}, {
|
|
7108
|
+
eventHandlers: {
|
|
7109
|
+
dragover(event) {
|
|
7110
|
+
this.setDropPos(this.view.posAtCoords({ x: event.clientX, y: event.clientY }));
|
|
7111
|
+
},
|
|
7112
|
+
dragleave(event) {
|
|
7113
|
+
if (event.target == this.view.contentDOM || !this.view.contentDOM.contains(event.relatedTarget))
|
|
7114
|
+
this.setDropPos(null);
|
|
7115
|
+
},
|
|
7116
|
+
dragend() {
|
|
7117
|
+
this.setDropPos(null);
|
|
7118
|
+
},
|
|
7119
|
+
drop() {
|
|
7120
|
+
this.setDropPos(null);
|
|
7121
|
+
}
|
|
7122
|
+
}
|
|
7123
|
+
});
|
|
7124
|
+
/**
|
|
7125
|
+
Draws a cursor at the current drop position when something is
|
|
7126
|
+
dragged over the editor.
|
|
7127
|
+
*/
|
|
7128
|
+
function dropCursor() {
|
|
7129
|
+
return [dropCursorPos, drawDropCursor];
|
|
7130
|
+
}
|
|
7131
|
+
|
|
6991
7132
|
function iterMatches(doc, re, from, to, f) {
|
|
6992
7133
|
re.lastIndex = 0;
|
|
6993
7134
|
for (let cursor = doc.iterRange(from, to), pos = from, m; !cursor.next().done; pos += cursor.value.length) {
|
|
@@ -6996,6 +7137,22 @@ function iterMatches(doc, re, from, to, f) {
|
|
|
6996
7137
|
f(pos + m.index, pos + m.index + m[0].length, m);
|
|
6997
7138
|
}
|
|
6998
7139
|
}
|
|
7140
|
+
function matchRanges(view, maxLength) {
|
|
7141
|
+
let visible = view.visibleRanges;
|
|
7142
|
+
if (visible.length == 1 && visible[0].from == view.viewport.from &&
|
|
7143
|
+
visible[0].to == view.viewport.to)
|
|
7144
|
+
return visible;
|
|
7145
|
+
let result = [];
|
|
7146
|
+
for (let { from, to } of visible) {
|
|
7147
|
+
from = Math.max(view.state.doc.lineAt(from).from, from - maxLength);
|
|
7148
|
+
to = Math.min(view.state.doc.lineAt(to).to, to + maxLength);
|
|
7149
|
+
if (result.length && result[result.length - 1].to >= from)
|
|
7150
|
+
result[result.length - 1].to = to;
|
|
7151
|
+
else
|
|
7152
|
+
result.push({ from, to });
|
|
7153
|
+
}
|
|
7154
|
+
return result;
|
|
7155
|
+
}
|
|
6999
7156
|
/**
|
|
7000
7157
|
Helper class used to make it easier to maintain decorations on
|
|
7001
7158
|
visible code that matches a given regular expression. To be used
|
|
@@ -7007,12 +7164,13 @@ class MatchDecorator {
|
|
|
7007
7164
|
Create a decorator.
|
|
7008
7165
|
*/
|
|
7009
7166
|
constructor(config) {
|
|
7010
|
-
let { regexp, decoration, boundary } = config;
|
|
7167
|
+
let { regexp, decoration, boundary, maxLength = 1000 } = config;
|
|
7011
7168
|
if (!regexp.global)
|
|
7012
7169
|
throw new RangeError("The regular expression given to MatchDecorator should have its 'g' flag set");
|
|
7013
7170
|
this.regexp = regexp;
|
|
7014
7171
|
this.getDeco = typeof decoration == "function" ? decoration : () => decoration;
|
|
7015
7172
|
this.boundary = boundary;
|
|
7173
|
+
this.maxLength = maxLength;
|
|
7016
7174
|
}
|
|
7017
7175
|
/**
|
|
7018
7176
|
Compute the full set of decorations for matches in the given
|
|
@@ -7021,7 +7179,7 @@ class MatchDecorator {
|
|
|
7021
7179
|
*/
|
|
7022
7180
|
createDeco(view) {
|
|
7023
7181
|
let build = new RangeSetBuilder();
|
|
7024
|
-
for (let { from, to } of view.
|
|
7182
|
+
for (let { from, to } of matchRanges(view, this.maxLength))
|
|
7025
7183
|
iterMatches(view.state.doc, this.regexp, from, to, (a, b, m) => build.add(a, b, this.getDeco(m, view, a)));
|
|
7026
7184
|
return build.finish();
|
|
7027
7185
|
}
|
|
@@ -7322,4 +7480,4 @@ function placeholder(content) {
|
|
|
7322
7480
|
*/
|
|
7323
7481
|
const __test = { HeightMap, HeightOracle, MeasuredHeights, QueryType, ChangedRange, computeOrder, moveVisually };
|
|
7324
7482
|
|
|
7325
|
-
export { BidiSpan, BlockInfo, BlockType, Decoration, Direction, EditorView, MatchDecorator, PluginField, PluginFieldProvider, ViewPlugin, ViewUpdate, WidgetType, __test, drawSelection, highlightActiveLine, highlightSpecialChars, keymap, logException, placeholder, runScopeHandlers, scrollPastEnd };
|
|
7483
|
+
export { BidiSpan, BlockInfo, BlockType, Decoration, Direction, EditorView, MatchDecorator, PluginField, PluginFieldProvider, ViewPlugin, ViewUpdate, WidgetType, __test, drawSelection, dropCursor, highlightActiveLine, highlightSpecialChars, keymap, logException, placeholder, runScopeHandlers, scrollPastEnd };
|