sqlui 0.1.67 → 0.1.69
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.release-version +1 -1
- data/app/server.rb +1 -1
- data/app/views/sqlui.erb +134 -8
- data/client/resources/help.css +38 -0
- data/client/resources/sqlui.css +34 -22
- data/client/resources/sqlui.js +1018 -1307
- metadata +3 -2
data/client/resources/sqlui.js
CHANGED
@@ -3971,11 +3971,11 @@
|
|
3971
3971
|
constructor(root) {
|
3972
3972
|
if (!root.head && root.adoptedStyleSheets && typeof CSSStyleSheet != "undefined") {
|
3973
3973
|
if (adoptedSet) {
|
3974
|
-
root.adoptedStyleSheets = [adoptedSet.sheet
|
3974
|
+
root.adoptedStyleSheets = [adoptedSet.sheet, ...root.adoptedStyleSheets];
|
3975
3975
|
return root[SET] = adoptedSet
|
3976
3976
|
}
|
3977
3977
|
this.sheet = new CSSStyleSheet;
|
3978
|
-
root.adoptedStyleSheets = [this.sheet
|
3978
|
+
root.adoptedStyleSheets = [this.sheet, ...root.adoptedStyleSheets];
|
3979
3979
|
adoptedSet = this;
|
3980
3980
|
} else {
|
3981
3981
|
this.styleTag = (root.ownerDocument || root).createElement("style");
|
@@ -4490,11 +4490,6 @@
|
|
4490
4490
|
this.dom = null;
|
4491
4491
|
this.dirty = 2 /* Dirty.Node */;
|
4492
4492
|
}
|
4493
|
-
get editorView() {
|
4494
|
-
if (!this.parent)
|
4495
|
-
throw new Error("Accessing view in orphan content view");
|
4496
|
-
return this.parent.editorView;
|
4497
|
-
}
|
4498
4493
|
get overrideDOMText() { return null; }
|
4499
4494
|
get posAtStart() {
|
4500
4495
|
return this.parent ? this.parent.posBefore(this) : 0;
|
@@ -4518,7 +4513,7 @@
|
|
4518
4513
|
// (side > 0) or directly on (when the browser supports it) the
|
4519
4514
|
// given position.
|
4520
4515
|
coordsAt(_pos, _side) { return null; }
|
4521
|
-
sync(track) {
|
4516
|
+
sync(view, track) {
|
4522
4517
|
if (this.dirty & 2 /* Dirty.Node */) {
|
4523
4518
|
let parent = this.dom;
|
4524
4519
|
let prev = null, next;
|
@@ -4529,7 +4524,7 @@
|
|
4529
4524
|
if (!contentView || !contentView.parent && contentView.canReuseDOM(child))
|
4530
4525
|
child.reuseDOM(next);
|
4531
4526
|
}
|
4532
|
-
child.sync(track);
|
4527
|
+
child.sync(view, track);
|
4533
4528
|
child.dirty = 0 /* Dirty.Not */;
|
4534
4529
|
}
|
4535
4530
|
next = prev ? prev.nextSibling : parent.firstChild;
|
@@ -4553,7 +4548,7 @@
|
|
4553
4548
|
else if (this.dirty & 1 /* Dirty.Child */) {
|
4554
4549
|
for (let child of this.children)
|
4555
4550
|
if (child.dirty) {
|
4556
|
-
child.sync(track);
|
4551
|
+
child.sync(view, track);
|
4557
4552
|
child.dirty = 0 /* Dirty.Not */;
|
4558
4553
|
}
|
4559
4554
|
}
|
@@ -4680,6 +4675,7 @@
|
|
4680
4675
|
}
|
4681
4676
|
static get(node) { return node.cmView; }
|
4682
4677
|
get isEditable() { return true; }
|
4678
|
+
get isWidget() { return false; }
|
4683
4679
|
merge(from, to, source, hasStart, openStart, openEnd) {
|
4684
4680
|
return false;
|
4685
4681
|
}
|
@@ -4847,7 +4843,7 @@
|
|
4847
4843
|
createDOM(textDOM) {
|
4848
4844
|
this.setDOM(textDOM || document.createTextNode(this.text));
|
4849
4845
|
}
|
4850
|
-
sync(track) {
|
4846
|
+
sync(view, track) {
|
4851
4847
|
if (!this.dom)
|
4852
4848
|
this.createDOM();
|
4853
4849
|
if (this.dom.nodeValue != this.text) {
|
@@ -4908,12 +4904,12 @@
|
|
4908
4904
|
this.dirty |= 4 /* Dirty.Attrs */ | 2 /* Dirty.Node */;
|
4909
4905
|
}
|
4910
4906
|
}
|
4911
|
-
sync(track) {
|
4907
|
+
sync(view, track) {
|
4912
4908
|
if (!this.dom)
|
4913
4909
|
this.setDOM(this.setAttrs(document.createElement(this.mark.tagName)));
|
4914
4910
|
else if (this.dirty & 4 /* Dirty.Attrs */)
|
4915
4911
|
this.setAttrs(this.dom);
|
4916
|
-
super.sync(track);
|
4912
|
+
super.sync(view, track);
|
4917
4913
|
}
|
4918
4914
|
merge(from, to, source, _hasStart, openStart, openEnd) {
|
4919
4915
|
if (source && (!(source instanceof MarkView && source.mark.eq(this.mark)) ||
|
@@ -4997,12 +4993,12 @@
|
|
4997
4993
|
this.length -= from;
|
4998
4994
|
return result;
|
4999
4995
|
}
|
5000
|
-
sync() {
|
5001
|
-
if (!this.dom || !this.widget.updateDOM(this.dom)) {
|
4996
|
+
sync(view) {
|
4997
|
+
if (!this.dom || !this.widget.updateDOM(this.dom, view)) {
|
5002
4998
|
if (this.dom && this.prevWidget)
|
5003
4999
|
this.prevWidget.destroy(this.dom);
|
5004
5000
|
this.prevWidget = null;
|
5005
|
-
this.setDOM(this.widget.toDOM(
|
5001
|
+
this.setDOM(this.widget.toDOM(view));
|
5006
5002
|
this.dom.contentEditable = "false";
|
5007
5003
|
}
|
5008
5004
|
}
|
@@ -5035,7 +5031,7 @@
|
|
5035
5031
|
let top = this;
|
5036
5032
|
while (top.parent)
|
5037
5033
|
top = top.parent;
|
5038
|
-
let view = top
|
5034
|
+
let { view } = top, text = view && view.state.doc, start = this.posAtStart;
|
5039
5035
|
return text ? text.slice(start, start + this.length) : Text.empty;
|
5040
5036
|
}
|
5041
5037
|
domAtPos(pos) {
|
@@ -5054,6 +5050,7 @@
|
|
5054
5050
|
return this.length ? rect : flattenRect(rect, this.side > 0);
|
5055
5051
|
}
|
5056
5052
|
get isEditable() { return false; }
|
5053
|
+
get isWidget() { return true; }
|
5057
5054
|
destroy() {
|
5058
5055
|
super.destroy();
|
5059
5056
|
if (this.dom)
|
@@ -5116,8 +5113,9 @@
|
|
5116
5113
|
}
|
5117
5114
|
function posFromDOMInCompositionTree(node, offset, view, text) {
|
5118
5115
|
if (view instanceof MarkView) {
|
5116
|
+
let pos = 0;
|
5119
5117
|
for (let child of view.children) {
|
5120
|
-
let
|
5118
|
+
let hasComp = contains(child.dom, text);
|
5121
5119
|
if (contains(child.dom, node))
|
5122
5120
|
return pos + (hasComp ? posFromDOMInCompositionTree(node, offset, child, text) : child.localPosFromDOM(node, offset));
|
5123
5121
|
pos += hasComp ? text.nodeValue.length : child.length;
|
@@ -5151,7 +5149,7 @@
|
|
5151
5149
|
}
|
5152
5150
|
}
|
5153
5151
|
getSide() { return this.side; }
|
5154
|
-
domAtPos(pos) { return DOMPos.before(this.dom); }
|
5152
|
+
domAtPos(pos) { return this.side > 0 ? DOMPos.before(this.dom) : DOMPos.after(this.dom); }
|
5155
5153
|
localPosFromDOM() { return 0; }
|
5156
5154
|
domBoundsAround() { return null; }
|
5157
5155
|
coordsAt(pos) {
|
@@ -5327,7 +5325,7 @@
|
|
5327
5325
|
couldn't (in which case the widget will be redrawn). The default
|
5328
5326
|
implementation just returns false.
|
5329
5327
|
*/
|
5330
|
-
updateDOM(dom) { return false; }
|
5328
|
+
updateDOM(dom, view) { return false; }
|
5331
5329
|
/**
|
5332
5330
|
@internal
|
5333
5331
|
*/
|
@@ -5642,7 +5640,7 @@
|
|
5642
5640
|
this.dirty |= 4 /* Dirty.Attrs */ | 2 /* Dirty.Node */;
|
5643
5641
|
}
|
5644
5642
|
}
|
5645
|
-
sync(track) {
|
5643
|
+
sync(view, track) {
|
5646
5644
|
var _a;
|
5647
5645
|
if (!this.dom) {
|
5648
5646
|
this.setDOM(document.createElement("div"));
|
@@ -5659,7 +5657,7 @@
|
|
5659
5657
|
this.dom.classList.add("cm-line");
|
5660
5658
|
this.prevAttrs = undefined;
|
5661
5659
|
}
|
5662
|
-
super.sync(track);
|
5660
|
+
super.sync(view, track);
|
5663
5661
|
let last = this.dom.lastChild;
|
5664
5662
|
while (last && ContentView.get(last) instanceof MarkView)
|
5665
5663
|
last = last.lastChild;
|
@@ -5674,7 +5672,7 @@
|
|
5674
5672
|
measureTextSize() {
|
5675
5673
|
if (this.children.length == 0 || this.length > 20)
|
5676
5674
|
return null;
|
5677
|
-
let totalWidth = 0;
|
5675
|
+
let totalWidth = 0, textHeight;
|
5678
5676
|
for (let child of this.children) {
|
5679
5677
|
if (!(child instanceof TextView) || /[^ -~]/.test(child.text))
|
5680
5678
|
return null;
|
@@ -5682,14 +5680,26 @@
|
|
5682
5680
|
if (rects.length != 1)
|
5683
5681
|
return null;
|
5684
5682
|
totalWidth += rects[0].width;
|
5683
|
+
textHeight = rects[0].height;
|
5685
5684
|
}
|
5686
5685
|
return !totalWidth ? null : {
|
5687
5686
|
lineHeight: this.dom.getBoundingClientRect().height,
|
5688
|
-
charWidth: totalWidth / this.length
|
5687
|
+
charWidth: totalWidth / this.length,
|
5688
|
+
textHeight
|
5689
5689
|
};
|
5690
5690
|
}
|
5691
5691
|
coordsAt(pos, side) {
|
5692
|
-
|
5692
|
+
let rect = coordsInChildren(this, pos, side);
|
5693
|
+
// Correct rectangle height for empty lines when the returned
|
5694
|
+
// height is larger than the text height.
|
5695
|
+
if (!this.children.length && rect && this.parent) {
|
5696
|
+
let { heightOracle } = this.parent.view.viewState, height = rect.bottom - rect.top;
|
5697
|
+
if (Math.abs(height - heightOracle.lineHeight) < 2 && heightOracle.textHeight < height) {
|
5698
|
+
let dist = (height - heightOracle.textHeight) / 2;
|
5699
|
+
return { top: rect.top + dist, bottom: rect.bottom - dist, left: rect.left, right: rect.left };
|
5700
|
+
}
|
5701
|
+
}
|
5702
|
+
return rect;
|
5693
5703
|
}
|
5694
5704
|
become(_other) { return false; }
|
5695
5705
|
get type() { return BlockType.Text; }
|
@@ -5734,12 +5744,12 @@
|
|
5734
5744
|
return end;
|
5735
5745
|
}
|
5736
5746
|
get children() { return noChildren; }
|
5737
|
-
sync() {
|
5738
|
-
if (!this.dom || !this.widget.updateDOM(this.dom)) {
|
5747
|
+
sync(view) {
|
5748
|
+
if (!this.dom || !this.widget.updateDOM(this.dom, view)) {
|
5739
5749
|
if (this.dom && this.prevWidget)
|
5740
5750
|
this.prevWidget.destroy(this.dom);
|
5741
5751
|
this.prevWidget = null;
|
5742
|
-
this.setDOM(this.widget.toDOM(
|
5752
|
+
this.setDOM(this.widget.toDOM(view));
|
5743
5753
|
this.dom.contentEditable = "false";
|
5744
5754
|
}
|
5745
5755
|
}
|
@@ -5763,6 +5773,8 @@
|
|
5763
5773
|
}
|
5764
5774
|
ignoreMutation() { return true; }
|
5765
5775
|
ignoreEvent(event) { return this.widget.ignoreEvent(event); }
|
5776
|
+
get isEditable() { return false; }
|
5777
|
+
get isWidget() { return true; }
|
5766
5778
|
destroy() {
|
5767
5779
|
super.destroy();
|
5768
5780
|
if (this.dom)
|
@@ -5944,6 +5956,7 @@
|
|
5944
5956
|
const exceptionSink = /*@__PURE__*/Facet.define();
|
5945
5957
|
const updateListener = /*@__PURE__*/Facet.define();
|
5946
5958
|
const inputHandler$1 = /*@__PURE__*/Facet.define();
|
5959
|
+
const focusChangeEffect = /*@__PURE__*/Facet.define();
|
5947
5960
|
const perLineTextDirection = /*@__PURE__*/Facet.define({
|
5948
5961
|
combine: values => values.some(x => x)
|
5949
5962
|
});
|
@@ -6186,11 +6199,6 @@
|
|
6186
6199
|
let changedRanges = [];
|
6187
6200
|
this.changes.iterChangedRanges((fromA, toA, fromB, toB) => changedRanges.push(new ChangedRange(fromA, toA, fromB, toB)));
|
6188
6201
|
this.changedRanges = changedRanges;
|
6189
|
-
let focus = view.hasFocus;
|
6190
|
-
if (focus != view.inputState.notifiedFocused) {
|
6191
|
-
view.inputState.notifiedFocused = focus;
|
6192
|
-
this.flags |= 1 /* UpdateFlag.Focus */;
|
6193
|
-
}
|
6194
6202
|
}
|
6195
6203
|
/**
|
6196
6204
|
@internal
|
@@ -6693,7 +6701,6 @@
|
|
6693
6701
|
this.updateDeco();
|
6694
6702
|
this.updateInner([new ChangedRange(0, 0, 0, view.state.doc.length)], 0);
|
6695
6703
|
}
|
6696
|
-
get editorView() { return this.view; }
|
6697
6704
|
get length() { return this.view.state.doc.length; }
|
6698
6705
|
// Update the document view to a given state. scrollIntoView can be
|
6699
6706
|
// used as a hint to compute a new viewport that includes that
|
@@ -6753,7 +6760,7 @@
|
|
6753
6760
|
// selection from the one it displays (issue #218). This tries
|
6754
6761
|
// to detect that situation.
|
6755
6762
|
let track = browser.chrome || browser.ios ? { node: observer.selectionRange.focusNode, written: false } : undefined;
|
6756
|
-
this.sync(track);
|
6763
|
+
this.sync(this.view, track);
|
6757
6764
|
this.dirty = 0 /* Dirty.Not */;
|
6758
6765
|
if (track && (track.written || observer.selectionRange.focusNode != track.node))
|
6759
6766
|
this.forceSelection = true;
|
@@ -6972,7 +6979,7 @@
|
|
6972
6979
|
}
|
6973
6980
|
}
|
6974
6981
|
// If no workable line exists, force a layout of a measurable element
|
6975
|
-
let dummy = document.createElement("div"), lineHeight, charWidth;
|
6982
|
+
let dummy = document.createElement("div"), lineHeight, charWidth, textHeight;
|
6976
6983
|
dummy.className = "cm-line";
|
6977
6984
|
dummy.style.width = "99999px";
|
6978
6985
|
dummy.textContent = "abc def ghi jkl mno pqr stu";
|
@@ -6981,9 +6988,10 @@
|
|
6981
6988
|
let rect = clientRectsFor(dummy.firstChild)[0];
|
6982
6989
|
lineHeight = dummy.getBoundingClientRect().height;
|
6983
6990
|
charWidth = rect ? rect.width / 27 : 7;
|
6991
|
+
textHeight = rect ? rect.height : lineHeight;
|
6984
6992
|
dummy.remove();
|
6985
6993
|
});
|
6986
|
-
return { lineHeight, charWidth };
|
6994
|
+
return { lineHeight, charWidth, textHeight };
|
6987
6995
|
}
|
6988
6996
|
childCursor(pos = this.length) {
|
6989
6997
|
// Move back to start of last element when possible, so that
|
@@ -7148,22 +7156,32 @@
|
|
7148
7156
|
ignoreEvent() { return false; }
|
7149
7157
|
get customView() { return CompositionView; }
|
7150
7158
|
}
|
7151
|
-
function nearbyTextNode(
|
7152
|
-
|
7153
|
-
|
7154
|
-
|
7155
|
-
|
7156
|
-
node
|
7157
|
-
|
7158
|
-
|
7159
|
-
|
7160
|
-
|
7161
|
-
|
7159
|
+
function nearbyTextNode(startNode, startOffset, side) {
|
7160
|
+
if (side <= 0)
|
7161
|
+
for (let node = startNode, offset = startOffset;;) {
|
7162
|
+
if (node.nodeType == 3)
|
7163
|
+
return node;
|
7164
|
+
if (node.nodeType == 1 && offset > 0) {
|
7165
|
+
node = node.childNodes[offset - 1];
|
7166
|
+
offset = maxOffset(node);
|
7167
|
+
}
|
7168
|
+
else {
|
7169
|
+
break;
|
7170
|
+
}
|
7162
7171
|
}
|
7163
|
-
|
7164
|
-
|
7172
|
+
if (side >= 0)
|
7173
|
+
for (let node = startNode, offset = startOffset;;) {
|
7174
|
+
if (node.nodeType == 3)
|
7175
|
+
return node;
|
7176
|
+
if (node.nodeType == 1 && offset < node.childNodes.length && side >= 0) {
|
7177
|
+
node = node.childNodes[offset];
|
7178
|
+
offset = 0;
|
7179
|
+
}
|
7180
|
+
else {
|
7181
|
+
break;
|
7182
|
+
}
|
7165
7183
|
}
|
7166
|
-
|
7184
|
+
return null;
|
7167
7185
|
}
|
7168
7186
|
function nextToUneditable(node, offset) {
|
7169
7187
|
if (node.nodeType != 1)
|
@@ -7326,11 +7344,11 @@
|
|
7326
7344
|
}
|
7327
7345
|
return { node, offset: closestOffset > -1 ? closestOffset : generalSide > 0 ? node.nodeValue.length : 0 };
|
7328
7346
|
}
|
7329
|
-
function posAtCoords(view,
|
7330
|
-
var _a;
|
7347
|
+
function posAtCoords(view, coords, precise, bias = -1) {
|
7348
|
+
var _a, _b;
|
7331
7349
|
let content = view.contentDOM.getBoundingClientRect(), docTop = content.top + view.viewState.paddingTop;
|
7332
7350
|
let block, { docHeight } = view.viewState;
|
7333
|
-
let yOffset = y - docTop;
|
7351
|
+
let { x, y } = coords, yOffset = y - docTop;
|
7334
7352
|
if (yOffset < 0)
|
7335
7353
|
return 0;
|
7336
7354
|
if (yOffset > docHeight)
|
@@ -7401,7 +7419,17 @@
|
|
7401
7419
|
return yOffset > block.top + block.height / 2 ? block.to : block.from;
|
7402
7420
|
({ node, offset } = domPosAtCoords(line.dom, x, y));
|
7403
7421
|
}
|
7404
|
-
|
7422
|
+
let nearest = view.docView.nearest(node);
|
7423
|
+
if (!nearest)
|
7424
|
+
return null;
|
7425
|
+
if (nearest.isWidget && ((_b = nearest.dom) === null || _b === void 0 ? void 0 : _b.nodeType) == 1) {
|
7426
|
+
let rect = nearest.dom.getBoundingClientRect();
|
7427
|
+
return coords.y < rect.top || coords.y <= rect.bottom && coords.x <= (rect.left + rect.right) / 2
|
7428
|
+
? nearest.posAtStart : nearest.posAtEnd;
|
7429
|
+
}
|
7430
|
+
else {
|
7431
|
+
return nearest.localPosFromDOM(node, offset) + nearest.posAtStart;
|
7432
|
+
}
|
7405
7433
|
}
|
7406
7434
|
function posAtCoordsImprecise(view, contentRect, block, x, y) {
|
7407
7435
|
let into = Math.round((x - contentRect.left) * view.defaultCharacterWidth);
|
@@ -7589,8 +7617,16 @@
|
|
7589
7617
|
this.registeredEvents.push(type);
|
7590
7618
|
}
|
7591
7619
|
view.scrollDOM.addEventListener("mousedown", (event) => {
|
7592
|
-
if (event.target == view.scrollDOM)
|
7620
|
+
if (event.target == view.scrollDOM && event.clientY > view.contentDOM.getBoundingClientRect().bottom) {
|
7593
7621
|
handleEvent(handlers.mousedown, event);
|
7622
|
+
if (!event.defaultPrevented && event.button == 2) {
|
7623
|
+
// Make sure the content covers the entire scroller height, in order
|
7624
|
+
// to catch a native context menu click below it
|
7625
|
+
let start = view.contentDOM.style.minHeight;
|
7626
|
+
view.contentDOM.style.minHeight = "100%";
|
7627
|
+
setTimeout(() => view.contentDOM.style.minHeight = start, 200);
|
7628
|
+
}
|
7629
|
+
}
|
7594
7630
|
});
|
7595
7631
|
if (browser.chrome && browser.chrome_version == 102) { // FIXME remove at some point
|
7596
7632
|
// On Chrome 102, viewport updates somehow stop wheel-based
|
@@ -7767,11 +7803,13 @@
|
|
7767
7803
|
this.multiple = view.state.facet(EditorState.allowMultipleSelections) && addsSelectionRange(view, startEvent);
|
7768
7804
|
this.dragMove = dragMovesSelection(view, startEvent);
|
7769
7805
|
this.dragging = isInPrimarySelection(view, startEvent) && getClickType(startEvent) == 1 ? null : false;
|
7806
|
+
}
|
7807
|
+
start(event) {
|
7770
7808
|
// When clicking outside of the selection, immediately apply the
|
7771
7809
|
// effect of starting the selection
|
7772
7810
|
if (this.dragging === false) {
|
7773
|
-
|
7774
|
-
this.select(
|
7811
|
+
event.preventDefault();
|
7812
|
+
this.select(event);
|
7775
7813
|
}
|
7776
7814
|
}
|
7777
7815
|
move(event) {
|
@@ -7963,9 +8001,11 @@
|
|
7963
8001
|
style = basicMouseSelection(view, event);
|
7964
8002
|
if (style) {
|
7965
8003
|
let mustFocus = view.root.activeElement != view.contentDOM;
|
8004
|
+
view.inputState.startMouseSelection(new MouseSelection(view, event, style, mustFocus));
|
7966
8005
|
if (mustFocus)
|
7967
8006
|
view.observer.ignore(() => focusPreventScroll(view.contentDOM));
|
7968
|
-
view.inputState.
|
8007
|
+
if (view.inputState.mouseSelection)
|
8008
|
+
view.inputState.mouseSelection.start(event);
|
7969
8009
|
}
|
7970
8010
|
};
|
7971
8011
|
function rangeForClick(view, pos, bias, type) {
|
@@ -8120,7 +8160,7 @@
|
|
8120
8160
|
view.observer.flush();
|
8121
8161
|
let data = brokenClipboardAPI ? null : event.clipboardData;
|
8122
8162
|
if (data) {
|
8123
|
-
doPaste(view, data.getData("text/plain"));
|
8163
|
+
doPaste(view, data.getData("text/plain") || data.getData("text/uri-text"));
|
8124
8164
|
event.preventDefault();
|
8125
8165
|
}
|
8126
8166
|
else {
|
@@ -8188,10 +8228,26 @@
|
|
8188
8228
|
userEvent: "delete.cut"
|
8189
8229
|
});
|
8190
8230
|
};
|
8231
|
+
const isFocusChange = /*@__PURE__*/Annotation.define();
|
8232
|
+
function focusChangeTransaction(state, focus) {
|
8233
|
+
let effects = [];
|
8234
|
+
for (let getEffect of state.facet(focusChangeEffect)) {
|
8235
|
+
let effect = getEffect(state, focus);
|
8236
|
+
if (effect)
|
8237
|
+
effects.push(effect);
|
8238
|
+
}
|
8239
|
+
return effects ? state.update({ effects, annotations: isFocusChange.of(true) }) : null;
|
8240
|
+
}
|
8191
8241
|
function updateForFocusChange(view) {
|
8192
8242
|
setTimeout(() => {
|
8193
|
-
|
8194
|
-
|
8243
|
+
let focus = view.hasFocus;
|
8244
|
+
if (focus != view.inputState.notifiedFocused) {
|
8245
|
+
let tr = focusChangeTransaction(view.state, focus);
|
8246
|
+
if (tr)
|
8247
|
+
view.dispatch(tr);
|
8248
|
+
else
|
8249
|
+
view.update([]);
|
8250
|
+
}
|
8195
8251
|
}, 10);
|
8196
8252
|
}
|
8197
8253
|
handlers.focus = view => {
|
@@ -8264,8 +8320,9 @@
|
|
8264
8320
|
this.lineWrapping = lineWrapping;
|
8265
8321
|
this.doc = Text.empty;
|
8266
8322
|
this.heightSamples = {};
|
8267
|
-
this.lineHeight = 14;
|
8323
|
+
this.lineHeight = 14; // The height of an entire line (line-height)
|
8268
8324
|
this.charWidth = 7;
|
8325
|
+
this.textHeight = 14; // The height of the actual font (font-size)
|
8269
8326
|
this.lineLength = 30;
|
8270
8327
|
// Used to track, during updateHeight, if any actual heights changed
|
8271
8328
|
this.heightChanged = false;
|
@@ -8273,7 +8330,7 @@
|
|
8273
8330
|
heightForGap(from, to) {
|
8274
8331
|
let lines = this.doc.lineAt(to).number - this.doc.lineAt(from).number + 1;
|
8275
8332
|
if (this.lineWrapping)
|
8276
|
-
lines += Math.ceil(((to - from) - (lines * this.lineLength * 0.5)) / this.lineLength);
|
8333
|
+
lines += Math.max(0, Math.ceil(((to - from) - (lines * this.lineLength * 0.5)) / this.lineLength));
|
8277
8334
|
return this.lineHeight * lines;
|
8278
8335
|
}
|
8279
8336
|
heightForLine(length) {
|
@@ -8300,12 +8357,13 @@
|
|
8300
8357
|
}
|
8301
8358
|
return newHeight;
|
8302
8359
|
}
|
8303
|
-
refresh(whiteSpace, lineHeight, charWidth, lineLength, knownHeights) {
|
8360
|
+
refresh(whiteSpace, lineHeight, charWidth, textHeight, lineLength, knownHeights) {
|
8304
8361
|
let lineWrapping = wrappingWhiteSpace.indexOf(whiteSpace) > -1;
|
8305
8362
|
let changed = Math.round(lineHeight) != Math.round(this.lineHeight) || this.lineWrapping != lineWrapping;
|
8306
8363
|
this.lineWrapping = lineWrapping;
|
8307
8364
|
this.lineHeight = lineHeight;
|
8308
8365
|
this.charWidth = charWidth;
|
8366
|
+
this.textHeight = textHeight;
|
8309
8367
|
this.lineLength = lineLength;
|
8310
8368
|
if (changed) {
|
8311
8369
|
this.heightSamples = {};
|
@@ -8418,11 +8476,11 @@
|
|
8418
8476
|
decomposeLeft(_to, result) { result.push(this); }
|
8419
8477
|
decomposeRight(_from, result) { result.push(this); }
|
8420
8478
|
applyChanges(decorations, oldDoc, oracle, changes) {
|
8421
|
-
let me = this;
|
8479
|
+
let me = this, doc = oracle.doc;
|
8422
8480
|
for (let i = changes.length - 1; i >= 0; i--) {
|
8423
8481
|
let { fromA, toA, fromB, toB } = changes[i];
|
8424
|
-
let start = me.lineAt(fromA, QueryType$1.ByPosNoHeight, oldDoc, 0, 0);
|
8425
|
-
let end = start.to >= toA ? start : me.lineAt(toA, QueryType$1.ByPosNoHeight,
|
8482
|
+
let start = me.lineAt(fromA, QueryType$1.ByPosNoHeight, oracle.setDoc(oldDoc), 0, 0);
|
8483
|
+
let end = start.to >= toA ? start : me.lineAt(toA, QueryType$1.ByPosNoHeight, oracle, 0, 0);
|
8426
8484
|
toB += end.to - toA;
|
8427
8485
|
toA = end.to;
|
8428
8486
|
while (i > 0 && start.from <= changes[i - 1].toA) {
|
@@ -8430,11 +8488,11 @@
|
|
8430
8488
|
fromB = changes[i - 1].fromB;
|
8431
8489
|
i--;
|
8432
8490
|
if (fromA < start.from)
|
8433
|
-
start = me.lineAt(fromA, QueryType$1.ByPosNoHeight,
|
8491
|
+
start = me.lineAt(fromA, QueryType$1.ByPosNoHeight, oracle, 0, 0);
|
8434
8492
|
}
|
8435
8493
|
fromB += start.from - fromA;
|
8436
8494
|
fromA = start.from;
|
8437
|
-
let nodes = NodeBuilder.build(oracle, decorations, fromB, toB);
|
8495
|
+
let nodes = NodeBuilder.build(oracle.setDoc(doc), decorations, fromB, toB);
|
8438
8496
|
me = me.replace(fromA, toA, nodes);
|
8439
8497
|
}
|
8440
8498
|
return me.updateHeight(oracle, 0);
|
@@ -8501,15 +8559,15 @@
|
|
8501
8559
|
super(length, height);
|
8502
8560
|
this.type = type;
|
8503
8561
|
}
|
8504
|
-
blockAt(_height,
|
8562
|
+
blockAt(_height, _oracle, top, offset) {
|
8505
8563
|
return new BlockInfo(offset, this.length, top, this.height, this.type);
|
8506
8564
|
}
|
8507
|
-
lineAt(_value, _type,
|
8508
|
-
return this.blockAt(0,
|
8565
|
+
lineAt(_value, _type, oracle, top, offset) {
|
8566
|
+
return this.blockAt(0, oracle, top, offset);
|
8509
8567
|
}
|
8510
|
-
forEachLine(from, to,
|
8568
|
+
forEachLine(from, to, oracle, top, offset, f) {
|
8511
8569
|
if (from <= offset + this.length && to >= offset)
|
8512
|
-
f(this.blockAt(0,
|
8570
|
+
f(this.blockAt(0, oracle, top, offset));
|
8513
8571
|
}
|
8514
8572
|
updateHeight(oracle, offset = 0, _force = false, measured) {
|
8515
8573
|
if (measured && measured.from <= offset && measured.more)
|
@@ -8555,35 +8613,60 @@
|
|
8555
8613
|
}
|
8556
8614
|
class HeightMapGap extends HeightMap {
|
8557
8615
|
constructor(length) { super(length, 0); }
|
8558
|
-
|
8559
|
-
let firstLine = doc.lineAt(offset).number, lastLine = doc.lineAt(offset + this.length).number;
|
8560
|
-
|
8616
|
+
heightMetrics(oracle, offset) {
|
8617
|
+
let firstLine = oracle.doc.lineAt(offset).number, lastLine = oracle.doc.lineAt(offset + this.length).number;
|
8618
|
+
let lines = lastLine - firstLine + 1;
|
8619
|
+
let perLine, perChar = 0;
|
8620
|
+
if (oracle.lineWrapping) {
|
8621
|
+
let totalPerLine = Math.min(this.height, oracle.lineHeight * lines);
|
8622
|
+
perLine = totalPerLine / lines;
|
8623
|
+
perChar = (this.height - totalPerLine) / (this.length - lines - 1);
|
8624
|
+
}
|
8625
|
+
else {
|
8626
|
+
perLine = this.height / lines;
|
8627
|
+
}
|
8628
|
+
return { firstLine, lastLine, perLine, perChar };
|
8561
8629
|
}
|
8562
|
-
blockAt(height,
|
8563
|
-
let { firstLine, lastLine,
|
8564
|
-
|
8565
|
-
|
8566
|
-
|
8630
|
+
blockAt(height, oracle, top, offset) {
|
8631
|
+
let { firstLine, lastLine, perLine, perChar } = this.heightMetrics(oracle, offset);
|
8632
|
+
if (oracle.lineWrapping) {
|
8633
|
+
let guess = offset + Math.round(Math.max(0, Math.min(1, (height - top) / this.height)) * this.length);
|
8634
|
+
let line = oracle.doc.lineAt(guess), lineHeight = perLine + line.length * perChar;
|
8635
|
+
let lineTop = Math.max(top, height - lineHeight / 2);
|
8636
|
+
return new BlockInfo(line.from, line.length, lineTop, lineHeight, BlockType.Text);
|
8637
|
+
}
|
8638
|
+
else {
|
8639
|
+
let line = Math.max(0, Math.min(lastLine - firstLine, Math.floor((height - top) / perLine)));
|
8640
|
+
let { from, length } = oracle.doc.line(firstLine + line);
|
8641
|
+
return new BlockInfo(from, length, top + perLine * line, perLine, BlockType.Text);
|
8642
|
+
}
|
8567
8643
|
}
|
8568
|
-
lineAt(value, type,
|
8644
|
+
lineAt(value, type, oracle, top, offset) {
|
8569
8645
|
if (type == QueryType$1.ByHeight)
|
8570
|
-
return this.blockAt(value,
|
8646
|
+
return this.blockAt(value, oracle, top, offset);
|
8571
8647
|
if (type == QueryType$1.ByPosNoHeight) {
|
8572
|
-
let { from, to } = doc.lineAt(value);
|
8648
|
+
let { from, to } = oracle.doc.lineAt(value);
|
8573
8649
|
return new BlockInfo(from, to - from, 0, 0, BlockType.Text);
|
8574
8650
|
}
|
8575
|
-
let { firstLine,
|
8576
|
-
let
|
8577
|
-
|
8578
|
-
|
8579
|
-
|
8580
|
-
|
8581
|
-
|
8582
|
-
|
8583
|
-
|
8584
|
-
|
8585
|
-
|
8586
|
-
|
8651
|
+
let { firstLine, perLine, perChar } = this.heightMetrics(oracle, offset);
|
8652
|
+
let line = oracle.doc.lineAt(value), lineHeight = perLine + line.length * perChar;
|
8653
|
+
let linesAbove = line.number - firstLine;
|
8654
|
+
let lineTop = top + perLine * linesAbove + perChar * (line.from - offset - linesAbove);
|
8655
|
+
return new BlockInfo(line.from, line.length, Math.max(top, Math.min(lineTop, top + this.height - lineHeight)), lineHeight, BlockType.Text);
|
8656
|
+
}
|
8657
|
+
forEachLine(from, to, oracle, top, offset, f) {
|
8658
|
+
from = Math.max(from, offset);
|
8659
|
+
to = Math.min(to, offset + this.length);
|
8660
|
+
let { firstLine, perLine, perChar } = this.heightMetrics(oracle, offset);
|
8661
|
+
for (let pos = from, lineTop = top; pos <= to;) {
|
8662
|
+
let line = oracle.doc.lineAt(pos);
|
8663
|
+
if (pos == from) {
|
8664
|
+
let linesAbove = line.number - firstLine;
|
8665
|
+
lineTop += perLine * linesAbove + perChar * (from - offset - linesAbove);
|
8666
|
+
}
|
8667
|
+
let lineHeight = perLine + perChar * line.length;
|
8668
|
+
f(new BlockInfo(line.from, line.length, lineTop, lineHeight, BlockType.Text));
|
8669
|
+
lineTop += lineHeight;
|
8587
8670
|
pos = line.to + 1;
|
8588
8671
|
}
|
8589
8672
|
}
|
@@ -8619,7 +8702,6 @@
|
|
8619
8702
|
// they would already have been added to the heightmap (gaps
|
8620
8703
|
// only contain plain text).
|
8621
8704
|
let nodes = [], pos = Math.max(offset, measured.from), singleHeight = -1;
|
8622
|
-
let wasChanged = oracle.heightChanged;
|
8623
8705
|
if (measured.from > offset)
|
8624
8706
|
nodes.push(new HeightMapGap(measured.from - offset - 1).updateHeight(oracle, offset));
|
8625
8707
|
while (pos <= end && measured.more) {
|
@@ -8639,8 +8721,9 @@
|
|
8639
8721
|
if (pos <= end)
|
8640
8722
|
nodes.push(null, new HeightMapGap(end - pos).updateHeight(oracle, pos));
|
8641
8723
|
let result = HeightMap.of(nodes);
|
8642
|
-
|
8643
|
-
Math.abs(singleHeight - this.
|
8724
|
+
if (singleHeight < 0 || Math.abs(result.height - this.height) >= Epsilon ||
|
8725
|
+
Math.abs(singleHeight - this.heightMetrics(oracle, offset).perLine) >= Epsilon)
|
8726
|
+
oracle.heightChanged = true;
|
8644
8727
|
return result;
|
8645
8728
|
}
|
8646
8729
|
else if (force || this.outdated) {
|
@@ -8659,40 +8742,40 @@
|
|
8659
8742
|
this.size = left.size + right.size;
|
8660
8743
|
}
|
8661
8744
|
get break() { return this.flags & 1 /* Flag.Break */; }
|
8662
|
-
blockAt(height,
|
8745
|
+
blockAt(height, oracle, top, offset) {
|
8663
8746
|
let mid = top + this.left.height;
|
8664
|
-
return height < mid ? this.left.blockAt(height,
|
8665
|
-
: this.right.blockAt(height,
|
8747
|
+
return height < mid ? this.left.blockAt(height, oracle, top, offset)
|
8748
|
+
: this.right.blockAt(height, oracle, mid, offset + this.left.length + this.break);
|
8666
8749
|
}
|
8667
|
-
lineAt(value, type,
|
8750
|
+
lineAt(value, type, oracle, top, offset) {
|
8668
8751
|
let rightTop = top + this.left.height, rightOffset = offset + this.left.length + this.break;
|
8669
8752
|
let left = type == QueryType$1.ByHeight ? value < rightTop : value < rightOffset;
|
8670
|
-
let base = left ? this.left.lineAt(value, type,
|
8671
|
-
: this.right.lineAt(value, type,
|
8753
|
+
let base = left ? this.left.lineAt(value, type, oracle, top, offset)
|
8754
|
+
: this.right.lineAt(value, type, oracle, rightTop, rightOffset);
|
8672
8755
|
if (this.break || (left ? base.to < rightOffset : base.from > rightOffset))
|
8673
8756
|
return base;
|
8674
8757
|
let subQuery = type == QueryType$1.ByPosNoHeight ? QueryType$1.ByPosNoHeight : QueryType$1.ByPos;
|
8675
8758
|
if (left)
|
8676
|
-
return base.join(this.right.lineAt(rightOffset, subQuery,
|
8759
|
+
return base.join(this.right.lineAt(rightOffset, subQuery, oracle, rightTop, rightOffset));
|
8677
8760
|
else
|
8678
|
-
return this.left.lineAt(rightOffset, subQuery,
|
8761
|
+
return this.left.lineAt(rightOffset, subQuery, oracle, top, offset).join(base);
|
8679
8762
|
}
|
8680
|
-
forEachLine(from, to,
|
8763
|
+
forEachLine(from, to, oracle, top, offset, f) {
|
8681
8764
|
let rightTop = top + this.left.height, rightOffset = offset + this.left.length + this.break;
|
8682
8765
|
if (this.break) {
|
8683
8766
|
if (from < rightOffset)
|
8684
|
-
this.left.forEachLine(from, to,
|
8767
|
+
this.left.forEachLine(from, to, oracle, top, offset, f);
|
8685
8768
|
if (to >= rightOffset)
|
8686
|
-
this.right.forEachLine(from, to,
|
8769
|
+
this.right.forEachLine(from, to, oracle, rightTop, rightOffset, f);
|
8687
8770
|
}
|
8688
8771
|
else {
|
8689
|
-
let mid = this.lineAt(rightOffset, QueryType$1.ByPos,
|
8772
|
+
let mid = this.lineAt(rightOffset, QueryType$1.ByPos, oracle, top, offset);
|
8690
8773
|
if (from < mid.from)
|
8691
|
-
this.left.forEachLine(from, mid.from - 1,
|
8774
|
+
this.left.forEachLine(from, mid.from - 1, oracle, top, offset, f);
|
8692
8775
|
if (mid.to >= from && mid.from <= to)
|
8693
8776
|
f(mid);
|
8694
8777
|
if (to > mid.to)
|
8695
|
-
this.right.forEachLine(mid.to + 1, to,
|
8778
|
+
this.right.forEachLine(mid.to + 1, to, oracle, rightTop, rightOffset, f);
|
8696
8779
|
}
|
8697
8780
|
}
|
8698
8781
|
replace(from, to, nodes) {
|
@@ -9042,11 +9125,11 @@
|
|
9042
9125
|
}
|
9043
9126
|
this.viewports = viewports.sort((a, b) => a.from - b.from);
|
9044
9127
|
this.scaler = this.heightMap.height <= 7000000 /* VP.MaxDOMHeight */ ? IdScaler :
|
9045
|
-
new BigScaler(this.heightOracle
|
9128
|
+
new BigScaler(this.heightOracle, this.heightMap, this.viewports);
|
9046
9129
|
}
|
9047
9130
|
updateViewportLines() {
|
9048
9131
|
this.viewportLines = [];
|
9049
|
-
this.heightMap.forEachLine(this.viewport.from, this.viewport.to, this.state.doc, 0, 0, block => {
|
9132
|
+
this.heightMap.forEachLine(this.viewport.from, this.viewport.to, this.heightOracle.setDoc(this.state.doc), 0, 0, block => {
|
9050
9133
|
this.viewportLines.push(this.scaler.scale == 1 ? block : scaleBlock(block, this.scaler));
|
9051
9134
|
});
|
9052
9135
|
}
|
@@ -9086,8 +9169,9 @@
|
|
9086
9169
|
let whiteSpace = style.whiteSpace;
|
9087
9170
|
this.defaultTextDirection = style.direction == "rtl" ? Direction.RTL : Direction.LTR;
|
9088
9171
|
let refresh = this.heightOracle.mustRefreshForWrapping(whiteSpace);
|
9089
|
-
let
|
9090
|
-
this.contentDOMHeight
|
9172
|
+
let domRect = dom.getBoundingClientRect();
|
9173
|
+
let measureContent = refresh || this.mustMeasureContent || this.contentDOMHeight != domRect.height;
|
9174
|
+
this.contentDOMHeight = domRect.height;
|
9091
9175
|
this.mustMeasureContent = false;
|
9092
9176
|
let result = 0, bias = 0;
|
9093
9177
|
// Vertical padding
|
@@ -9115,9 +9199,9 @@
|
|
9115
9199
|
}
|
9116
9200
|
if (!this.inView && !this.scrollTarget)
|
9117
9201
|
return 0;
|
9118
|
-
let contentWidth =
|
9202
|
+
let contentWidth = domRect.width;
|
9119
9203
|
if (this.contentDOMWidth != contentWidth || this.editorHeight != view.scrollDOM.clientHeight) {
|
9120
|
-
this.contentDOMWidth =
|
9204
|
+
this.contentDOMWidth = domRect.width;
|
9121
9205
|
this.editorHeight = view.scrollDOM.clientHeight;
|
9122
9206
|
result |= 8 /* UpdateFlag.Geometry */;
|
9123
9207
|
}
|
@@ -9126,8 +9210,8 @@
|
|
9126
9210
|
if (oracle.mustRefreshForHeights(lineHeights))
|
9127
9211
|
refresh = true;
|
9128
9212
|
if (refresh || oracle.lineWrapping && Math.abs(contentWidth - this.contentDOMWidth) > oracle.charWidth) {
|
9129
|
-
let { lineHeight, charWidth } = view.docView.measureTextSize();
|
9130
|
-
refresh = lineHeight > 0 && oracle.refresh(whiteSpace, lineHeight, charWidth, contentWidth / charWidth, lineHeights);
|
9213
|
+
let { lineHeight, charWidth, textHeight } = view.docView.measureTextSize();
|
9214
|
+
refresh = lineHeight > 0 && oracle.refresh(whiteSpace, lineHeight, charWidth, textHeight, contentWidth / charWidth, lineHeights);
|
9131
9215
|
if (refresh) {
|
9132
9216
|
view.docView.minWidth = 0;
|
9133
9217
|
result |= 8 /* UpdateFlag.Geometry */;
|
@@ -9146,7 +9230,8 @@
|
|
9146
9230
|
result |= 2 /* UpdateFlag.Height */;
|
9147
9231
|
}
|
9148
9232
|
let viewportChange = !this.viewportIsAppropriate(this.viewport, bias) ||
|
9149
|
-
this.scrollTarget && (this.scrollTarget.range.head < this.viewport.from ||
|
9233
|
+
this.scrollTarget && (this.scrollTarget.range.head < this.viewport.from ||
|
9234
|
+
this.scrollTarget.range.head > this.viewport.to);
|
9150
9235
|
if (viewportChange)
|
9151
9236
|
this.viewport = this.getViewport(bias, this.scrollTarget);
|
9152
9237
|
this.updateForViewport();
|
@@ -9172,36 +9257,37 @@
|
|
9172
9257
|
// bottom, depending on the bias (the change in viewport position
|
9173
9258
|
// since the last update). It'll hold a number between 0 and 1
|
9174
9259
|
let marginTop = 0.5 - Math.max(-0.5, Math.min(0.5, bias / 1000 /* VP.Margin */ / 2));
|
9175
|
-
let map = this.heightMap,
|
9176
|
-
let
|
9260
|
+
let map = this.heightMap, oracle = this.heightOracle;
|
9261
|
+
let { visibleTop, visibleBottom } = this;
|
9262
|
+
let viewport = new Viewport(map.lineAt(visibleTop - marginTop * 1000 /* VP.Margin */, QueryType$1.ByHeight, oracle, 0, 0).from, map.lineAt(visibleBottom + (1 - marginTop) * 1000 /* VP.Margin */, QueryType$1.ByHeight, oracle, 0, 0).to);
|
9177
9263
|
// If scrollTarget is given, make sure the viewport includes that position
|
9178
9264
|
if (scrollTarget) {
|
9179
9265
|
let { head } = scrollTarget.range;
|
9180
9266
|
if (head < viewport.from || head > viewport.to) {
|
9181
9267
|
let viewHeight = Math.min(this.editorHeight, this.pixelViewport.bottom - this.pixelViewport.top);
|
9182
|
-
let block = map.lineAt(head, QueryType$1.ByPos,
|
9268
|
+
let block = map.lineAt(head, QueryType$1.ByPos, oracle, 0, 0), topPos;
|
9183
9269
|
if (scrollTarget.y == "center")
|
9184
9270
|
topPos = (block.top + block.bottom) / 2 - viewHeight / 2;
|
9185
9271
|
else if (scrollTarget.y == "start" || scrollTarget.y == "nearest" && head < viewport.from)
|
9186
9272
|
topPos = block.top;
|
9187
9273
|
else
|
9188
9274
|
topPos = block.bottom - viewHeight;
|
9189
|
-
viewport = new Viewport(map.lineAt(topPos - 1000 /* VP.Margin */ / 2, QueryType$1.ByHeight,
|
9275
|
+
viewport = new Viewport(map.lineAt(topPos - 1000 /* VP.Margin */ / 2, QueryType$1.ByHeight, oracle, 0, 0).from, map.lineAt(topPos + viewHeight + 1000 /* VP.Margin */ / 2, QueryType$1.ByHeight, oracle, 0, 0).to);
|
9190
9276
|
}
|
9191
9277
|
}
|
9192
9278
|
return viewport;
|
9193
9279
|
}
|
9194
9280
|
mapViewport(viewport, changes) {
|
9195
9281
|
let from = changes.mapPos(viewport.from, -1), to = changes.mapPos(viewport.to, 1);
|
9196
|
-
return new Viewport(this.heightMap.lineAt(from, QueryType$1.ByPos, this.
|
9282
|
+
return new Viewport(this.heightMap.lineAt(from, QueryType$1.ByPos, this.heightOracle, 0, 0).from, this.heightMap.lineAt(to, QueryType$1.ByPos, this.heightOracle, 0, 0).to);
|
9197
9283
|
}
|
9198
9284
|
// Checks if a given viewport covers the visible part of the
|
9199
9285
|
// document and not too much beyond that.
|
9200
9286
|
viewportIsAppropriate({ from, to }, bias = 0) {
|
9201
9287
|
if (!this.inView)
|
9202
9288
|
return true;
|
9203
|
-
let { top } = this.heightMap.lineAt(from, QueryType$1.ByPos, this.
|
9204
|
-
let { bottom } = this.heightMap.lineAt(to, QueryType$1.ByPos, this.
|
9289
|
+
let { top } = this.heightMap.lineAt(from, QueryType$1.ByPos, this.heightOracle, 0, 0);
|
9290
|
+
let { bottom } = this.heightMap.lineAt(to, QueryType$1.ByPos, this.heightOracle, 0, 0);
|
9205
9291
|
let { visibleTop, visibleBottom } = this;
|
9206
9292
|
return (from == 0 || top <= visibleTop - Math.max(10 /* VP.MinCoverMargin */, Math.min(-bias, 250 /* VP.MaxCoverMargin */))) &&
|
9207
9293
|
(to == this.state.doc.length ||
|
@@ -9338,13 +9424,13 @@
|
|
9338
9424
|
}
|
9339
9425
|
lineBlockAt(pos) {
|
9340
9426
|
return (pos >= this.viewport.from && pos <= this.viewport.to && this.viewportLines.find(b => b.from <= pos && b.to >= pos)) ||
|
9341
|
-
scaleBlock(this.heightMap.lineAt(pos, QueryType$1.ByPos, this.
|
9427
|
+
scaleBlock(this.heightMap.lineAt(pos, QueryType$1.ByPos, this.heightOracle, 0, 0), this.scaler);
|
9342
9428
|
}
|
9343
9429
|
lineBlockAtHeight(height) {
|
9344
|
-
return scaleBlock(this.heightMap.lineAt(this.scaler.fromDOM(height), QueryType$1.ByHeight, this.
|
9430
|
+
return scaleBlock(this.heightMap.lineAt(this.scaler.fromDOM(height), QueryType$1.ByHeight, this.heightOracle, 0, 0), this.scaler);
|
9345
9431
|
}
|
9346
9432
|
elementAtHeight(height) {
|
9347
|
-
return scaleBlock(this.heightMap.blockAt(this.scaler.fromDOM(height), this.
|
9433
|
+
return scaleBlock(this.heightMap.blockAt(this.scaler.fromDOM(height), this.heightOracle, 0, 0), this.scaler);
|
9348
9434
|
}
|
9349
9435
|
get docHeight() {
|
9350
9436
|
return this.scaler.toDOM(this.heightMap.height);
|
@@ -9418,11 +9504,11 @@
|
|
9418
9504
|
// regions outside the viewports so that the total height is
|
9419
9505
|
// VP.MaxDOMHeight.
|
9420
9506
|
class BigScaler {
|
9421
|
-
constructor(
|
9507
|
+
constructor(oracle, heightMap, viewports) {
|
9422
9508
|
let vpHeight = 0, base = 0, domBase = 0;
|
9423
9509
|
this.viewports = viewports.map(({ from, to }) => {
|
9424
|
-
let top = heightMap.lineAt(from, QueryType$1.ByPos,
|
9425
|
-
let bottom = heightMap.lineAt(to, QueryType$1.ByPos,
|
9510
|
+
let top = heightMap.lineAt(from, QueryType$1.ByPos, oracle, 0, 0).top;
|
9511
|
+
let bottom = heightMap.lineAt(to, QueryType$1.ByPos, oracle, 0, 0).bottom;
|
9426
9512
|
vpHeight += bottom - top;
|
9427
9513
|
return { from, to, top, bottom, domTop: 0, domBottom: 0 };
|
9428
9514
|
});
|
@@ -9480,7 +9566,7 @@
|
|
9480
9566
|
}
|
9481
9567
|
});
|
9482
9568
|
}
|
9483
|
-
const baseTheme$1$
|
9569
|
+
const baseTheme$1$2 = /*@__PURE__*/buildTheme("." + baseThemeID, {
|
9484
9570
|
"&": {
|
9485
9571
|
position: "relative !important",
|
9486
9572
|
boxSizing: "border-box",
|
@@ -9536,6 +9622,9 @@
|
|
9536
9622
|
padding: "0 2px 0 6px"
|
9537
9623
|
},
|
9538
9624
|
".cm-layer": {
|
9625
|
+
position: "absolute",
|
9626
|
+
left: 0,
|
9627
|
+
top: 0,
|
9539
9628
|
contain: "size style",
|
9540
9629
|
"& > *": {
|
9541
9630
|
position: "absolute"
|
@@ -9575,6 +9664,9 @@
|
|
9575
9664
|
"&dark .cm-cursor": {
|
9576
9665
|
borderLeftColor: "#444"
|
9577
9666
|
},
|
9667
|
+
".cm-dropCursor": {
|
9668
|
+
position: "absolute"
|
9669
|
+
},
|
9578
9670
|
"&.cm-focused .cm-cursor": {
|
9579
9671
|
display: "block"
|
9580
9672
|
},
|
@@ -9786,7 +9878,7 @@
|
|
9786
9878
|
};
|
9787
9879
|
}
|
9788
9880
|
else if ((browser.mac || browser.android) && change && change.from == change.to && change.from == sel.head - 1 &&
|
9789
|
-
/^\. ?$/.test(change.insert.toString())) {
|
9881
|
+
/^\. ?$/.test(change.insert.toString()) && view.contentDOM.getAttribute("autocorrect") == "off") {
|
9790
9882
|
// Detect insert-period-on-double-space Mac and Android behavior,
|
9791
9883
|
// and transform it into a regular space insert.
|
9792
9884
|
if (newSel && change.insert.length == 2)
|
@@ -10540,6 +10632,20 @@
|
|
10540
10632
|
this.viewState.state = state;
|
10541
10633
|
return;
|
10542
10634
|
}
|
10635
|
+
let focus = this.hasFocus, focusFlag = 0, dispatchFocus = null;
|
10636
|
+
if (transactions.some(tr => tr.annotation(isFocusChange))) {
|
10637
|
+
this.inputState.notifiedFocused = focus;
|
10638
|
+
// If a focus-change transaction is being dispatched, set this update flag.
|
10639
|
+
focusFlag = 1 /* UpdateFlag.Focus */;
|
10640
|
+
}
|
10641
|
+
else if (focus != this.inputState.notifiedFocused) {
|
10642
|
+
this.inputState.notifiedFocused = focus;
|
10643
|
+
// Schedule a separate focus transaction if necessary, otherwise
|
10644
|
+
// add a flag to this update
|
10645
|
+
dispatchFocus = focusChangeTransaction(state, focus);
|
10646
|
+
if (!dispatchFocus)
|
10647
|
+
focusFlag = 1 /* UpdateFlag.Focus */;
|
10648
|
+
}
|
10543
10649
|
// If there was a pending DOM change, eagerly read it and try to
|
10544
10650
|
// apply it after the given transactions.
|
10545
10651
|
let pendingKey = this.observer.delayedAndroidKey, domChange = null;
|
@@ -10558,6 +10664,7 @@
|
|
10558
10664
|
if (state.facet(EditorState.phrases) != this.state.facet(EditorState.phrases))
|
10559
10665
|
return this.setState(state);
|
10560
10666
|
update = ViewUpdate.create(this, state, transactions);
|
10667
|
+
update.flags |= focusFlag;
|
10561
10668
|
let scrollTarget = this.viewState.scrollTarget;
|
10562
10669
|
try {
|
10563
10670
|
this.updateState = 2 /* UpdateState.Updating */;
|
@@ -10595,10 +10702,15 @@
|
|
10595
10702
|
if (!update.empty)
|
10596
10703
|
for (let listener of this.state.facet(updateListener))
|
10597
10704
|
listener(update);
|
10598
|
-
if (domChange)
|
10599
|
-
|
10600
|
-
|
10601
|
-
|
10705
|
+
if (dispatchFocus || domChange)
|
10706
|
+
Promise.resolve().then(() => {
|
10707
|
+
if (dispatchFocus && this.state == dispatchFocus.startState)
|
10708
|
+
this.dispatch(dispatchFocus);
|
10709
|
+
if (domChange) {
|
10710
|
+
if (!applyDOMChange(this, domChange) && pendingKey.force)
|
10711
|
+
dispatchKey(this.contentDOM, pendingKey.key, pendingKey.keyCode);
|
10712
|
+
}
|
10713
|
+
});
|
10602
10714
|
}
|
10603
10715
|
/**
|
10604
10716
|
Reset the view to the given state. (This will cause the entire
|
@@ -10673,7 +10785,7 @@
|
|
10673
10785
|
if (this.destroyed)
|
10674
10786
|
return;
|
10675
10787
|
if (this.measureScheduled > -1)
|
10676
|
-
cancelAnimationFrame(this.measureScheduled);
|
10788
|
+
this.win.cancelAnimationFrame(this.measureScheduled);
|
10677
10789
|
this.measureScheduled = 0; // Prevent requestMeasure calls from scheduling another animation frame
|
10678
10790
|
if (flush)
|
10679
10791
|
this.observer.forceFlush();
|
@@ -10809,7 +10921,7 @@
|
|
10809
10921
|
}
|
10810
10922
|
mountStyles() {
|
10811
10923
|
this.styleModules = this.state.facet(styleModule);
|
10812
|
-
StyleModule.mount(this.root, this.styleModules.concat(baseTheme$1$
|
10924
|
+
StyleModule.mount(this.root, this.styleModules.concat(baseTheme$1$2).reverse());
|
10813
10925
|
}
|
10814
10926
|
readMeasured() {
|
10815
10927
|
if (this.updateState == 2 /* UpdateState.Updating */)
|
@@ -11111,7 +11223,7 @@
|
|
11111
11223
|
this.dom.remove();
|
11112
11224
|
this.observer.destroy();
|
11113
11225
|
if (this.measureScheduled > -1)
|
11114
|
-
cancelAnimationFrame(this.measureScheduled);
|
11226
|
+
this.win.cancelAnimationFrame(this.measureScheduled);
|
11115
11227
|
this.destroyed = true;
|
11116
11228
|
}
|
11117
11229
|
/**
|
@@ -11200,6 +11312,11 @@
|
|
11200
11312
|
*/
|
11201
11313
|
EditorView.inputHandler = inputHandler$1;
|
11202
11314
|
/**
|
11315
|
+
This facet can be used to provide functions that create effects
|
11316
|
+
to be dispatched when the editor's focus state changes.
|
11317
|
+
*/
|
11318
|
+
EditorView.focusChangeEffect = focusChangeEffect;
|
11319
|
+
/**
|
11203
11320
|
By default, the editor assumes all its content has the same
|
11204
11321
|
[text direction](https://codemirror.net/6/docs/ref/#view.Direction). Configure this with a `true`
|
11205
11322
|
value to make it read the text direction of every (rendered)
|
@@ -11618,9 +11735,10 @@
|
|
11618
11735
|
let from = Math.max(range.from, view.viewport.from), to = Math.min(range.to, view.viewport.to);
|
11619
11736
|
let ltr = view.textDirection == Direction.LTR;
|
11620
11737
|
let content = view.contentDOM, contentRect = content.getBoundingClientRect(), base = getBase(view);
|
11621
|
-
let lineStyle = window.getComputedStyle(
|
11622
|
-
let leftSide = contentRect.left +
|
11623
|
-
|
11738
|
+
let lineElt = content.querySelector(".cm-line"), lineStyle = lineElt && window.getComputedStyle(lineElt);
|
11739
|
+
let leftSide = contentRect.left +
|
11740
|
+
(lineStyle ? parseInt(lineStyle.paddingLeft) + Math.min(0, parseInt(lineStyle.textIndent)) : 0);
|
11741
|
+
let rightSide = contentRect.right - (lineStyle ? parseInt(lineStyle.paddingRight) : 0);
|
11624
11742
|
let startBlock = blockAt(view, from), endBlock = blockAt(view, to);
|
11625
11743
|
let visualStart = startBlock.type == BlockType.Text ? startBlock : null;
|
11626
11744
|
let visualEnd = endBlock.type == BlockType.Text ? endBlock : null;
|
@@ -12482,6 +12600,7 @@
|
|
12482
12600
|
});
|
12483
12601
|
}
|
12484
12602
|
});
|
12603
|
+
const knownHeight = /*@__PURE__*/new WeakMap();
|
12485
12604
|
const tooltipPlugin = /*@__PURE__*/ViewPlugin.fromClass(class {
|
12486
12605
|
constructor(view) {
|
12487
12606
|
this.view = view;
|
@@ -12597,6 +12716,7 @@
|
|
12597
12716
|
};
|
12598
12717
|
}
|
12599
12718
|
writeMeasure(measured) {
|
12719
|
+
var _a;
|
12600
12720
|
let { editor, space } = measured;
|
12601
12721
|
let others = [];
|
12602
12722
|
for (let i = 0; i < this.manager.tooltips.length; i++) {
|
@@ -12612,7 +12732,7 @@
|
|
12612
12732
|
}
|
12613
12733
|
let arrow = tooltip.arrow ? tView.dom.querySelector(".cm-tooltip-arrow") : null;
|
12614
12734
|
let arrowHeight = arrow ? 7 /* Arrow.Size */ : 0;
|
12615
|
-
let width = size.right - size.left, height = size.bottom - size.top;
|
12735
|
+
let width = size.right - size.left, height = (_a = knownHeight.get(tView)) !== null && _a !== void 0 ? _a : size.bottom - size.top;
|
12616
12736
|
let offset = tView.offset || noOffset, ltr = this.view.textDirection == Direction.LTR;
|
12617
12737
|
let left = size.width > space.right - space.left ? (ltr ? space.left : space.right - size.width)
|
12618
12738
|
: ltr ? Math.min(pos.left - (arrow ? 14 /* Arrow.Offset */ : 0) + offset.x, space.right - width)
|
@@ -12629,6 +12749,7 @@
|
|
12629
12749
|
dom.style.top = Outside;
|
12630
12750
|
continue;
|
12631
12751
|
}
|
12752
|
+
knownHeight.set(tView, height);
|
12632
12753
|
dom.style.height = (height = spaceVert) + "px";
|
12633
12754
|
}
|
12634
12755
|
else if (dom.style.height) {
|
@@ -12744,214 +12865,6 @@
|
|
12744
12865
|
const showTooltip = /*@__PURE__*/Facet.define({
|
12745
12866
|
enables: [tooltipPlugin, baseTheme$4]
|
12746
12867
|
});
|
12747
|
-
const showHoverTooltip = /*@__PURE__*/Facet.define();
|
12748
|
-
class HoverTooltipHost {
|
12749
|
-
constructor(view) {
|
12750
|
-
this.view = view;
|
12751
|
-
this.mounted = false;
|
12752
|
-
this.dom = document.createElement("div");
|
12753
|
-
this.dom.classList.add("cm-tooltip-hover");
|
12754
|
-
this.manager = new TooltipViewManager(view, showHoverTooltip, t => this.createHostedView(t));
|
12755
|
-
}
|
12756
|
-
// Needs to be static so that host tooltip instances always match
|
12757
|
-
static create(view) {
|
12758
|
-
return new HoverTooltipHost(view);
|
12759
|
-
}
|
12760
|
-
createHostedView(tooltip) {
|
12761
|
-
let hostedView = tooltip.create(this.view);
|
12762
|
-
hostedView.dom.classList.add("cm-tooltip-section");
|
12763
|
-
this.dom.appendChild(hostedView.dom);
|
12764
|
-
if (this.mounted && hostedView.mount)
|
12765
|
-
hostedView.mount(this.view);
|
12766
|
-
return hostedView;
|
12767
|
-
}
|
12768
|
-
mount(view) {
|
12769
|
-
for (let hostedView of this.manager.tooltipViews) {
|
12770
|
-
if (hostedView.mount)
|
12771
|
-
hostedView.mount(view);
|
12772
|
-
}
|
12773
|
-
this.mounted = true;
|
12774
|
-
}
|
12775
|
-
positioned(space) {
|
12776
|
-
for (let hostedView of this.manager.tooltipViews) {
|
12777
|
-
if (hostedView.positioned)
|
12778
|
-
hostedView.positioned(space);
|
12779
|
-
}
|
12780
|
-
}
|
12781
|
-
update(update) {
|
12782
|
-
this.manager.update(update);
|
12783
|
-
}
|
12784
|
-
}
|
12785
|
-
const showHoverTooltipHost = /*@__PURE__*/showTooltip.compute([showHoverTooltip], state => {
|
12786
|
-
let tooltips = state.facet(showHoverTooltip).filter(t => t);
|
12787
|
-
if (tooltips.length === 0)
|
12788
|
-
return null;
|
12789
|
-
return {
|
12790
|
-
pos: Math.min(...tooltips.map(t => t.pos)),
|
12791
|
-
end: Math.max(...tooltips.filter(t => t.end != null).map(t => t.end)),
|
12792
|
-
create: HoverTooltipHost.create,
|
12793
|
-
above: tooltips[0].above,
|
12794
|
-
arrow: tooltips.some(t => t.arrow),
|
12795
|
-
};
|
12796
|
-
});
|
12797
|
-
class HoverPlugin {
|
12798
|
-
constructor(view, source, field, setHover, hoverTime) {
|
12799
|
-
this.view = view;
|
12800
|
-
this.source = source;
|
12801
|
-
this.field = field;
|
12802
|
-
this.setHover = setHover;
|
12803
|
-
this.hoverTime = hoverTime;
|
12804
|
-
this.hoverTimeout = -1;
|
12805
|
-
this.restartTimeout = -1;
|
12806
|
-
this.pending = null;
|
12807
|
-
this.lastMove = { x: 0, y: 0, target: view.dom, time: 0 };
|
12808
|
-
this.checkHover = this.checkHover.bind(this);
|
12809
|
-
view.dom.addEventListener("mouseleave", this.mouseleave = this.mouseleave.bind(this));
|
12810
|
-
view.dom.addEventListener("mousemove", this.mousemove = this.mousemove.bind(this));
|
12811
|
-
}
|
12812
|
-
update() {
|
12813
|
-
if (this.pending) {
|
12814
|
-
this.pending = null;
|
12815
|
-
clearTimeout(this.restartTimeout);
|
12816
|
-
this.restartTimeout = setTimeout(() => this.startHover(), 20);
|
12817
|
-
}
|
12818
|
-
}
|
12819
|
-
get active() {
|
12820
|
-
return this.view.state.field(this.field);
|
12821
|
-
}
|
12822
|
-
checkHover() {
|
12823
|
-
this.hoverTimeout = -1;
|
12824
|
-
if (this.active)
|
12825
|
-
return;
|
12826
|
-
let hovered = Date.now() - this.lastMove.time;
|
12827
|
-
if (hovered < this.hoverTime)
|
12828
|
-
this.hoverTimeout = setTimeout(this.checkHover, this.hoverTime - hovered);
|
12829
|
-
else
|
12830
|
-
this.startHover();
|
12831
|
-
}
|
12832
|
-
startHover() {
|
12833
|
-
clearTimeout(this.restartTimeout);
|
12834
|
-
let { lastMove } = this;
|
12835
|
-
let pos = this.view.contentDOM.contains(lastMove.target) ? this.view.posAtCoords(lastMove) : null;
|
12836
|
-
if (pos == null)
|
12837
|
-
return;
|
12838
|
-
let posCoords = this.view.coordsAtPos(pos);
|
12839
|
-
if (posCoords == null || lastMove.y < posCoords.top || lastMove.y > posCoords.bottom ||
|
12840
|
-
lastMove.x < posCoords.left - this.view.defaultCharacterWidth ||
|
12841
|
-
lastMove.x > posCoords.right + this.view.defaultCharacterWidth)
|
12842
|
-
return;
|
12843
|
-
let bidi = this.view.bidiSpans(this.view.state.doc.lineAt(pos)).find(s => s.from <= pos && s.to >= pos);
|
12844
|
-
let rtl = bidi && bidi.dir == Direction.RTL ? -1 : 1;
|
12845
|
-
let open = this.source(this.view, pos, (lastMove.x < posCoords.left ? -rtl : rtl));
|
12846
|
-
if (open === null || open === void 0 ? void 0 : open.then) {
|
12847
|
-
let pending = this.pending = { pos };
|
12848
|
-
open.then(result => {
|
12849
|
-
if (this.pending == pending) {
|
12850
|
-
this.pending = null;
|
12851
|
-
if (result)
|
12852
|
-
this.view.dispatch({ effects: this.setHover.of(result) });
|
12853
|
-
}
|
12854
|
-
}, e => logException(this.view.state, e, "hover tooltip"));
|
12855
|
-
}
|
12856
|
-
else if (open) {
|
12857
|
-
this.view.dispatch({ effects: this.setHover.of(open) });
|
12858
|
-
}
|
12859
|
-
}
|
12860
|
-
mousemove(event) {
|
12861
|
-
var _a;
|
12862
|
-
this.lastMove = { x: event.clientX, y: event.clientY, target: event.target, time: Date.now() };
|
12863
|
-
if (this.hoverTimeout < 0)
|
12864
|
-
this.hoverTimeout = setTimeout(this.checkHover, this.hoverTime);
|
12865
|
-
let tooltip = this.active;
|
12866
|
-
if (tooltip && !isInTooltip(this.lastMove.target) || this.pending) {
|
12867
|
-
let { pos } = tooltip || this.pending, end = (_a = tooltip === null || tooltip === void 0 ? void 0 : tooltip.end) !== null && _a !== void 0 ? _a : pos;
|
12868
|
-
if ((pos == end ? this.view.posAtCoords(this.lastMove) != pos
|
12869
|
-
: !isOverRange(this.view, pos, end, event.clientX, event.clientY, 6 /* Hover.MaxDist */))) {
|
12870
|
-
this.view.dispatch({ effects: this.setHover.of(null) });
|
12871
|
-
this.pending = null;
|
12872
|
-
}
|
12873
|
-
}
|
12874
|
-
}
|
12875
|
-
mouseleave(e) {
|
12876
|
-
clearTimeout(this.hoverTimeout);
|
12877
|
-
this.hoverTimeout = -1;
|
12878
|
-
if (this.active && !isInTooltip(e.relatedTarget))
|
12879
|
-
this.view.dispatch({ effects: this.setHover.of(null) });
|
12880
|
-
}
|
12881
|
-
destroy() {
|
12882
|
-
clearTimeout(this.hoverTimeout);
|
12883
|
-
this.view.dom.removeEventListener("mouseleave", this.mouseleave);
|
12884
|
-
this.view.dom.removeEventListener("mousemove", this.mousemove);
|
12885
|
-
}
|
12886
|
-
}
|
12887
|
-
function isInTooltip(elt) {
|
12888
|
-
for (let cur = elt; cur; cur = cur.parentNode)
|
12889
|
-
if (cur.nodeType == 1 && cur.classList.contains("cm-tooltip"))
|
12890
|
-
return true;
|
12891
|
-
return false;
|
12892
|
-
}
|
12893
|
-
function isOverRange(view, from, to, x, y, margin) {
|
12894
|
-
let range = document.createRange();
|
12895
|
-
let fromDOM = view.domAtPos(from), toDOM = view.domAtPos(to);
|
12896
|
-
range.setEnd(toDOM.node, toDOM.offset);
|
12897
|
-
range.setStart(fromDOM.node, fromDOM.offset);
|
12898
|
-
let rects = range.getClientRects();
|
12899
|
-
range.detach();
|
12900
|
-
for (let i = 0; i < rects.length; i++) {
|
12901
|
-
let rect = rects[i];
|
12902
|
-
let dist = Math.max(rect.top - y, y - rect.bottom, rect.left - x, x - rect.right);
|
12903
|
-
if (dist <= margin)
|
12904
|
-
return true;
|
12905
|
-
}
|
12906
|
-
return false;
|
12907
|
-
}
|
12908
|
-
/**
|
12909
|
-
Set up a hover tooltip, which shows up when the pointer hovers
|
12910
|
-
over ranges of text. The callback is called when the mouse hovers
|
12911
|
-
over the document text. It should, if there is a tooltip
|
12912
|
-
associated with position `pos`, return the tooltip description
|
12913
|
-
(either directly or in a promise). The `side` argument indicates
|
12914
|
-
on which side of the position the pointer is—it will be -1 if the
|
12915
|
-
pointer is before the position, 1 if after the position.
|
12916
|
-
|
12917
|
-
Note that all hover tooltips are hosted within a single tooltip
|
12918
|
-
container element. This allows multiple tooltips over the same
|
12919
|
-
range to be "merged" together without overlapping.
|
12920
|
-
*/
|
12921
|
-
function hoverTooltip(source, options = {}) {
|
12922
|
-
let setHover = StateEffect.define();
|
12923
|
-
let hoverState = StateField.define({
|
12924
|
-
create() { return null; },
|
12925
|
-
update(value, tr) {
|
12926
|
-
if (value && (options.hideOnChange && (tr.docChanged || tr.selection) ||
|
12927
|
-
options.hideOn && options.hideOn(tr, value)))
|
12928
|
-
return null;
|
12929
|
-
if (value && tr.docChanged) {
|
12930
|
-
let newPos = tr.changes.mapPos(value.pos, -1, MapMode.TrackDel);
|
12931
|
-
if (newPos == null)
|
12932
|
-
return null;
|
12933
|
-
let copy = Object.assign(Object.create(null), value);
|
12934
|
-
copy.pos = newPos;
|
12935
|
-
if (value.end != null)
|
12936
|
-
copy.end = tr.changes.mapPos(value.end);
|
12937
|
-
value = copy;
|
12938
|
-
}
|
12939
|
-
for (let effect of tr.effects) {
|
12940
|
-
if (effect.is(setHover))
|
12941
|
-
value = effect.value;
|
12942
|
-
if (effect.is(closeHoverTooltipEffect))
|
12943
|
-
value = null;
|
12944
|
-
}
|
12945
|
-
return value;
|
12946
|
-
},
|
12947
|
-
provide: f => showHoverTooltip.from(f)
|
12948
|
-
});
|
12949
|
-
return [
|
12950
|
-
hoverState,
|
12951
|
-
ViewPlugin.define(view => new HoverPlugin(view, source, hoverState, setHover, options.hoverTime || 300 /* Hover.Time */)),
|
12952
|
-
showHoverTooltipHost
|
12953
|
-
];
|
12954
|
-
}
|
12955
12868
|
/**
|
12956
12869
|
Get the active tooltip view for a given tooltip, if available.
|
12957
12870
|
*/
|
@@ -12962,7 +12875,6 @@
|
|
12962
12875
|
let found = plugin.manager.tooltips.indexOf(tooltip);
|
12963
12876
|
return found < 0 ? null : plugin.manager.tooltipViews[found];
|
12964
12877
|
}
|
12965
|
-
const closeHoverTooltipEffect = /*@__PURE__*/StateEffect.define();
|
12966
12878
|
|
12967
12879
|
const panelConfig = /*@__PURE__*/Facet.define({
|
12968
12880
|
combine(configs) {
|
@@ -14943,45 +14855,59 @@
|
|
14943
14855
|
new NodeProp({ perNode: true });
|
14944
14856
|
|
14945
14857
|
let nextTagID = 0;
|
14946
|
-
|
14947
|
-
|
14948
|
-
|
14949
|
-
|
14950
|
-
|
14951
|
-
|
14952
|
-
|
14953
|
-
|
14954
|
-
|
14955
|
-
|
14956
|
-
|
14957
|
-
|
14958
|
-
|
14959
|
-
|
14960
|
-
|
14961
|
-
|
14962
|
-
|
14858
|
+
/**
|
14859
|
+
Highlighting tags are markers that denote a highlighting category.
|
14860
|
+
They are [associated](#highlight.styleTags) with parts of a syntax
|
14861
|
+
tree by a language mode, and then mapped to an actual CSS style by
|
14862
|
+
a [highlighter](#highlight.Highlighter).
|
14863
|
+
|
14864
|
+
Because syntax tree node types and highlight styles have to be
|
14865
|
+
able to talk the same language, CodeMirror uses a mostly _closed_
|
14866
|
+
[vocabulary](#highlight.tags) of syntax tags (as opposed to
|
14867
|
+
traditional open string-based systems, which make it hard for
|
14868
|
+
highlighting themes to cover all the tokens produced by the
|
14869
|
+
various languages).
|
14870
|
+
|
14871
|
+
It _is_ possible to [define](#highlight.Tag^define) your own
|
14872
|
+
highlighting tags for system-internal use (where you control both
|
14873
|
+
the language package and the highlighter), but such tags will not
|
14874
|
+
be picked up by regular highlighters (though you can derive them
|
14875
|
+
from standard tags to allow highlighters to fall back to those).
|
14876
|
+
*/
|
14963
14877
|
class Tag {
|
14964
|
-
|
14878
|
+
/**
|
14879
|
+
@internal
|
14880
|
+
*/
|
14965
14881
|
constructor(
|
14966
|
-
|
14967
|
-
|
14882
|
+
/**
|
14883
|
+
The set of this tag and all its parent tags, starting with
|
14884
|
+
this one itself and sorted in order of decreasing specificity.
|
14885
|
+
*/
|
14968
14886
|
set,
|
14969
|
-
|
14970
|
-
|
14887
|
+
/**
|
14888
|
+
The base unmodified tag that this one is based on, if it's
|
14889
|
+
modified @internal
|
14890
|
+
*/
|
14971
14891
|
base,
|
14972
|
-
|
14892
|
+
/**
|
14893
|
+
The modifiers applied to this.base @internal
|
14894
|
+
*/
|
14973
14895
|
modified) {
|
14974
14896
|
this.set = set;
|
14975
14897
|
this.base = base;
|
14976
14898
|
this.modified = modified;
|
14977
|
-
|
14899
|
+
/**
|
14900
|
+
@internal
|
14901
|
+
*/
|
14978
14902
|
this.id = nextTagID++;
|
14979
14903
|
}
|
14980
|
-
|
14981
|
-
|
14982
|
-
|
14983
|
-
|
14984
|
-
|
14904
|
+
/**
|
14905
|
+
Define a new tag. If `parent` is given, the tag is treated as a
|
14906
|
+
sub-tag of that parent, and
|
14907
|
+
[highlighters](#highlight.tagHighlighter) that don't mention
|
14908
|
+
this tag will try to fall back to the parent tag (or grandparent
|
14909
|
+
tag, etc).
|
14910
|
+
*/
|
14985
14911
|
static define(parent) {
|
14986
14912
|
if (parent === null || parent === void 0 ? void 0 : parent.base)
|
14987
14913
|
throw new Error("Can not derive from a modified tag");
|
@@ -14992,16 +14918,18 @@
|
|
14992
14918
|
tag.set.push(t);
|
14993
14919
|
return tag;
|
14994
14920
|
}
|
14995
|
-
|
14996
|
-
|
14997
|
-
|
14998
|
-
|
14999
|
-
|
15000
|
-
|
15001
|
-
|
15002
|
-
|
15003
|
-
|
15004
|
-
|
14921
|
+
/**
|
14922
|
+
Define a tag _modifier_, which is a function that, given a tag,
|
14923
|
+
will return a tag that is a subtag of the original. Applying the
|
14924
|
+
same modifier to a twice tag will return the same value (`m1(t1)
|
14925
|
+
== m1(t1)`) and applying multiple modifiers will, regardless or
|
14926
|
+
order, produce the same tag (`m1(m2(t1)) == m2(m1(t1))`).
|
14927
|
+
|
14928
|
+
When multiple modifiers are applied to a given base tag, each
|
14929
|
+
smaller set of modifiers is registered as a parent, so that for
|
14930
|
+
example `m1(m2(m3(t1)))` is a subtype of `m1(m2(t1))`,
|
14931
|
+
`m1(m3(t1)`, and so on.
|
14932
|
+
*/
|
15005
14933
|
static defineModifier() {
|
15006
14934
|
let mod = new Modifier;
|
15007
14935
|
return (tag) => {
|
@@ -15046,55 +14974,57 @@
|
|
15046
14974
|
}
|
15047
14975
|
return sets.sort((a, b) => b.length - a.length);
|
15048
14976
|
}
|
15049
|
-
|
15050
|
-
|
15051
|
-
|
15052
|
-
|
15053
|
-
|
15054
|
-
|
15055
|
-
|
15056
|
-
|
15057
|
-
|
15058
|
-
|
15059
|
-
|
15060
|
-
|
15061
|
-
|
15062
|
-
|
15063
|
-
|
15064
|
-
|
15065
|
-
|
15066
|
-
|
15067
|
-
|
15068
|
-
|
15069
|
-
|
15070
|
-
|
15071
|
-
|
15072
|
-
|
15073
|
-
|
15074
|
-
|
15075
|
-
|
15076
|
-
|
15077
|
-
|
15078
|
-
|
15079
|
-
|
15080
|
-
|
15081
|
-
|
15082
|
-
|
15083
|
-
|
15084
|
-
|
15085
|
-
|
15086
|
-
|
15087
|
-
|
15088
|
-
|
15089
|
-
|
15090
|
-
|
15091
|
-
|
15092
|
-
|
15093
|
-
|
15094
|
-
|
15095
|
-
|
15096
|
-
|
15097
|
-
|
14977
|
+
/**
|
14978
|
+
This function is used to add a set of tags to a language syntax
|
14979
|
+
via [`NodeSet.extend`](#common.NodeSet.extend) or
|
14980
|
+
[`LRParser.configure`](#lr.LRParser.configure).
|
14981
|
+
|
14982
|
+
The argument object maps node selectors to [highlighting
|
14983
|
+
tags](#highlight.Tag) or arrays of tags.
|
14984
|
+
|
14985
|
+
Node selectors may hold one or more (space-separated) node paths.
|
14986
|
+
Such a path can be a [node name](#common.NodeType.name), or
|
14987
|
+
multiple node names (or `*` wildcards) separated by slash
|
14988
|
+
characters, as in `"Block/Declaration/VariableName"`. Such a path
|
14989
|
+
matches the final node but only if its direct parent nodes are the
|
14990
|
+
other nodes mentioned. A `*` in such a path matches any parent,
|
14991
|
+
but only a single level—wildcards that match multiple parents
|
14992
|
+
aren't supported, both for efficiency reasons and because Lezer
|
14993
|
+
trees make it rather hard to reason about what they would match.)
|
14994
|
+
|
14995
|
+
A path can be ended with `/...` to indicate that the tag assigned
|
14996
|
+
to the node should also apply to all child nodes, even if they
|
14997
|
+
match their own style (by default, only the innermost style is
|
14998
|
+
used).
|
14999
|
+
|
15000
|
+
When a path ends in `!`, as in `Attribute!`, no further matching
|
15001
|
+
happens for the node's child nodes, and the entire node gets the
|
15002
|
+
given style.
|
15003
|
+
|
15004
|
+
In this notation, node names that contain `/`, `!`, `*`, or `...`
|
15005
|
+
must be quoted as JSON strings.
|
15006
|
+
|
15007
|
+
For example:
|
15008
|
+
|
15009
|
+
```javascript
|
15010
|
+
parser.withProps(
|
15011
|
+
styleTags({
|
15012
|
+
// Style Number and BigNumber nodes
|
15013
|
+
"Number BigNumber": tags.number,
|
15014
|
+
// Style Escape nodes whose parent is String
|
15015
|
+
"String/Escape": tags.escape,
|
15016
|
+
// Style anything inside Attributes nodes
|
15017
|
+
"Attributes!": tags.meta,
|
15018
|
+
// Add a style to all content inside Italic nodes
|
15019
|
+
"Italic/...": tags.emphasis,
|
15020
|
+
// Style InvalidString nodes as both `string` and `invalid`
|
15021
|
+
"InvalidString": [tags.string, tags.invalid],
|
15022
|
+
// Style the node named "/" as punctuation
|
15023
|
+
'"/"': tags.punctuation
|
15024
|
+
})
|
15025
|
+
)
|
15026
|
+
```
|
15027
|
+
*/
|
15098
15028
|
function styleTags(spec) {
|
15099
15029
|
let byName = Object.create(null);
|
15100
15030
|
for (let prop in spec) {
|
@@ -15103,10 +15033,10 @@
|
|
15103
15033
|
tags = [tags];
|
15104
15034
|
for (let part of prop.split(" "))
|
15105
15035
|
if (part) {
|
15106
|
-
let pieces = [], mode = 2 /*
|
15036
|
+
let pieces = [], mode = 2 /* Normal */, rest = part;
|
15107
15037
|
for (let pos = 0;;) {
|
15108
15038
|
if (rest == "..." && pos > 0 && pos + 3 == part.length) {
|
15109
|
-
mode = 1 /*
|
15039
|
+
mode = 1 /* Inherit */;
|
15110
15040
|
break;
|
15111
15041
|
}
|
15112
15042
|
let m = /^"(?:[^"\\]|\\.)*?"|[^\/!]+/.exec(rest);
|
@@ -15118,7 +15048,7 @@
|
|
15118
15048
|
break;
|
15119
15049
|
let next = part[pos++];
|
15120
15050
|
if (pos == part.length && next == "!") {
|
15121
|
-
mode = 0 /*
|
15051
|
+
mode = 0 /* Opaque */;
|
15122
15052
|
break;
|
15123
15053
|
}
|
15124
15054
|
if (next != "/")
|
@@ -15142,8 +15072,8 @@
|
|
15142
15072
|
this.context = context;
|
15143
15073
|
this.next = next;
|
15144
15074
|
}
|
15145
|
-
get opaque() { return this.mode == 0 /*
|
15146
|
-
get inherit() { return this.mode == 1 /*
|
15075
|
+
get opaque() { return this.mode == 0 /* Opaque */; }
|
15076
|
+
get inherit() { return this.mode == 1 /* Inherit */; }
|
15147
15077
|
sort(other) {
|
15148
15078
|
if (!other || other.depth < this.depth) {
|
15149
15079
|
this.next = other;
|
@@ -15154,10 +15084,12 @@
|
|
15154
15084
|
}
|
15155
15085
|
get depth() { return this.context ? this.context.length : 0; }
|
15156
15086
|
}
|
15157
|
-
Rule.empty = new Rule([], 2 /*
|
15158
|
-
|
15159
|
-
|
15160
|
-
|
15087
|
+
Rule.empty = new Rule([], 2 /* Normal */, null);
|
15088
|
+
/**
|
15089
|
+
Define a [highlighter](#highlight.Highlighter) from an array of
|
15090
|
+
tag/class pairs. Classes associated with more specific tags will
|
15091
|
+
take precedence.
|
15092
|
+
*/
|
15161
15093
|
function tagHighlighter(tags, options) {
|
15162
15094
|
let map = Object.create(null);
|
15163
15095
|
for (let style of tags) {
|
@@ -15194,16 +15126,24 @@
|
|
15194
15126
|
}
|
15195
15127
|
return result;
|
15196
15128
|
}
|
15197
|
-
|
15198
|
-
|
15129
|
+
/**
|
15130
|
+
Highlight the given [tree](#common.Tree) with the given
|
15131
|
+
[highlighter](#highlight.Highlighter).
|
15132
|
+
*/
|
15199
15133
|
function highlightTree(tree, highlighter,
|
15200
|
-
|
15201
|
-
|
15202
|
-
|
15134
|
+
/**
|
15135
|
+
Assign styling to a region of the text. Will be called, in order
|
15136
|
+
of position, for any ranges where more than zero classes apply.
|
15137
|
+
`classes` is a space separated string of CSS classes.
|
15138
|
+
*/
|
15203
15139
|
putStyle,
|
15204
|
-
|
15140
|
+
/**
|
15141
|
+
The start of the range to highlight.
|
15142
|
+
*/
|
15205
15143
|
from = 0,
|
15206
|
-
|
15144
|
+
/**
|
15145
|
+
The end of the range.
|
15146
|
+
*/
|
15207
15147
|
to = tree.length) {
|
15208
15148
|
let builder = new HighlightBuilder(from, Array.isArray(highlighter) ? highlighter : [highlighter], putStyle);
|
15209
15149
|
builder.highlightRange(tree.cursor(), from, to, "", builder.highlighters);
|
@@ -15241,7 +15181,7 @@
|
|
15241
15181
|
if (cls)
|
15242
15182
|
cls += " ";
|
15243
15183
|
cls += tagCls;
|
15244
|
-
if (rule.mode == 1 /*
|
15184
|
+
if (rule.mode == 1 /* Inherit */)
|
15245
15185
|
inheritedClass += (inheritedClass ? " " : "") + tagCls;
|
15246
15186
|
}
|
15247
15187
|
this.startSpan(cursor.from, cls);
|
@@ -15288,9 +15228,11 @@
|
|
15288
15228
|
}
|
15289
15229
|
}
|
15290
15230
|
}
|
15291
|
-
|
15292
|
-
|
15293
|
-
|
15231
|
+
/**
|
15232
|
+
Match a syntax node's [highlight rules](#highlight.styleTags). If
|
15233
|
+
there's a match, return its set of tags, and whether it is
|
15234
|
+
opaque (uses a `!`) or applies to all child nodes (`/...`).
|
15235
|
+
*/
|
15294
15236
|
function getStyleTags(node) {
|
15295
15237
|
let rule = node.type.prop(ruleNodeProp);
|
15296
15238
|
while (rule && rule.context && !node.matchContext(rule.context))
|
@@ -15299,268 +15241,440 @@
|
|
15299
15241
|
}
|
15300
15242
|
const t = Tag.define;
|
15301
15243
|
const comment = t(), name = t(), typeName = t(name), propertyName = t(name), literal = t(), string = t(literal), number = t(literal), content = t(), heading = t(content), keyword = t(), operator = t(), punctuation = t(), bracket = t(punctuation), meta = t();
|
15302
|
-
|
15303
|
-
|
15304
|
-
|
15305
|
-
|
15306
|
-
|
15307
|
-
|
15308
|
-
|
15309
|
-
|
15310
|
-
|
15311
|
-
|
15312
|
-
|
15313
|
-
|
15314
|
-
|
15315
|
-
|
15316
|
-
|
15317
|
-
|
15318
|
-
|
15319
|
-
|
15244
|
+
/**
|
15245
|
+
The default set of highlighting [tags](#highlight.Tag).
|
15246
|
+
|
15247
|
+
This collection is heavily biased towards programming languages,
|
15248
|
+
and necessarily incomplete. A full ontology of syntactic
|
15249
|
+
constructs would fill a stack of books, and be impractical to
|
15250
|
+
write themes for. So try to make do with this set. If all else
|
15251
|
+
fails, [open an
|
15252
|
+
issue](https://github.com/codemirror/codemirror.next) to propose a
|
15253
|
+
new tag, or [define](#highlight.Tag^define) a local custom tag for
|
15254
|
+
your use case.
|
15255
|
+
|
15256
|
+
Note that it is not obligatory to always attach the most specific
|
15257
|
+
tag possible to an element—if your grammar can't easily
|
15258
|
+
distinguish a certain type of element (such as a local variable),
|
15259
|
+
it is okay to style it as its more general variant (a variable).
|
15260
|
+
|
15261
|
+
For tags that extend some parent tag, the documentation links to
|
15262
|
+
the parent.
|
15263
|
+
*/
|
15320
15264
|
const tags = {
|
15321
|
-
|
15265
|
+
/**
|
15266
|
+
A comment.
|
15267
|
+
*/
|
15322
15268
|
comment,
|
15323
|
-
|
15269
|
+
/**
|
15270
|
+
A line [comment](#highlight.tags.comment).
|
15271
|
+
*/
|
15324
15272
|
lineComment: t(comment),
|
15325
|
-
|
15273
|
+
/**
|
15274
|
+
A block [comment](#highlight.tags.comment).
|
15275
|
+
*/
|
15326
15276
|
blockComment: t(comment),
|
15327
|
-
|
15277
|
+
/**
|
15278
|
+
A documentation [comment](#highlight.tags.comment).
|
15279
|
+
*/
|
15328
15280
|
docComment: t(comment),
|
15329
|
-
|
15281
|
+
/**
|
15282
|
+
Any kind of identifier.
|
15283
|
+
*/
|
15330
15284
|
name,
|
15331
|
-
|
15285
|
+
/**
|
15286
|
+
The [name](#highlight.tags.name) of a variable.
|
15287
|
+
*/
|
15332
15288
|
variableName: t(name),
|
15333
|
-
|
15289
|
+
/**
|
15290
|
+
A type [name](#highlight.tags.name).
|
15291
|
+
*/
|
15334
15292
|
typeName: typeName,
|
15335
|
-
|
15293
|
+
/**
|
15294
|
+
A tag name (subtag of [`typeName`](#highlight.tags.typeName)).
|
15295
|
+
*/
|
15336
15296
|
tagName: t(typeName),
|
15337
|
-
|
15297
|
+
/**
|
15298
|
+
A property or field [name](#highlight.tags.name).
|
15299
|
+
*/
|
15338
15300
|
propertyName: propertyName,
|
15339
|
-
|
15301
|
+
/**
|
15302
|
+
An attribute name (subtag of [`propertyName`](#highlight.tags.propertyName)).
|
15303
|
+
*/
|
15340
15304
|
attributeName: t(propertyName),
|
15341
|
-
|
15305
|
+
/**
|
15306
|
+
The [name](#highlight.tags.name) of a class.
|
15307
|
+
*/
|
15342
15308
|
className: t(name),
|
15343
|
-
|
15309
|
+
/**
|
15310
|
+
A label [name](#highlight.tags.name).
|
15311
|
+
*/
|
15344
15312
|
labelName: t(name),
|
15345
|
-
|
15313
|
+
/**
|
15314
|
+
A namespace [name](#highlight.tags.name).
|
15315
|
+
*/
|
15346
15316
|
namespace: t(name),
|
15347
|
-
|
15317
|
+
/**
|
15318
|
+
The [name](#highlight.tags.name) of a macro.
|
15319
|
+
*/
|
15348
15320
|
macroName: t(name),
|
15349
|
-
|
15321
|
+
/**
|
15322
|
+
A literal value.
|
15323
|
+
*/
|
15350
15324
|
literal,
|
15351
|
-
|
15325
|
+
/**
|
15326
|
+
A string [literal](#highlight.tags.literal).
|
15327
|
+
*/
|
15352
15328
|
string,
|
15353
|
-
|
15329
|
+
/**
|
15330
|
+
A documentation [string](#highlight.tags.string).
|
15331
|
+
*/
|
15354
15332
|
docString: t(string),
|
15355
|
-
|
15333
|
+
/**
|
15334
|
+
A character literal (subtag of [string](#highlight.tags.string)).
|
15335
|
+
*/
|
15356
15336
|
character: t(string),
|
15357
|
-
|
15337
|
+
/**
|
15338
|
+
An attribute value (subtag of [string](#highlight.tags.string)).
|
15339
|
+
*/
|
15358
15340
|
attributeValue: t(string),
|
15359
|
-
|
15341
|
+
/**
|
15342
|
+
A number [literal](#highlight.tags.literal).
|
15343
|
+
*/
|
15360
15344
|
number,
|
15361
|
-
|
15345
|
+
/**
|
15346
|
+
An integer [number](#highlight.tags.number) literal.
|
15347
|
+
*/
|
15362
15348
|
integer: t(number),
|
15363
|
-
|
15349
|
+
/**
|
15350
|
+
A floating-point [number](#highlight.tags.number) literal.
|
15351
|
+
*/
|
15364
15352
|
float: t(number),
|
15365
|
-
|
15353
|
+
/**
|
15354
|
+
A boolean [literal](#highlight.tags.literal).
|
15355
|
+
*/
|
15366
15356
|
bool: t(literal),
|
15367
|
-
|
15357
|
+
/**
|
15358
|
+
Regular expression [literal](#highlight.tags.literal).
|
15359
|
+
*/
|
15368
15360
|
regexp: t(literal),
|
15369
|
-
|
15370
|
-
|
15361
|
+
/**
|
15362
|
+
An escape [literal](#highlight.tags.literal), for example a
|
15363
|
+
backslash escape in a string.
|
15364
|
+
*/
|
15371
15365
|
escape: t(literal),
|
15372
|
-
|
15366
|
+
/**
|
15367
|
+
A color [literal](#highlight.tags.literal).
|
15368
|
+
*/
|
15373
15369
|
color: t(literal),
|
15374
|
-
|
15370
|
+
/**
|
15371
|
+
A URL [literal](#highlight.tags.literal).
|
15372
|
+
*/
|
15375
15373
|
url: t(literal),
|
15376
|
-
|
15374
|
+
/**
|
15375
|
+
A language keyword.
|
15376
|
+
*/
|
15377
15377
|
keyword,
|
15378
|
-
|
15379
|
-
|
15378
|
+
/**
|
15379
|
+
The [keyword](#highlight.tags.keyword) for the self or this
|
15380
|
+
object.
|
15381
|
+
*/
|
15380
15382
|
self: t(keyword),
|
15381
|
-
|
15383
|
+
/**
|
15384
|
+
The [keyword](#highlight.tags.keyword) for null.
|
15385
|
+
*/
|
15382
15386
|
null: t(keyword),
|
15383
|
-
|
15387
|
+
/**
|
15388
|
+
A [keyword](#highlight.tags.keyword) denoting some atomic value.
|
15389
|
+
*/
|
15384
15390
|
atom: t(keyword),
|
15385
|
-
|
15391
|
+
/**
|
15392
|
+
A [keyword](#highlight.tags.keyword) that represents a unit.
|
15393
|
+
*/
|
15386
15394
|
unit: t(keyword),
|
15387
|
-
|
15395
|
+
/**
|
15396
|
+
A modifier [keyword](#highlight.tags.keyword).
|
15397
|
+
*/
|
15388
15398
|
modifier: t(keyword),
|
15389
|
-
|
15399
|
+
/**
|
15400
|
+
A [keyword](#highlight.tags.keyword) that acts as an operator.
|
15401
|
+
*/
|
15390
15402
|
operatorKeyword: t(keyword),
|
15391
|
-
|
15403
|
+
/**
|
15404
|
+
A control-flow related [keyword](#highlight.tags.keyword).
|
15405
|
+
*/
|
15392
15406
|
controlKeyword: t(keyword),
|
15393
|
-
|
15407
|
+
/**
|
15408
|
+
A [keyword](#highlight.tags.keyword) that defines something.
|
15409
|
+
*/
|
15394
15410
|
definitionKeyword: t(keyword),
|
15395
|
-
|
15396
|
-
|
15411
|
+
/**
|
15412
|
+
A [keyword](#highlight.tags.keyword) related to defining or
|
15413
|
+
interfacing with modules.
|
15414
|
+
*/
|
15397
15415
|
moduleKeyword: t(keyword),
|
15398
|
-
|
15416
|
+
/**
|
15417
|
+
An operator.
|
15418
|
+
*/
|
15399
15419
|
operator,
|
15400
|
-
|
15420
|
+
/**
|
15421
|
+
An [operator](#highlight.tags.operator) that dereferences something.
|
15422
|
+
*/
|
15401
15423
|
derefOperator: t(operator),
|
15402
|
-
|
15424
|
+
/**
|
15425
|
+
Arithmetic-related [operator](#highlight.tags.operator).
|
15426
|
+
*/
|
15403
15427
|
arithmeticOperator: t(operator),
|
15404
|
-
|
15428
|
+
/**
|
15429
|
+
Logical [operator](#highlight.tags.operator).
|
15430
|
+
*/
|
15405
15431
|
logicOperator: t(operator),
|
15406
|
-
|
15432
|
+
/**
|
15433
|
+
Bit [operator](#highlight.tags.operator).
|
15434
|
+
*/
|
15407
15435
|
bitwiseOperator: t(operator),
|
15408
|
-
|
15436
|
+
/**
|
15437
|
+
Comparison [operator](#highlight.tags.operator).
|
15438
|
+
*/
|
15409
15439
|
compareOperator: t(operator),
|
15410
|
-
|
15440
|
+
/**
|
15441
|
+
[Operator](#highlight.tags.operator) that updates its operand.
|
15442
|
+
*/
|
15411
15443
|
updateOperator: t(operator),
|
15412
|
-
|
15444
|
+
/**
|
15445
|
+
[Operator](#highlight.tags.operator) that defines something.
|
15446
|
+
*/
|
15413
15447
|
definitionOperator: t(operator),
|
15414
|
-
|
15448
|
+
/**
|
15449
|
+
Type-related [operator](#highlight.tags.operator).
|
15450
|
+
*/
|
15415
15451
|
typeOperator: t(operator),
|
15416
|
-
|
15452
|
+
/**
|
15453
|
+
Control-flow [operator](#highlight.tags.operator).
|
15454
|
+
*/
|
15417
15455
|
controlOperator: t(operator),
|
15418
|
-
|
15456
|
+
/**
|
15457
|
+
Program or markup punctuation.
|
15458
|
+
*/
|
15419
15459
|
punctuation,
|
15420
|
-
|
15421
|
-
|
15460
|
+
/**
|
15461
|
+
[Punctuation](#highlight.tags.punctuation) that separates
|
15462
|
+
things.
|
15463
|
+
*/
|
15422
15464
|
separator: t(punctuation),
|
15423
|
-
|
15465
|
+
/**
|
15466
|
+
Bracket-style [punctuation](#highlight.tags.punctuation).
|
15467
|
+
*/
|
15424
15468
|
bracket,
|
15425
|
-
|
15426
|
-
|
15469
|
+
/**
|
15470
|
+
Angle [brackets](#highlight.tags.bracket) (usually `<` and `>`
|
15471
|
+
tokens).
|
15472
|
+
*/
|
15427
15473
|
angleBracket: t(bracket),
|
15428
|
-
|
15429
|
-
|
15474
|
+
/**
|
15475
|
+
Square [brackets](#highlight.tags.bracket) (usually `[` and `]`
|
15476
|
+
tokens).
|
15477
|
+
*/
|
15430
15478
|
squareBracket: t(bracket),
|
15431
|
-
|
15432
|
-
|
15479
|
+
/**
|
15480
|
+
Parentheses (usually `(` and `)` tokens). Subtag of
|
15481
|
+
[bracket](#highlight.tags.bracket).
|
15482
|
+
*/
|
15433
15483
|
paren: t(bracket),
|
15434
|
-
|
15435
|
-
|
15484
|
+
/**
|
15485
|
+
Braces (usually `{` and `}` tokens). Subtag of
|
15486
|
+
[bracket](#highlight.tags.bracket).
|
15487
|
+
*/
|
15436
15488
|
brace: t(bracket),
|
15437
|
-
|
15489
|
+
/**
|
15490
|
+
Content, for example plain text in XML or markup documents.
|
15491
|
+
*/
|
15438
15492
|
content,
|
15439
|
-
|
15493
|
+
/**
|
15494
|
+
[Content](#highlight.tags.content) that represents a heading.
|
15495
|
+
*/
|
15440
15496
|
heading,
|
15441
|
-
|
15497
|
+
/**
|
15498
|
+
A level 1 [heading](#highlight.tags.heading).
|
15499
|
+
*/
|
15442
15500
|
heading1: t(heading),
|
15443
|
-
|
15501
|
+
/**
|
15502
|
+
A level 2 [heading](#highlight.tags.heading).
|
15503
|
+
*/
|
15444
15504
|
heading2: t(heading),
|
15445
|
-
|
15505
|
+
/**
|
15506
|
+
A level 3 [heading](#highlight.tags.heading).
|
15507
|
+
*/
|
15446
15508
|
heading3: t(heading),
|
15447
|
-
|
15509
|
+
/**
|
15510
|
+
A level 4 [heading](#highlight.tags.heading).
|
15511
|
+
*/
|
15448
15512
|
heading4: t(heading),
|
15449
|
-
|
15513
|
+
/**
|
15514
|
+
A level 5 [heading](#highlight.tags.heading).
|
15515
|
+
*/
|
15450
15516
|
heading5: t(heading),
|
15451
|
-
|
15517
|
+
/**
|
15518
|
+
A level 6 [heading](#highlight.tags.heading).
|
15519
|
+
*/
|
15452
15520
|
heading6: t(heading),
|
15453
|
-
|
15521
|
+
/**
|
15522
|
+
A prose separator (such as a horizontal rule).
|
15523
|
+
*/
|
15454
15524
|
contentSeparator: t(content),
|
15455
|
-
|
15525
|
+
/**
|
15526
|
+
[Content](#highlight.tags.content) that represents a list.
|
15527
|
+
*/
|
15456
15528
|
list: t(content),
|
15457
|
-
|
15529
|
+
/**
|
15530
|
+
[Content](#highlight.tags.content) that represents a quote.
|
15531
|
+
*/
|
15458
15532
|
quote: t(content),
|
15459
|
-
|
15533
|
+
/**
|
15534
|
+
[Content](#highlight.tags.content) that is emphasized.
|
15535
|
+
*/
|
15460
15536
|
emphasis: t(content),
|
15461
|
-
|
15537
|
+
/**
|
15538
|
+
[Content](#highlight.tags.content) that is styled strong.
|
15539
|
+
*/
|
15462
15540
|
strong: t(content),
|
15463
|
-
|
15541
|
+
/**
|
15542
|
+
[Content](#highlight.tags.content) that is part of a link.
|
15543
|
+
*/
|
15464
15544
|
link: t(content),
|
15465
|
-
|
15466
|
-
|
15545
|
+
/**
|
15546
|
+
[Content](#highlight.tags.content) that is styled as code or
|
15547
|
+
monospace.
|
15548
|
+
*/
|
15467
15549
|
monospace: t(content),
|
15468
|
-
|
15469
|
-
|
15550
|
+
/**
|
15551
|
+
[Content](#highlight.tags.content) that has a strike-through
|
15552
|
+
style.
|
15553
|
+
*/
|
15470
15554
|
strikethrough: t(content),
|
15471
|
-
|
15555
|
+
/**
|
15556
|
+
Inserted text in a change-tracking format.
|
15557
|
+
*/
|
15472
15558
|
inserted: t(),
|
15473
|
-
|
15559
|
+
/**
|
15560
|
+
Deleted text.
|
15561
|
+
*/
|
15474
15562
|
deleted: t(),
|
15475
|
-
|
15563
|
+
/**
|
15564
|
+
Changed text.
|
15565
|
+
*/
|
15476
15566
|
changed: t(),
|
15477
|
-
|
15567
|
+
/**
|
15568
|
+
An invalid or unsyntactic element.
|
15569
|
+
*/
|
15478
15570
|
invalid: t(),
|
15479
|
-
|
15571
|
+
/**
|
15572
|
+
Metadata or meta-instruction.
|
15573
|
+
*/
|
15480
15574
|
meta,
|
15481
|
-
|
15482
|
-
|
15575
|
+
/**
|
15576
|
+
[Metadata](#highlight.tags.meta) that applies to the entire
|
15577
|
+
document.
|
15578
|
+
*/
|
15483
15579
|
documentMeta: t(meta),
|
15484
|
-
|
15485
|
-
|
15580
|
+
/**
|
15581
|
+
[Metadata](#highlight.tags.meta) that annotates or adds
|
15582
|
+
attributes to a given syntactic element.
|
15583
|
+
*/
|
15486
15584
|
annotation: t(meta),
|
15487
|
-
|
15488
|
-
|
15585
|
+
/**
|
15586
|
+
Processing instruction or preprocessor directive. Subtag of
|
15587
|
+
[meta](#highlight.tags.meta).
|
15588
|
+
*/
|
15489
15589
|
processingInstruction: t(meta),
|
15490
|
-
|
15491
|
-
|
15492
|
-
|
15590
|
+
/**
|
15591
|
+
[Modifier](#highlight.Tag^defineModifier) that indicates that a
|
15592
|
+
given element is being defined. Expected to be used with the
|
15593
|
+
various [name](#highlight.tags.name) tags.
|
15594
|
+
*/
|
15493
15595
|
definition: Tag.defineModifier(),
|
15494
|
-
|
15495
|
-
|
15496
|
-
|
15596
|
+
/**
|
15597
|
+
[Modifier](#highlight.Tag^defineModifier) that indicates that
|
15598
|
+
something is constant. Mostly expected to be used with
|
15599
|
+
[variable names](#highlight.tags.variableName).
|
15600
|
+
*/
|
15497
15601
|
constant: Tag.defineModifier(),
|
15498
|
-
|
15499
|
-
|
15500
|
-
|
15501
|
-
|
15602
|
+
/**
|
15603
|
+
[Modifier](#highlight.Tag^defineModifier) used to indicate that
|
15604
|
+
a [variable](#highlight.tags.variableName) or [property
|
15605
|
+
name](#highlight.tags.propertyName) is being called or defined
|
15606
|
+
as a function.
|
15607
|
+
*/
|
15502
15608
|
function: Tag.defineModifier(),
|
15503
|
-
|
15504
|
-
|
15505
|
-
|
15609
|
+
/**
|
15610
|
+
[Modifier](#highlight.Tag^defineModifier) that can be applied to
|
15611
|
+
[names](#highlight.tags.name) to indicate that they belong to
|
15612
|
+
the language's standard environment.
|
15613
|
+
*/
|
15506
15614
|
standard: Tag.defineModifier(),
|
15507
|
-
|
15508
|
-
|
15615
|
+
/**
|
15616
|
+
[Modifier](#highlight.Tag^defineModifier) that indicates a given
|
15617
|
+
[names](#highlight.tags.name) is local to some scope.
|
15618
|
+
*/
|
15509
15619
|
local: Tag.defineModifier(),
|
15510
|
-
|
15511
|
-
|
15512
|
-
|
15513
|
-
|
15514
|
-
|
15515
|
-
|
15620
|
+
/**
|
15621
|
+
A generic variant [modifier](#highlight.Tag^defineModifier) that
|
15622
|
+
can be used to tag language-specific alternative variants of
|
15623
|
+
some common tag. It is recommended for themes to define special
|
15624
|
+
forms of at least the [string](#highlight.tags.string) and
|
15625
|
+
[variable name](#highlight.tags.variableName) tags, since those
|
15626
|
+
come up a lot.
|
15627
|
+
*/
|
15516
15628
|
special: Tag.defineModifier()
|
15517
15629
|
};
|
15518
|
-
|
15519
|
-
|
15520
|
-
|
15521
|
-
|
15522
|
-
|
15523
|
-
|
15524
|
-
|
15525
|
-
|
15526
|
-
|
15527
|
-
|
15528
|
-
|
15529
|
-
|
15530
|
-
|
15531
|
-
|
15532
|
-
|
15533
|
-
|
15534
|
-
|
15535
|
-
|
15536
|
-
|
15537
|
-
|
15538
|
-
|
15539
|
-
|
15540
|
-
|
15541
|
-
|
15542
|
-
|
15543
|
-
|
15544
|
-
|
15545
|
-
|
15546
|
-
|
15547
|
-
|
15548
|
-
|
15549
|
-
|
15550
|
-
|
15551
|
-
|
15552
|
-
|
15553
|
-
|
15554
|
-
|
15555
|
-
|
15556
|
-
|
15557
|
-
|
15558
|
-
|
15559
|
-
|
15560
|
-
|
15561
|
-
|
15562
|
-
|
15563
|
-
|
15630
|
+
/**
|
15631
|
+
This is a highlighter that adds stable, predictable classes to
|
15632
|
+
tokens, for styling with external CSS.
|
15633
|
+
|
15634
|
+
The following tags are mapped to their name prefixed with `"tok-"`
|
15635
|
+
(for example `"tok-comment"`):
|
15636
|
+
|
15637
|
+
* [`link`](#highlight.tags.link)
|
15638
|
+
* [`heading`](#highlight.tags.heading)
|
15639
|
+
* [`emphasis`](#highlight.tags.emphasis)
|
15640
|
+
* [`strong`](#highlight.tags.strong)
|
15641
|
+
* [`keyword`](#highlight.tags.keyword)
|
15642
|
+
* [`atom`](#highlight.tags.atom)
|
15643
|
+
* [`bool`](#highlight.tags.bool)
|
15644
|
+
* [`url`](#highlight.tags.url)
|
15645
|
+
* [`labelName`](#highlight.tags.labelName)
|
15646
|
+
* [`inserted`](#highlight.tags.inserted)
|
15647
|
+
* [`deleted`](#highlight.tags.deleted)
|
15648
|
+
* [`literal`](#highlight.tags.literal)
|
15649
|
+
* [`string`](#highlight.tags.string)
|
15650
|
+
* [`number`](#highlight.tags.number)
|
15651
|
+
* [`variableName`](#highlight.tags.variableName)
|
15652
|
+
* [`typeName`](#highlight.tags.typeName)
|
15653
|
+
* [`namespace`](#highlight.tags.namespace)
|
15654
|
+
* [`className`](#highlight.tags.className)
|
15655
|
+
* [`macroName`](#highlight.tags.macroName)
|
15656
|
+
* [`propertyName`](#highlight.tags.propertyName)
|
15657
|
+
* [`operator`](#highlight.tags.operator)
|
15658
|
+
* [`comment`](#highlight.tags.comment)
|
15659
|
+
* [`meta`](#highlight.tags.meta)
|
15660
|
+
* [`punctuation`](#highlight.tags.punctuation)
|
15661
|
+
* [`invalid`](#highlight.tags.invalid)
|
15662
|
+
|
15663
|
+
In addition, these mappings are provided:
|
15664
|
+
|
15665
|
+
* [`regexp`](#highlight.tags.regexp),
|
15666
|
+
[`escape`](#highlight.tags.escape), and
|
15667
|
+
[`special`](#highlight.tags.special)[`(string)`](#highlight.tags.string)
|
15668
|
+
are mapped to `"tok-string2"`
|
15669
|
+
* [`special`](#highlight.tags.special)[`(variableName)`](#highlight.tags.variableName)
|
15670
|
+
to `"tok-variableName2"`
|
15671
|
+
* [`local`](#highlight.tags.local)[`(variableName)`](#highlight.tags.variableName)
|
15672
|
+
to `"tok-variableName tok-local"`
|
15673
|
+
* [`definition`](#highlight.tags.definition)[`(variableName)`](#highlight.tags.variableName)
|
15674
|
+
to `"tok-variableName tok-definition"`
|
15675
|
+
* [`definition`](#highlight.tags.definition)[`(propertyName)`](#highlight.tags.propertyName)
|
15676
|
+
to `"tok-propertyName tok-definition"`
|
15677
|
+
*/
|
15564
15678
|
tagHighlighter([
|
15565
15679
|
{ tag: tags.link, class: "tok-link" },
|
15566
15680
|
{ tag: tags.heading, class: "tok-heading" },
|
@@ -15614,6 +15728,11 @@
|
|
15614
15728
|
});
|
15615
15729
|
}
|
15616
15730
|
/**
|
15731
|
+
Syntax node prop used to register sublangauges. Should be added to
|
15732
|
+
the top level node type for the language.
|
15733
|
+
*/
|
15734
|
+
const sublanguageProp = /*@__PURE__*/new NodeProp();
|
15735
|
+
/**
|
15617
15736
|
A language object manages parsing and per-language
|
15618
15737
|
[metadata](https://codemirror.net/6/docs/ref/#state.EditorState.languageDataAt). Parse data is
|
15619
15738
|
managed as a [Lezer](https://lezer.codemirror.net) tree. The class
|
@@ -15650,14 +15769,28 @@
|
|
15650
15769
|
this.parser = parser;
|
15651
15770
|
this.extension = [
|
15652
15771
|
language.of(this),
|
15653
|
-
EditorState.languageData.of((state, pos, side) =>
|
15772
|
+
EditorState.languageData.of((state, pos, side) => {
|
15773
|
+
let top = topNodeAt(state, pos, side), data = top.type.prop(languageDataProp);
|
15774
|
+
if (!data)
|
15775
|
+
return [];
|
15776
|
+
let base = state.facet(data), sub = top.type.prop(sublanguageProp);
|
15777
|
+
if (sub) {
|
15778
|
+
let innerNode = top.resolve(pos - top.from, side);
|
15779
|
+
for (let sublang of sub)
|
15780
|
+
if (sublang.test(innerNode, state)) {
|
15781
|
+
let data = state.facet(sublang.facet);
|
15782
|
+
return sublang.type == "replace" ? data : data.concat(base);
|
15783
|
+
}
|
15784
|
+
}
|
15785
|
+
return base;
|
15786
|
+
})
|
15654
15787
|
].concat(extraExtensions);
|
15655
15788
|
}
|
15656
15789
|
/**
|
15657
15790
|
Query whether this language is active at the given position.
|
15658
15791
|
*/
|
15659
15792
|
isActiveAt(state, pos, side = -1) {
|
15660
|
-
return
|
15793
|
+
return topNodeAt(state, pos, side).type.prop(languageDataProp) == this.data;
|
15661
15794
|
}
|
15662
15795
|
/**
|
15663
15796
|
Find the document regions that were parsed using this language.
|
@@ -15712,16 +15845,14 @@
|
|
15712
15845
|
@internal
|
15713
15846
|
*/
|
15714
15847
|
Language.setState = /*@__PURE__*/StateEffect.define();
|
15715
|
-
function
|
15716
|
-
let topLang = state.facet(language);
|
15717
|
-
if (!topLang)
|
15718
|
-
|
15719
|
-
|
15720
|
-
|
15721
|
-
for (let node = syntaxTree(state).topNode; node; node = node.enter(pos, side, IterMode.ExcludeBuffers))
|
15722
|
-
facet = node.type.prop(languageDataProp) || facet;
|
15848
|
+
function topNodeAt(state, pos, side) {
|
15849
|
+
let topLang = state.facet(language), tree = syntaxTree(state).topNode;
|
15850
|
+
if (!topLang || topLang.allowsNesting) {
|
15851
|
+
for (let node = tree; node; node = node.enter(pos, side, IterMode.ExcludeBuffers))
|
15852
|
+
if (node.type.isTop)
|
15853
|
+
tree = node;
|
15723
15854
|
}
|
15724
|
-
return
|
15855
|
+
return tree;
|
15725
15856
|
}
|
15726
15857
|
/**
|
15727
15858
|
A subclass of [`Language`](https://codemirror.net/6/docs/ref/#language.Language) for use with Lezer
|
@@ -15763,13 +15894,13 @@
|
|
15763
15894
|
}
|
15764
15895
|
// Lezer-style Input object for a Text document.
|
15765
15896
|
class DocInput {
|
15766
|
-
constructor(doc
|
15897
|
+
constructor(doc) {
|
15767
15898
|
this.doc = doc;
|
15768
|
-
this.length = length;
|
15769
15899
|
this.cursorPos = 0;
|
15770
15900
|
this.string = "";
|
15771
15901
|
this.cursor = doc.iter();
|
15772
15902
|
}
|
15903
|
+
get length() { return this.doc.length; }
|
15773
15904
|
syncTo(pos) {
|
15774
15905
|
this.string = this.cursor.next(pos - this.cursorPos).value;
|
15775
15906
|
this.cursorPos = pos + this.string.length;
|
@@ -16217,17 +16348,18 @@
|
|
16217
16348
|
*/
|
16218
16349
|
const indentService = /*@__PURE__*/Facet.define();
|
16219
16350
|
/**
|
16220
|
-
Facet for overriding the unit by which indentation happens.
|
16221
|
-
|
16222
|
-
|
16351
|
+
Facet for overriding the unit by which indentation happens. Should
|
16352
|
+
be a string consisting either entirely of the same whitespace
|
16353
|
+
character. When not set, this defaults to 2 spaces.
|
16223
16354
|
*/
|
16224
16355
|
const indentUnit = /*@__PURE__*/Facet.define({
|
16225
16356
|
combine: values => {
|
16226
16357
|
if (!values.length)
|
16227
16358
|
return " ";
|
16228
|
-
|
16359
|
+
let unit = values[0];
|
16360
|
+
if (!unit || /\S/.test(unit) || Array.from(unit).some(e => e != unit[0]))
|
16229
16361
|
throw new Error("Invalid indent unit: " + JSON.stringify(values[0]));
|
16230
|
-
return
|
16362
|
+
return unit;
|
16231
16363
|
}
|
16232
16364
|
});
|
16233
16365
|
/**
|
@@ -16247,14 +16379,16 @@
|
|
16247
16379
|
tabs.
|
16248
16380
|
*/
|
16249
16381
|
function indentString(state, cols) {
|
16250
|
-
let result = "", ts = state.tabSize;
|
16251
|
-
if (
|
16382
|
+
let result = "", ts = state.tabSize, ch = state.facet(indentUnit)[0];
|
16383
|
+
if (ch == "\t") {
|
16252
16384
|
while (cols >= ts) {
|
16253
16385
|
result += "\t";
|
16254
16386
|
cols -= ts;
|
16255
16387
|
}
|
16388
|
+
ch = " ";
|
16389
|
+
}
|
16256
16390
|
for (let i = 0; i < cols; i++)
|
16257
|
-
result +=
|
16391
|
+
result += ch;
|
16258
16392
|
return result;
|
16259
16393
|
}
|
16260
16394
|
/**
|
@@ -16802,7 +16936,7 @@
|
|
16802
16936
|
Create an extension that configures code folding.
|
16803
16937
|
*/
|
16804
16938
|
function codeFolding(config) {
|
16805
|
-
let result = [foldState, baseTheme$1$
|
16939
|
+
let result = [foldState, baseTheme$1$1];
|
16806
16940
|
if (config)
|
16807
16941
|
result.push(foldConfig.of(config));
|
16808
16942
|
return result;
|
@@ -16911,7 +17045,7 @@
|
|
16911
17045
|
codeFolding()
|
16912
17046
|
];
|
16913
17047
|
}
|
16914
|
-
const baseTheme$1$
|
17048
|
+
const baseTheme$1$1 = /*@__PURE__*/EditorView.baseTheme({
|
16915
17049
|
".cm-foldPlaceholder": {
|
16916
17050
|
backgroundColor: "#eee",
|
16917
17051
|
border: "1px solid #ddd",
|
@@ -17307,7 +17441,7 @@
|
|
17307
17441
|
if available, otherwise falling back to block comments.
|
17308
17442
|
*/
|
17309
17443
|
const toggleComment = target => {
|
17310
|
-
let config = getConfig(target.state);
|
17444
|
+
let { state } = target, line = state.doc.lineAt(state.selection.main.from), config = getConfig(target.state, line.from);
|
17311
17445
|
return config.line ? toggleLineComment(target) : config.block ? toggleBlockCommentByLine(target) : false;
|
17312
17446
|
};
|
17313
17447
|
function command(f, option) {
|
@@ -17340,7 +17474,7 @@
|
|
17340
17474
|
block comments.
|
17341
17475
|
*/
|
17342
17476
|
const toggleBlockCommentByLine = /*@__PURE__*/command((o, s) => changeBlockComment(o, s, selectedLineRanges(s)), 0 /* CommentOption.Toggle */);
|
17343
|
-
function getConfig(state, pos
|
17477
|
+
function getConfig(state, pos) {
|
17344
17478
|
let data = state.languageDataAt("commentTokens", pos);
|
17345
17479
|
return data.length ? data[0] : {};
|
17346
17480
|
}
|
@@ -17422,13 +17556,13 @@
|
|
17422
17556
|
let prevLine = -1;
|
17423
17557
|
for (let { from, to } of ranges) {
|
17424
17558
|
let startI = lines.length, minIndent = 1e9;
|
17559
|
+
let token = getConfig(state, from).line;
|
17560
|
+
if (!token)
|
17561
|
+
continue;
|
17425
17562
|
for (let pos = from; pos <= to;) {
|
17426
17563
|
let line = state.doc.lineAt(pos);
|
17427
17564
|
if (line.from > prevLine && (from == to || to > line.from)) {
|
17428
17565
|
prevLine = line.from;
|
17429
|
-
let token = getConfig(state, pos).line;
|
17430
|
-
if (!token)
|
17431
|
-
continue;
|
17432
17566
|
let indent = /^\s*/.exec(line.text)[0].length;
|
17433
17567
|
let empty = indent == line.length;
|
17434
17568
|
let comment = line.text.slice(indent, indent + token.length) == token ? indent : -1;
|
@@ -17910,21 +18044,41 @@
|
|
17910
18044
|
Move the selection one line down.
|
17911
18045
|
*/
|
17912
18046
|
const cursorLineDown = view => cursorByLine(view, true);
|
17913
|
-
function
|
17914
|
-
|
18047
|
+
function pageInfo(view) {
|
18048
|
+
let selfScroll = view.scrollDOM.clientHeight < view.scrollDOM.scrollHeight - 2;
|
18049
|
+
let marginTop = 0, marginBottom = 0, height;
|
18050
|
+
if (selfScroll) {
|
18051
|
+
for (let source of view.state.facet(EditorView.scrollMargins)) {
|
18052
|
+
let margins = source(view);
|
18053
|
+
if (margins === null || margins === void 0 ? void 0 : margins.top)
|
18054
|
+
marginTop = Math.max(margins === null || margins === void 0 ? void 0 : margins.top, marginTop);
|
18055
|
+
if (margins === null || margins === void 0 ? void 0 : margins.bottom)
|
18056
|
+
marginBottom = Math.max(margins === null || margins === void 0 ? void 0 : margins.bottom, marginBottom);
|
18057
|
+
}
|
18058
|
+
height = view.scrollDOM.clientHeight - marginTop - marginBottom;
|
18059
|
+
}
|
18060
|
+
else {
|
18061
|
+
height = (view.dom.ownerDocument.defaultView || window).innerHeight;
|
18062
|
+
}
|
18063
|
+
return { marginTop, marginBottom, selfScroll,
|
18064
|
+
height: Math.max(view.defaultLineHeight, height - 5) };
|
17915
18065
|
}
|
17916
18066
|
function cursorByPage(view, forward) {
|
18067
|
+
let page = pageInfo(view);
|
17917
18068
|
let { state } = view, selection = updateSel(state.selection, range => {
|
17918
|
-
return range.empty ? view.moveVertically(range, forward,
|
18069
|
+
return range.empty ? view.moveVertically(range, forward, page.height)
|
18070
|
+
: rangeEnd(range, forward);
|
17919
18071
|
});
|
17920
18072
|
if (selection.eq(state.selection))
|
17921
18073
|
return false;
|
17922
|
-
let startPos = view.coordsAtPos(state.selection.main.head);
|
17923
|
-
let scrollRect = view.scrollDOM.getBoundingClientRect();
|
17924
18074
|
let effect;
|
17925
|
-
if (
|
17926
|
-
startPos
|
17927
|
-
|
18075
|
+
if (page.selfScroll) {
|
18076
|
+
let startPos = view.coordsAtPos(state.selection.main.head);
|
18077
|
+
let scrollRect = view.scrollDOM.getBoundingClientRect();
|
18078
|
+
let scrollTop = scrollRect.top + page.marginTop, scrollBottom = scrollRect.bottom - page.marginBottom;
|
18079
|
+
if (startPos && startPos.top > scrollTop && startPos.bottom < scrollBottom)
|
18080
|
+
effect = EditorView.scrollIntoView(selection.main.head, { y: "start", yMargin: startPos.top - scrollTop });
|
18081
|
+
}
|
17928
18082
|
view.dispatch(setSel(state, selection), { effects: effect });
|
17929
18083
|
return true;
|
17930
18084
|
}
|
@@ -18051,7 +18205,7 @@
|
|
18051
18205
|
*/
|
18052
18206
|
const selectLineDown = view => selectByLine(view, true);
|
18053
18207
|
function selectByPage(view, forward) {
|
18054
|
-
return extendSel(view, range => view.moveVertically(range, forward,
|
18208
|
+
return extendSel(view, range => view.moveVertically(range, forward, pageInfo(view).height));
|
18055
18209
|
}
|
18056
18210
|
/**
|
18057
18211
|
Move the selection head one page up.
|
@@ -19072,16 +19226,13 @@
|
|
19072
19226
|
`-`, document percentages suffixed with `%`, and an optional
|
19073
19227
|
column position by adding `:` and a second number after the line
|
19074
19228
|
number.
|
19075
|
-
|
19076
|
-
The dialog can be styled with the `panel.gotoLine` theme
|
19077
|
-
selector.
|
19078
19229
|
*/
|
19079
19230
|
const gotoLine = view => {
|
19080
19231
|
let panel = getPanel(view, createLineDialog);
|
19081
19232
|
if (!panel) {
|
19082
19233
|
let effects = [dialogEffect.of(true)];
|
19083
19234
|
if (view.state.field(dialogField, false) == null)
|
19084
|
-
effects.push(StateEffect.appendConfig.of([dialogField, baseTheme$1
|
19235
|
+
effects.push(StateEffect.appendConfig.of([dialogField, baseTheme$1]));
|
19085
19236
|
view.dispatch({ effects });
|
19086
19237
|
panel = getPanel(view, createLineDialog);
|
19087
19238
|
}
|
@@ -19089,7 +19240,7 @@
|
|
19089
19240
|
panel.dom.querySelector("input").focus();
|
19090
19241
|
return true;
|
19091
19242
|
};
|
19092
|
-
const baseTheme$1
|
19243
|
+
const baseTheme$1 = /*@__PURE__*/EditorView.baseTheme({
|
19093
19244
|
".cm-panel.cm-gotoLine": {
|
19094
19245
|
padding: "2px 6px 4px",
|
19095
19246
|
"& label": { fontSize: "80%" }
|
@@ -19261,7 +19412,8 @@
|
|
19261
19412
|
caseSensitive: false,
|
19262
19413
|
literal: false,
|
19263
19414
|
wholeWord: false,
|
19264
|
-
createPanel: view => new SearchPanel(view)
|
19415
|
+
createPanel: view => new SearchPanel(view),
|
19416
|
+
scrollToMatch: range => EditorView.scrollIntoView(range)
|
19265
19417
|
});
|
19266
19418
|
}
|
19267
19419
|
});
|
@@ -19450,7 +19602,7 @@
|
|
19450
19602
|
once).
|
19451
19603
|
*/
|
19452
19604
|
const setSearchQuery = /*@__PURE__*/StateEffect.define();
|
19453
|
-
const togglePanel
|
19605
|
+
const togglePanel = /*@__PURE__*/StateEffect.define();
|
19454
19606
|
const searchState = /*@__PURE__*/StateField.define({
|
19455
19607
|
create(state) {
|
19456
19608
|
return new SearchState(defaultQuery(state).create(), null);
|
@@ -19459,7 +19611,7 @@
|
|
19459
19611
|
for (let effect of tr.effects) {
|
19460
19612
|
if (effect.is(setSearchQuery))
|
19461
19613
|
value = new SearchState(effect.value.create(), value.panel);
|
19462
|
-
else if (effect.is(togglePanel
|
19614
|
+
else if (effect.is(togglePanel))
|
19463
19615
|
value = new SearchState(value.query, effect.value ? createSearchPanel : null);
|
19464
19616
|
}
|
19465
19617
|
return value;
|
@@ -19519,10 +19671,11 @@
|
|
19519
19671
|
let next = query.nextMatch(view.state, to, to);
|
19520
19672
|
if (!next)
|
19521
19673
|
return false;
|
19674
|
+
let selection = EditorSelection.single(next.from, next.to);
|
19675
|
+
let config = view.state.facet(searchConfigFacet);
|
19522
19676
|
view.dispatch({
|
19523
|
-
selection
|
19524
|
-
|
19525
|
-
effects: announceMatch(view, next),
|
19677
|
+
selection,
|
19678
|
+
effects: [announceMatch(view, next), config.scrollToMatch(selection.main)],
|
19526
19679
|
userEvent: "select.search"
|
19527
19680
|
});
|
19528
19681
|
return true;
|
@@ -19534,13 +19687,14 @@
|
|
19534
19687
|
*/
|
19535
19688
|
const findPrevious = /*@__PURE__*/searchCommand((view, { query }) => {
|
19536
19689
|
let { state } = view, { from } = state.selection.main;
|
19537
|
-
let
|
19538
|
-
if (!
|
19690
|
+
let prev = query.prevMatch(state, from, from);
|
19691
|
+
if (!prev)
|
19539
19692
|
return false;
|
19693
|
+
let selection = EditorSelection.single(prev.from, prev.to);
|
19694
|
+
let config = view.state.facet(searchConfigFacet);
|
19540
19695
|
view.dispatch({
|
19541
|
-
selection
|
19542
|
-
|
19543
|
-
effects: announceMatch(view, range),
|
19696
|
+
selection,
|
19697
|
+
effects: [announceMatch(view, prev), config.scrollToMatch(selection.main)],
|
19544
19698
|
userEvent: "select.search"
|
19545
19699
|
});
|
19546
19700
|
return true;
|
@@ -19591,22 +19745,21 @@
|
|
19591
19745
|
if (!next)
|
19592
19746
|
return false;
|
19593
19747
|
let changes = [], selection, replacement;
|
19594
|
-
let
|
19748
|
+
let effects = [];
|
19595
19749
|
if (next.from == from && next.to == to) {
|
19596
19750
|
replacement = state.toText(query.getReplacement(next));
|
19597
19751
|
changes.push({ from: next.from, to: next.to, insert: replacement });
|
19598
19752
|
next = query.nextMatch(state, next.from, next.to);
|
19599
|
-
|
19753
|
+
effects.push(EditorView.announce.of(state.phrase("replaced match on line $", state.doc.lineAt(from).number) + "."));
|
19600
19754
|
}
|
19601
19755
|
if (next) {
|
19602
19756
|
let off = changes.length == 0 || changes[0].from >= next.to ? 0 : next.to - next.from - replacement.length;
|
19603
|
-
selection =
|
19604
|
-
|
19757
|
+
selection = EditorSelection.single(next.from - off, next.to - off);
|
19758
|
+
effects.push(announceMatch(view, next));
|
19759
|
+
effects.push(state.facet(searchConfigFacet).scrollToMatch(selection.main));
|
19605
19760
|
}
|
19606
19761
|
view.dispatch({
|
19607
|
-
changes, selection,
|
19608
|
-
scrollIntoView: !!selection,
|
19609
|
-
effects: announce,
|
19762
|
+
changes, selection, effects,
|
19610
19763
|
userEvent: "input.replace"
|
19611
19764
|
});
|
19612
19765
|
return true;
|
@@ -19669,7 +19822,7 @@
|
|
19669
19822
|
}
|
19670
19823
|
else {
|
19671
19824
|
view.dispatch({ effects: [
|
19672
|
-
togglePanel
|
19825
|
+
togglePanel.of(true),
|
19673
19826
|
state ? setSearchQuery.of(defaultQuery(view.state, state.query.spec)) : StateEffect.appendConfig.of(searchExtensions)
|
19674
19827
|
] });
|
19675
19828
|
}
|
@@ -19685,7 +19838,7 @@
|
|
19685
19838
|
let panel = getPanel(view, createSearchPanel);
|
19686
19839
|
if (panel && panel.dom.contains(view.root.activeElement))
|
19687
19840
|
view.focus();
|
19688
|
-
view.dispatch({ effects: togglePanel
|
19841
|
+
view.dispatch({ effects: togglePanel.of(false) });
|
19689
19842
|
return true;
|
19690
19843
|
};
|
19691
19844
|
/**
|
@@ -19990,9 +20143,12 @@
|
|
19990
20143
|
*/
|
19991
20144
|
function ifNotIn(nodes, source) {
|
19992
20145
|
return (context) => {
|
19993
|
-
for (let pos = syntaxTree(context.state).resolveInner(context.pos, -1); pos; pos = pos.parent)
|
20146
|
+
for (let pos = syntaxTree(context.state).resolveInner(context.pos, -1); pos; pos = pos.parent) {
|
19994
20147
|
if (nodes.indexOf(pos.name) > -1)
|
19995
20148
|
return null;
|
20149
|
+
if (pos.type.isTop)
|
20150
|
+
break;
|
20151
|
+
}
|
19996
20152
|
return source(context);
|
19997
20153
|
};
|
19998
20154
|
}
|
@@ -20097,13 +20253,18 @@
|
|
20097
20253
|
// For single-character queries, only match when they occur right
|
20098
20254
|
// at the start
|
20099
20255
|
if (chars.length == 1) {
|
20100
|
-
let first = codePointAt(word, 0);
|
20101
|
-
|
20102
|
-
|
20256
|
+
let first = codePointAt(word, 0), firstSize = codePointSize(first);
|
20257
|
+
let score = firstSize == word.length ? 0 : -100 /* Penalty.NotFull */;
|
20258
|
+
if (first == chars[0]) ;
|
20259
|
+
else if (first == folded[0])
|
20260
|
+
score += -200 /* Penalty.CaseFold */;
|
20261
|
+
else
|
20262
|
+
return null;
|
20263
|
+
return [score, 0, firstSize];
|
20103
20264
|
}
|
20104
20265
|
let direct = word.indexOf(this.pattern);
|
20105
20266
|
if (direct == 0)
|
20106
|
-
return [0
|
20267
|
+
return [word.length == this.pattern.length ? 0 : -100 /* Penalty.NotFull */, 0, this.pattern.length];
|
20107
20268
|
let len = chars.length, anyTo = 0;
|
20108
20269
|
if (direct < 0) {
|
20109
20270
|
for (let i = 0, e = Math.min(word.length, 200); i < e && anyTo < len;) {
|
@@ -20159,7 +20320,7 @@
|
|
20159
20320
|
if (byWordTo == len && byWord[0] == 0 && wordAdjacent)
|
20160
20321
|
return this.result(-100 /* Penalty.ByWord */ + (byWordFolded ? -200 /* Penalty.CaseFold */ : 0), byWord, word);
|
20161
20322
|
if (adjacentTo == len && adjacentStart == 0)
|
20162
|
-
return [-200 /* Penalty.CaseFold */ - word.length, 0, adjacentEnd];
|
20323
|
+
return [-200 /* Penalty.CaseFold */ - word.length + (adjacentEnd == word.length ? 0 : -100 /* Penalty.NotFull */), 0, adjacentEnd];
|
20163
20324
|
if (direct > -1)
|
20164
20325
|
return [-700 /* Penalty.NotStart */ - word.length, direct, direct + this.pattern.length];
|
20165
20326
|
if (adjacentTo == len)
|
@@ -20944,7 +21105,7 @@
|
|
20944
21105
|
}
|
20945
21106
|
});
|
20946
21107
|
|
20947
|
-
const baseTheme
|
21108
|
+
const baseTheme = /*@__PURE__*/EditorView.baseTheme({
|
20948
21109
|
".cm-tooltip.cm-tooltip-autocomplete": {
|
20949
21110
|
"& > ul": {
|
20950
21111
|
fontFamily: "monospace",
|
@@ -21320,7 +21481,7 @@
|
|
21320
21481
|
completionConfig.of(config),
|
21321
21482
|
completionPlugin,
|
21322
21483
|
completionKeymapExt,
|
21323
|
-
baseTheme
|
21484
|
+
baseTheme
|
21324
21485
|
];
|
21325
21486
|
}
|
21326
21487
|
/**
|
@@ -21345,560 +21506,6 @@
|
|
21345
21506
|
];
|
21346
21507
|
const completionKeymapExt = /*@__PURE__*/Prec.highest(/*@__PURE__*/keymap.computeN([completionConfig], state => state.facet(completionConfig).defaultKeymap ? [completionKeymap] : []));
|
21347
21508
|
|
21348
|
-
class SelectedDiagnostic {
|
21349
|
-
constructor(from, to, diagnostic) {
|
21350
|
-
this.from = from;
|
21351
|
-
this.to = to;
|
21352
|
-
this.diagnostic = diagnostic;
|
21353
|
-
}
|
21354
|
-
}
|
21355
|
-
class LintState {
|
21356
|
-
constructor(diagnostics, panel, selected) {
|
21357
|
-
this.diagnostics = diagnostics;
|
21358
|
-
this.panel = panel;
|
21359
|
-
this.selected = selected;
|
21360
|
-
}
|
21361
|
-
static init(diagnostics, panel, state) {
|
21362
|
-
// Filter the list of diagnostics for which to create markers
|
21363
|
-
let markedDiagnostics = diagnostics;
|
21364
|
-
let diagnosticFilter = state.facet(lintConfig).markerFilter;
|
21365
|
-
if (diagnosticFilter)
|
21366
|
-
markedDiagnostics = diagnosticFilter(markedDiagnostics);
|
21367
|
-
let ranges = Decoration.set(markedDiagnostics.map((d) => {
|
21368
|
-
// For zero-length ranges or ranges covering only a line break, create a widget
|
21369
|
-
return d.from == d.to || (d.from == d.to - 1 && state.doc.lineAt(d.from).to == d.from)
|
21370
|
-
? Decoration.widget({
|
21371
|
-
widget: new DiagnosticWidget(d),
|
21372
|
-
diagnostic: d
|
21373
|
-
}).range(d.from)
|
21374
|
-
: Decoration.mark({
|
21375
|
-
attributes: { class: "cm-lintRange cm-lintRange-" + d.severity },
|
21376
|
-
diagnostic: d
|
21377
|
-
}).range(d.from, d.to);
|
21378
|
-
}), true);
|
21379
|
-
return new LintState(ranges, panel, findDiagnostic(ranges));
|
21380
|
-
}
|
21381
|
-
}
|
21382
|
-
function findDiagnostic(diagnostics, diagnostic = null, after = 0) {
|
21383
|
-
let found = null;
|
21384
|
-
diagnostics.between(after, 1e9, (from, to, { spec }) => {
|
21385
|
-
if (diagnostic && spec.diagnostic != diagnostic)
|
21386
|
-
return;
|
21387
|
-
found = new SelectedDiagnostic(from, to, spec.diagnostic);
|
21388
|
-
return false;
|
21389
|
-
});
|
21390
|
-
return found;
|
21391
|
-
}
|
21392
|
-
function hideTooltip(tr, tooltip) {
|
21393
|
-
return !!(tr.effects.some(e => e.is(setDiagnosticsEffect)) || tr.changes.touchesRange(tooltip.pos));
|
21394
|
-
}
|
21395
|
-
function maybeEnableLint(state, effects) {
|
21396
|
-
return state.field(lintState, false) ? effects : effects.concat(StateEffect.appendConfig.of([
|
21397
|
-
lintState,
|
21398
|
-
EditorView.decorations.compute([lintState], state => {
|
21399
|
-
let { selected, panel } = state.field(lintState);
|
21400
|
-
return !selected || !panel || selected.from == selected.to ? Decoration.none : Decoration.set([
|
21401
|
-
activeMark.range(selected.from, selected.to)
|
21402
|
-
]);
|
21403
|
-
}),
|
21404
|
-
hoverTooltip(lintTooltip, { hideOn: hideTooltip }),
|
21405
|
-
baseTheme
|
21406
|
-
]));
|
21407
|
-
}
|
21408
|
-
/**
|
21409
|
-
Returns a transaction spec which updates the current set of
|
21410
|
-
diagnostics, and enables the lint extension if if wasn't already
|
21411
|
-
active.
|
21412
|
-
*/
|
21413
|
-
function setDiagnostics(state, diagnostics) {
|
21414
|
-
return {
|
21415
|
-
effects: maybeEnableLint(state, [setDiagnosticsEffect.of(diagnostics)])
|
21416
|
-
};
|
21417
|
-
}
|
21418
|
-
/**
|
21419
|
-
The state effect that updates the set of active diagnostics. Can
|
21420
|
-
be useful when writing an extension that needs to track these.
|
21421
|
-
*/
|
21422
|
-
const setDiagnosticsEffect = /*@__PURE__*/StateEffect.define();
|
21423
|
-
const togglePanel = /*@__PURE__*/StateEffect.define();
|
21424
|
-
const movePanelSelection = /*@__PURE__*/StateEffect.define();
|
21425
|
-
const lintState = /*@__PURE__*/StateField.define({
|
21426
|
-
create() {
|
21427
|
-
return new LintState(Decoration.none, null, null);
|
21428
|
-
},
|
21429
|
-
update(value, tr) {
|
21430
|
-
if (tr.docChanged) {
|
21431
|
-
let mapped = value.diagnostics.map(tr.changes), selected = null;
|
21432
|
-
if (value.selected) {
|
21433
|
-
let selPos = tr.changes.mapPos(value.selected.from, 1);
|
21434
|
-
selected = findDiagnostic(mapped, value.selected.diagnostic, selPos) || findDiagnostic(mapped, null, selPos);
|
21435
|
-
}
|
21436
|
-
value = new LintState(mapped, value.panel, selected);
|
21437
|
-
}
|
21438
|
-
for (let effect of tr.effects) {
|
21439
|
-
if (effect.is(setDiagnosticsEffect)) {
|
21440
|
-
value = LintState.init(effect.value, value.panel, tr.state);
|
21441
|
-
}
|
21442
|
-
else if (effect.is(togglePanel)) {
|
21443
|
-
value = new LintState(value.diagnostics, effect.value ? LintPanel.open : null, value.selected);
|
21444
|
-
}
|
21445
|
-
else if (effect.is(movePanelSelection)) {
|
21446
|
-
value = new LintState(value.diagnostics, value.panel, effect.value);
|
21447
|
-
}
|
21448
|
-
}
|
21449
|
-
return value;
|
21450
|
-
},
|
21451
|
-
provide: f => [showPanel.from(f, val => val.panel),
|
21452
|
-
EditorView.decorations.from(f, s => s.diagnostics)]
|
21453
|
-
});
|
21454
|
-
const activeMark = /*@__PURE__*/Decoration.mark({ class: "cm-lintRange cm-lintRange-active" });
|
21455
|
-
function lintTooltip(view, pos, side) {
|
21456
|
-
let { diagnostics } = view.state.field(lintState);
|
21457
|
-
let found = [], stackStart = 2e8, stackEnd = 0;
|
21458
|
-
diagnostics.between(pos - (side < 0 ? 1 : 0), pos + (side > 0 ? 1 : 0), (from, to, { spec }) => {
|
21459
|
-
if (pos >= from && pos <= to &&
|
21460
|
-
(from == to || ((pos > from || side > 0) && (pos < to || side < 0)))) {
|
21461
|
-
found.push(spec.diagnostic);
|
21462
|
-
stackStart = Math.min(from, stackStart);
|
21463
|
-
stackEnd = Math.max(to, stackEnd);
|
21464
|
-
}
|
21465
|
-
});
|
21466
|
-
let diagnosticFilter = view.state.facet(lintConfig).tooltipFilter;
|
21467
|
-
if (diagnosticFilter)
|
21468
|
-
found = diagnosticFilter(found);
|
21469
|
-
if (!found.length)
|
21470
|
-
return null;
|
21471
|
-
return {
|
21472
|
-
pos: stackStart,
|
21473
|
-
end: stackEnd,
|
21474
|
-
above: view.state.doc.lineAt(stackStart).to < stackEnd,
|
21475
|
-
create() {
|
21476
|
-
return { dom: diagnosticsTooltip(view, found) };
|
21477
|
-
}
|
21478
|
-
};
|
21479
|
-
}
|
21480
|
-
function diagnosticsTooltip(view, diagnostics) {
|
21481
|
-
return crelt("ul", { class: "cm-tooltip-lint" }, diagnostics.map(d => renderDiagnostic(view, d, false)));
|
21482
|
-
}
|
21483
|
-
/**
|
21484
|
-
Command to open and focus the lint panel.
|
21485
|
-
*/
|
21486
|
-
const openLintPanel = (view) => {
|
21487
|
-
let field = view.state.field(lintState, false);
|
21488
|
-
if (!field || !field.panel)
|
21489
|
-
view.dispatch({ effects: maybeEnableLint(view.state, [togglePanel.of(true)]) });
|
21490
|
-
let panel = getPanel(view, LintPanel.open);
|
21491
|
-
if (panel)
|
21492
|
-
panel.dom.querySelector(".cm-panel-lint ul").focus();
|
21493
|
-
return true;
|
21494
|
-
};
|
21495
|
-
/**
|
21496
|
-
Command to close the lint panel, when open.
|
21497
|
-
*/
|
21498
|
-
const closeLintPanel = (view) => {
|
21499
|
-
let field = view.state.field(lintState, false);
|
21500
|
-
if (!field || !field.panel)
|
21501
|
-
return false;
|
21502
|
-
view.dispatch({ effects: togglePanel.of(false) });
|
21503
|
-
return true;
|
21504
|
-
};
|
21505
|
-
/**
|
21506
|
-
Move the selection to the next diagnostic.
|
21507
|
-
*/
|
21508
|
-
const nextDiagnostic = (view) => {
|
21509
|
-
let field = view.state.field(lintState, false);
|
21510
|
-
if (!field)
|
21511
|
-
return false;
|
21512
|
-
let sel = view.state.selection.main, next = field.diagnostics.iter(sel.to + 1);
|
21513
|
-
if (!next.value) {
|
21514
|
-
next = field.diagnostics.iter(0);
|
21515
|
-
if (!next.value || next.from == sel.from && next.to == sel.to)
|
21516
|
-
return false;
|
21517
|
-
}
|
21518
|
-
view.dispatch({ selection: { anchor: next.from, head: next.to }, scrollIntoView: true });
|
21519
|
-
return true;
|
21520
|
-
};
|
21521
|
-
/**
|
21522
|
-
A set of default key bindings for the lint functionality.
|
21523
|
-
|
21524
|
-
- Ctrl-Shift-m (Cmd-Shift-m on macOS): [`openLintPanel`](https://codemirror.net/6/docs/ref/#lint.openLintPanel)
|
21525
|
-
- F8: [`nextDiagnostic`](https://codemirror.net/6/docs/ref/#lint.nextDiagnostic)
|
21526
|
-
*/
|
21527
|
-
const lintKeymap = [
|
21528
|
-
{ key: "Mod-Shift-m", run: openLintPanel, preventDefault: true },
|
21529
|
-
{ key: "F8", run: nextDiagnostic }
|
21530
|
-
];
|
21531
|
-
const lintPlugin = /*@__PURE__*/ViewPlugin.fromClass(class {
|
21532
|
-
constructor(view) {
|
21533
|
-
this.view = view;
|
21534
|
-
this.timeout = -1;
|
21535
|
-
this.set = true;
|
21536
|
-
let { delay } = view.state.facet(lintConfig);
|
21537
|
-
this.lintTime = Date.now() + delay;
|
21538
|
-
this.run = this.run.bind(this);
|
21539
|
-
this.timeout = setTimeout(this.run, delay);
|
21540
|
-
}
|
21541
|
-
run() {
|
21542
|
-
let now = Date.now();
|
21543
|
-
if (now < this.lintTime - 10) {
|
21544
|
-
setTimeout(this.run, this.lintTime - now);
|
21545
|
-
}
|
21546
|
-
else {
|
21547
|
-
this.set = false;
|
21548
|
-
let { state } = this.view, { sources } = state.facet(lintConfig);
|
21549
|
-
Promise.all(sources.map(source => Promise.resolve(source(this.view)))).then(annotations => {
|
21550
|
-
let all = annotations.reduce((a, b) => a.concat(b));
|
21551
|
-
if (this.view.state.doc == state.doc)
|
21552
|
-
this.view.dispatch(setDiagnostics(this.view.state, all));
|
21553
|
-
}, error => { logException(this.view.state, error); });
|
21554
|
-
}
|
21555
|
-
}
|
21556
|
-
update(update) {
|
21557
|
-
let config = update.state.facet(lintConfig);
|
21558
|
-
if (update.docChanged || config != update.startState.facet(lintConfig)) {
|
21559
|
-
this.lintTime = Date.now() + config.delay;
|
21560
|
-
if (!this.set) {
|
21561
|
-
this.set = true;
|
21562
|
-
this.timeout = setTimeout(this.run, config.delay);
|
21563
|
-
}
|
21564
|
-
}
|
21565
|
-
}
|
21566
|
-
force() {
|
21567
|
-
if (this.set) {
|
21568
|
-
this.lintTime = Date.now();
|
21569
|
-
this.run();
|
21570
|
-
}
|
21571
|
-
}
|
21572
|
-
destroy() {
|
21573
|
-
clearTimeout(this.timeout);
|
21574
|
-
}
|
21575
|
-
});
|
21576
|
-
const lintConfig = /*@__PURE__*/Facet.define({
|
21577
|
-
combine(input) {
|
21578
|
-
return Object.assign({ sources: input.map(i => i.source) }, combineConfig(input.map(i => i.config), {
|
21579
|
-
delay: 750,
|
21580
|
-
markerFilter: null,
|
21581
|
-
tooltipFilter: null
|
21582
|
-
}));
|
21583
|
-
},
|
21584
|
-
enables: lintPlugin
|
21585
|
-
});
|
21586
|
-
function assignKeys(actions) {
|
21587
|
-
let assigned = [];
|
21588
|
-
if (actions)
|
21589
|
-
actions: for (let { name } of actions) {
|
21590
|
-
for (let i = 0; i < name.length; i++) {
|
21591
|
-
let ch = name[i];
|
21592
|
-
if (/[a-zA-Z]/.test(ch) && !assigned.some(c => c.toLowerCase() == ch.toLowerCase())) {
|
21593
|
-
assigned.push(ch);
|
21594
|
-
continue actions;
|
21595
|
-
}
|
21596
|
-
}
|
21597
|
-
assigned.push("");
|
21598
|
-
}
|
21599
|
-
return assigned;
|
21600
|
-
}
|
21601
|
-
function renderDiagnostic(view, diagnostic, inPanel) {
|
21602
|
-
var _a;
|
21603
|
-
let keys = inPanel ? assignKeys(diagnostic.actions) : [];
|
21604
|
-
return crelt("li", { class: "cm-diagnostic cm-diagnostic-" + diagnostic.severity }, crelt("span", { class: "cm-diagnosticText" }, diagnostic.renderMessage ? diagnostic.renderMessage() : diagnostic.message), (_a = diagnostic.actions) === null || _a === void 0 ? void 0 : _a.map((action, i) => {
|
21605
|
-
let click = (e) => {
|
21606
|
-
e.preventDefault();
|
21607
|
-
let found = findDiagnostic(view.state.field(lintState).diagnostics, diagnostic);
|
21608
|
-
if (found)
|
21609
|
-
action.apply(view, found.from, found.to);
|
21610
|
-
};
|
21611
|
-
let { name } = action, keyIndex = keys[i] ? name.indexOf(keys[i]) : -1;
|
21612
|
-
let nameElt = keyIndex < 0 ? name : [name.slice(0, keyIndex),
|
21613
|
-
crelt("u", name.slice(keyIndex, keyIndex + 1)),
|
21614
|
-
name.slice(keyIndex + 1)];
|
21615
|
-
return crelt("button", {
|
21616
|
-
type: "button",
|
21617
|
-
class: "cm-diagnosticAction",
|
21618
|
-
onclick: click,
|
21619
|
-
onmousedown: click,
|
21620
|
-
"aria-label": ` Action: ${name}${keyIndex < 0 ? "" : ` (access key "${keys[i]})"`}.`
|
21621
|
-
}, nameElt);
|
21622
|
-
}), diagnostic.source && crelt("div", { class: "cm-diagnosticSource" }, diagnostic.source));
|
21623
|
-
}
|
21624
|
-
class DiagnosticWidget extends WidgetType {
|
21625
|
-
constructor(diagnostic) {
|
21626
|
-
super();
|
21627
|
-
this.diagnostic = diagnostic;
|
21628
|
-
}
|
21629
|
-
eq(other) { return other.diagnostic == this.diagnostic; }
|
21630
|
-
toDOM() {
|
21631
|
-
return crelt("span", { class: "cm-lintPoint cm-lintPoint-" + this.diagnostic.severity });
|
21632
|
-
}
|
21633
|
-
}
|
21634
|
-
class PanelItem {
|
21635
|
-
constructor(view, diagnostic) {
|
21636
|
-
this.diagnostic = diagnostic;
|
21637
|
-
this.id = "item_" + Math.floor(Math.random() * 0xffffffff).toString(16);
|
21638
|
-
this.dom = renderDiagnostic(view, diagnostic, true);
|
21639
|
-
this.dom.id = this.id;
|
21640
|
-
this.dom.setAttribute("role", "option");
|
21641
|
-
}
|
21642
|
-
}
|
21643
|
-
class LintPanel {
|
21644
|
-
constructor(view) {
|
21645
|
-
this.view = view;
|
21646
|
-
this.items = [];
|
21647
|
-
let onkeydown = (event) => {
|
21648
|
-
if (event.keyCode == 27) { // Escape
|
21649
|
-
closeLintPanel(this.view);
|
21650
|
-
this.view.focus();
|
21651
|
-
}
|
21652
|
-
else if (event.keyCode == 38 || event.keyCode == 33) { // ArrowUp, PageUp
|
21653
|
-
this.moveSelection((this.selectedIndex - 1 + this.items.length) % this.items.length);
|
21654
|
-
}
|
21655
|
-
else if (event.keyCode == 40 || event.keyCode == 34) { // ArrowDown, PageDown
|
21656
|
-
this.moveSelection((this.selectedIndex + 1) % this.items.length);
|
21657
|
-
}
|
21658
|
-
else if (event.keyCode == 36) { // Home
|
21659
|
-
this.moveSelection(0);
|
21660
|
-
}
|
21661
|
-
else if (event.keyCode == 35) { // End
|
21662
|
-
this.moveSelection(this.items.length - 1);
|
21663
|
-
}
|
21664
|
-
else if (event.keyCode == 13) { // Enter
|
21665
|
-
this.view.focus();
|
21666
|
-
}
|
21667
|
-
else if (event.keyCode >= 65 && event.keyCode <= 90 && this.selectedIndex >= 0) { // A-Z
|
21668
|
-
let { diagnostic } = this.items[this.selectedIndex], keys = assignKeys(diagnostic.actions);
|
21669
|
-
for (let i = 0; i < keys.length; i++)
|
21670
|
-
if (keys[i].toUpperCase().charCodeAt(0) == event.keyCode) {
|
21671
|
-
let found = findDiagnostic(this.view.state.field(lintState).diagnostics, diagnostic);
|
21672
|
-
if (found)
|
21673
|
-
diagnostic.actions[i].apply(view, found.from, found.to);
|
21674
|
-
}
|
21675
|
-
}
|
21676
|
-
else {
|
21677
|
-
return;
|
21678
|
-
}
|
21679
|
-
event.preventDefault();
|
21680
|
-
};
|
21681
|
-
let onclick = (event) => {
|
21682
|
-
for (let i = 0; i < this.items.length; i++) {
|
21683
|
-
if (this.items[i].dom.contains(event.target))
|
21684
|
-
this.moveSelection(i);
|
21685
|
-
}
|
21686
|
-
};
|
21687
|
-
this.list = crelt("ul", {
|
21688
|
-
tabIndex: 0,
|
21689
|
-
role: "listbox",
|
21690
|
-
"aria-label": this.view.state.phrase("Diagnostics"),
|
21691
|
-
onkeydown,
|
21692
|
-
onclick
|
21693
|
-
});
|
21694
|
-
this.dom = crelt("div", { class: "cm-panel-lint" }, this.list, crelt("button", {
|
21695
|
-
type: "button",
|
21696
|
-
name: "close",
|
21697
|
-
"aria-label": this.view.state.phrase("close"),
|
21698
|
-
onclick: () => closeLintPanel(this.view)
|
21699
|
-
}, "×"));
|
21700
|
-
this.update();
|
21701
|
-
}
|
21702
|
-
get selectedIndex() {
|
21703
|
-
let selected = this.view.state.field(lintState).selected;
|
21704
|
-
if (!selected)
|
21705
|
-
return -1;
|
21706
|
-
for (let i = 0; i < this.items.length; i++)
|
21707
|
-
if (this.items[i].diagnostic == selected.diagnostic)
|
21708
|
-
return i;
|
21709
|
-
return -1;
|
21710
|
-
}
|
21711
|
-
update() {
|
21712
|
-
let { diagnostics, selected } = this.view.state.field(lintState);
|
21713
|
-
let i = 0, needsSync = false, newSelectedItem = null;
|
21714
|
-
diagnostics.between(0, this.view.state.doc.length, (_start, _end, { spec }) => {
|
21715
|
-
let found = -1, item;
|
21716
|
-
for (let j = i; j < this.items.length; j++)
|
21717
|
-
if (this.items[j].diagnostic == spec.diagnostic) {
|
21718
|
-
found = j;
|
21719
|
-
break;
|
21720
|
-
}
|
21721
|
-
if (found < 0) {
|
21722
|
-
item = new PanelItem(this.view, spec.diagnostic);
|
21723
|
-
this.items.splice(i, 0, item);
|
21724
|
-
needsSync = true;
|
21725
|
-
}
|
21726
|
-
else {
|
21727
|
-
item = this.items[found];
|
21728
|
-
if (found > i) {
|
21729
|
-
this.items.splice(i, found - i);
|
21730
|
-
needsSync = true;
|
21731
|
-
}
|
21732
|
-
}
|
21733
|
-
if (selected && item.diagnostic == selected.diagnostic) {
|
21734
|
-
if (!item.dom.hasAttribute("aria-selected")) {
|
21735
|
-
item.dom.setAttribute("aria-selected", "true");
|
21736
|
-
newSelectedItem = item;
|
21737
|
-
}
|
21738
|
-
}
|
21739
|
-
else if (item.dom.hasAttribute("aria-selected")) {
|
21740
|
-
item.dom.removeAttribute("aria-selected");
|
21741
|
-
}
|
21742
|
-
i++;
|
21743
|
-
});
|
21744
|
-
while (i < this.items.length && !(this.items.length == 1 && this.items[0].diagnostic.from < 0)) {
|
21745
|
-
needsSync = true;
|
21746
|
-
this.items.pop();
|
21747
|
-
}
|
21748
|
-
if (this.items.length == 0) {
|
21749
|
-
this.items.push(new PanelItem(this.view, {
|
21750
|
-
from: -1, to: -1,
|
21751
|
-
severity: "info",
|
21752
|
-
message: this.view.state.phrase("No diagnostics")
|
21753
|
-
}));
|
21754
|
-
needsSync = true;
|
21755
|
-
}
|
21756
|
-
if (newSelectedItem) {
|
21757
|
-
this.list.setAttribute("aria-activedescendant", newSelectedItem.id);
|
21758
|
-
this.view.requestMeasure({
|
21759
|
-
key: this,
|
21760
|
-
read: () => ({ sel: newSelectedItem.dom.getBoundingClientRect(), panel: this.list.getBoundingClientRect() }),
|
21761
|
-
write: ({ sel, panel }) => {
|
21762
|
-
if (sel.top < panel.top)
|
21763
|
-
this.list.scrollTop -= panel.top - sel.top;
|
21764
|
-
else if (sel.bottom > panel.bottom)
|
21765
|
-
this.list.scrollTop += sel.bottom - panel.bottom;
|
21766
|
-
}
|
21767
|
-
});
|
21768
|
-
}
|
21769
|
-
else if (this.selectedIndex < 0) {
|
21770
|
-
this.list.removeAttribute("aria-activedescendant");
|
21771
|
-
}
|
21772
|
-
if (needsSync)
|
21773
|
-
this.sync();
|
21774
|
-
}
|
21775
|
-
sync() {
|
21776
|
-
let domPos = this.list.firstChild;
|
21777
|
-
function rm() {
|
21778
|
-
let prev = domPos;
|
21779
|
-
domPos = prev.nextSibling;
|
21780
|
-
prev.remove();
|
21781
|
-
}
|
21782
|
-
for (let item of this.items) {
|
21783
|
-
if (item.dom.parentNode == this.list) {
|
21784
|
-
while (domPos != item.dom)
|
21785
|
-
rm();
|
21786
|
-
domPos = item.dom.nextSibling;
|
21787
|
-
}
|
21788
|
-
else {
|
21789
|
-
this.list.insertBefore(item.dom, domPos);
|
21790
|
-
}
|
21791
|
-
}
|
21792
|
-
while (domPos)
|
21793
|
-
rm();
|
21794
|
-
}
|
21795
|
-
moveSelection(selectedIndex) {
|
21796
|
-
if (this.selectedIndex < 0)
|
21797
|
-
return;
|
21798
|
-
let field = this.view.state.field(lintState);
|
21799
|
-
let selection = findDiagnostic(field.diagnostics, this.items[selectedIndex].diagnostic);
|
21800
|
-
if (!selection)
|
21801
|
-
return;
|
21802
|
-
this.view.dispatch({
|
21803
|
-
selection: { anchor: selection.from, head: selection.to },
|
21804
|
-
scrollIntoView: true,
|
21805
|
-
effects: movePanelSelection.of(selection)
|
21806
|
-
});
|
21807
|
-
}
|
21808
|
-
static open(view) { return new LintPanel(view); }
|
21809
|
-
}
|
21810
|
-
function svg(content, attrs = `viewBox="0 0 40 40"`) {
|
21811
|
-
return `url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" ${attrs}>${encodeURIComponent(content)}</svg>')`;
|
21812
|
-
}
|
21813
|
-
function underline(color) {
|
21814
|
-
return svg(`<path d="m0 2.5 l2 -1.5 l1 0 l2 1.5 l1 0" stroke="${color}" fill="none" stroke-width=".7"/>`, `width="6" height="3"`);
|
21815
|
-
}
|
21816
|
-
const baseTheme = /*@__PURE__*/EditorView.baseTheme({
|
21817
|
-
".cm-diagnostic": {
|
21818
|
-
padding: "3px 6px 3px 8px",
|
21819
|
-
marginLeft: "-1px",
|
21820
|
-
display: "block",
|
21821
|
-
whiteSpace: "pre-wrap"
|
21822
|
-
},
|
21823
|
-
".cm-diagnostic-error": { borderLeft: "5px solid #d11" },
|
21824
|
-
".cm-diagnostic-warning": { borderLeft: "5px solid orange" },
|
21825
|
-
".cm-diagnostic-info": { borderLeft: "5px solid #999" },
|
21826
|
-
".cm-diagnosticAction": {
|
21827
|
-
font: "inherit",
|
21828
|
-
border: "none",
|
21829
|
-
padding: "2px 4px",
|
21830
|
-
backgroundColor: "#444",
|
21831
|
-
color: "white",
|
21832
|
-
borderRadius: "3px",
|
21833
|
-
marginLeft: "8px"
|
21834
|
-
},
|
21835
|
-
".cm-diagnosticSource": {
|
21836
|
-
fontSize: "70%",
|
21837
|
-
opacity: .7
|
21838
|
-
},
|
21839
|
-
".cm-lintRange": {
|
21840
|
-
backgroundPosition: "left bottom",
|
21841
|
-
backgroundRepeat: "repeat-x",
|
21842
|
-
paddingBottom: "0.7px",
|
21843
|
-
},
|
21844
|
-
".cm-lintRange-error": { backgroundImage: /*@__PURE__*/underline("#d11") },
|
21845
|
-
".cm-lintRange-warning": { backgroundImage: /*@__PURE__*/underline("orange") },
|
21846
|
-
".cm-lintRange-info": { backgroundImage: /*@__PURE__*/underline("#999") },
|
21847
|
-
".cm-lintRange-active": { backgroundColor: "#ffdd9980" },
|
21848
|
-
".cm-tooltip-lint": {
|
21849
|
-
padding: 0,
|
21850
|
-
margin: 0
|
21851
|
-
},
|
21852
|
-
".cm-lintPoint": {
|
21853
|
-
position: "relative",
|
21854
|
-
"&:after": {
|
21855
|
-
content: '""',
|
21856
|
-
position: "absolute",
|
21857
|
-
bottom: 0,
|
21858
|
-
left: "-2px",
|
21859
|
-
borderLeft: "3px solid transparent",
|
21860
|
-
borderRight: "3px solid transparent",
|
21861
|
-
borderBottom: "4px solid #d11"
|
21862
|
-
}
|
21863
|
-
},
|
21864
|
-
".cm-lintPoint-warning": {
|
21865
|
-
"&:after": { borderBottomColor: "orange" }
|
21866
|
-
},
|
21867
|
-
".cm-lintPoint-info": {
|
21868
|
-
"&:after": { borderBottomColor: "#999" }
|
21869
|
-
},
|
21870
|
-
".cm-panel.cm-panel-lint": {
|
21871
|
-
position: "relative",
|
21872
|
-
"& ul": {
|
21873
|
-
maxHeight: "100px",
|
21874
|
-
overflowY: "auto",
|
21875
|
-
"& [aria-selected]": {
|
21876
|
-
backgroundColor: "#ddd",
|
21877
|
-
"& u": { textDecoration: "underline" }
|
21878
|
-
},
|
21879
|
-
"&:focus [aria-selected]": {
|
21880
|
-
background_fallback: "#bdf",
|
21881
|
-
backgroundColor: "Highlight",
|
21882
|
-
color_fallback: "white",
|
21883
|
-
color: "HighlightText"
|
21884
|
-
},
|
21885
|
-
"& u": { textDecoration: "none" },
|
21886
|
-
padding: 0,
|
21887
|
-
margin: 0
|
21888
|
-
},
|
21889
|
-
"& [name=close]": {
|
21890
|
-
position: "absolute",
|
21891
|
-
top: "0",
|
21892
|
-
right: "2px",
|
21893
|
-
background: "inherit",
|
21894
|
-
border: "none",
|
21895
|
-
font: "inherit",
|
21896
|
-
padding: 0,
|
21897
|
-
margin: 0
|
21898
|
-
}
|
21899
|
-
}
|
21900
|
-
});
|
21901
|
-
|
21902
21509
|
function base64Encode (str) {
|
21903
21510
|
// https://stackoverflow.com/questions/30106476/using-javascripts-atob-to-decode-base64-doesnt-properly-decode-utf-8-strings
|
21904
21511
|
return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g,
|
@@ -24275,8 +23882,7 @@
|
|
24275
23882
|
...searchKeymap,
|
24276
23883
|
...historyKeymap,
|
24277
23884
|
...foldKeymap,
|
24278
|
-
...completionKeymap
|
24279
|
-
...lintKeymap
|
23885
|
+
...completionKeymap
|
24280
23886
|
]);
|
24281
23887
|
const sqlConfig = {
|
24282
23888
|
dialect: MySQL,
|
@@ -24535,6 +24141,7 @@
|
|
24535
24141
|
this.headerRenderer = headerRenderer;
|
24536
24142
|
this.cellRenderer = cellRenderer;
|
24537
24143
|
|
24144
|
+
this.classList.add('resize-table');
|
24538
24145
|
this.style.tableLayout = 'auto';
|
24539
24146
|
this.style.width = '100%';
|
24540
24147
|
|
@@ -24806,12 +24413,19 @@
|
|
24806
24413
|
closeElement.focus();
|
24807
24414
|
}
|
24808
24415
|
|
24416
|
+
function closePopup () {
|
24417
|
+
const wrapperElement = document.getElementById('popup-wrapper');
|
24418
|
+
if (wrapperElement) {
|
24419
|
+
document.body.removeChild(wrapperElement);
|
24420
|
+
return true
|
24421
|
+
}
|
24422
|
+
return false
|
24423
|
+
}
|
24424
|
+
|
24809
24425
|
document.addEventListener('keydown', (event) => {
|
24810
24426
|
if (event.code === 'Escape') {
|
24811
|
-
|
24812
|
-
if (wrapperElement) {
|
24427
|
+
if (closePopup()) {
|
24813
24428
|
event.preventDefault();
|
24814
|
-
document.body.removeChild(wrapperElement);
|
24815
24429
|
}
|
24816
24430
|
} else if (event.code === 'Tab') {
|
24817
24431
|
const wrapperElement = document.getElementById('popup-wrapper');
|
@@ -24870,9 +24484,10 @@
|
|
24870
24484
|
|
24871
24485
|
function init (parent, onSubmit, onShiftSubmit) {
|
24872
24486
|
addEventListener('#query-tab-button', 'click', (event) => selectTab(event, 'query'));
|
24487
|
+
addEventListener('#graph-tab-button', 'click', (event) => selectTab(event, 'graph'));
|
24873
24488
|
addEventListener('#saved-tab-button', 'click', (event) => selectTab(event, 'saved'));
|
24874
24489
|
addEventListener('#structure-tab-button', 'click', (event) => selectTab(event, 'structure'));
|
24875
|
-
addEventListener('#
|
24490
|
+
addEventListener('#help-tab-button', 'click', (event) => selectTab(event, 'help'));
|
24876
24491
|
addEventListener('#cancel-button', 'click', () => clearResult());
|
24877
24492
|
|
24878
24493
|
addEventListener('#query-box', 'click', () => {
|
@@ -25023,14 +24638,24 @@
|
|
25023
24638
|
|
25024
24639
|
function focus (selection = null) {
|
25025
24640
|
window.editorView.focus();
|
25026
|
-
if (selection)
|
24641
|
+
if (selection) {
|
24642
|
+
setSelection(selection);
|
24643
|
+
}
|
25027
24644
|
}
|
25028
24645
|
|
25029
|
-
function
|
24646
|
+
function getEditorValue () {
|
25030
24647
|
return window.editorView.state.doc.toString()
|
25031
24648
|
}
|
25032
24649
|
|
25033
|
-
function
|
24650
|
+
function isLastEditorValueSet (value) {
|
24651
|
+
return window.lastEditorValueSet === value
|
24652
|
+
}
|
24653
|
+
|
24654
|
+
function setEditorValue (value) {
|
24655
|
+
window.lastEditorValueSet = value;
|
24656
|
+
if (getEditorValue() === value) {
|
24657
|
+
return
|
24658
|
+
}
|
25034
24659
|
window.editorView.dispatch({
|
25035
24660
|
changes: {
|
25036
24661
|
from: 0,
|
@@ -25046,7 +24671,7 @@
|
|
25046
24671
|
|
25047
24672
|
function getTabFromUrl (url) {
|
25048
24673
|
const match = url.pathname.match(/\/([^/]+)$/);
|
25049
|
-
if (match && ['query', 'graph', 'structure', '
|
24674
|
+
if (match && ['query', 'graph', 'saved', 'structure', 'help'].includes(match[1])) {
|
25050
24675
|
return match[1]
|
25051
24676
|
} else {
|
25052
24677
|
throw new Error(`invalid tab: ${url.pathname}`)
|
@@ -25055,14 +24680,16 @@
|
|
25055
24680
|
|
25056
24681
|
function updateTabs () {
|
25057
24682
|
const url = new URL(window.location);
|
24683
|
+
setActionInUrl(url, 'query');
|
24684
|
+
document.getElementById('query-tab-button').href = url.pathname + url.search;
|
25058
24685
|
setActionInUrl(url, 'graph');
|
25059
24686
|
document.getElementById('graph-tab-button').href = url.pathname + url.search;
|
25060
24687
|
setActionInUrl(url, 'saved');
|
25061
24688
|
document.getElementById('saved-tab-button').href = url.pathname + url.search;
|
25062
24689
|
setActionInUrl(url, 'structure');
|
25063
24690
|
document.getElementById('structure-tab-button').href = url.pathname + url.search;
|
25064
|
-
setActionInUrl(url, '
|
25065
|
-
document.getElementById('
|
24691
|
+
setActionInUrl(url, 'help');
|
24692
|
+
document.getElementById('help-tab-button').href = url.pathname + url.search;
|
25066
24693
|
}
|
25067
24694
|
|
25068
24695
|
function selectTab (event, tab) {
|
@@ -25072,6 +24699,8 @@
|
|
25072
24699
|
}
|
25073
24700
|
|
25074
24701
|
function route (target = null, event = null, url = null, internal = false) {
|
24702
|
+
closePopup();
|
24703
|
+
|
25075
24704
|
if (url) {
|
25076
24705
|
if (event) {
|
25077
24706
|
event.preventDefault();
|
@@ -25111,7 +24740,7 @@
|
|
25111
24740
|
|
25112
24741
|
switch (window.tab) {
|
25113
24742
|
case 'query':
|
25114
|
-
|
24743
|
+
selectQueryTab(internal);
|
25115
24744
|
break
|
25116
24745
|
case 'graph':
|
25117
24746
|
selectGraphTab(internal);
|
@@ -25122,6 +24751,9 @@
|
|
25122
24751
|
case 'structure':
|
25123
24752
|
selectStructureTab();
|
25124
24753
|
break
|
24754
|
+
case 'help':
|
24755
|
+
selectHelpTab();
|
24756
|
+
break
|
25125
24757
|
default:
|
25126
24758
|
throw new Error(`Unexpected tab: ${window.tab}`)
|
25127
24759
|
}
|
@@ -25149,42 +24781,53 @@
|
|
25149
24781
|
selected.style.display = 'flex';
|
25150
24782
|
});
|
25151
24783
|
|
24784
|
+
const schemaNames = Object.keys(window.metadata.schemas);
|
24785
|
+
const schemasElement = document.getElementById('schemas');
|
24786
|
+
const tablesElement = document.getElementById('tables');
|
24787
|
+
if (schemaNames.length === 1) {
|
24788
|
+
setTimeout(() => { tablesElement.focus(); }, 0);
|
24789
|
+
} else {
|
24790
|
+
setTimeout(() => { schemasElement.focus(); }, 0);
|
24791
|
+
}
|
24792
|
+
|
25152
24793
|
if (window.structureLoaded) {
|
25153
24794
|
return
|
25154
24795
|
}
|
25155
24796
|
|
25156
|
-
const schemasElement = document.getElementById('schemas');
|
25157
|
-
const tablesElement = document.getElementById('tables');
|
25158
24797
|
const statsElement = document.getElementById('stats');
|
25159
24798
|
statsElement.innerHTML = statsHtml(null);
|
25160
24799
|
|
25161
24800
|
const columnsElement = document.getElementById('columns');
|
25162
24801
|
const indexesElement = document.getElementById('indexes');
|
25163
24802
|
|
25164
|
-
const schemaNames = Object.keys(window.metadata.schemas);
|
25165
24803
|
if (schemaNames.length === 1) {
|
25166
24804
|
schemasElement.style.display = 'none';
|
25167
24805
|
// TODO: duplicate code
|
25168
|
-
while (tablesElement.firstChild) {
|
25169
|
-
tablesElement.removeChild(tablesElement.firstChild);
|
25170
|
-
}
|
25171
24806
|
const schemaName = schemaNames[0];
|
25172
24807
|
const schema = window.metadata.schemas[schemaName];
|
25173
24808
|
const tableNames = Object.keys(schema.tables);
|
24809
|
+
|
25174
24810
|
tableNames.forEach(function (tableName) {
|
25175
24811
|
const optionElement = document.createElement('option');
|
25176
24812
|
optionElement.value = tableName;
|
25177
24813
|
optionElement.innerText = tableName;
|
25178
24814
|
tablesElement.appendChild(optionElement);
|
25179
24815
|
});
|
24816
|
+
if (tableNames.length > 0) {
|
24817
|
+
tablesElement.value = tableNames[0];
|
24818
|
+
}
|
25180
24819
|
} else {
|
25181
24820
|
schemasElement.style.display = 'flex';
|
24821
|
+
|
25182
24822
|
schemaNames.forEach(function (schemaName) {
|
25183
24823
|
const optionElement = document.createElement('option');
|
25184
24824
|
optionElement.value = schemaName;
|
25185
24825
|
optionElement.innerText = schemaName;
|
25186
24826
|
schemasElement.appendChild(optionElement);
|
25187
24827
|
});
|
24828
|
+
if (schemaNames.length > 0) {
|
24829
|
+
schemasElement.value = schemaNames[0];
|
24830
|
+
}
|
25188
24831
|
schemasElement.addEventListener('change', function () {
|
25189
24832
|
while (statsElement.firstChild) {
|
25190
24833
|
statsElement.removeChild(statsElement.firstChild);
|
@@ -25202,12 +24845,16 @@
|
|
25202
24845
|
const schemaName = schemasElement.value;
|
25203
24846
|
const schema = window.metadata.schemas[schemaName];
|
25204
24847
|
const tableNames = Object.keys(schema.tables);
|
24848
|
+
|
25205
24849
|
tableNames.forEach(function (tableName) {
|
25206
24850
|
const optionElement = document.createElement('option');
|
25207
24851
|
optionElement.value = tableName;
|
25208
24852
|
optionElement.innerText = tableName;
|
25209
24853
|
tablesElement.appendChild(optionElement);
|
25210
24854
|
});
|
24855
|
+
if (tableNames.length > 0) {
|
24856
|
+
tablesElement.value = tableNames[0];
|
24857
|
+
}
|
25211
24858
|
});
|
25212
24859
|
}
|
25213
24860
|
tablesElement.addEventListener('change', function () {
|
@@ -25269,6 +24916,20 @@
|
|
25269
24916
|
}
|
25270
24917
|
});
|
25271
24918
|
window.structureLoaded = true;
|
24919
|
+
|
24920
|
+
if (schemaNames.length === 1) {
|
24921
|
+
setTimeout(() => { tablesElement.focus(); }, 0);
|
24922
|
+
} else {
|
24923
|
+
setTimeout(() => { schemasElement.focus(); }, 0);
|
24924
|
+
}
|
24925
|
+
|
24926
|
+
tablesElement.dispatchEvent(new Event('change'));
|
24927
|
+
}
|
24928
|
+
|
24929
|
+
function selectHelpTab () {
|
24930
|
+
const helpBoxElement = document.getElementById('help-box');
|
24931
|
+
helpBoxElement.style.display = 'block';
|
24932
|
+
setTimeout(() => { helpBoxElement.focus(); }, 0);
|
25272
24933
|
}
|
25273
24934
|
|
25274
24935
|
function selectGraphTab (internal) {
|
@@ -25278,12 +24939,11 @@
|
|
25278
24939
|
document.getElementById('fetch-sql-box').style.display = 'none';
|
25279
24940
|
document.getElementById('cancel-button').style.visibility = 'hidden';
|
25280
24941
|
updateDownloadButtons(window?.sqlFetch);
|
25281
|
-
maybeFetchResult(internal);
|
25282
|
-
|
25283
24942
|
focus(getSelection());
|
24943
|
+
maybeFetchResult(internal);
|
25284
24944
|
}
|
25285
24945
|
|
25286
|
-
function
|
24946
|
+
function selectQueryTab (internal) {
|
25287
24947
|
document.getElementById('query-box').style.display = 'flex';
|
25288
24948
|
document.getElementById('submit-box').style.display = 'flex';
|
25289
24949
|
document.getElementById('result-box').style.display = 'flex';
|
@@ -25299,6 +24959,8 @@
|
|
25299
24959
|
});
|
25300
24960
|
|
25301
24961
|
const savedElement = document.getElementById('saved-box');
|
24962
|
+
setTimeout(() => { savedElement.focus(); }, 0);
|
24963
|
+
|
25302
24964
|
const saved = window.metadata.saved;
|
25303
24965
|
const numFiles = Object.keys(saved).length;
|
25304
24966
|
setStatus(`${numFiles} file${numFiles === 1 ? '' : 's'}`);
|
@@ -25332,7 +24994,6 @@
|
|
25332
24994
|
runLinkElement.href = runUrl.pathname + runUrl.search;
|
25333
24995
|
addEventListener(runLinkElement, 'click', (event) => {
|
25334
24996
|
clearResult();
|
25335
|
-
route(event.target, event, viewUrl, true);
|
25336
24997
|
route(event.target, event, runUrl, true);
|
25337
24998
|
});
|
25338
24999
|
|
@@ -25375,15 +25036,18 @@
|
|
25375
25036
|
if (!target || !event) {
|
25376
25037
|
throw new Error('you must specify target and event')
|
25377
25038
|
}
|
25378
|
-
|
25039
|
+
|
25040
|
+
window.lastSetSelectionValueFromUrlParam = null;
|
25041
|
+
window.lastEditorValueSet = null;
|
25042
|
+
|
25379
25043
|
const url = new URL(window.location);
|
25380
|
-
let sql =
|
25044
|
+
let sql = getEditorValue().trim();
|
25381
25045
|
sql = sql === '' ? null : sql;
|
25382
25046
|
|
25383
25047
|
url.searchParams.set('run', 'true');
|
25384
25048
|
|
25385
25049
|
if (url.searchParams.has('file')) {
|
25386
|
-
if (window.metadata.saved[url.searchParams.get('file')].contents !==
|
25050
|
+
if (window.metadata.saved[url.searchParams.get('file')].contents !== getEditorValue()) {
|
25387
25051
|
url.searchParams.delete('file');
|
25388
25052
|
url.searchParams.set('sql', sql);
|
25389
25053
|
}
|
@@ -25563,18 +25227,36 @@
|
|
25563
25227
|
const hasSqluiReferrer = document.referrer && new URL(document.referrer).origin === url.origin;
|
25564
25228
|
const variables = parseSqlVariables(params);
|
25565
25229
|
|
25230
|
+
if (params.has('file') && params.has('sql')) {
|
25231
|
+
// TODO: show an error.
|
25232
|
+
throw new Error('You can only specify a file or sql, not both.')
|
25233
|
+
}
|
25234
|
+
|
25566
25235
|
// Only allow auto-run if coming from another SQLUI page. The idea here is to let the app link to URLs with run=true
|
25567
25236
|
// but not other apps. This allows meta/shift-clicking to run a query.
|
25568
|
-
let run = false;
|
25569
25237
|
if (params.has('run')) {
|
25570
|
-
run = (internal || hasSqluiReferrer) && ['1', 'true'].includes(params.get('run')?.toLowerCase());
|
25571
25238
|
url.searchParams.delete('run');
|
25572
25239
|
window.history.replaceState({}, '', url);
|
25573
|
-
|
25240
|
+
clearResult();
|
25574
25241
|
|
25575
|
-
|
25576
|
-
|
25577
|
-
|
25242
|
+
if (!internal && !hasSqluiReferrer) {
|
25243
|
+
throw new Error('run only allowed for internal usage')
|
25244
|
+
}
|
25245
|
+
|
25246
|
+
if (params.has('sql') || params.has('file')) {
|
25247
|
+
const sqlFetch = buildSqlFetch(sql, file, variables, selection);
|
25248
|
+
setEditorValue(sqlFetch.sql);
|
25249
|
+
if (params.has('selection')) {
|
25250
|
+
window.lastSetSelectionValueFromUrlParam = selection;
|
25251
|
+
focus(selection);
|
25252
|
+
} else {
|
25253
|
+
window.lastSetSelectionValueFromUrlParam = null;
|
25254
|
+
}
|
25255
|
+
fetchSql(sqlFetch);
|
25256
|
+
return
|
25257
|
+
} else {
|
25258
|
+
throw new Error('run param specified without sql or file')
|
25259
|
+
}
|
25578
25260
|
}
|
25579
25261
|
|
25580
25262
|
const existingRequest = window.sqlFetch;
|
@@ -25586,7 +25268,7 @@
|
|
25586
25268
|
const queryMatches = sqlMatches || fileMatches;
|
25587
25269
|
if (selectionMatches && queryMatches && variablesMatch) {
|
25588
25270
|
displaySqlFetch(existingRequest);
|
25589
|
-
if (params.has('selection')) {
|
25271
|
+
if (params.has('selection') && window.lastSetSelectionValueFromUrlParam !== selection) {
|
25590
25272
|
focus(selection);
|
25591
25273
|
}
|
25592
25274
|
return
|
@@ -25596,13 +25278,12 @@
|
|
25596
25278
|
clearResult();
|
25597
25279
|
|
25598
25280
|
const sqlFetch = buildSqlFetch(sql, file, variables, selection);
|
25599
|
-
if (params.has('sql') || params.has('file')) {
|
25600
|
-
|
25601
|
-
if (run) {
|
25602
|
-
fetchSql(sqlFetch);
|
25603
|
-
}
|
25281
|
+
if ((params.has('sql') || params.has('file')) && !isLastEditorValueSet(sqlFetch.sql)) {
|
25282
|
+
setEditorValue(sqlFetch.sql);
|
25604
25283
|
}
|
25605
|
-
|
25284
|
+
|
25285
|
+
if (params.has('selection') && window.lastSetSelectionValueFromUrlParam !== selection) {
|
25286
|
+
window.lastSetSelectionValueFromUrlParam = selection;
|
25606
25287
|
focus(selection);
|
25607
25288
|
}
|
25608
25289
|
}
|
@@ -25784,7 +25465,7 @@
|
|
25784
25465
|
const row = parseInt(node.dataset.row);
|
25785
25466
|
const column = parseInt(node.dataset.column);
|
25786
25467
|
const title = window.sqlFetch.result.columns[column].replaceAll('\n', '¶');
|
25787
|
-
if (event.metaKey) {
|
25468
|
+
if (event.metaKey || event.ctrlKey) {
|
25788
25469
|
createPopup(title, window.sqlFetch.result.rows[row][column]);
|
25789
25470
|
} else if (event.altKey) {
|
25790
25471
|
copyTextToClipboard(window.sqlFetch.result.rows[row][column]);
|
@@ -26009,8 +25690,38 @@
|
|
26009
25690
|
});
|
26010
25691
|
|
26011
25692
|
document.addEventListener('keydown', (event) => {
|
25693
|
+
if (event.code === 'ControlLeft' || event.code === 'ControlRight') {
|
25694
|
+
Array.prototype.forEach.call(document.getElementsByClassName('keyboard-shortcut-indicator'), function (selected) {
|
25695
|
+
selected.style.visibility = 'visible';
|
25696
|
+
});
|
25697
|
+
}
|
25698
|
+
|
26012
25699
|
if (event.code === 'Escape') {
|
26013
25700
|
focus();
|
25701
|
+
return
|
25702
|
+
}
|
25703
|
+
|
25704
|
+
const isMac = navigator.userAgent.includes('Mac');
|
25705
|
+
if (isMac && event.code === 'Digit0' && event.ctrlKey) {
|
25706
|
+
document.getElementById('header-link').click();
|
25707
|
+
} else if (isMac && event.code === 'Digit1' && event.ctrlKey) {
|
25708
|
+
selectTab(event, 'query');
|
25709
|
+
} else if (isMac && event.code === 'Digit2' && event.ctrlKey) {
|
25710
|
+
selectTab(event, 'graph');
|
25711
|
+
} else if (isMac && event.code === 'Digit3' && event.ctrlKey) {
|
25712
|
+
selectTab(event, 'saved');
|
25713
|
+
} else if (isMac && event.code === 'Digit4' && event.ctrlKey) {
|
25714
|
+
selectTab(event, 'structure');
|
25715
|
+
} else if (isMac && event.code === 'Digit5' && event.ctrlKey) {
|
25716
|
+
selectTab(event, 'help');
|
25717
|
+
}
|
25718
|
+
});
|
25719
|
+
|
25720
|
+
document.addEventListener('keyup', (event) => {
|
25721
|
+
if ((event.code === 'ControlLeft' || event.code === 'ControlRight') && !event.ctrlKey) {
|
25722
|
+
Array.prototype.forEach.call(document.getElementsByClassName('keyboard-shortcut-indicator'), function (selected) {
|
25723
|
+
selected.style.visibility = 'hidden';
|
25724
|
+
});
|
26014
25725
|
}
|
26015
25726
|
});
|
26016
25727
|
|