@codemirror/view 6.6.0 → 6.7.1
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 +28 -0
- package/dist/index.cjs +308 -155
- package/dist/index.d.ts +30 -3
- package/dist/index.js +304 -153
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -187,6 +187,26 @@ function scrollRectIntoView(dom, rect, side, x, y, xMargin, yMargin, ltr) {
|
|
|
187
187
|
}
|
|
188
188
|
}
|
|
189
189
|
}
|
|
190
|
+
function scrollableParent(dom) {
|
|
191
|
+
let doc = dom.ownerDocument;
|
|
192
|
+
for (let cur = dom.parentNode; cur;) {
|
|
193
|
+
if (cur == doc.body) {
|
|
194
|
+
break;
|
|
195
|
+
}
|
|
196
|
+
else if (cur.nodeType == 1) {
|
|
197
|
+
if (cur.scrollHeight > cur.clientHeight || cur.scrollWidth > cur.clientWidth)
|
|
198
|
+
return cur;
|
|
199
|
+
cur = cur.assignedSlot || cur.parentNode;
|
|
200
|
+
}
|
|
201
|
+
else if (cur.nodeType == 11) {
|
|
202
|
+
cur = cur.host;
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
break;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
return null;
|
|
209
|
+
}
|
|
190
210
|
class DOMSelectionState {
|
|
191
211
|
constructor() {
|
|
192
212
|
this.anchorNode = null;
|
|
@@ -1598,6 +1618,7 @@ class ContentBuilder {
|
|
|
1598
1618
|
this.curLine = null;
|
|
1599
1619
|
this.breakAtStart = 0;
|
|
1600
1620
|
this.pendingBuffer = 0 /* Buf.No */;
|
|
1621
|
+
this.bufferMarks = [];
|
|
1601
1622
|
// Set to false directly after a widget that covers the position after it
|
|
1602
1623
|
this.atCursorPos = true;
|
|
1603
1624
|
this.openStart = -1;
|
|
@@ -1620,20 +1641,20 @@ class ContentBuilder {
|
|
|
1620
1641
|
}
|
|
1621
1642
|
return this.curLine;
|
|
1622
1643
|
}
|
|
1623
|
-
flushBuffer(active) {
|
|
1644
|
+
flushBuffer(active = this.bufferMarks) {
|
|
1624
1645
|
if (this.pendingBuffer) {
|
|
1625
1646
|
this.curLine.append(wrapMarks(new WidgetBufferView(-1), active), active.length);
|
|
1626
1647
|
this.pendingBuffer = 0 /* Buf.No */;
|
|
1627
1648
|
}
|
|
1628
1649
|
}
|
|
1629
1650
|
addBlockWidget(view) {
|
|
1630
|
-
this.flushBuffer(
|
|
1651
|
+
this.flushBuffer();
|
|
1631
1652
|
this.curLine = null;
|
|
1632
1653
|
this.content.push(view);
|
|
1633
1654
|
}
|
|
1634
1655
|
finish(openEnd) {
|
|
1635
|
-
if (
|
|
1636
|
-
this.flushBuffer(
|
|
1656
|
+
if (this.pendingBuffer && openEnd <= this.bufferMarks.length)
|
|
1657
|
+
this.flushBuffer();
|
|
1637
1658
|
else
|
|
1638
1659
|
this.pendingBuffer = 0 /* Buf.No */;
|
|
1639
1660
|
if (!this.posCovered())
|
|
@@ -1653,8 +1674,9 @@ class ContentBuilder {
|
|
|
1653
1674
|
this.content[this.content.length - 1].breakAfter = 1;
|
|
1654
1675
|
else
|
|
1655
1676
|
this.breakAtStart = 1;
|
|
1656
|
-
this.flushBuffer(
|
|
1677
|
+
this.flushBuffer();
|
|
1657
1678
|
this.curLine = null;
|
|
1679
|
+
this.atCursorPos = true;
|
|
1658
1680
|
length--;
|
|
1659
1681
|
continue;
|
|
1660
1682
|
}
|
|
@@ -1696,7 +1718,7 @@ class ContentBuilder {
|
|
|
1696
1718
|
else {
|
|
1697
1719
|
let view = WidgetView.create(deco.widget || new NullWidget("span"), len, len ? 0 : deco.startSide);
|
|
1698
1720
|
let cursorBefore = this.atCursorPos && !view.isEditable && openStart <= active.length && (from < to || deco.startSide > 0);
|
|
1699
|
-
let cursorAfter = !view.isEditable && (from < to || deco.startSide <= 0);
|
|
1721
|
+
let cursorAfter = !view.isEditable && (from < to || openStart > active.length || deco.startSide <= 0);
|
|
1700
1722
|
let line = this.getLine();
|
|
1701
1723
|
if (this.pendingBuffer == 2 /* Buf.IfCursor */ && !cursorBefore)
|
|
1702
1724
|
this.pendingBuffer = 0 /* Buf.No */;
|
|
@@ -1707,7 +1729,9 @@ class ContentBuilder {
|
|
|
1707
1729
|
}
|
|
1708
1730
|
line.append(wrapMarks(view, active), openStart);
|
|
1709
1731
|
this.atCursorPos = cursorAfter;
|
|
1710
|
-
this.pendingBuffer = !cursorAfter ? 0 /* Buf.No */ : from < to ? 1 /* Buf.Yes */ : 2 /* Buf.IfCursor */;
|
|
1732
|
+
this.pendingBuffer = !cursorAfter ? 0 /* Buf.No */ : from < to || openStart > active.length ? 1 /* Buf.Yes */ : 2 /* Buf.IfCursor */;
|
|
1733
|
+
if (this.pendingBuffer)
|
|
1734
|
+
this.bufferMarks = active.slice();
|
|
1711
1735
|
}
|
|
1712
1736
|
}
|
|
1713
1737
|
else if (this.doc.lineAt(this.pos).from == this.pos) { // Line decoration
|
|
@@ -3381,22 +3405,30 @@ class InputState {
|
|
|
3381
3405
|
this.compositionFirstChange = null;
|
|
3382
3406
|
this.compositionEndedAt = 0;
|
|
3383
3407
|
this.mouseSelection = null;
|
|
3408
|
+
let handleEvent = (handler, event) => {
|
|
3409
|
+
if (this.ignoreDuringComposition(event))
|
|
3410
|
+
return;
|
|
3411
|
+
if (event.type == "keydown" && this.keydown(view, event))
|
|
3412
|
+
return;
|
|
3413
|
+
if (this.mustFlushObserver(event))
|
|
3414
|
+
view.observer.forceFlush();
|
|
3415
|
+
if (this.runCustomHandlers(event.type, view, event))
|
|
3416
|
+
event.preventDefault();
|
|
3417
|
+
else
|
|
3418
|
+
handler(view, event);
|
|
3419
|
+
};
|
|
3384
3420
|
for (let type in handlers) {
|
|
3385
3421
|
let handler = handlers[type];
|
|
3386
|
-
view.contentDOM.addEventListener(type,
|
|
3387
|
-
if (
|
|
3388
|
-
|
|
3389
|
-
if (type == "keydown" && this.keydown(view, event))
|
|
3390
|
-
return;
|
|
3391
|
-
if (this.mustFlushObserver(event))
|
|
3392
|
-
view.observer.forceFlush();
|
|
3393
|
-
if (this.runCustomHandlers(type, view, event))
|
|
3394
|
-
event.preventDefault();
|
|
3395
|
-
else
|
|
3396
|
-
handler(view, event);
|
|
3422
|
+
view.contentDOM.addEventListener(type, event => {
|
|
3423
|
+
if (eventBelongsToEditor(view, event))
|
|
3424
|
+
handleEvent(handler, event);
|
|
3397
3425
|
}, handlerOptions[type]);
|
|
3398
3426
|
this.registeredEvents.push(type);
|
|
3399
3427
|
}
|
|
3428
|
+
view.scrollDOM.addEventListener("mousedown", (event) => {
|
|
3429
|
+
if (event.target == view.scrollDOM)
|
|
3430
|
+
handleEvent(handlers.mousedown, event);
|
|
3431
|
+
});
|
|
3400
3432
|
if (browser.chrome && browser.chrome_version == 102) { // FIXME remove at some point
|
|
3401
3433
|
// On Chrome 102, viewport updates somehow stop wheel-based
|
|
3402
3434
|
// scrolling. Turning off pointer events during the scroll seems
|
|
@@ -3553,12 +3585,18 @@ const PendingKeys = [
|
|
|
3553
3585
|
const EmacsyPendingKeys = "dthko";
|
|
3554
3586
|
// Key codes for modifier keys
|
|
3555
3587
|
const modifierCodes = [16, 17, 18, 20, 91, 92, 224, 225];
|
|
3588
|
+
function dragScrollSpeed(dist) {
|
|
3589
|
+
return dist * 0.7 + 8;
|
|
3590
|
+
}
|
|
3556
3591
|
class MouseSelection {
|
|
3557
3592
|
constructor(view, startEvent, style, mustSelect) {
|
|
3558
3593
|
this.view = view;
|
|
3559
3594
|
this.style = style;
|
|
3560
3595
|
this.mustSelect = mustSelect;
|
|
3596
|
+
this.scrollSpeed = { x: 0, y: 0 };
|
|
3597
|
+
this.scrolling = -1;
|
|
3561
3598
|
this.lastEvent = startEvent;
|
|
3599
|
+
this.scrollParent = scrollableParent(view.contentDOM);
|
|
3562
3600
|
let doc = view.contentDOM.ownerDocument;
|
|
3563
3601
|
doc.addEventListener("mousemove", this.move = this.move.bind(this));
|
|
3564
3602
|
doc.addEventListener("mouseup", this.up = this.up.bind(this));
|
|
@@ -3574,11 +3612,24 @@ class MouseSelection {
|
|
|
3574
3612
|
}
|
|
3575
3613
|
}
|
|
3576
3614
|
move(event) {
|
|
3615
|
+
var _a;
|
|
3577
3616
|
if (event.buttons == 0)
|
|
3578
3617
|
return this.destroy();
|
|
3579
3618
|
if (this.dragging !== false)
|
|
3580
3619
|
return;
|
|
3581
3620
|
this.select(this.lastEvent = event);
|
|
3621
|
+
let sx = 0, sy = 0;
|
|
3622
|
+
let rect = ((_a = this.scrollParent) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect())
|
|
3623
|
+
|| { left: 0, top: 0, right: this.view.win.innerWidth, bottom: this.view.win.innerHeight };
|
|
3624
|
+
if (event.clientX <= rect.left)
|
|
3625
|
+
sx = -dragScrollSpeed(rect.left - event.clientX);
|
|
3626
|
+
else if (event.clientX >= rect.right)
|
|
3627
|
+
sx = dragScrollSpeed(event.clientX - rect.right);
|
|
3628
|
+
if (event.clientY <= rect.top)
|
|
3629
|
+
sy = -dragScrollSpeed(rect.top - event.clientY);
|
|
3630
|
+
else if (event.clientY >= rect.bottom)
|
|
3631
|
+
sy = dragScrollSpeed(event.clientY - rect.bottom);
|
|
3632
|
+
this.setScrollSpeed(sx, sy);
|
|
3582
3633
|
}
|
|
3583
3634
|
up(event) {
|
|
3584
3635
|
if (this.dragging == null)
|
|
@@ -3588,19 +3639,41 @@ class MouseSelection {
|
|
|
3588
3639
|
this.destroy();
|
|
3589
3640
|
}
|
|
3590
3641
|
destroy() {
|
|
3642
|
+
this.setScrollSpeed(0, 0);
|
|
3591
3643
|
let doc = this.view.contentDOM.ownerDocument;
|
|
3592
3644
|
doc.removeEventListener("mousemove", this.move);
|
|
3593
3645
|
doc.removeEventListener("mouseup", this.up);
|
|
3594
3646
|
this.view.inputState.mouseSelection = null;
|
|
3595
3647
|
}
|
|
3648
|
+
setScrollSpeed(sx, sy) {
|
|
3649
|
+
this.scrollSpeed = { x: sx, y: sy };
|
|
3650
|
+
if (sx || sy) {
|
|
3651
|
+
if (this.scrolling < 0)
|
|
3652
|
+
this.scrolling = setInterval(() => this.scroll(), 50);
|
|
3653
|
+
}
|
|
3654
|
+
else if (this.scrolling > -1) {
|
|
3655
|
+
clearInterval(this.scrolling);
|
|
3656
|
+
this.scrolling = -1;
|
|
3657
|
+
}
|
|
3658
|
+
}
|
|
3659
|
+
scroll() {
|
|
3660
|
+
if (this.scrollParent) {
|
|
3661
|
+
this.scrollParent.scrollLeft += this.scrollSpeed.x;
|
|
3662
|
+
this.scrollParent.scrollTop += this.scrollSpeed.y;
|
|
3663
|
+
}
|
|
3664
|
+
else {
|
|
3665
|
+
this.view.win.scrollBy(this.scrollSpeed.x, this.scrollSpeed.y);
|
|
3666
|
+
}
|
|
3667
|
+
if (this.dragging === false)
|
|
3668
|
+
this.select(this.lastEvent);
|
|
3669
|
+
}
|
|
3596
3670
|
select(event) {
|
|
3597
3671
|
let selection = this.style.get(event, this.extend, this.multiple);
|
|
3598
3672
|
if (this.mustSelect || !selection.eq(this.view.state.selection) ||
|
|
3599
3673
|
selection.main.assoc != this.view.state.selection.main.assoc)
|
|
3600
3674
|
this.view.dispatch({
|
|
3601
3675
|
selection,
|
|
3602
|
-
userEvent: "select.pointer"
|
|
3603
|
-
scrollIntoView: true
|
|
3676
|
+
userEvent: "select.pointer"
|
|
3604
3677
|
});
|
|
3605
3678
|
this.mustSelect = false;
|
|
3606
3679
|
}
|
|
@@ -3791,23 +3864,15 @@ function getClickType(event) {
|
|
|
3791
3864
|
function basicMouseSelection(view, event) {
|
|
3792
3865
|
let start = queryPos(view, event), type = getClickType(event);
|
|
3793
3866
|
let startSel = view.state.selection;
|
|
3794
|
-
let last = start, lastEvent = event;
|
|
3795
3867
|
return {
|
|
3796
3868
|
update(update) {
|
|
3797
3869
|
if (update.docChanged) {
|
|
3798
3870
|
start.pos = update.changes.mapPos(start.pos);
|
|
3799
3871
|
startSel = startSel.map(update.changes);
|
|
3800
|
-
lastEvent = null;
|
|
3801
3872
|
}
|
|
3802
3873
|
},
|
|
3803
3874
|
get(event, extend, multiple) {
|
|
3804
|
-
let cur;
|
|
3805
|
-
if (lastEvent && event.clientX == lastEvent.clientX && event.clientY == lastEvent.clientY)
|
|
3806
|
-
cur = last;
|
|
3807
|
-
else {
|
|
3808
|
-
cur = last = queryPos(view, event);
|
|
3809
|
-
lastEvent = event;
|
|
3810
|
-
}
|
|
3875
|
+
let cur = queryPos(view, event);
|
|
3811
3876
|
let range = rangeForClick(view, cur.pos, cur.bias, type);
|
|
3812
3877
|
if (start.pos != cur.pos && !extend) {
|
|
3813
3878
|
let startRange = rangeForClick(view, start.pos, start.bias, type);
|
|
@@ -5284,7 +5349,6 @@ const baseTheme$1 = /*@__PURE__*/buildTheme("." + baseThemeID, {
|
|
|
5284
5349
|
margin: 0,
|
|
5285
5350
|
flexGrow: 2,
|
|
5286
5351
|
flexShrink: 0,
|
|
5287
|
-
minHeight: "100%",
|
|
5288
5352
|
display: "block",
|
|
5289
5353
|
whiteSpace: "pre",
|
|
5290
5354
|
wordWrap: "normal",
|
|
@@ -5431,6 +5495,21 @@ const baseTheme$1 = /*@__PURE__*/buildTheme("." + baseThemeID, {
|
|
|
5431
5495
|
display: "inline-block",
|
|
5432
5496
|
verticalAlign: "top",
|
|
5433
5497
|
},
|
|
5498
|
+
".cm-highlightSpace:before": {
|
|
5499
|
+
content: "attr(data-display)",
|
|
5500
|
+
position: "absolute",
|
|
5501
|
+
pointerEvents: "none",
|
|
5502
|
+
color: "#888"
|
|
5503
|
+
},
|
|
5504
|
+
".cm-highlightTab": {
|
|
5505
|
+
backgroundImage: `url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="200" height="20"><path stroke="%23888" stroke-width="1" fill="none" d="M1 10H196L190 5M190 15L196 10M197 4L197 16"/></svg>')`,
|
|
5506
|
+
backgroundSize: "auto 100%",
|
|
5507
|
+
backgroundPosition: "right 90%",
|
|
5508
|
+
backgroundRepeat: "no-repeat"
|
|
5509
|
+
},
|
|
5510
|
+
".cm-trailingSpace": {
|
|
5511
|
+
backgroundColor: "#ff332255"
|
|
5512
|
+
},
|
|
5434
5513
|
".cm-button": {
|
|
5435
5514
|
verticalAlign: "middle",
|
|
5436
5515
|
color: "inherit",
|
|
@@ -5733,7 +5812,8 @@ class DOMObserver {
|
|
|
5733
5812
|
this.lastChange = 0;
|
|
5734
5813
|
this.scrollTargets = [];
|
|
5735
5814
|
this.intersection = null;
|
|
5736
|
-
this.
|
|
5815
|
+
this.resizeScroll = null;
|
|
5816
|
+
this.resizeContent = null;
|
|
5737
5817
|
this.intersecting = false;
|
|
5738
5818
|
this.gapIntersection = null;
|
|
5739
5819
|
this.gaps = [];
|
|
@@ -5771,12 +5851,14 @@ class DOMObserver {
|
|
|
5771
5851
|
this.onPrint = this.onPrint.bind(this);
|
|
5772
5852
|
this.onScroll = this.onScroll.bind(this);
|
|
5773
5853
|
if (typeof ResizeObserver == "function") {
|
|
5774
|
-
this.
|
|
5854
|
+
this.resizeScroll = new ResizeObserver(() => {
|
|
5775
5855
|
var _a;
|
|
5776
5856
|
if (((_a = this.view.docView) === null || _a === void 0 ? void 0 : _a.lastUpdate) < Date.now() - 75)
|
|
5777
5857
|
this.onResize();
|
|
5778
5858
|
});
|
|
5779
|
-
this.
|
|
5859
|
+
this.resizeScroll.observe(view.scrollDOM);
|
|
5860
|
+
this.resizeContent = new ResizeObserver(() => this.view.requestMeasure());
|
|
5861
|
+
this.resizeContent.observe(view.contentDOM);
|
|
5780
5862
|
}
|
|
5781
5863
|
this.addWindowListeners(this.win = view.win);
|
|
5782
5864
|
this.start();
|
|
@@ -6095,11 +6177,12 @@ class DOMObserver {
|
|
|
6095
6177
|
win.document.removeEventListener("selectionchange", this.onSelectionChange);
|
|
6096
6178
|
}
|
|
6097
6179
|
destroy() {
|
|
6098
|
-
var _a, _b, _c;
|
|
6180
|
+
var _a, _b, _c, _d;
|
|
6099
6181
|
this.stop();
|
|
6100
6182
|
(_a = this.intersection) === null || _a === void 0 ? void 0 : _a.disconnect();
|
|
6101
6183
|
(_b = this.gapIntersection) === null || _b === void 0 ? void 0 : _b.disconnect();
|
|
6102
|
-
(_c = this.
|
|
6184
|
+
(_c = this.resizeScroll) === null || _c === void 0 ? void 0 : _c.disconnect();
|
|
6185
|
+
(_d = this.resizeContent) === null || _d === void 0 ? void 0 : _d.disconnect();
|
|
6103
6186
|
for (let dom of this.scrollTargets)
|
|
6104
6187
|
dom.removeEventListener("scroll", this.onScroll);
|
|
6105
6188
|
this.removeWindowListeners(this.win);
|
|
@@ -6198,7 +6281,7 @@ class EditorView {
|
|
|
6198
6281
|
this.scrollDOM.className = "cm-scroller";
|
|
6199
6282
|
this.scrollDOM.appendChild(this.contentDOM);
|
|
6200
6283
|
this.announceDOM = document.createElement("div");
|
|
6201
|
-
this.announceDOM.style.cssText = "position:
|
|
6284
|
+
this.announceDOM.style.cssText = "position: fixed; top: -10000px";
|
|
6202
6285
|
this.announceDOM.setAttribute("aria-live", "polite");
|
|
6203
6286
|
this.dom = document.createElement("div");
|
|
6204
6287
|
this.dom.appendChild(this.announceDOM);
|
|
@@ -7289,7 +7372,8 @@ a rectangle at a given set of coordinates.
|
|
|
7289
7372
|
*/
|
|
7290
7373
|
class RectangleMarker {
|
|
7291
7374
|
/**
|
|
7292
|
-
Create a marker with the given class and dimensions.
|
|
7375
|
+
Create a marker with the given class and dimensions. If `width`
|
|
7376
|
+
is null, the DOM element will get no width style.
|
|
7293
7377
|
*/
|
|
7294
7378
|
constructor(className, left, top, width, height) {
|
|
7295
7379
|
this.className = className;
|
|
@@ -7313,7 +7397,7 @@ class RectangleMarker {
|
|
|
7313
7397
|
adjust(elt) {
|
|
7314
7398
|
elt.style.left = this.left + "px";
|
|
7315
7399
|
elt.style.top = this.top + "px";
|
|
7316
|
-
if (this.width
|
|
7400
|
+
if (this.width != null)
|
|
7317
7401
|
elt.style.width = this.width + "px";
|
|
7318
7402
|
elt.style.height = this.height + "px";
|
|
7319
7403
|
}
|
|
@@ -7321,6 +7405,129 @@ class RectangleMarker {
|
|
|
7321
7405
|
return this.left == p.left && this.top == p.top && this.width == p.width && this.height == p.height &&
|
|
7322
7406
|
this.className == p.className;
|
|
7323
7407
|
}
|
|
7408
|
+
/**
|
|
7409
|
+
Create a set of rectangles for the given selection range,
|
|
7410
|
+
assigning them theclass`className`. Will create a single
|
|
7411
|
+
rectangle for empty ranges, and a set of selection-style
|
|
7412
|
+
rectangles covering the range's content (in a bidi-aware
|
|
7413
|
+
way) for non-empty ones.
|
|
7414
|
+
*/
|
|
7415
|
+
static forRange(view, className, range) {
|
|
7416
|
+
if (range.empty) {
|
|
7417
|
+
let pos = view.coordsAtPos(range.head, range.assoc || 1);
|
|
7418
|
+
if (!pos)
|
|
7419
|
+
return [];
|
|
7420
|
+
let base = getBase(view);
|
|
7421
|
+
return [new RectangleMarker(className, pos.left - base.left, pos.top - base.top, null, pos.bottom - pos.top)];
|
|
7422
|
+
}
|
|
7423
|
+
else {
|
|
7424
|
+
return rectanglesForRange(view, className, range);
|
|
7425
|
+
}
|
|
7426
|
+
}
|
|
7427
|
+
}
|
|
7428
|
+
function getBase(view) {
|
|
7429
|
+
let rect = view.scrollDOM.getBoundingClientRect();
|
|
7430
|
+
let left = view.textDirection == Direction.LTR ? rect.left : rect.right - view.scrollDOM.clientWidth;
|
|
7431
|
+
return { left: left - view.scrollDOM.scrollLeft, top: rect.top - view.scrollDOM.scrollTop };
|
|
7432
|
+
}
|
|
7433
|
+
function wrappedLine(view, pos, inside) {
|
|
7434
|
+
let range = EditorSelection.cursor(pos);
|
|
7435
|
+
return { from: Math.max(inside.from, view.moveToLineBoundary(range, false, true).from),
|
|
7436
|
+
to: Math.min(inside.to, view.moveToLineBoundary(range, true, true).from),
|
|
7437
|
+
type: BlockType.Text };
|
|
7438
|
+
}
|
|
7439
|
+
function blockAt(view, pos) {
|
|
7440
|
+
let line = view.lineBlockAt(pos);
|
|
7441
|
+
if (Array.isArray(line.type))
|
|
7442
|
+
for (let l of line.type) {
|
|
7443
|
+
if (l.to > pos || l.to == pos && (l.to == line.to || l.type == BlockType.Text))
|
|
7444
|
+
return l;
|
|
7445
|
+
}
|
|
7446
|
+
return line;
|
|
7447
|
+
}
|
|
7448
|
+
function rectanglesForRange(view, className, range) {
|
|
7449
|
+
if (range.to <= view.viewport.from || range.from >= view.viewport.to)
|
|
7450
|
+
return [];
|
|
7451
|
+
let from = Math.max(range.from, view.viewport.from), to = Math.min(range.to, view.viewport.to);
|
|
7452
|
+
let ltr = view.textDirection == Direction.LTR;
|
|
7453
|
+
let content = view.contentDOM, contentRect = content.getBoundingClientRect(), base = getBase(view);
|
|
7454
|
+
let lineStyle = window.getComputedStyle(content.firstChild);
|
|
7455
|
+
let leftSide = contentRect.left + parseInt(lineStyle.paddingLeft) + Math.min(0, parseInt(lineStyle.textIndent));
|
|
7456
|
+
let rightSide = contentRect.right - parseInt(lineStyle.paddingRight);
|
|
7457
|
+
let startBlock = blockAt(view, from), endBlock = blockAt(view, to);
|
|
7458
|
+
let visualStart = startBlock.type == BlockType.Text ? startBlock : null;
|
|
7459
|
+
let visualEnd = endBlock.type == BlockType.Text ? endBlock : null;
|
|
7460
|
+
if (view.lineWrapping) {
|
|
7461
|
+
if (visualStart)
|
|
7462
|
+
visualStart = wrappedLine(view, from, visualStart);
|
|
7463
|
+
if (visualEnd)
|
|
7464
|
+
visualEnd = wrappedLine(view, to, visualEnd);
|
|
7465
|
+
}
|
|
7466
|
+
if (visualStart && visualEnd && visualStart.from == visualEnd.from) {
|
|
7467
|
+
return pieces(drawForLine(range.from, range.to, visualStart));
|
|
7468
|
+
}
|
|
7469
|
+
else {
|
|
7470
|
+
let top = visualStart ? drawForLine(range.from, null, visualStart) : drawForWidget(startBlock, false);
|
|
7471
|
+
let bottom = visualEnd ? drawForLine(null, range.to, visualEnd) : drawForWidget(endBlock, true);
|
|
7472
|
+
let between = [];
|
|
7473
|
+
if ((visualStart || startBlock).to < (visualEnd || endBlock).from - 1)
|
|
7474
|
+
between.push(piece(leftSide, top.bottom, rightSide, bottom.top));
|
|
7475
|
+
else if (top.bottom < bottom.top && view.elementAtHeight((top.bottom + bottom.top) / 2).type == BlockType.Text)
|
|
7476
|
+
top.bottom = bottom.top = (top.bottom + bottom.top) / 2;
|
|
7477
|
+
return pieces(top).concat(between).concat(pieces(bottom));
|
|
7478
|
+
}
|
|
7479
|
+
function piece(left, top, right, bottom) {
|
|
7480
|
+
return new RectangleMarker(className, left - base.left, top - base.top - 0.01 /* C.Epsilon */, right - left, bottom - top + 0.01 /* C.Epsilon */);
|
|
7481
|
+
}
|
|
7482
|
+
function pieces({ top, bottom, horizontal }) {
|
|
7483
|
+
let pieces = [];
|
|
7484
|
+
for (let i = 0; i < horizontal.length; i += 2)
|
|
7485
|
+
pieces.push(piece(horizontal[i], top, horizontal[i + 1], bottom));
|
|
7486
|
+
return pieces;
|
|
7487
|
+
}
|
|
7488
|
+
// Gets passed from/to in line-local positions
|
|
7489
|
+
function drawForLine(from, to, line) {
|
|
7490
|
+
let top = 1e9, bottom = -1e9, horizontal = [];
|
|
7491
|
+
function addSpan(from, fromOpen, to, toOpen, dir) {
|
|
7492
|
+
// Passing 2/-2 is a kludge to force the view to return
|
|
7493
|
+
// coordinates on the proper side of block widgets, since
|
|
7494
|
+
// normalizing the side there, though appropriate for most
|
|
7495
|
+
// coordsAtPos queries, would break selection drawing.
|
|
7496
|
+
let fromCoords = view.coordsAtPos(from, (from == line.to ? -2 : 2));
|
|
7497
|
+
let toCoords = view.coordsAtPos(to, (to == line.from ? 2 : -2));
|
|
7498
|
+
top = Math.min(fromCoords.top, toCoords.top, top);
|
|
7499
|
+
bottom = Math.max(fromCoords.bottom, toCoords.bottom, bottom);
|
|
7500
|
+
if (dir == Direction.LTR)
|
|
7501
|
+
horizontal.push(ltr && fromOpen ? leftSide : fromCoords.left, ltr && toOpen ? rightSide : toCoords.right);
|
|
7502
|
+
else
|
|
7503
|
+
horizontal.push(!ltr && toOpen ? leftSide : toCoords.left, !ltr && fromOpen ? rightSide : fromCoords.right);
|
|
7504
|
+
}
|
|
7505
|
+
let start = from !== null && from !== void 0 ? from : line.from, end = to !== null && to !== void 0 ? to : line.to;
|
|
7506
|
+
// Split the range by visible range and document line
|
|
7507
|
+
for (let r of view.visibleRanges)
|
|
7508
|
+
if (r.to > start && r.from < end) {
|
|
7509
|
+
for (let pos = Math.max(r.from, start), endPos = Math.min(r.to, end);;) {
|
|
7510
|
+
let docLine = view.state.doc.lineAt(pos);
|
|
7511
|
+
for (let span of view.bidiSpans(docLine)) {
|
|
7512
|
+
let spanFrom = span.from + docLine.from, spanTo = span.to + docLine.from;
|
|
7513
|
+
if (spanFrom >= endPos)
|
|
7514
|
+
break;
|
|
7515
|
+
if (spanTo > pos)
|
|
7516
|
+
addSpan(Math.max(spanFrom, pos), from == null && spanFrom <= start, Math.min(spanTo, endPos), to == null && spanTo >= end, span.dir);
|
|
7517
|
+
}
|
|
7518
|
+
pos = docLine.to + 1;
|
|
7519
|
+
if (pos >= endPos)
|
|
7520
|
+
break;
|
|
7521
|
+
}
|
|
7522
|
+
}
|
|
7523
|
+
if (horizontal.length == 0)
|
|
7524
|
+
addSpan(start, from == null, end, to == null, view.textDirection);
|
|
7525
|
+
return { top, bottom, horizontal };
|
|
7526
|
+
}
|
|
7527
|
+
function drawForWidget(block, top) {
|
|
7528
|
+
let y = contentRect.top + (top ? block.top : block.bottom);
|
|
7529
|
+
return { top: y, bottom: y, horizontal: [] };
|
|
7530
|
+
}
|
|
7324
7531
|
}
|
|
7325
7532
|
function sameMarker(a, b) {
|
|
7326
7533
|
return a.constructor == b.constructor && a.eq(b);
|
|
@@ -7380,6 +7587,8 @@ class LayerView {
|
|
|
7380
7587
|
}
|
|
7381
7588
|
}
|
|
7382
7589
|
destroy() {
|
|
7590
|
+
if (this.layer.destroy)
|
|
7591
|
+
this.layer.destroy(this.dom, this.view);
|
|
7383
7592
|
this.dom.remove();
|
|
7384
7593
|
}
|
|
7385
7594
|
}
|
|
@@ -7444,8 +7653,9 @@ const cursorLayer = /*@__PURE__*/layer({
|
|
|
7444
7653
|
for (let r of state.selection.ranges) {
|
|
7445
7654
|
let prim = r == state.selection.main;
|
|
7446
7655
|
if (r.empty ? !prim || CanHidePrimary : conf.drawRangeCursor) {
|
|
7447
|
-
let
|
|
7448
|
-
|
|
7656
|
+
let className = prim ? "cm-cursor cm-cursor-primary" : "cm-cursor cm-cursor-secondary";
|
|
7657
|
+
let cursor = r.empty ? r : EditorSelection.cursor(r.head, r.head > r.anchor ? -1 : 1);
|
|
7658
|
+
for (let piece of RectangleMarker.forRange(view, className, cursor))
|
|
7449
7659
|
cursors.push(piece);
|
|
7450
7660
|
}
|
|
7451
7661
|
}
|
|
@@ -7470,7 +7680,8 @@ function setBlinkRate(state, dom) {
|
|
|
7470
7680
|
const selectionLayer = /*@__PURE__*/layer({
|
|
7471
7681
|
above: false,
|
|
7472
7682
|
markers(view) {
|
|
7473
|
-
return view.state.selection.ranges.map(r => r.empty ? [] :
|
|
7683
|
+
return view.state.selection.ranges.map(r => r.empty ? [] : RectangleMarker.forRange(view, "cm-selectionBackground", r))
|
|
7684
|
+
.reduce((a, b) => a.concat(b));
|
|
7474
7685
|
},
|
|
7475
7686
|
update(update, dom) {
|
|
7476
7687
|
return update.docChanged || update.selectionSet || update.viewportChanged || configChanged(update);
|
|
@@ -7486,117 +7697,6 @@ const themeSpec = {
|
|
|
7486
7697
|
if (CanHidePrimary)
|
|
7487
7698
|
themeSpec[".cm-line"].caretColor = "transparent !important";
|
|
7488
7699
|
const hideNativeSelection = /*@__PURE__*/Prec.highest(/*@__PURE__*/EditorView.theme(themeSpec));
|
|
7489
|
-
function getBase(view) {
|
|
7490
|
-
let rect = view.scrollDOM.getBoundingClientRect();
|
|
7491
|
-
let left = view.textDirection == Direction.LTR ? rect.left : rect.right - view.scrollDOM.clientWidth;
|
|
7492
|
-
return { left: left - view.scrollDOM.scrollLeft, top: rect.top - view.scrollDOM.scrollTop };
|
|
7493
|
-
}
|
|
7494
|
-
function wrappedLine(view, pos, inside) {
|
|
7495
|
-
let range = EditorSelection.cursor(pos);
|
|
7496
|
-
return { from: Math.max(inside.from, view.moveToLineBoundary(range, false, true).from),
|
|
7497
|
-
to: Math.min(inside.to, view.moveToLineBoundary(range, true, true).from),
|
|
7498
|
-
type: BlockType.Text };
|
|
7499
|
-
}
|
|
7500
|
-
function blockAt(view, pos) {
|
|
7501
|
-
let line = view.lineBlockAt(pos);
|
|
7502
|
-
if (Array.isArray(line.type))
|
|
7503
|
-
for (let l of line.type) {
|
|
7504
|
-
if (l.to > pos || l.to == pos && (l.to == line.to || l.type == BlockType.Text))
|
|
7505
|
-
return l;
|
|
7506
|
-
}
|
|
7507
|
-
return line;
|
|
7508
|
-
}
|
|
7509
|
-
function measureRange(view, range) {
|
|
7510
|
-
if (range.to <= view.viewport.from || range.from >= view.viewport.to)
|
|
7511
|
-
return [];
|
|
7512
|
-
let from = Math.max(range.from, view.viewport.from), to = Math.min(range.to, view.viewport.to);
|
|
7513
|
-
let ltr = view.textDirection == Direction.LTR;
|
|
7514
|
-
let content = view.contentDOM, contentRect = content.getBoundingClientRect(), base = getBase(view);
|
|
7515
|
-
let lineStyle = window.getComputedStyle(content.firstChild);
|
|
7516
|
-
let leftSide = contentRect.left + parseInt(lineStyle.paddingLeft) + Math.min(0, parseInt(lineStyle.textIndent));
|
|
7517
|
-
let rightSide = contentRect.right - parseInt(lineStyle.paddingRight);
|
|
7518
|
-
let startBlock = blockAt(view, from), endBlock = blockAt(view, to);
|
|
7519
|
-
let visualStart = startBlock.type == BlockType.Text ? startBlock : null;
|
|
7520
|
-
let visualEnd = endBlock.type == BlockType.Text ? endBlock : null;
|
|
7521
|
-
if (view.lineWrapping) {
|
|
7522
|
-
if (visualStart)
|
|
7523
|
-
visualStart = wrappedLine(view, from, visualStart);
|
|
7524
|
-
if (visualEnd)
|
|
7525
|
-
visualEnd = wrappedLine(view, to, visualEnd);
|
|
7526
|
-
}
|
|
7527
|
-
if (visualStart && visualEnd && visualStart.from == visualEnd.from) {
|
|
7528
|
-
return pieces(drawForLine(range.from, range.to, visualStart));
|
|
7529
|
-
}
|
|
7530
|
-
else {
|
|
7531
|
-
let top = visualStart ? drawForLine(range.from, null, visualStart) : drawForWidget(startBlock, false);
|
|
7532
|
-
let bottom = visualEnd ? drawForLine(null, range.to, visualEnd) : drawForWidget(endBlock, true);
|
|
7533
|
-
let between = [];
|
|
7534
|
-
if ((visualStart || startBlock).to < (visualEnd || endBlock).from - 1)
|
|
7535
|
-
between.push(piece(leftSide, top.bottom, rightSide, bottom.top));
|
|
7536
|
-
else if (top.bottom < bottom.top && view.elementAtHeight((top.bottom + bottom.top) / 2).type == BlockType.Text)
|
|
7537
|
-
top.bottom = bottom.top = (top.bottom + bottom.top) / 2;
|
|
7538
|
-
return pieces(top).concat(between).concat(pieces(bottom));
|
|
7539
|
-
}
|
|
7540
|
-
function piece(left, top, right, bottom) {
|
|
7541
|
-
return new RectangleMarker("cm-selectionBackground", left - base.left, top - base.top - 0.01 /* C.Epsilon */, right - left, bottom - top + 0.01 /* C.Epsilon */);
|
|
7542
|
-
}
|
|
7543
|
-
function pieces({ top, bottom, horizontal }) {
|
|
7544
|
-
let pieces = [];
|
|
7545
|
-
for (let i = 0; i < horizontal.length; i += 2)
|
|
7546
|
-
pieces.push(piece(horizontal[i], top, horizontal[i + 1], bottom));
|
|
7547
|
-
return pieces;
|
|
7548
|
-
}
|
|
7549
|
-
// Gets passed from/to in line-local positions
|
|
7550
|
-
function drawForLine(from, to, line) {
|
|
7551
|
-
let top = 1e9, bottom = -1e9, horizontal = [];
|
|
7552
|
-
function addSpan(from, fromOpen, to, toOpen, dir) {
|
|
7553
|
-
// Passing 2/-2 is a kludge to force the view to return
|
|
7554
|
-
// coordinates on the proper side of block widgets, since
|
|
7555
|
-
// normalizing the side there, though appropriate for most
|
|
7556
|
-
// coordsAtPos queries, would break selection drawing.
|
|
7557
|
-
let fromCoords = view.coordsAtPos(from, (from == line.to ? -2 : 2));
|
|
7558
|
-
let toCoords = view.coordsAtPos(to, (to == line.from ? 2 : -2));
|
|
7559
|
-
top = Math.min(fromCoords.top, toCoords.top, top);
|
|
7560
|
-
bottom = Math.max(fromCoords.bottom, toCoords.bottom, bottom);
|
|
7561
|
-
if (dir == Direction.LTR)
|
|
7562
|
-
horizontal.push(ltr && fromOpen ? leftSide : fromCoords.left, ltr && toOpen ? rightSide : toCoords.right);
|
|
7563
|
-
else
|
|
7564
|
-
horizontal.push(!ltr && toOpen ? leftSide : toCoords.left, !ltr && fromOpen ? rightSide : fromCoords.right);
|
|
7565
|
-
}
|
|
7566
|
-
let start = from !== null && from !== void 0 ? from : line.from, end = to !== null && to !== void 0 ? to : line.to;
|
|
7567
|
-
// Split the range by visible range and document line
|
|
7568
|
-
for (let r of view.visibleRanges)
|
|
7569
|
-
if (r.to > start && r.from < end) {
|
|
7570
|
-
for (let pos = Math.max(r.from, start), endPos = Math.min(r.to, end);;) {
|
|
7571
|
-
let docLine = view.state.doc.lineAt(pos);
|
|
7572
|
-
for (let span of view.bidiSpans(docLine)) {
|
|
7573
|
-
let spanFrom = span.from + docLine.from, spanTo = span.to + docLine.from;
|
|
7574
|
-
if (spanFrom >= endPos)
|
|
7575
|
-
break;
|
|
7576
|
-
if (spanTo > pos)
|
|
7577
|
-
addSpan(Math.max(spanFrom, pos), from == null && spanFrom <= start, Math.min(spanTo, endPos), to == null && spanTo >= end, span.dir);
|
|
7578
|
-
}
|
|
7579
|
-
pos = docLine.to + 1;
|
|
7580
|
-
if (pos >= endPos)
|
|
7581
|
-
break;
|
|
7582
|
-
}
|
|
7583
|
-
}
|
|
7584
|
-
if (horizontal.length == 0)
|
|
7585
|
-
addSpan(start, from == null, end, to == null, view.textDirection);
|
|
7586
|
-
return { top, bottom, horizontal };
|
|
7587
|
-
}
|
|
7588
|
-
function drawForWidget(block, top) {
|
|
7589
|
-
let y = contentRect.top + (top ? block.top : block.bottom);
|
|
7590
|
-
return { top: y, bottom: y, horizontal: [] };
|
|
7591
|
-
}
|
|
7592
|
-
}
|
|
7593
|
-
function measureCursor(view, cursor, primary) {
|
|
7594
|
-
let pos = view.coordsAtPos(cursor.head, cursor.assoc || 1);
|
|
7595
|
-
if (!pos)
|
|
7596
|
-
return null;
|
|
7597
|
-
let base = getBase(view);
|
|
7598
|
-
return new RectangleMarker(primary ? "cm-cursor cm-cursor-primary" : "cm-cursor cm-cursor-secondary", pos.left - base.left, pos.top - base.top, -1, pos.bottom - pos.top);
|
|
7599
|
-
}
|
|
7600
7700
|
|
|
7601
7701
|
const setDropCursorPos = /*@__PURE__*/StateEffect.define({
|
|
7602
7702
|
map(pos, mapping) { return pos == null ? null : mapping.mapPos(pos); }
|
|
@@ -9363,9 +9463,60 @@ function highlightActiveLineGutter() {
|
|
|
9363
9463
|
return activeLineGutterHighlighter;
|
|
9364
9464
|
}
|
|
9365
9465
|
|
|
9466
|
+
const WhitespaceDeco = /*@__PURE__*/new Map();
|
|
9467
|
+
function getWhitespaceDeco(space) {
|
|
9468
|
+
let deco = WhitespaceDeco.get(space);
|
|
9469
|
+
if (!deco)
|
|
9470
|
+
WhitespaceDeco.set(space, deco = Decoration.mark({
|
|
9471
|
+
attributes: space === "\t" ? {
|
|
9472
|
+
class: "cm-highlightTab",
|
|
9473
|
+
} : {
|
|
9474
|
+
class: "cm-highlightSpace",
|
|
9475
|
+
"data-display": space.replace(/ /g, "·")
|
|
9476
|
+
}
|
|
9477
|
+
}));
|
|
9478
|
+
return deco;
|
|
9479
|
+
}
|
|
9480
|
+
function matcher(decorator) {
|
|
9481
|
+
return ViewPlugin.define(view => ({
|
|
9482
|
+
decorations: decorator.createDeco(view),
|
|
9483
|
+
update(u) {
|
|
9484
|
+
this.decorations = decorator.updateDeco(u, this.decorations);
|
|
9485
|
+
},
|
|
9486
|
+
}), {
|
|
9487
|
+
decorations: v => v.decorations
|
|
9488
|
+
});
|
|
9489
|
+
}
|
|
9490
|
+
const whitespaceHighlighter = /*@__PURE__*/matcher(/*@__PURE__*/new MatchDecorator({
|
|
9491
|
+
regexp: /\t| +/g,
|
|
9492
|
+
decoration: match => getWhitespaceDeco(match[0]),
|
|
9493
|
+
boundary: /\S/,
|
|
9494
|
+
}));
|
|
9495
|
+
/**
|
|
9496
|
+
Returns an extension that highlights whitespace, adding a
|
|
9497
|
+
`cm-highlightSpace` class to stretches of spaces, and a
|
|
9498
|
+
`cm-highlightTab` class to individual tab characters. By default,
|
|
9499
|
+
the former are shown as faint dots, and the latter as arrows.
|
|
9500
|
+
*/
|
|
9501
|
+
function highlightWhitespace() {
|
|
9502
|
+
return whitespaceHighlighter;
|
|
9503
|
+
}
|
|
9504
|
+
const trailingHighlighter = /*@__PURE__*/matcher(/*@__PURE__*/new MatchDecorator({
|
|
9505
|
+
regexp: /\s+$/g,
|
|
9506
|
+
decoration: /*@__PURE__*/Decoration.mark({ class: "cm-trailingSpace" }),
|
|
9507
|
+
boundary: /\S/,
|
|
9508
|
+
}));
|
|
9509
|
+
/**
|
|
9510
|
+
Returns an extension that adds a `cm-trailingSpace` class to all
|
|
9511
|
+
trailing whitespace.
|
|
9512
|
+
*/
|
|
9513
|
+
function highlightTrailingWhitespace() {
|
|
9514
|
+
return trailingHighlighter;
|
|
9515
|
+
}
|
|
9516
|
+
|
|
9366
9517
|
/**
|
|
9367
9518
|
@internal
|
|
9368
9519
|
*/
|
|
9369
9520
|
const __test = { HeightMap, HeightOracle, MeasuredHeights, QueryType, ChangedRange, computeOrder, moveVisually };
|
|
9370
9521
|
|
|
9371
|
-
export { BidiSpan, BlockInfo, BlockType, Decoration, Direction, EditorView, GutterMarker, MatchDecorator, RectangleMarker, ViewPlugin, ViewUpdate, WidgetType, __test, closeHoverTooltips, crosshairCursor, drawSelection, dropCursor, getPanel, getTooltip, gutter, gutterLineClass, gutters, hasHoverTooltips, highlightActiveLine, highlightActiveLineGutter, highlightSpecialChars, hoverTooltip, keymap, layer, lineNumberMarkers, lineNumbers, logException, panels, placeholder, rectangularSelection, repositionTooltips, runScopeHandlers, scrollPastEnd, showPanel, showTooltip, tooltips };
|
|
9522
|
+
export { BidiSpan, BlockInfo, BlockType, Decoration, Direction, EditorView, GutterMarker, MatchDecorator, RectangleMarker, ViewPlugin, ViewUpdate, WidgetType, __test, closeHoverTooltips, crosshairCursor, drawSelection, dropCursor, getPanel, getTooltip, gutter, gutterLineClass, gutters, hasHoverTooltips, highlightActiveLine, highlightActiveLineGutter, highlightSpecialChars, highlightTrailingWhitespace, highlightWhitespace, hoverTooltip, keymap, layer, lineNumberMarkers, lineNumbers, logException, panels, placeholder, rectangularSelection, repositionTooltips, runScopeHandlers, scrollPastEnd, showPanel, showTooltip, tooltips };
|