sqlui 0.1.66 → 0.1.68
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/database_metadata.rb +78 -1
- data/app/server.rb +1 -1
- data/app/sql_parser.rb +3 -3
- data/app/views/databases.erb +22 -30
- data/app/views/sqlui.erb +83 -4
- data/client/resources/help.css +30 -0
- data/client/resources/sqlui.css +86 -58
- data/client/resources/sqlui.js +938 -508
- 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
|
});
|
@@ -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();
|
@@ -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) {
|
@@ -14943,45 +15064,59 @@
|
|
14943
15064
|
new NodeProp({ perNode: true });
|
14944
15065
|
|
14945
15066
|
let nextTagID = 0;
|
14946
|
-
|
14947
|
-
|
14948
|
-
|
14949
|
-
|
14950
|
-
|
14951
|
-
|
14952
|
-
|
14953
|
-
|
14954
|
-
|
14955
|
-
|
14956
|
-
|
14957
|
-
|
14958
|
-
|
14959
|
-
|
14960
|
-
|
14961
|
-
|
14962
|
-
|
15067
|
+
/**
|
15068
|
+
Highlighting tags are markers that denote a highlighting category.
|
15069
|
+
They are [associated](#highlight.styleTags) with parts of a syntax
|
15070
|
+
tree by a language mode, and then mapped to an actual CSS style by
|
15071
|
+
a [highlighter](#highlight.Highlighter).
|
15072
|
+
|
15073
|
+
Because syntax tree node types and highlight styles have to be
|
15074
|
+
able to talk the same language, CodeMirror uses a mostly _closed_
|
15075
|
+
[vocabulary](#highlight.tags) of syntax tags (as opposed to
|
15076
|
+
traditional open string-based systems, which make it hard for
|
15077
|
+
highlighting themes to cover all the tokens produced by the
|
15078
|
+
various languages).
|
15079
|
+
|
15080
|
+
It _is_ possible to [define](#highlight.Tag^define) your own
|
15081
|
+
highlighting tags for system-internal use (where you control both
|
15082
|
+
the language package and the highlighter), but such tags will not
|
15083
|
+
be picked up by regular highlighters (though you can derive them
|
15084
|
+
from standard tags to allow highlighters to fall back to those).
|
15085
|
+
*/
|
14963
15086
|
class Tag {
|
14964
|
-
|
15087
|
+
/**
|
15088
|
+
@internal
|
15089
|
+
*/
|
14965
15090
|
constructor(
|
14966
|
-
|
14967
|
-
|
15091
|
+
/**
|
15092
|
+
The set of this tag and all its parent tags, starting with
|
15093
|
+
this one itself and sorted in order of decreasing specificity.
|
15094
|
+
*/
|
14968
15095
|
set,
|
14969
|
-
|
14970
|
-
|
15096
|
+
/**
|
15097
|
+
The base unmodified tag that this one is based on, if it's
|
15098
|
+
modified @internal
|
15099
|
+
*/
|
14971
15100
|
base,
|
14972
|
-
|
15101
|
+
/**
|
15102
|
+
The modifiers applied to this.base @internal
|
15103
|
+
*/
|
14973
15104
|
modified) {
|
14974
15105
|
this.set = set;
|
14975
15106
|
this.base = base;
|
14976
15107
|
this.modified = modified;
|
14977
|
-
|
15108
|
+
/**
|
15109
|
+
@internal
|
15110
|
+
*/
|
14978
15111
|
this.id = nextTagID++;
|
14979
15112
|
}
|
14980
|
-
|
14981
|
-
|
14982
|
-
|
14983
|
-
|
14984
|
-
|
15113
|
+
/**
|
15114
|
+
Define a new tag. If `parent` is given, the tag is treated as a
|
15115
|
+
sub-tag of that parent, and
|
15116
|
+
[highlighters](#highlight.tagHighlighter) that don't mention
|
15117
|
+
this tag will try to fall back to the parent tag (or grandparent
|
15118
|
+
tag, etc).
|
15119
|
+
*/
|
14985
15120
|
static define(parent) {
|
14986
15121
|
if (parent === null || parent === void 0 ? void 0 : parent.base)
|
14987
15122
|
throw new Error("Can not derive from a modified tag");
|
@@ -14992,16 +15127,18 @@
|
|
14992
15127
|
tag.set.push(t);
|
14993
15128
|
return tag;
|
14994
15129
|
}
|
14995
|
-
|
14996
|
-
|
14997
|
-
|
14998
|
-
|
14999
|
-
|
15000
|
-
|
15001
|
-
|
15002
|
-
|
15003
|
-
|
15004
|
-
|
15130
|
+
/**
|
15131
|
+
Define a tag _modifier_, which is a function that, given a tag,
|
15132
|
+
will return a tag that is a subtag of the original. Applying the
|
15133
|
+
same modifier to a twice tag will return the same value (`m1(t1)
|
15134
|
+
== m1(t1)`) and applying multiple modifiers will, regardless or
|
15135
|
+
order, produce the same tag (`m1(m2(t1)) == m2(m1(t1))`).
|
15136
|
+
|
15137
|
+
When multiple modifiers are applied to a given base tag, each
|
15138
|
+
smaller set of modifiers is registered as a parent, so that for
|
15139
|
+
example `m1(m2(m3(t1)))` is a subtype of `m1(m2(t1))`,
|
15140
|
+
`m1(m3(t1)`, and so on.
|
15141
|
+
*/
|
15005
15142
|
static defineModifier() {
|
15006
15143
|
let mod = new Modifier;
|
15007
15144
|
return (tag) => {
|
@@ -15046,55 +15183,57 @@
|
|
15046
15183
|
}
|
15047
15184
|
return sets.sort((a, b) => b.length - a.length);
|
15048
15185
|
}
|
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
|
-
|
15186
|
+
/**
|
15187
|
+
This function is used to add a set of tags to a language syntax
|
15188
|
+
via [`NodeSet.extend`](#common.NodeSet.extend) or
|
15189
|
+
[`LRParser.configure`](#lr.LRParser.configure).
|
15190
|
+
|
15191
|
+
The argument object maps node selectors to [highlighting
|
15192
|
+
tags](#highlight.Tag) or arrays of tags.
|
15193
|
+
|
15194
|
+
Node selectors may hold one or more (space-separated) node paths.
|
15195
|
+
Such a path can be a [node name](#common.NodeType.name), or
|
15196
|
+
multiple node names (or `*` wildcards) separated by slash
|
15197
|
+
characters, as in `"Block/Declaration/VariableName"`. Such a path
|
15198
|
+
matches the final node but only if its direct parent nodes are the
|
15199
|
+
other nodes mentioned. A `*` in such a path matches any parent,
|
15200
|
+
but only a single level—wildcards that match multiple parents
|
15201
|
+
aren't supported, both for efficiency reasons and because Lezer
|
15202
|
+
trees make it rather hard to reason about what they would match.)
|
15203
|
+
|
15204
|
+
A path can be ended with `/...` to indicate that the tag assigned
|
15205
|
+
to the node should also apply to all child nodes, even if they
|
15206
|
+
match their own style (by default, only the innermost style is
|
15207
|
+
used).
|
15208
|
+
|
15209
|
+
When a path ends in `!`, as in `Attribute!`, no further matching
|
15210
|
+
happens for the node's child nodes, and the entire node gets the
|
15211
|
+
given style.
|
15212
|
+
|
15213
|
+
In this notation, node names that contain `/`, `!`, `*`, or `...`
|
15214
|
+
must be quoted as JSON strings.
|
15215
|
+
|
15216
|
+
For example:
|
15217
|
+
|
15218
|
+
```javascript
|
15219
|
+
parser.withProps(
|
15220
|
+
styleTags({
|
15221
|
+
// Style Number and BigNumber nodes
|
15222
|
+
"Number BigNumber": tags.number,
|
15223
|
+
// Style Escape nodes whose parent is String
|
15224
|
+
"String/Escape": tags.escape,
|
15225
|
+
// Style anything inside Attributes nodes
|
15226
|
+
"Attributes!": tags.meta,
|
15227
|
+
// Add a style to all content inside Italic nodes
|
15228
|
+
"Italic/...": tags.emphasis,
|
15229
|
+
// Style InvalidString nodes as both `string` and `invalid`
|
15230
|
+
"InvalidString": [tags.string, tags.invalid],
|
15231
|
+
// Style the node named "/" as punctuation
|
15232
|
+
'"/"': tags.punctuation
|
15233
|
+
})
|
15234
|
+
)
|
15235
|
+
```
|
15236
|
+
*/
|
15098
15237
|
function styleTags(spec) {
|
15099
15238
|
let byName = Object.create(null);
|
15100
15239
|
for (let prop in spec) {
|
@@ -15103,10 +15242,10 @@
|
|
15103
15242
|
tags = [tags];
|
15104
15243
|
for (let part of prop.split(" "))
|
15105
15244
|
if (part) {
|
15106
|
-
let pieces = [], mode = 2 /*
|
15245
|
+
let pieces = [], mode = 2 /* Normal */, rest = part;
|
15107
15246
|
for (let pos = 0;;) {
|
15108
15247
|
if (rest == "..." && pos > 0 && pos + 3 == part.length) {
|
15109
|
-
mode = 1 /*
|
15248
|
+
mode = 1 /* Inherit */;
|
15110
15249
|
break;
|
15111
15250
|
}
|
15112
15251
|
let m = /^"(?:[^"\\]|\\.)*?"|[^\/!]+/.exec(rest);
|
@@ -15118,7 +15257,7 @@
|
|
15118
15257
|
break;
|
15119
15258
|
let next = part[pos++];
|
15120
15259
|
if (pos == part.length && next == "!") {
|
15121
|
-
mode = 0 /*
|
15260
|
+
mode = 0 /* Opaque */;
|
15122
15261
|
break;
|
15123
15262
|
}
|
15124
15263
|
if (next != "/")
|
@@ -15142,8 +15281,8 @@
|
|
15142
15281
|
this.context = context;
|
15143
15282
|
this.next = next;
|
15144
15283
|
}
|
15145
|
-
get opaque() { return this.mode == 0 /*
|
15146
|
-
get inherit() { return this.mode == 1 /*
|
15284
|
+
get opaque() { return this.mode == 0 /* Opaque */; }
|
15285
|
+
get inherit() { return this.mode == 1 /* Inherit */; }
|
15147
15286
|
sort(other) {
|
15148
15287
|
if (!other || other.depth < this.depth) {
|
15149
15288
|
this.next = other;
|
@@ -15154,10 +15293,12 @@
|
|
15154
15293
|
}
|
15155
15294
|
get depth() { return this.context ? this.context.length : 0; }
|
15156
15295
|
}
|
15157
|
-
Rule.empty = new Rule([], 2 /*
|
15158
|
-
|
15159
|
-
|
15160
|
-
|
15296
|
+
Rule.empty = new Rule([], 2 /* Normal */, null);
|
15297
|
+
/**
|
15298
|
+
Define a [highlighter](#highlight.Highlighter) from an array of
|
15299
|
+
tag/class pairs. Classes associated with more specific tags will
|
15300
|
+
take precedence.
|
15301
|
+
*/
|
15161
15302
|
function tagHighlighter(tags, options) {
|
15162
15303
|
let map = Object.create(null);
|
15163
15304
|
for (let style of tags) {
|
@@ -15194,16 +15335,24 @@
|
|
15194
15335
|
}
|
15195
15336
|
return result;
|
15196
15337
|
}
|
15197
|
-
|
15198
|
-
|
15338
|
+
/**
|
15339
|
+
Highlight the given [tree](#common.Tree) with the given
|
15340
|
+
[highlighter](#highlight.Highlighter).
|
15341
|
+
*/
|
15199
15342
|
function highlightTree(tree, highlighter,
|
15200
|
-
|
15201
|
-
|
15202
|
-
|
15343
|
+
/**
|
15344
|
+
Assign styling to a region of the text. Will be called, in order
|
15345
|
+
of position, for any ranges where more than zero classes apply.
|
15346
|
+
`classes` is a space separated string of CSS classes.
|
15347
|
+
*/
|
15203
15348
|
putStyle,
|
15204
|
-
|
15349
|
+
/**
|
15350
|
+
The start of the range to highlight.
|
15351
|
+
*/
|
15205
15352
|
from = 0,
|
15206
|
-
|
15353
|
+
/**
|
15354
|
+
The end of the range.
|
15355
|
+
*/
|
15207
15356
|
to = tree.length) {
|
15208
15357
|
let builder = new HighlightBuilder(from, Array.isArray(highlighter) ? highlighter : [highlighter], putStyle);
|
15209
15358
|
builder.highlightRange(tree.cursor(), from, to, "", builder.highlighters);
|
@@ -15241,7 +15390,7 @@
|
|
15241
15390
|
if (cls)
|
15242
15391
|
cls += " ";
|
15243
15392
|
cls += tagCls;
|
15244
|
-
if (rule.mode == 1 /*
|
15393
|
+
if (rule.mode == 1 /* Inherit */)
|
15245
15394
|
inheritedClass += (inheritedClass ? " " : "") + tagCls;
|
15246
15395
|
}
|
15247
15396
|
this.startSpan(cursor.from, cls);
|
@@ -15288,9 +15437,11 @@
|
|
15288
15437
|
}
|
15289
15438
|
}
|
15290
15439
|
}
|
15291
|
-
|
15292
|
-
|
15293
|
-
|
15440
|
+
/**
|
15441
|
+
Match a syntax node's [highlight rules](#highlight.styleTags). If
|
15442
|
+
there's a match, return its set of tags, and whether it is
|
15443
|
+
opaque (uses a `!`) or applies to all child nodes (`/...`).
|
15444
|
+
*/
|
15294
15445
|
function getStyleTags(node) {
|
15295
15446
|
let rule = node.type.prop(ruleNodeProp);
|
15296
15447
|
while (rule && rule.context && !node.matchContext(rule.context))
|
@@ -15299,268 +15450,440 @@
|
|
15299
15450
|
}
|
15300
15451
|
const t = Tag.define;
|
15301
15452
|
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
|
-
|
15453
|
+
/**
|
15454
|
+
The default set of highlighting [tags](#highlight.Tag).
|
15455
|
+
|
15456
|
+
This collection is heavily biased towards programming languages,
|
15457
|
+
and necessarily incomplete. A full ontology of syntactic
|
15458
|
+
constructs would fill a stack of books, and be impractical to
|
15459
|
+
write themes for. So try to make do with this set. If all else
|
15460
|
+
fails, [open an
|
15461
|
+
issue](https://github.com/codemirror/codemirror.next) to propose a
|
15462
|
+
new tag, or [define](#highlight.Tag^define) a local custom tag for
|
15463
|
+
your use case.
|
15464
|
+
|
15465
|
+
Note that it is not obligatory to always attach the most specific
|
15466
|
+
tag possible to an element—if your grammar can't easily
|
15467
|
+
distinguish a certain type of element (such as a local variable),
|
15468
|
+
it is okay to style it as its more general variant (a variable).
|
15469
|
+
|
15470
|
+
For tags that extend some parent tag, the documentation links to
|
15471
|
+
the parent.
|
15472
|
+
*/
|
15320
15473
|
const tags = {
|
15321
|
-
|
15474
|
+
/**
|
15475
|
+
A comment.
|
15476
|
+
*/
|
15322
15477
|
comment,
|
15323
|
-
|
15478
|
+
/**
|
15479
|
+
A line [comment](#highlight.tags.comment).
|
15480
|
+
*/
|
15324
15481
|
lineComment: t(comment),
|
15325
|
-
|
15482
|
+
/**
|
15483
|
+
A block [comment](#highlight.tags.comment).
|
15484
|
+
*/
|
15326
15485
|
blockComment: t(comment),
|
15327
|
-
|
15486
|
+
/**
|
15487
|
+
A documentation [comment](#highlight.tags.comment).
|
15488
|
+
*/
|
15328
15489
|
docComment: t(comment),
|
15329
|
-
|
15490
|
+
/**
|
15491
|
+
Any kind of identifier.
|
15492
|
+
*/
|
15330
15493
|
name,
|
15331
|
-
|
15494
|
+
/**
|
15495
|
+
The [name](#highlight.tags.name) of a variable.
|
15496
|
+
*/
|
15332
15497
|
variableName: t(name),
|
15333
|
-
|
15498
|
+
/**
|
15499
|
+
A type [name](#highlight.tags.name).
|
15500
|
+
*/
|
15334
15501
|
typeName: typeName,
|
15335
|
-
|
15502
|
+
/**
|
15503
|
+
A tag name (subtag of [`typeName`](#highlight.tags.typeName)).
|
15504
|
+
*/
|
15336
15505
|
tagName: t(typeName),
|
15337
|
-
|
15506
|
+
/**
|
15507
|
+
A property or field [name](#highlight.tags.name).
|
15508
|
+
*/
|
15338
15509
|
propertyName: propertyName,
|
15339
|
-
|
15510
|
+
/**
|
15511
|
+
An attribute name (subtag of [`propertyName`](#highlight.tags.propertyName)).
|
15512
|
+
*/
|
15340
15513
|
attributeName: t(propertyName),
|
15341
|
-
|
15514
|
+
/**
|
15515
|
+
The [name](#highlight.tags.name) of a class.
|
15516
|
+
*/
|
15342
15517
|
className: t(name),
|
15343
|
-
|
15518
|
+
/**
|
15519
|
+
A label [name](#highlight.tags.name).
|
15520
|
+
*/
|
15344
15521
|
labelName: t(name),
|
15345
|
-
|
15522
|
+
/**
|
15523
|
+
A namespace [name](#highlight.tags.name).
|
15524
|
+
*/
|
15346
15525
|
namespace: t(name),
|
15347
|
-
|
15526
|
+
/**
|
15527
|
+
The [name](#highlight.tags.name) of a macro.
|
15528
|
+
*/
|
15348
15529
|
macroName: t(name),
|
15349
|
-
|
15530
|
+
/**
|
15531
|
+
A literal value.
|
15532
|
+
*/
|
15350
15533
|
literal,
|
15351
|
-
|
15534
|
+
/**
|
15535
|
+
A string [literal](#highlight.tags.literal).
|
15536
|
+
*/
|
15352
15537
|
string,
|
15353
|
-
|
15538
|
+
/**
|
15539
|
+
A documentation [string](#highlight.tags.string).
|
15540
|
+
*/
|
15354
15541
|
docString: t(string),
|
15355
|
-
|
15542
|
+
/**
|
15543
|
+
A character literal (subtag of [string](#highlight.tags.string)).
|
15544
|
+
*/
|
15356
15545
|
character: t(string),
|
15357
|
-
|
15546
|
+
/**
|
15547
|
+
An attribute value (subtag of [string](#highlight.tags.string)).
|
15548
|
+
*/
|
15358
15549
|
attributeValue: t(string),
|
15359
|
-
|
15550
|
+
/**
|
15551
|
+
A number [literal](#highlight.tags.literal).
|
15552
|
+
*/
|
15360
15553
|
number,
|
15361
|
-
|
15554
|
+
/**
|
15555
|
+
An integer [number](#highlight.tags.number) literal.
|
15556
|
+
*/
|
15362
15557
|
integer: t(number),
|
15363
|
-
|
15558
|
+
/**
|
15559
|
+
A floating-point [number](#highlight.tags.number) literal.
|
15560
|
+
*/
|
15364
15561
|
float: t(number),
|
15365
|
-
|
15562
|
+
/**
|
15563
|
+
A boolean [literal](#highlight.tags.literal).
|
15564
|
+
*/
|
15366
15565
|
bool: t(literal),
|
15367
|
-
|
15566
|
+
/**
|
15567
|
+
Regular expression [literal](#highlight.tags.literal).
|
15568
|
+
*/
|
15368
15569
|
regexp: t(literal),
|
15369
|
-
|
15370
|
-
|
15570
|
+
/**
|
15571
|
+
An escape [literal](#highlight.tags.literal), for example a
|
15572
|
+
backslash escape in a string.
|
15573
|
+
*/
|
15371
15574
|
escape: t(literal),
|
15372
|
-
|
15575
|
+
/**
|
15576
|
+
A color [literal](#highlight.tags.literal).
|
15577
|
+
*/
|
15373
15578
|
color: t(literal),
|
15374
|
-
|
15579
|
+
/**
|
15580
|
+
A URL [literal](#highlight.tags.literal).
|
15581
|
+
*/
|
15375
15582
|
url: t(literal),
|
15376
|
-
|
15583
|
+
/**
|
15584
|
+
A language keyword.
|
15585
|
+
*/
|
15377
15586
|
keyword,
|
15378
|
-
|
15379
|
-
|
15587
|
+
/**
|
15588
|
+
The [keyword](#highlight.tags.keyword) for the self or this
|
15589
|
+
object.
|
15590
|
+
*/
|
15380
15591
|
self: t(keyword),
|
15381
|
-
|
15592
|
+
/**
|
15593
|
+
The [keyword](#highlight.tags.keyword) for null.
|
15594
|
+
*/
|
15382
15595
|
null: t(keyword),
|
15383
|
-
|
15596
|
+
/**
|
15597
|
+
A [keyword](#highlight.tags.keyword) denoting some atomic value.
|
15598
|
+
*/
|
15384
15599
|
atom: t(keyword),
|
15385
|
-
|
15600
|
+
/**
|
15601
|
+
A [keyword](#highlight.tags.keyword) that represents a unit.
|
15602
|
+
*/
|
15386
15603
|
unit: t(keyword),
|
15387
|
-
|
15604
|
+
/**
|
15605
|
+
A modifier [keyword](#highlight.tags.keyword).
|
15606
|
+
*/
|
15388
15607
|
modifier: t(keyword),
|
15389
|
-
|
15608
|
+
/**
|
15609
|
+
A [keyword](#highlight.tags.keyword) that acts as an operator.
|
15610
|
+
*/
|
15390
15611
|
operatorKeyword: t(keyword),
|
15391
|
-
|
15612
|
+
/**
|
15613
|
+
A control-flow related [keyword](#highlight.tags.keyword).
|
15614
|
+
*/
|
15392
15615
|
controlKeyword: t(keyword),
|
15393
|
-
|
15616
|
+
/**
|
15617
|
+
A [keyword](#highlight.tags.keyword) that defines something.
|
15618
|
+
*/
|
15394
15619
|
definitionKeyword: t(keyword),
|
15395
|
-
|
15396
|
-
|
15620
|
+
/**
|
15621
|
+
A [keyword](#highlight.tags.keyword) related to defining or
|
15622
|
+
interfacing with modules.
|
15623
|
+
*/
|
15397
15624
|
moduleKeyword: t(keyword),
|
15398
|
-
|
15625
|
+
/**
|
15626
|
+
An operator.
|
15627
|
+
*/
|
15399
15628
|
operator,
|
15400
|
-
|
15629
|
+
/**
|
15630
|
+
An [operator](#highlight.tags.operator) that dereferences something.
|
15631
|
+
*/
|
15401
15632
|
derefOperator: t(operator),
|
15402
|
-
|
15633
|
+
/**
|
15634
|
+
Arithmetic-related [operator](#highlight.tags.operator).
|
15635
|
+
*/
|
15403
15636
|
arithmeticOperator: t(operator),
|
15404
|
-
|
15637
|
+
/**
|
15638
|
+
Logical [operator](#highlight.tags.operator).
|
15639
|
+
*/
|
15405
15640
|
logicOperator: t(operator),
|
15406
|
-
|
15641
|
+
/**
|
15642
|
+
Bit [operator](#highlight.tags.operator).
|
15643
|
+
*/
|
15407
15644
|
bitwiseOperator: t(operator),
|
15408
|
-
|
15645
|
+
/**
|
15646
|
+
Comparison [operator](#highlight.tags.operator).
|
15647
|
+
*/
|
15409
15648
|
compareOperator: t(operator),
|
15410
|
-
|
15649
|
+
/**
|
15650
|
+
[Operator](#highlight.tags.operator) that updates its operand.
|
15651
|
+
*/
|
15411
15652
|
updateOperator: t(operator),
|
15412
|
-
|
15653
|
+
/**
|
15654
|
+
[Operator](#highlight.tags.operator) that defines something.
|
15655
|
+
*/
|
15413
15656
|
definitionOperator: t(operator),
|
15414
|
-
|
15657
|
+
/**
|
15658
|
+
Type-related [operator](#highlight.tags.operator).
|
15659
|
+
*/
|
15415
15660
|
typeOperator: t(operator),
|
15416
|
-
|
15661
|
+
/**
|
15662
|
+
Control-flow [operator](#highlight.tags.operator).
|
15663
|
+
*/
|
15417
15664
|
controlOperator: t(operator),
|
15418
|
-
|
15665
|
+
/**
|
15666
|
+
Program or markup punctuation.
|
15667
|
+
*/
|
15419
15668
|
punctuation,
|
15420
|
-
|
15421
|
-
|
15669
|
+
/**
|
15670
|
+
[Punctuation](#highlight.tags.punctuation) that separates
|
15671
|
+
things.
|
15672
|
+
*/
|
15422
15673
|
separator: t(punctuation),
|
15423
|
-
|
15674
|
+
/**
|
15675
|
+
Bracket-style [punctuation](#highlight.tags.punctuation).
|
15676
|
+
*/
|
15424
15677
|
bracket,
|
15425
|
-
|
15426
|
-
|
15678
|
+
/**
|
15679
|
+
Angle [brackets](#highlight.tags.bracket) (usually `<` and `>`
|
15680
|
+
tokens).
|
15681
|
+
*/
|
15427
15682
|
angleBracket: t(bracket),
|
15428
|
-
|
15429
|
-
|
15683
|
+
/**
|
15684
|
+
Square [brackets](#highlight.tags.bracket) (usually `[` and `]`
|
15685
|
+
tokens).
|
15686
|
+
*/
|
15430
15687
|
squareBracket: t(bracket),
|
15431
|
-
|
15432
|
-
|
15688
|
+
/**
|
15689
|
+
Parentheses (usually `(` and `)` tokens). Subtag of
|
15690
|
+
[bracket](#highlight.tags.bracket).
|
15691
|
+
*/
|
15433
15692
|
paren: t(bracket),
|
15434
|
-
|
15435
|
-
|
15693
|
+
/**
|
15694
|
+
Braces (usually `{` and `}` tokens). Subtag of
|
15695
|
+
[bracket](#highlight.tags.bracket).
|
15696
|
+
*/
|
15436
15697
|
brace: t(bracket),
|
15437
|
-
|
15698
|
+
/**
|
15699
|
+
Content, for example plain text in XML or markup documents.
|
15700
|
+
*/
|
15438
15701
|
content,
|
15439
|
-
|
15702
|
+
/**
|
15703
|
+
[Content](#highlight.tags.content) that represents a heading.
|
15704
|
+
*/
|
15440
15705
|
heading,
|
15441
|
-
|
15706
|
+
/**
|
15707
|
+
A level 1 [heading](#highlight.tags.heading).
|
15708
|
+
*/
|
15442
15709
|
heading1: t(heading),
|
15443
|
-
|
15710
|
+
/**
|
15711
|
+
A level 2 [heading](#highlight.tags.heading).
|
15712
|
+
*/
|
15444
15713
|
heading2: t(heading),
|
15445
|
-
|
15714
|
+
/**
|
15715
|
+
A level 3 [heading](#highlight.tags.heading).
|
15716
|
+
*/
|
15446
15717
|
heading3: t(heading),
|
15447
|
-
|
15718
|
+
/**
|
15719
|
+
A level 4 [heading](#highlight.tags.heading).
|
15720
|
+
*/
|
15448
15721
|
heading4: t(heading),
|
15449
|
-
|
15722
|
+
/**
|
15723
|
+
A level 5 [heading](#highlight.tags.heading).
|
15724
|
+
*/
|
15450
15725
|
heading5: t(heading),
|
15451
|
-
|
15726
|
+
/**
|
15727
|
+
A level 6 [heading](#highlight.tags.heading).
|
15728
|
+
*/
|
15452
15729
|
heading6: t(heading),
|
15453
|
-
|
15730
|
+
/**
|
15731
|
+
A prose separator (such as a horizontal rule).
|
15732
|
+
*/
|
15454
15733
|
contentSeparator: t(content),
|
15455
|
-
|
15734
|
+
/**
|
15735
|
+
[Content](#highlight.tags.content) that represents a list.
|
15736
|
+
*/
|
15456
15737
|
list: t(content),
|
15457
|
-
|
15738
|
+
/**
|
15739
|
+
[Content](#highlight.tags.content) that represents a quote.
|
15740
|
+
*/
|
15458
15741
|
quote: t(content),
|
15459
|
-
|
15742
|
+
/**
|
15743
|
+
[Content](#highlight.tags.content) that is emphasized.
|
15744
|
+
*/
|
15460
15745
|
emphasis: t(content),
|
15461
|
-
|
15746
|
+
/**
|
15747
|
+
[Content](#highlight.tags.content) that is styled strong.
|
15748
|
+
*/
|
15462
15749
|
strong: t(content),
|
15463
|
-
|
15750
|
+
/**
|
15751
|
+
[Content](#highlight.tags.content) that is part of a link.
|
15752
|
+
*/
|
15464
15753
|
link: t(content),
|
15465
|
-
|
15466
|
-
|
15754
|
+
/**
|
15755
|
+
[Content](#highlight.tags.content) that is styled as code or
|
15756
|
+
monospace.
|
15757
|
+
*/
|
15467
15758
|
monospace: t(content),
|
15468
|
-
|
15469
|
-
|
15759
|
+
/**
|
15760
|
+
[Content](#highlight.tags.content) that has a strike-through
|
15761
|
+
style.
|
15762
|
+
*/
|
15470
15763
|
strikethrough: t(content),
|
15471
|
-
|
15764
|
+
/**
|
15765
|
+
Inserted text in a change-tracking format.
|
15766
|
+
*/
|
15472
15767
|
inserted: t(),
|
15473
|
-
|
15768
|
+
/**
|
15769
|
+
Deleted text.
|
15770
|
+
*/
|
15474
15771
|
deleted: t(),
|
15475
|
-
|
15772
|
+
/**
|
15773
|
+
Changed text.
|
15774
|
+
*/
|
15476
15775
|
changed: t(),
|
15477
|
-
|
15776
|
+
/**
|
15777
|
+
An invalid or unsyntactic element.
|
15778
|
+
*/
|
15478
15779
|
invalid: t(),
|
15479
|
-
|
15780
|
+
/**
|
15781
|
+
Metadata or meta-instruction.
|
15782
|
+
*/
|
15480
15783
|
meta,
|
15481
|
-
|
15482
|
-
|
15784
|
+
/**
|
15785
|
+
[Metadata](#highlight.tags.meta) that applies to the entire
|
15786
|
+
document.
|
15787
|
+
*/
|
15483
15788
|
documentMeta: t(meta),
|
15484
|
-
|
15485
|
-
|
15789
|
+
/**
|
15790
|
+
[Metadata](#highlight.tags.meta) that annotates or adds
|
15791
|
+
attributes to a given syntactic element.
|
15792
|
+
*/
|
15486
15793
|
annotation: t(meta),
|
15487
|
-
|
15488
|
-
|
15794
|
+
/**
|
15795
|
+
Processing instruction or preprocessor directive. Subtag of
|
15796
|
+
[meta](#highlight.tags.meta).
|
15797
|
+
*/
|
15489
15798
|
processingInstruction: t(meta),
|
15490
|
-
|
15491
|
-
|
15492
|
-
|
15799
|
+
/**
|
15800
|
+
[Modifier](#highlight.Tag^defineModifier) that indicates that a
|
15801
|
+
given element is being defined. Expected to be used with the
|
15802
|
+
various [name](#highlight.tags.name) tags.
|
15803
|
+
*/
|
15493
15804
|
definition: Tag.defineModifier(),
|
15494
|
-
|
15495
|
-
|
15496
|
-
|
15805
|
+
/**
|
15806
|
+
[Modifier](#highlight.Tag^defineModifier) that indicates that
|
15807
|
+
something is constant. Mostly expected to be used with
|
15808
|
+
[variable names](#highlight.tags.variableName).
|
15809
|
+
*/
|
15497
15810
|
constant: Tag.defineModifier(),
|
15498
|
-
|
15499
|
-
|
15500
|
-
|
15501
|
-
|
15811
|
+
/**
|
15812
|
+
[Modifier](#highlight.Tag^defineModifier) used to indicate that
|
15813
|
+
a [variable](#highlight.tags.variableName) or [property
|
15814
|
+
name](#highlight.tags.propertyName) is being called or defined
|
15815
|
+
as a function.
|
15816
|
+
*/
|
15502
15817
|
function: Tag.defineModifier(),
|
15503
|
-
|
15504
|
-
|
15505
|
-
|
15818
|
+
/**
|
15819
|
+
[Modifier](#highlight.Tag^defineModifier) that can be applied to
|
15820
|
+
[names](#highlight.tags.name) to indicate that they belong to
|
15821
|
+
the language's standard environment.
|
15822
|
+
*/
|
15506
15823
|
standard: Tag.defineModifier(),
|
15507
|
-
|
15508
|
-
|
15824
|
+
/**
|
15825
|
+
[Modifier](#highlight.Tag^defineModifier) that indicates a given
|
15826
|
+
[names](#highlight.tags.name) is local to some scope.
|
15827
|
+
*/
|
15509
15828
|
local: Tag.defineModifier(),
|
15510
|
-
|
15511
|
-
|
15512
|
-
|
15513
|
-
|
15514
|
-
|
15515
|
-
|
15829
|
+
/**
|
15830
|
+
A generic variant [modifier](#highlight.Tag^defineModifier) that
|
15831
|
+
can be used to tag language-specific alternative variants of
|
15832
|
+
some common tag. It is recommended for themes to define special
|
15833
|
+
forms of at least the [string](#highlight.tags.string) and
|
15834
|
+
[variable name](#highlight.tags.variableName) tags, since those
|
15835
|
+
come up a lot.
|
15836
|
+
*/
|
15516
15837
|
special: Tag.defineModifier()
|
15517
15838
|
};
|
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
|
-
|
15839
|
+
/**
|
15840
|
+
This is a highlighter that adds stable, predictable classes to
|
15841
|
+
tokens, for styling with external CSS.
|
15842
|
+
|
15843
|
+
The following tags are mapped to their name prefixed with `"tok-"`
|
15844
|
+
(for example `"tok-comment"`):
|
15845
|
+
|
15846
|
+
* [`link`](#highlight.tags.link)
|
15847
|
+
* [`heading`](#highlight.tags.heading)
|
15848
|
+
* [`emphasis`](#highlight.tags.emphasis)
|
15849
|
+
* [`strong`](#highlight.tags.strong)
|
15850
|
+
* [`keyword`](#highlight.tags.keyword)
|
15851
|
+
* [`atom`](#highlight.tags.atom)
|
15852
|
+
* [`bool`](#highlight.tags.bool)
|
15853
|
+
* [`url`](#highlight.tags.url)
|
15854
|
+
* [`labelName`](#highlight.tags.labelName)
|
15855
|
+
* [`inserted`](#highlight.tags.inserted)
|
15856
|
+
* [`deleted`](#highlight.tags.deleted)
|
15857
|
+
* [`literal`](#highlight.tags.literal)
|
15858
|
+
* [`string`](#highlight.tags.string)
|
15859
|
+
* [`number`](#highlight.tags.number)
|
15860
|
+
* [`variableName`](#highlight.tags.variableName)
|
15861
|
+
* [`typeName`](#highlight.tags.typeName)
|
15862
|
+
* [`namespace`](#highlight.tags.namespace)
|
15863
|
+
* [`className`](#highlight.tags.className)
|
15864
|
+
* [`macroName`](#highlight.tags.macroName)
|
15865
|
+
* [`propertyName`](#highlight.tags.propertyName)
|
15866
|
+
* [`operator`](#highlight.tags.operator)
|
15867
|
+
* [`comment`](#highlight.tags.comment)
|
15868
|
+
* [`meta`](#highlight.tags.meta)
|
15869
|
+
* [`punctuation`](#highlight.tags.punctuation)
|
15870
|
+
* [`invalid`](#highlight.tags.invalid)
|
15871
|
+
|
15872
|
+
In addition, these mappings are provided:
|
15873
|
+
|
15874
|
+
* [`regexp`](#highlight.tags.regexp),
|
15875
|
+
[`escape`](#highlight.tags.escape), and
|
15876
|
+
[`special`](#highlight.tags.special)[`(string)`](#highlight.tags.string)
|
15877
|
+
are mapped to `"tok-string2"`
|
15878
|
+
* [`special`](#highlight.tags.special)[`(variableName)`](#highlight.tags.variableName)
|
15879
|
+
to `"tok-variableName2"`
|
15880
|
+
* [`local`](#highlight.tags.local)[`(variableName)`](#highlight.tags.variableName)
|
15881
|
+
to `"tok-variableName tok-local"`
|
15882
|
+
* [`definition`](#highlight.tags.definition)[`(variableName)`](#highlight.tags.variableName)
|
15883
|
+
to `"tok-variableName tok-definition"`
|
15884
|
+
* [`definition`](#highlight.tags.definition)[`(propertyName)`](#highlight.tags.propertyName)
|
15885
|
+
to `"tok-propertyName tok-definition"`
|
15886
|
+
*/
|
15564
15887
|
tagHighlighter([
|
15565
15888
|
{ tag: tags.link, class: "tok-link" },
|
15566
15889
|
{ tag: tags.heading, class: "tok-heading" },
|
@@ -15614,6 +15937,11 @@
|
|
15614
15937
|
});
|
15615
15938
|
}
|
15616
15939
|
/**
|
15940
|
+
Syntax node prop used to register sublangauges. Should be added to
|
15941
|
+
the top level node type for the language.
|
15942
|
+
*/
|
15943
|
+
const sublanguageProp = /*@__PURE__*/new NodeProp();
|
15944
|
+
/**
|
15617
15945
|
A language object manages parsing and per-language
|
15618
15946
|
[metadata](https://codemirror.net/6/docs/ref/#state.EditorState.languageDataAt). Parse data is
|
15619
15947
|
managed as a [Lezer](https://lezer.codemirror.net) tree. The class
|
@@ -15650,14 +15978,28 @@
|
|
15650
15978
|
this.parser = parser;
|
15651
15979
|
this.extension = [
|
15652
15980
|
language.of(this),
|
15653
|
-
EditorState.languageData.of((state, pos, side) =>
|
15981
|
+
EditorState.languageData.of((state, pos, side) => {
|
15982
|
+
let top = topNodeAt(state, pos, side), data = top.type.prop(languageDataProp);
|
15983
|
+
if (!data)
|
15984
|
+
return [];
|
15985
|
+
let base = state.facet(data), sub = top.type.prop(sublanguageProp);
|
15986
|
+
if (sub) {
|
15987
|
+
let innerNode = top.resolve(pos - top.from, side);
|
15988
|
+
for (let sublang of sub)
|
15989
|
+
if (sublang.test(innerNode, state)) {
|
15990
|
+
let data = state.facet(sublang.facet);
|
15991
|
+
return sublang.type == "replace" ? data : data.concat(base);
|
15992
|
+
}
|
15993
|
+
}
|
15994
|
+
return base;
|
15995
|
+
})
|
15654
15996
|
].concat(extraExtensions);
|
15655
15997
|
}
|
15656
15998
|
/**
|
15657
15999
|
Query whether this language is active at the given position.
|
15658
16000
|
*/
|
15659
16001
|
isActiveAt(state, pos, side = -1) {
|
15660
|
-
return
|
16002
|
+
return topNodeAt(state, pos, side).type.prop(languageDataProp) == this.data;
|
15661
16003
|
}
|
15662
16004
|
/**
|
15663
16005
|
Find the document regions that were parsed using this language.
|
@@ -15712,16 +16054,14 @@
|
|
15712
16054
|
@internal
|
15713
16055
|
*/
|
15714
16056
|
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;
|
16057
|
+
function topNodeAt(state, pos, side) {
|
16058
|
+
let topLang = state.facet(language), tree = syntaxTree(state).topNode;
|
16059
|
+
if (!topLang || topLang.allowsNesting) {
|
16060
|
+
for (let node = tree; node; node = node.enter(pos, side, IterMode.ExcludeBuffers))
|
16061
|
+
if (node.type.isTop)
|
16062
|
+
tree = node;
|
15723
16063
|
}
|
15724
|
-
return
|
16064
|
+
return tree;
|
15725
16065
|
}
|
15726
16066
|
/**
|
15727
16067
|
A subclass of [`Language`](https://codemirror.net/6/docs/ref/#language.Language) for use with Lezer
|
@@ -15763,13 +16103,13 @@
|
|
15763
16103
|
}
|
15764
16104
|
// Lezer-style Input object for a Text document.
|
15765
16105
|
class DocInput {
|
15766
|
-
constructor(doc
|
16106
|
+
constructor(doc) {
|
15767
16107
|
this.doc = doc;
|
15768
|
-
this.length = length;
|
15769
16108
|
this.cursorPos = 0;
|
15770
16109
|
this.string = "";
|
15771
16110
|
this.cursor = doc.iter();
|
15772
16111
|
}
|
16112
|
+
get length() { return this.doc.length; }
|
15773
16113
|
syncTo(pos) {
|
15774
16114
|
this.string = this.cursor.next(pos - this.cursorPos).value;
|
15775
16115
|
this.cursorPos = pos + this.string.length;
|
@@ -16217,17 +16557,18 @@
|
|
16217
16557
|
*/
|
16218
16558
|
const indentService = /*@__PURE__*/Facet.define();
|
16219
16559
|
/**
|
16220
|
-
Facet for overriding the unit by which indentation happens.
|
16221
|
-
|
16222
|
-
|
16560
|
+
Facet for overriding the unit by which indentation happens. Should
|
16561
|
+
be a string consisting either entirely of the same whitespace
|
16562
|
+
character. When not set, this defaults to 2 spaces.
|
16223
16563
|
*/
|
16224
16564
|
const indentUnit = /*@__PURE__*/Facet.define({
|
16225
16565
|
combine: values => {
|
16226
16566
|
if (!values.length)
|
16227
16567
|
return " ";
|
16228
|
-
|
16568
|
+
let unit = values[0];
|
16569
|
+
if (!unit || /\S/.test(unit) || Array.from(unit).some(e => e != unit[0]))
|
16229
16570
|
throw new Error("Invalid indent unit: " + JSON.stringify(values[0]));
|
16230
|
-
return
|
16571
|
+
return unit;
|
16231
16572
|
}
|
16232
16573
|
});
|
16233
16574
|
/**
|
@@ -16247,14 +16588,16 @@
|
|
16247
16588
|
tabs.
|
16248
16589
|
*/
|
16249
16590
|
function indentString(state, cols) {
|
16250
|
-
let result = "", ts = state.tabSize;
|
16251
|
-
if (
|
16591
|
+
let result = "", ts = state.tabSize, ch = state.facet(indentUnit)[0];
|
16592
|
+
if (ch == "\t") {
|
16252
16593
|
while (cols >= ts) {
|
16253
16594
|
result += "\t";
|
16254
16595
|
cols -= ts;
|
16255
16596
|
}
|
16597
|
+
ch = " ";
|
16598
|
+
}
|
16256
16599
|
for (let i = 0; i < cols; i++)
|
16257
|
-
result +=
|
16600
|
+
result += ch;
|
16258
16601
|
return result;
|
16259
16602
|
}
|
16260
16603
|
/**
|
@@ -17307,7 +17650,7 @@
|
|
17307
17650
|
if available, otherwise falling back to block comments.
|
17308
17651
|
*/
|
17309
17652
|
const toggleComment = target => {
|
17310
|
-
let config = getConfig(target.state);
|
17653
|
+
let { state } = target, line = state.doc.lineAt(state.selection.main.from), config = getConfig(target.state, line.from);
|
17311
17654
|
return config.line ? toggleLineComment(target) : config.block ? toggleBlockCommentByLine(target) : false;
|
17312
17655
|
};
|
17313
17656
|
function command(f, option) {
|
@@ -17340,7 +17683,7 @@
|
|
17340
17683
|
block comments.
|
17341
17684
|
*/
|
17342
17685
|
const toggleBlockCommentByLine = /*@__PURE__*/command((o, s) => changeBlockComment(o, s, selectedLineRanges(s)), 0 /* CommentOption.Toggle */);
|
17343
|
-
function getConfig(state, pos
|
17686
|
+
function getConfig(state, pos) {
|
17344
17687
|
let data = state.languageDataAt("commentTokens", pos);
|
17345
17688
|
return data.length ? data[0] : {};
|
17346
17689
|
}
|
@@ -17422,13 +17765,13 @@
|
|
17422
17765
|
let prevLine = -1;
|
17423
17766
|
for (let { from, to } of ranges) {
|
17424
17767
|
let startI = lines.length, minIndent = 1e9;
|
17768
|
+
let token = getConfig(state, from).line;
|
17769
|
+
if (!token)
|
17770
|
+
continue;
|
17425
17771
|
for (let pos = from; pos <= to;) {
|
17426
17772
|
let line = state.doc.lineAt(pos);
|
17427
17773
|
if (line.from > prevLine && (from == to || to > line.from)) {
|
17428
17774
|
prevLine = line.from;
|
17429
|
-
let token = getConfig(state, pos).line;
|
17430
|
-
if (!token)
|
17431
|
-
continue;
|
17432
17775
|
let indent = /^\s*/.exec(line.text)[0].length;
|
17433
17776
|
let empty = indent == line.length;
|
17434
17777
|
let comment = line.text.slice(indent, indent + token.length) == token ? indent : -1;
|
@@ -17910,21 +18253,41 @@
|
|
17910
18253
|
Move the selection one line down.
|
17911
18254
|
*/
|
17912
18255
|
const cursorLineDown = view => cursorByLine(view, true);
|
17913
|
-
function
|
17914
|
-
|
18256
|
+
function pageInfo(view) {
|
18257
|
+
let selfScroll = view.scrollDOM.clientHeight < view.scrollDOM.scrollHeight - 2;
|
18258
|
+
let marginTop = 0, marginBottom = 0, height;
|
18259
|
+
if (selfScroll) {
|
18260
|
+
for (let source of view.state.facet(EditorView.scrollMargins)) {
|
18261
|
+
let margins = source(view);
|
18262
|
+
if (margins === null || margins === void 0 ? void 0 : margins.top)
|
18263
|
+
marginTop = Math.max(margins === null || margins === void 0 ? void 0 : margins.top, marginTop);
|
18264
|
+
if (margins === null || margins === void 0 ? void 0 : margins.bottom)
|
18265
|
+
marginBottom = Math.max(margins === null || margins === void 0 ? void 0 : margins.bottom, marginBottom);
|
18266
|
+
}
|
18267
|
+
height = view.scrollDOM.clientHeight - marginTop - marginBottom;
|
18268
|
+
}
|
18269
|
+
else {
|
18270
|
+
height = (view.dom.ownerDocument.defaultView || window).innerHeight;
|
18271
|
+
}
|
18272
|
+
return { marginTop, marginBottom, selfScroll,
|
18273
|
+
height: Math.max(view.defaultLineHeight, height - 5) };
|
17915
18274
|
}
|
17916
18275
|
function cursorByPage(view, forward) {
|
18276
|
+
let page = pageInfo(view);
|
17917
18277
|
let { state } = view, selection = updateSel(state.selection, range => {
|
17918
|
-
return range.empty ? view.moveVertically(range, forward,
|
18278
|
+
return range.empty ? view.moveVertically(range, forward, page.height)
|
18279
|
+
: rangeEnd(range, forward);
|
17919
18280
|
});
|
17920
18281
|
if (selection.eq(state.selection))
|
17921
18282
|
return false;
|
17922
|
-
let startPos = view.coordsAtPos(state.selection.main.head);
|
17923
|
-
let scrollRect = view.scrollDOM.getBoundingClientRect();
|
17924
18283
|
let effect;
|
17925
|
-
if (
|
17926
|
-
startPos
|
17927
|
-
|
18284
|
+
if (page.selfScroll) {
|
18285
|
+
let startPos = view.coordsAtPos(state.selection.main.head);
|
18286
|
+
let scrollRect = view.scrollDOM.getBoundingClientRect();
|
18287
|
+
let scrollTop = scrollRect.top + page.marginTop, scrollBottom = scrollRect.bottom - page.marginBottom;
|
18288
|
+
if (startPos && startPos.top > scrollTop && startPos.bottom < scrollBottom)
|
18289
|
+
effect = EditorView.scrollIntoView(selection.main.head, { y: "start", yMargin: startPos.top - scrollTop });
|
18290
|
+
}
|
17928
18291
|
view.dispatch(setSel(state, selection), { effects: effect });
|
17929
18292
|
return true;
|
17930
18293
|
}
|
@@ -18051,7 +18414,7 @@
|
|
18051
18414
|
*/
|
18052
18415
|
const selectLineDown = view => selectByLine(view, true);
|
18053
18416
|
function selectByPage(view, forward) {
|
18054
|
-
return extendSel(view, range => view.moveVertically(range, forward,
|
18417
|
+
return extendSel(view, range => view.moveVertically(range, forward, pageInfo(view).height));
|
18055
18418
|
}
|
18056
18419
|
/**
|
18057
18420
|
Move the selection head one page up.
|
@@ -19072,9 +19435,6 @@
|
|
19072
19435
|
`-`, document percentages suffixed with `%`, and an optional
|
19073
19436
|
column position by adding `:` and a second number after the line
|
19074
19437
|
number.
|
19075
|
-
|
19076
|
-
The dialog can be styled with the `panel.gotoLine` theme
|
19077
|
-
selector.
|
19078
19438
|
*/
|
19079
19439
|
const gotoLine = view => {
|
19080
19440
|
let panel = getPanel(view, createLineDialog);
|
@@ -19261,7 +19621,8 @@
|
|
19261
19621
|
caseSensitive: false,
|
19262
19622
|
literal: false,
|
19263
19623
|
wholeWord: false,
|
19264
|
-
createPanel: view => new SearchPanel(view)
|
19624
|
+
createPanel: view => new SearchPanel(view),
|
19625
|
+
scrollToMatch: range => EditorView.scrollIntoView(range)
|
19265
19626
|
});
|
19266
19627
|
}
|
19267
19628
|
});
|
@@ -19519,10 +19880,11 @@
|
|
19519
19880
|
let next = query.nextMatch(view.state, to, to);
|
19520
19881
|
if (!next)
|
19521
19882
|
return false;
|
19883
|
+
let selection = EditorSelection.single(next.from, next.to);
|
19884
|
+
let config = view.state.facet(searchConfigFacet);
|
19522
19885
|
view.dispatch({
|
19523
|
-
selection
|
19524
|
-
|
19525
|
-
effects: announceMatch(view, next),
|
19886
|
+
selection,
|
19887
|
+
effects: [announceMatch(view, next), config.scrollToMatch(selection.main)],
|
19526
19888
|
userEvent: "select.search"
|
19527
19889
|
});
|
19528
19890
|
return true;
|
@@ -19534,13 +19896,14 @@
|
|
19534
19896
|
*/
|
19535
19897
|
const findPrevious = /*@__PURE__*/searchCommand((view, { query }) => {
|
19536
19898
|
let { state } = view, { from } = state.selection.main;
|
19537
|
-
let
|
19538
|
-
if (!
|
19899
|
+
let prev = query.prevMatch(state, from, from);
|
19900
|
+
if (!prev)
|
19539
19901
|
return false;
|
19902
|
+
let selection = EditorSelection.single(prev.from, prev.to);
|
19903
|
+
let config = view.state.facet(searchConfigFacet);
|
19540
19904
|
view.dispatch({
|
19541
|
-
selection
|
19542
|
-
|
19543
|
-
effects: announceMatch(view, range),
|
19905
|
+
selection,
|
19906
|
+
effects: [announceMatch(view, prev), config.scrollToMatch(selection.main)],
|
19544
19907
|
userEvent: "select.search"
|
19545
19908
|
});
|
19546
19909
|
return true;
|
@@ -19591,22 +19954,21 @@
|
|
19591
19954
|
if (!next)
|
19592
19955
|
return false;
|
19593
19956
|
let changes = [], selection, replacement;
|
19594
|
-
let
|
19957
|
+
let effects = [];
|
19595
19958
|
if (next.from == from && next.to == to) {
|
19596
19959
|
replacement = state.toText(query.getReplacement(next));
|
19597
19960
|
changes.push({ from: next.from, to: next.to, insert: replacement });
|
19598
19961
|
next = query.nextMatch(state, next.from, next.to);
|
19599
|
-
|
19962
|
+
effects.push(EditorView.announce.of(state.phrase("replaced match on line $", state.doc.lineAt(from).number) + "."));
|
19600
19963
|
}
|
19601
19964
|
if (next) {
|
19602
19965
|
let off = changes.length == 0 || changes[0].from >= next.to ? 0 : next.to - next.from - replacement.length;
|
19603
|
-
selection =
|
19604
|
-
|
19966
|
+
selection = EditorSelection.single(next.from - off, next.to - off);
|
19967
|
+
effects.push(announceMatch(view, next));
|
19968
|
+
effects.push(state.facet(searchConfigFacet).scrollToMatch(selection.main));
|
19605
19969
|
}
|
19606
19970
|
view.dispatch({
|
19607
|
-
changes, selection,
|
19608
|
-
scrollIntoView: !!selection,
|
19609
|
-
effects: announce,
|
19971
|
+
changes, selection, effects,
|
19610
19972
|
userEvent: "input.replace"
|
19611
19973
|
});
|
19612
19974
|
return true;
|
@@ -19990,9 +20352,12 @@
|
|
19990
20352
|
*/
|
19991
20353
|
function ifNotIn(nodes, source) {
|
19992
20354
|
return (context) => {
|
19993
|
-
for (let pos = syntaxTree(context.state).resolveInner(context.pos, -1); pos; pos = pos.parent)
|
20355
|
+
for (let pos = syntaxTree(context.state).resolveInner(context.pos, -1); pos; pos = pos.parent) {
|
19994
20356
|
if (nodes.indexOf(pos.name) > -1)
|
19995
20357
|
return null;
|
20358
|
+
if (pos.type.isTop)
|
20359
|
+
break;
|
20360
|
+
}
|
19996
20361
|
return source(context);
|
19997
20362
|
};
|
19998
20363
|
}
|
@@ -20097,13 +20462,18 @@
|
|
20097
20462
|
// For single-character queries, only match when they occur right
|
20098
20463
|
// at the start
|
20099
20464
|
if (chars.length == 1) {
|
20100
|
-
let first = codePointAt(word, 0);
|
20101
|
-
|
20102
|
-
|
20465
|
+
let first = codePointAt(word, 0), firstSize = codePointSize(first);
|
20466
|
+
let score = firstSize == word.length ? 0 : -100 /* Penalty.NotFull */;
|
20467
|
+
if (first == chars[0]) ;
|
20468
|
+
else if (first == folded[0])
|
20469
|
+
score += -200 /* Penalty.CaseFold */;
|
20470
|
+
else
|
20471
|
+
return null;
|
20472
|
+
return [score, 0, firstSize];
|
20103
20473
|
}
|
20104
20474
|
let direct = word.indexOf(this.pattern);
|
20105
20475
|
if (direct == 0)
|
20106
|
-
return [0
|
20476
|
+
return [word.length == this.pattern.length ? 0 : -100 /* Penalty.NotFull */, 0, this.pattern.length];
|
20107
20477
|
let len = chars.length, anyTo = 0;
|
20108
20478
|
if (direct < 0) {
|
20109
20479
|
for (let i = 0, e = Math.min(word.length, 200); i < e && anyTo < len;) {
|
@@ -20159,7 +20529,7 @@
|
|
20159
20529
|
if (byWordTo == len && byWord[0] == 0 && wordAdjacent)
|
20160
20530
|
return this.result(-100 /* Penalty.ByWord */ + (byWordFolded ? -200 /* Penalty.CaseFold */ : 0), byWord, word);
|
20161
20531
|
if (adjacentTo == len && adjacentStart == 0)
|
20162
|
-
return [-200 /* Penalty.CaseFold */ - word.length, 0, adjacentEnd];
|
20532
|
+
return [-200 /* Penalty.CaseFold */ - word.length + (adjacentEnd == word.length ? 0 : -100 /* Penalty.NotFull */), 0, adjacentEnd];
|
20163
20533
|
if (direct > -1)
|
20164
20534
|
return [-700 /* Penalty.NotStart */ - word.length, direct, direct + this.pattern.length];
|
20165
20535
|
if (adjacentTo == len)
|
@@ -21555,7 +21925,8 @@
|
|
21555
21925
|
}
|
21556
21926
|
update(update) {
|
21557
21927
|
let config = update.state.facet(lintConfig);
|
21558
|
-
if (update.docChanged || config != update.startState.facet(lintConfig)
|
21928
|
+
if (update.docChanged || config != update.startState.facet(lintConfig) ||
|
21929
|
+
config.needsRefresh && config.needsRefresh(update)) {
|
21559
21930
|
this.lintTime = Date.now() + config.delay;
|
21560
21931
|
if (!this.set) {
|
21561
21932
|
this.set = true;
|
@@ -21578,7 +21949,10 @@
|
|
21578
21949
|
return Object.assign({ sources: input.map(i => i.source) }, combineConfig(input.map(i => i.config), {
|
21579
21950
|
delay: 750,
|
21580
21951
|
markerFilter: null,
|
21581
|
-
tooltipFilter: null
|
21952
|
+
tooltipFilter: null,
|
21953
|
+
needsRefresh: null
|
21954
|
+
}, {
|
21955
|
+
needsRefresh: (a, b) => !a ? b : !b ? a : u => a(u) || b(u)
|
21582
21956
|
}));
|
21583
21957
|
},
|
21584
21958
|
enables: lintPlugin
|
@@ -21602,8 +21976,11 @@
|
|
21602
21976
|
var _a;
|
21603
21977
|
let keys = inPanel ? assignKeys(diagnostic.actions) : [];
|
21604
21978
|
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) => {
|
21979
|
+
let fired = false, click = (e) => {
|
21606
21980
|
e.preventDefault();
|
21981
|
+
if (fired)
|
21982
|
+
return;
|
21983
|
+
fired = true;
|
21607
21984
|
let found = findDiagnostic(view.state.field(lintState).diagnostics, diagnostic);
|
21608
21985
|
if (found)
|
21609
21986
|
action.apply(view, found.from, found.to);
|
@@ -21830,7 +22207,8 @@
|
|
21830
22207
|
backgroundColor: "#444",
|
21831
22208
|
color: "white",
|
21832
22209
|
borderRadius: "3px",
|
21833
|
-
marginLeft: "8px"
|
22210
|
+
marginLeft: "8px",
|
22211
|
+
cursor: "pointer"
|
21834
22212
|
},
|
21835
22213
|
".cm-diagnosticSource": {
|
21836
22214
|
fontSize: "70%",
|
@@ -24535,6 +24913,7 @@
|
|
24535
24913
|
this.headerRenderer = headerRenderer;
|
24536
24914
|
this.cellRenderer = cellRenderer;
|
24537
24915
|
|
24916
|
+
this.classList.add('resize-table');
|
24538
24917
|
this.style.tableLayout = 'auto';
|
24539
24918
|
this.style.width = '100%';
|
24540
24919
|
|
@@ -24870,9 +25249,10 @@
|
|
24870
25249
|
|
24871
25250
|
function init (parent, onSubmit, onShiftSubmit) {
|
24872
25251
|
addEventListener('#query-tab-button', 'click', (event) => selectTab(event, 'query'));
|
25252
|
+
addEventListener('#graph-tab-button', 'click', (event) => selectTab(event, 'graph'));
|
24873
25253
|
addEventListener('#saved-tab-button', 'click', (event) => selectTab(event, 'saved'));
|
24874
25254
|
addEventListener('#structure-tab-button', 'click', (event) => selectTab(event, 'structure'));
|
24875
|
-
addEventListener('#
|
25255
|
+
addEventListener('#help-tab-button', 'click', (event) => selectTab(event, 'help'));
|
24876
25256
|
addEventListener('#cancel-button', 'click', () => clearResult());
|
24877
25257
|
|
24878
25258
|
addEventListener('#query-box', 'click', () => {
|
@@ -25046,7 +25426,7 @@
|
|
25046
25426
|
|
25047
25427
|
function getTabFromUrl (url) {
|
25048
25428
|
const match = url.pathname.match(/\/([^/]+)$/);
|
25049
|
-
if (match && ['query', 'graph', 'structure', '
|
25429
|
+
if (match && ['query', 'graph', 'saved', 'structure', 'help'].includes(match[1])) {
|
25050
25430
|
return match[1]
|
25051
25431
|
} else {
|
25052
25432
|
throw new Error(`invalid tab: ${url.pathname}`)
|
@@ -25055,14 +25435,16 @@
|
|
25055
25435
|
|
25056
25436
|
function updateTabs () {
|
25057
25437
|
const url = new URL(window.location);
|
25438
|
+
setActionInUrl(url, 'query');
|
25439
|
+
document.getElementById('query-tab-button').href = url.pathname + url.search;
|
25058
25440
|
setActionInUrl(url, 'graph');
|
25059
25441
|
document.getElementById('graph-tab-button').href = url.pathname + url.search;
|
25060
25442
|
setActionInUrl(url, 'saved');
|
25061
25443
|
document.getElementById('saved-tab-button').href = url.pathname + url.search;
|
25062
25444
|
setActionInUrl(url, 'structure');
|
25063
25445
|
document.getElementById('structure-tab-button').href = url.pathname + url.search;
|
25064
|
-
setActionInUrl(url, '
|
25065
|
-
document.getElementById('
|
25446
|
+
setActionInUrl(url, 'help');
|
25447
|
+
document.getElementById('help-tab-button').href = url.pathname + url.search;
|
25066
25448
|
}
|
25067
25449
|
|
25068
25450
|
function selectTab (event, tab) {
|
@@ -25122,11 +25504,31 @@
|
|
25122
25504
|
case 'structure':
|
25123
25505
|
selectStructureTab();
|
25124
25506
|
break
|
25507
|
+
case 'help':
|
25508
|
+
selectHelpTab();
|
25509
|
+
break
|
25125
25510
|
default:
|
25126
25511
|
throw new Error(`Unexpected tab: ${window.tab}`)
|
25127
25512
|
}
|
25128
25513
|
}
|
25129
25514
|
|
25515
|
+
function statsHtml (info) {
|
25516
|
+
const hidden = info == null;
|
25517
|
+
info ||= {};
|
25518
|
+
return `
|
25519
|
+
<table ${hidden ? 'style="visibility: hidden;"' : ''}>
|
25520
|
+
<tr><td>created:</td><td>${valueOrNullHtml(info.created_at)}</td></tr>
|
25521
|
+
<tr><td>updated:</td><td>${valueOrNullHtml(info.updated_at)}</td></tr>
|
25522
|
+
<tr><td>data size:</td><td>${valueOrNullHtml(info.data_size)}</td></tr>
|
25523
|
+
<tr><td>index size:</td><td>${valueOrNullHtml(info.index_size)}</td></tr>
|
25524
|
+
<tr><td>rows:</td><td>${valueOrNullHtml(info.rows)}</td></tr>
|
25525
|
+
<tr><td>row size:</td><td>${valueOrNullHtml(info.average_row_size)}</td></tr>
|
25526
|
+
<tr><td>encoding:</td><td>${valueOrNullHtml(info.encoding)}</td></tr>
|
25527
|
+
<tr><td>auto increment:</td><td>${valueOrNullHtml(info.auto_increment)}</td></tr>
|
25528
|
+
</table>
|
25529
|
+
`
|
25530
|
+
}
|
25531
|
+
|
25130
25532
|
function selectStructureTab () {
|
25131
25533
|
Array.prototype.forEach.call(document.getElementsByClassName('structure-element'), function (selected) {
|
25132
25534
|
selected.style.display = 'flex';
|
@@ -25138,6 +25540,9 @@
|
|
25138
25540
|
|
25139
25541
|
const schemasElement = document.getElementById('schemas');
|
25140
25542
|
const tablesElement = document.getElementById('tables');
|
25543
|
+
const statsElement = document.getElementById('stats');
|
25544
|
+
statsElement.innerHTML = statsHtml(null);
|
25545
|
+
|
25141
25546
|
const columnsElement = document.getElementById('columns');
|
25142
25547
|
const indexesElement = document.getElementById('indexes');
|
25143
25548
|
|
@@ -25166,6 +25571,10 @@
|
|
25166
25571
|
schemasElement.appendChild(optionElement);
|
25167
25572
|
});
|
25168
25573
|
schemasElement.addEventListener('change', function () {
|
25574
|
+
while (statsElement.firstChild) {
|
25575
|
+
statsElement.removeChild(statsElement.firstChild);
|
25576
|
+
}
|
25577
|
+
statsElement.innerHTML = statsHtml(null);
|
25169
25578
|
while (tablesElement.firstChild) {
|
25170
25579
|
tablesElement.removeChild(tablesElement.firstChild);
|
25171
25580
|
}
|
@@ -25187,6 +25596,9 @@
|
|
25187
25596
|
});
|
25188
25597
|
}
|
25189
25598
|
tablesElement.addEventListener('change', function () {
|
25599
|
+
while (statsElement.firstChild) {
|
25600
|
+
statsElement.removeChild(statsElement.firstChild);
|
25601
|
+
}
|
25190
25602
|
while (columnsElement.firstChild) {
|
25191
25603
|
columnsElement.removeChild(columnsElement.firstChild);
|
25192
25604
|
}
|
@@ -25196,7 +25608,9 @@
|
|
25196
25608
|
const schemaName = schemaNames.length === 1 ? schemaNames[0] : schemasElement.value;
|
25197
25609
|
const tableName = tablesElement.value;
|
25198
25610
|
const table = window.metadata.schemas[schemaName].tables[tableName];
|
25611
|
+
const info = table.info;
|
25199
25612
|
|
25613
|
+
statsElement.innerHTML = statsHtml(info);
|
25200
25614
|
const columnEntries = Object.entries(table.columns);
|
25201
25615
|
if (columnEntries.length > 0) {
|
25202
25616
|
const columns = Object.keys(columnEntries[0][1]);
|
@@ -25242,6 +25656,10 @@
|
|
25242
25656
|
window.structureLoaded = true;
|
25243
25657
|
}
|
25244
25658
|
|
25659
|
+
function selectHelpTab () {
|
25660
|
+
document.getElementById('help-box').style.display = 'block';
|
25661
|
+
}
|
25662
|
+
|
25245
25663
|
function selectGraphTab (internal) {
|
25246
25664
|
document.getElementById('query-box').style.display = 'flex';
|
25247
25665
|
document.getElementById('submit-box').style.display = 'flex';
|
@@ -25284,7 +25702,7 @@
|
|
25284
25702
|
viewUrl.searchParams.set('file', file.filename);
|
25285
25703
|
|
25286
25704
|
const viewLinkElement = document.createElement('a');
|
25287
|
-
viewLinkElement.classList.add('view-link');
|
25705
|
+
viewLinkElement.classList.add('link', 'view-link');
|
25288
25706
|
viewLinkElement.innerText = 'view';
|
25289
25707
|
viewLinkElement.href = viewUrl.pathname + viewUrl.search;
|
25290
25708
|
addEventListener(viewLinkElement, 'click', (event) => {
|
@@ -25298,7 +25716,7 @@
|
|
25298
25716
|
runUrl.searchParams.set('run', 'true');
|
25299
25717
|
|
25300
25718
|
const runLinkElement = document.createElement('a');
|
25301
|
-
runLinkElement.classList.add('run-link');
|
25719
|
+
runLinkElement.classList.add('link', 'run-link');
|
25302
25720
|
runLinkElement.innerText = 'run';
|
25303
25721
|
runLinkElement.href = runUrl.pathname + runUrl.search;
|
25304
25722
|
addEventListener(runLinkElement, 'click', (event) => {
|
@@ -25309,25 +25727,31 @@
|
|
25309
25727
|
|
25310
25728
|
const nameElement = document.createElement('h2');
|
25311
25729
|
nameElement.innerText = file.filename;
|
25730
|
+
nameElement.classList.add('name');
|
25312
25731
|
|
25313
|
-
const
|
25314
|
-
|
25315
|
-
|
25316
|
-
|
25317
|
-
nameAndLinksElement.appendChild(runLinkElement);
|
25732
|
+
const linksElement = document.createElement('div');
|
25733
|
+
linksElement.classList.add('links');
|
25734
|
+
linksElement.appendChild(viewLinkElement);
|
25735
|
+
linksElement.appendChild(runLinkElement);
|
25318
25736
|
|
25319
25737
|
const descriptionElement = document.createElement('p');
|
25320
25738
|
descriptionElement.innerText = file.description;
|
25739
|
+
descriptionElement.classList.add('description');
|
25321
25740
|
|
25322
25741
|
const divElement = document.createElement('div');
|
25323
25742
|
divElement.classList.add('saved-list-item');
|
25324
|
-
divElement.appendChild(
|
25743
|
+
divElement.appendChild(nameElement);
|
25744
|
+
divElement.appendChild(linksElement);
|
25325
25745
|
divElement.appendChild(descriptionElement);
|
25326
25746
|
|
25327
25747
|
savedElement.appendChild(divElement);
|
25328
25748
|
});
|
25329
25749
|
}
|
25330
25750
|
|
25751
|
+
function valueOrNullHtml (value) {
|
25752
|
+
return value == null ? '<span style="color: #888">null</span>' : value
|
25753
|
+
}
|
25754
|
+
|
25331
25755
|
function submitAll (target, event) {
|
25332
25756
|
submit(target, event);
|
25333
25757
|
}
|
@@ -25973,6 +26397,12 @@
|
|
25973
26397
|
}
|
25974
26398
|
});
|
25975
26399
|
|
26400
|
+
document.addEventListener('keydown', (event) => {
|
26401
|
+
if (event.code === 'Escape') {
|
26402
|
+
focus();
|
26403
|
+
}
|
26404
|
+
});
|
26405
|
+
|
25976
26406
|
window.onload = function () {
|
25977
26407
|
Promise.all([
|
25978
26408
|
google.charts.load('current', { packages: ['corechart', 'line'] }),
|