@codemirror/view 6.8.0 → 6.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +20 -0
- package/dist/index.cjs +122 -75
- package/dist/index.d.ts +5 -0
- package/dist/index.js +122 -75
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,23 @@
|
|
|
1
|
+
## 6.9.0 (2023-02-15)
|
|
2
|
+
|
|
3
|
+
### Bug fixes
|
|
4
|
+
|
|
5
|
+
Fix an issue where inaccurate estimated vertical positions could cause the viewport to not converge in line-wrapped editors.
|
|
6
|
+
|
|
7
|
+
Don't suppress double-space to period conversion when autocorrect is enabled.
|
|
8
|
+
|
|
9
|
+
Make sure the measuring code notices when the scaling of the editor is changed, and does a full measure in that case.
|
|
10
|
+
|
|
11
|
+
### New features
|
|
12
|
+
|
|
13
|
+
The new `EditorView.focusChangeEffect` facet can be used to dispatch a state effect when the editor is focused or blurred.
|
|
14
|
+
|
|
15
|
+
## 6.8.1 (2023-02-08)
|
|
16
|
+
|
|
17
|
+
### Bug fixes
|
|
18
|
+
|
|
19
|
+
Fix an issue where tooltips that have their height reduced have their height flicker when scrolling or otherwise interacting with the editor.
|
|
20
|
+
|
|
1
21
|
## 6.8.0 (2023-02-07)
|
|
2
22
|
|
|
3
23
|
### Bug fixes
|
package/dist/index.cjs
CHANGED
|
@@ -1784,6 +1784,7 @@ const mouseSelectionStyle = state.Facet.define();
|
|
|
1784
1784
|
const exceptionSink = state.Facet.define();
|
|
1785
1785
|
const updateListener = state.Facet.define();
|
|
1786
1786
|
const inputHandler = state.Facet.define();
|
|
1787
|
+
const focusChangeEffect = state.Facet.define();
|
|
1787
1788
|
const perLineTextDirection = state.Facet.define({
|
|
1788
1789
|
combine: values => values.some(x => x)
|
|
1789
1790
|
});
|
|
@@ -4034,8 +4035,18 @@ handlers.copy = handlers.cut = (view, event) => {
|
|
|
4034
4035
|
};
|
|
4035
4036
|
function updateForFocusChange(view) {
|
|
4036
4037
|
setTimeout(() => {
|
|
4037
|
-
if (view.hasFocus != view.inputState.notifiedFocused)
|
|
4038
|
-
view.
|
|
4038
|
+
if (view.hasFocus != view.inputState.notifiedFocused) {
|
|
4039
|
+
let effects = [], focus = !view.inputState.notifiedFocused;
|
|
4040
|
+
for (let getEffect of view.state.facet(focusChangeEffect)) {
|
|
4041
|
+
let effect = getEffect(view.state, focus);
|
|
4042
|
+
if (effect)
|
|
4043
|
+
effects.push(effect);
|
|
4044
|
+
}
|
|
4045
|
+
if (effects.length)
|
|
4046
|
+
view.dispatch({ effects });
|
|
4047
|
+
else
|
|
4048
|
+
view.update([]);
|
|
4049
|
+
}
|
|
4039
4050
|
}, 10);
|
|
4040
4051
|
}
|
|
4041
4052
|
handlers.focus = view => {
|
|
@@ -4117,7 +4128,7 @@ class HeightOracle {
|
|
|
4117
4128
|
heightForGap(from, to) {
|
|
4118
4129
|
let lines = this.doc.lineAt(to).number - this.doc.lineAt(from).number + 1;
|
|
4119
4130
|
if (this.lineWrapping)
|
|
4120
|
-
lines += Math.ceil(((to - from) - (lines * this.lineLength * 0.5)) / this.lineLength);
|
|
4131
|
+
lines += Math.max(0, Math.ceil(((to - from) - (lines * this.lineLength * 0.5)) / this.lineLength));
|
|
4121
4132
|
return this.lineHeight * lines;
|
|
4122
4133
|
}
|
|
4123
4134
|
heightForLine(length) {
|
|
@@ -4263,11 +4274,11 @@ class HeightMap {
|
|
|
4263
4274
|
decomposeLeft(_to, result) { result.push(this); }
|
|
4264
4275
|
decomposeRight(_from, result) { result.push(this); }
|
|
4265
4276
|
applyChanges(decorations, oldDoc, oracle, changes) {
|
|
4266
|
-
let me = this;
|
|
4277
|
+
let me = this, doc = oracle.doc;
|
|
4267
4278
|
for (let i = changes.length - 1; i >= 0; i--) {
|
|
4268
4279
|
let { fromA, toA, fromB, toB } = changes[i];
|
|
4269
|
-
let start = me.lineAt(fromA, QueryType.ByPosNoHeight, oldDoc, 0, 0);
|
|
4270
|
-
let end = start.to >= toA ? start : me.lineAt(toA, QueryType.ByPosNoHeight,
|
|
4280
|
+
let start = me.lineAt(fromA, QueryType.ByPosNoHeight, oracle.setDoc(oldDoc), 0, 0);
|
|
4281
|
+
let end = start.to >= toA ? start : me.lineAt(toA, QueryType.ByPosNoHeight, oracle, 0, 0);
|
|
4271
4282
|
toB += end.to - toA;
|
|
4272
4283
|
toA = end.to;
|
|
4273
4284
|
while (i > 0 && start.from <= changes[i - 1].toA) {
|
|
@@ -4275,11 +4286,11 @@ class HeightMap {
|
|
|
4275
4286
|
fromB = changes[i - 1].fromB;
|
|
4276
4287
|
i--;
|
|
4277
4288
|
if (fromA < start.from)
|
|
4278
|
-
start = me.lineAt(fromA, QueryType.ByPosNoHeight,
|
|
4289
|
+
start = me.lineAt(fromA, QueryType.ByPosNoHeight, oracle, 0, 0);
|
|
4279
4290
|
}
|
|
4280
4291
|
fromB += start.from - fromA;
|
|
4281
4292
|
fromA = start.from;
|
|
4282
|
-
let nodes = NodeBuilder.build(oracle, decorations, fromB, toB);
|
|
4293
|
+
let nodes = NodeBuilder.build(oracle.setDoc(doc), decorations, fromB, toB);
|
|
4283
4294
|
me = me.replace(fromA, toA, nodes);
|
|
4284
4295
|
}
|
|
4285
4296
|
return me.updateHeight(oracle, 0);
|
|
@@ -4346,15 +4357,15 @@ class HeightMapBlock extends HeightMap {
|
|
|
4346
4357
|
super(length, height);
|
|
4347
4358
|
this.type = type;
|
|
4348
4359
|
}
|
|
4349
|
-
blockAt(_height,
|
|
4360
|
+
blockAt(_height, _oracle, top, offset) {
|
|
4350
4361
|
return new BlockInfo(offset, this.length, top, this.height, this.type);
|
|
4351
4362
|
}
|
|
4352
|
-
lineAt(_value, _type,
|
|
4353
|
-
return this.blockAt(0,
|
|
4363
|
+
lineAt(_value, _type, oracle, top, offset) {
|
|
4364
|
+
return this.blockAt(0, oracle, top, offset);
|
|
4354
4365
|
}
|
|
4355
|
-
forEachLine(from, to,
|
|
4366
|
+
forEachLine(from, to, oracle, top, offset, f) {
|
|
4356
4367
|
if (from <= offset + this.length && to >= offset)
|
|
4357
|
-
f(this.blockAt(0,
|
|
4368
|
+
f(this.blockAt(0, oracle, top, offset));
|
|
4358
4369
|
}
|
|
4359
4370
|
updateHeight(oracle, offset = 0, _force = false, measured) {
|
|
4360
4371
|
if (measured && measured.from <= offset && measured.more)
|
|
@@ -4400,35 +4411,60 @@ class HeightMapText extends HeightMapBlock {
|
|
|
4400
4411
|
}
|
|
4401
4412
|
class HeightMapGap extends HeightMap {
|
|
4402
4413
|
constructor(length) { super(length, 0); }
|
|
4403
|
-
|
|
4404
|
-
let firstLine = doc.lineAt(offset).number, lastLine = doc.lineAt(offset + this.length).number;
|
|
4405
|
-
|
|
4414
|
+
heightMetrics(oracle, offset) {
|
|
4415
|
+
let firstLine = oracle.doc.lineAt(offset).number, lastLine = oracle.doc.lineAt(offset + this.length).number;
|
|
4416
|
+
let lines = lastLine - firstLine + 1;
|
|
4417
|
+
let perLine, perChar = 0;
|
|
4418
|
+
if (oracle.lineWrapping) {
|
|
4419
|
+
let totalPerLine = Math.min(this.height, oracle.lineHeight * lines);
|
|
4420
|
+
perLine = totalPerLine / lines;
|
|
4421
|
+
perChar = (this.height - totalPerLine) / (this.length - lines - 1);
|
|
4422
|
+
}
|
|
4423
|
+
else {
|
|
4424
|
+
perLine = this.height / lines;
|
|
4425
|
+
}
|
|
4426
|
+
return { firstLine, lastLine, perLine, perChar };
|
|
4406
4427
|
}
|
|
4407
|
-
blockAt(height,
|
|
4408
|
-
let { firstLine, lastLine,
|
|
4409
|
-
|
|
4410
|
-
|
|
4411
|
-
|
|
4428
|
+
blockAt(height, oracle, top, offset) {
|
|
4429
|
+
let { firstLine, lastLine, perLine, perChar } = this.heightMetrics(oracle, offset);
|
|
4430
|
+
if (oracle.lineWrapping) {
|
|
4431
|
+
let guess = offset + Math.round(Math.max(0, Math.min(1, (height - top) / this.height)) * this.length);
|
|
4432
|
+
let line = oracle.doc.lineAt(guess), lineHeight = perLine + line.length * perChar;
|
|
4433
|
+
let lineTop = Math.max(top, height - lineHeight / 2);
|
|
4434
|
+
return new BlockInfo(line.from, line.length, lineTop, lineHeight, exports.BlockType.Text);
|
|
4435
|
+
}
|
|
4436
|
+
else {
|
|
4437
|
+
let line = Math.max(0, Math.min(lastLine - firstLine, Math.floor((height - top) / perLine)));
|
|
4438
|
+
let { from, length } = oracle.doc.line(firstLine + line);
|
|
4439
|
+
return new BlockInfo(from, length, top + perLine * line, perLine, exports.BlockType.Text);
|
|
4440
|
+
}
|
|
4412
4441
|
}
|
|
4413
|
-
lineAt(value, type,
|
|
4442
|
+
lineAt(value, type, oracle, top, offset) {
|
|
4414
4443
|
if (type == QueryType.ByHeight)
|
|
4415
|
-
return this.blockAt(value,
|
|
4444
|
+
return this.blockAt(value, oracle, top, offset);
|
|
4416
4445
|
if (type == QueryType.ByPosNoHeight) {
|
|
4417
|
-
let { from, to } = doc.lineAt(value);
|
|
4446
|
+
let { from, to } = oracle.doc.lineAt(value);
|
|
4418
4447
|
return new BlockInfo(from, to - from, 0, 0, exports.BlockType.Text);
|
|
4419
4448
|
}
|
|
4420
|
-
let { firstLine,
|
|
4421
|
-
let
|
|
4422
|
-
|
|
4423
|
-
|
|
4424
|
-
|
|
4425
|
-
|
|
4426
|
-
|
|
4427
|
-
|
|
4428
|
-
|
|
4429
|
-
|
|
4430
|
-
|
|
4431
|
-
|
|
4449
|
+
let { firstLine, perLine, perChar } = this.heightMetrics(oracle, offset);
|
|
4450
|
+
let line = oracle.doc.lineAt(value), lineHeight = perLine + line.length * perChar;
|
|
4451
|
+
let linesAbove = line.number - firstLine;
|
|
4452
|
+
let lineTop = top + perLine * linesAbove + perChar * (line.from - offset - linesAbove);
|
|
4453
|
+
return new BlockInfo(line.from, line.length, Math.max(top, Math.min(lineTop, top + this.height - lineHeight)), lineHeight, exports.BlockType.Text);
|
|
4454
|
+
}
|
|
4455
|
+
forEachLine(from, to, oracle, top, offset, f) {
|
|
4456
|
+
from = Math.max(from, offset);
|
|
4457
|
+
to = Math.min(to, offset + this.length);
|
|
4458
|
+
let { firstLine, perLine, perChar } = this.heightMetrics(oracle, offset);
|
|
4459
|
+
for (let pos = from, lineTop = top; pos <= to;) {
|
|
4460
|
+
let line = oracle.doc.lineAt(pos);
|
|
4461
|
+
if (pos == from) {
|
|
4462
|
+
let linesAbove = line.number - firstLine;
|
|
4463
|
+
lineTop += perLine * linesAbove + perChar * (from - offset - linesAbove);
|
|
4464
|
+
}
|
|
4465
|
+
let lineHeight = perLine + perChar * line.length;
|
|
4466
|
+
f(new BlockInfo(line.from, line.length, lineTop, lineHeight, exports.BlockType.Text));
|
|
4467
|
+
lineTop += lineHeight;
|
|
4432
4468
|
pos = line.to + 1;
|
|
4433
4469
|
}
|
|
4434
4470
|
}
|
|
@@ -4464,7 +4500,6 @@ class HeightMapGap extends HeightMap {
|
|
|
4464
4500
|
// they would already have been added to the heightmap (gaps
|
|
4465
4501
|
// only contain plain text).
|
|
4466
4502
|
let nodes = [], pos = Math.max(offset, measured.from), singleHeight = -1;
|
|
4467
|
-
let wasChanged = oracle.heightChanged;
|
|
4468
4503
|
if (measured.from > offset)
|
|
4469
4504
|
nodes.push(new HeightMapGap(measured.from - offset - 1).updateHeight(oracle, offset));
|
|
4470
4505
|
while (pos <= end && measured.more) {
|
|
@@ -4484,8 +4519,9 @@ class HeightMapGap extends HeightMap {
|
|
|
4484
4519
|
if (pos <= end)
|
|
4485
4520
|
nodes.push(null, new HeightMapGap(end - pos).updateHeight(oracle, pos));
|
|
4486
4521
|
let result = HeightMap.of(nodes);
|
|
4487
|
-
|
|
4488
|
-
Math.abs(singleHeight - this.
|
|
4522
|
+
if (singleHeight < 0 || Math.abs(result.height - this.height) >= Epsilon ||
|
|
4523
|
+
Math.abs(singleHeight - this.heightMetrics(oracle, offset).perLine) >= Epsilon)
|
|
4524
|
+
oracle.heightChanged = true;
|
|
4489
4525
|
return result;
|
|
4490
4526
|
}
|
|
4491
4527
|
else if (force || this.outdated) {
|
|
@@ -4504,40 +4540,40 @@ class HeightMapBranch extends HeightMap {
|
|
|
4504
4540
|
this.size = left.size + right.size;
|
|
4505
4541
|
}
|
|
4506
4542
|
get break() { return this.flags & 1 /* Flag.Break */; }
|
|
4507
|
-
blockAt(height,
|
|
4543
|
+
blockAt(height, oracle, top, offset) {
|
|
4508
4544
|
let mid = top + this.left.height;
|
|
4509
|
-
return height < mid ? this.left.blockAt(height,
|
|
4510
|
-
: this.right.blockAt(height,
|
|
4545
|
+
return height < mid ? this.left.blockAt(height, oracle, top, offset)
|
|
4546
|
+
: this.right.blockAt(height, oracle, mid, offset + this.left.length + this.break);
|
|
4511
4547
|
}
|
|
4512
|
-
lineAt(value, type,
|
|
4548
|
+
lineAt(value, type, oracle, top, offset) {
|
|
4513
4549
|
let rightTop = top + this.left.height, rightOffset = offset + this.left.length + this.break;
|
|
4514
4550
|
let left = type == QueryType.ByHeight ? value < rightTop : value < rightOffset;
|
|
4515
|
-
let base = left ? this.left.lineAt(value, type,
|
|
4516
|
-
: this.right.lineAt(value, type,
|
|
4551
|
+
let base = left ? this.left.lineAt(value, type, oracle, top, offset)
|
|
4552
|
+
: this.right.lineAt(value, type, oracle, rightTop, rightOffset);
|
|
4517
4553
|
if (this.break || (left ? base.to < rightOffset : base.from > rightOffset))
|
|
4518
4554
|
return base;
|
|
4519
4555
|
let subQuery = type == QueryType.ByPosNoHeight ? QueryType.ByPosNoHeight : QueryType.ByPos;
|
|
4520
4556
|
if (left)
|
|
4521
|
-
return base.join(this.right.lineAt(rightOffset, subQuery,
|
|
4557
|
+
return base.join(this.right.lineAt(rightOffset, subQuery, oracle, rightTop, rightOffset));
|
|
4522
4558
|
else
|
|
4523
|
-
return this.left.lineAt(rightOffset, subQuery,
|
|
4559
|
+
return this.left.lineAt(rightOffset, subQuery, oracle, top, offset).join(base);
|
|
4524
4560
|
}
|
|
4525
|
-
forEachLine(from, to,
|
|
4561
|
+
forEachLine(from, to, oracle, top, offset, f) {
|
|
4526
4562
|
let rightTop = top + this.left.height, rightOffset = offset + this.left.length + this.break;
|
|
4527
4563
|
if (this.break) {
|
|
4528
4564
|
if (from < rightOffset)
|
|
4529
|
-
this.left.forEachLine(from, to,
|
|
4565
|
+
this.left.forEachLine(from, to, oracle, top, offset, f);
|
|
4530
4566
|
if (to >= rightOffset)
|
|
4531
|
-
this.right.forEachLine(from, to,
|
|
4567
|
+
this.right.forEachLine(from, to, oracle, rightTop, rightOffset, f);
|
|
4532
4568
|
}
|
|
4533
4569
|
else {
|
|
4534
|
-
let mid = this.lineAt(rightOffset, QueryType.ByPos,
|
|
4570
|
+
let mid = this.lineAt(rightOffset, QueryType.ByPos, oracle, top, offset);
|
|
4535
4571
|
if (from < mid.from)
|
|
4536
|
-
this.left.forEachLine(from, mid.from - 1,
|
|
4572
|
+
this.left.forEachLine(from, mid.from - 1, oracle, top, offset, f);
|
|
4537
4573
|
if (mid.to >= from && mid.from <= to)
|
|
4538
4574
|
f(mid);
|
|
4539
4575
|
if (to > mid.to)
|
|
4540
|
-
this.right.forEachLine(mid.to + 1, to,
|
|
4576
|
+
this.right.forEachLine(mid.to + 1, to, oracle, rightTop, rightOffset, f);
|
|
4541
4577
|
}
|
|
4542
4578
|
}
|
|
4543
4579
|
replace(from, to, nodes) {
|
|
@@ -4887,11 +4923,11 @@ class ViewState {
|
|
|
4887
4923
|
}
|
|
4888
4924
|
this.viewports = viewports.sort((a, b) => a.from - b.from);
|
|
4889
4925
|
this.scaler = this.heightMap.height <= 7000000 /* VP.MaxDOMHeight */ ? IdScaler :
|
|
4890
|
-
new BigScaler(this.heightOracle
|
|
4926
|
+
new BigScaler(this.heightOracle, this.heightMap, this.viewports);
|
|
4891
4927
|
}
|
|
4892
4928
|
updateViewportLines() {
|
|
4893
4929
|
this.viewportLines = [];
|
|
4894
|
-
this.heightMap.forEachLine(this.viewport.from, this.viewport.to, this.state.doc, 0, 0, block => {
|
|
4930
|
+
this.heightMap.forEachLine(this.viewport.from, this.viewport.to, this.heightOracle.setDoc(this.state.doc), 0, 0, block => {
|
|
4895
4931
|
this.viewportLines.push(this.scaler.scale == 1 ? block : scaleBlock(block, this.scaler));
|
|
4896
4932
|
});
|
|
4897
4933
|
}
|
|
@@ -4931,8 +4967,9 @@ class ViewState {
|
|
|
4931
4967
|
let whiteSpace = style.whiteSpace;
|
|
4932
4968
|
this.defaultTextDirection = style.direction == "rtl" ? exports.Direction.RTL : exports.Direction.LTR;
|
|
4933
4969
|
let refresh = this.heightOracle.mustRefreshForWrapping(whiteSpace);
|
|
4934
|
-
let
|
|
4935
|
-
this.contentDOMHeight
|
|
4970
|
+
let domRect = dom.getBoundingClientRect();
|
|
4971
|
+
let measureContent = refresh || this.mustMeasureContent || this.contentDOMHeight != domRect.height;
|
|
4972
|
+
this.contentDOMHeight = domRect.height;
|
|
4936
4973
|
this.mustMeasureContent = false;
|
|
4937
4974
|
let result = 0, bias = 0;
|
|
4938
4975
|
// Vertical padding
|
|
@@ -4960,9 +4997,9 @@ class ViewState {
|
|
|
4960
4997
|
}
|
|
4961
4998
|
if (!this.inView && !this.scrollTarget)
|
|
4962
4999
|
return 0;
|
|
4963
|
-
let contentWidth =
|
|
5000
|
+
let contentWidth = domRect.width;
|
|
4964
5001
|
if (this.contentDOMWidth != contentWidth || this.editorHeight != view.scrollDOM.clientHeight) {
|
|
4965
|
-
this.contentDOMWidth =
|
|
5002
|
+
this.contentDOMWidth = domRect.width;
|
|
4966
5003
|
this.editorHeight = view.scrollDOM.clientHeight;
|
|
4967
5004
|
result |= 8 /* UpdateFlag.Geometry */;
|
|
4968
5005
|
}
|
|
@@ -4991,7 +5028,8 @@ class ViewState {
|
|
|
4991
5028
|
result |= 2 /* UpdateFlag.Height */;
|
|
4992
5029
|
}
|
|
4993
5030
|
let viewportChange = !this.viewportIsAppropriate(this.viewport, bias) ||
|
|
4994
|
-
this.scrollTarget && (this.scrollTarget.range.head < this.viewport.from ||
|
|
5031
|
+
this.scrollTarget && (this.scrollTarget.range.head < this.viewport.from ||
|
|
5032
|
+
this.scrollTarget.range.head > this.viewport.to);
|
|
4995
5033
|
if (viewportChange)
|
|
4996
5034
|
this.viewport = this.getViewport(bias, this.scrollTarget);
|
|
4997
5035
|
this.updateForViewport();
|
|
@@ -5017,36 +5055,37 @@ class ViewState {
|
|
|
5017
5055
|
// bottom, depending on the bias (the change in viewport position
|
|
5018
5056
|
// since the last update). It'll hold a number between 0 and 1
|
|
5019
5057
|
let marginTop = 0.5 - Math.max(-0.5, Math.min(0.5, bias / 1000 /* VP.Margin */ / 2));
|
|
5020
|
-
let map = this.heightMap,
|
|
5021
|
-
let
|
|
5058
|
+
let map = this.heightMap, oracle = this.heightOracle;
|
|
5059
|
+
let { visibleTop, visibleBottom } = this;
|
|
5060
|
+
let viewport = new Viewport(map.lineAt(visibleTop - marginTop * 1000 /* VP.Margin */, QueryType.ByHeight, oracle, 0, 0).from, map.lineAt(visibleBottom + (1 - marginTop) * 1000 /* VP.Margin */, QueryType.ByHeight, oracle, 0, 0).to);
|
|
5022
5061
|
// If scrollTarget is given, make sure the viewport includes that position
|
|
5023
5062
|
if (scrollTarget) {
|
|
5024
5063
|
let { head } = scrollTarget.range;
|
|
5025
5064
|
if (head < viewport.from || head > viewport.to) {
|
|
5026
5065
|
let viewHeight = Math.min(this.editorHeight, this.pixelViewport.bottom - this.pixelViewport.top);
|
|
5027
|
-
let block = map.lineAt(head, QueryType.ByPos,
|
|
5066
|
+
let block = map.lineAt(head, QueryType.ByPos, oracle, 0, 0), topPos;
|
|
5028
5067
|
if (scrollTarget.y == "center")
|
|
5029
5068
|
topPos = (block.top + block.bottom) / 2 - viewHeight / 2;
|
|
5030
5069
|
else if (scrollTarget.y == "start" || scrollTarget.y == "nearest" && head < viewport.from)
|
|
5031
5070
|
topPos = block.top;
|
|
5032
5071
|
else
|
|
5033
5072
|
topPos = block.bottom - viewHeight;
|
|
5034
|
-
viewport = new Viewport(map.lineAt(topPos - 1000 /* VP.Margin */ / 2, QueryType.ByHeight,
|
|
5073
|
+
viewport = new Viewport(map.lineAt(topPos - 1000 /* VP.Margin */ / 2, QueryType.ByHeight, oracle, 0, 0).from, map.lineAt(topPos + viewHeight + 1000 /* VP.Margin */ / 2, QueryType.ByHeight, oracle, 0, 0).to);
|
|
5035
5074
|
}
|
|
5036
5075
|
}
|
|
5037
5076
|
return viewport;
|
|
5038
5077
|
}
|
|
5039
5078
|
mapViewport(viewport, changes) {
|
|
5040
5079
|
let from = changes.mapPos(viewport.from, -1), to = changes.mapPos(viewport.to, 1);
|
|
5041
|
-
return new Viewport(this.heightMap.lineAt(from, QueryType.ByPos, this.
|
|
5080
|
+
return new Viewport(this.heightMap.lineAt(from, QueryType.ByPos, this.heightOracle, 0, 0).from, this.heightMap.lineAt(to, QueryType.ByPos, this.heightOracle, 0, 0).to);
|
|
5042
5081
|
}
|
|
5043
5082
|
// Checks if a given viewport covers the visible part of the
|
|
5044
5083
|
// document and not too much beyond that.
|
|
5045
5084
|
viewportIsAppropriate({ from, to }, bias = 0) {
|
|
5046
5085
|
if (!this.inView)
|
|
5047
5086
|
return true;
|
|
5048
|
-
let { top } = this.heightMap.lineAt(from, QueryType.ByPos, this.
|
|
5049
|
-
let { bottom } = this.heightMap.lineAt(to, QueryType.ByPos, this.
|
|
5087
|
+
let { top } = this.heightMap.lineAt(from, QueryType.ByPos, this.heightOracle, 0, 0);
|
|
5088
|
+
let { bottom } = this.heightMap.lineAt(to, QueryType.ByPos, this.heightOracle, 0, 0);
|
|
5050
5089
|
let { visibleTop, visibleBottom } = this;
|
|
5051
5090
|
return (from == 0 || top <= visibleTop - Math.max(10 /* VP.MinCoverMargin */, Math.min(-bias, 250 /* VP.MaxCoverMargin */))) &&
|
|
5052
5091
|
(to == this.state.doc.length ||
|
|
@@ -5183,13 +5222,13 @@ class ViewState {
|
|
|
5183
5222
|
}
|
|
5184
5223
|
lineBlockAt(pos) {
|
|
5185
5224
|
return (pos >= this.viewport.from && pos <= this.viewport.to && this.viewportLines.find(b => b.from <= pos && b.to >= pos)) ||
|
|
5186
|
-
scaleBlock(this.heightMap.lineAt(pos, QueryType.ByPos, this.
|
|
5225
|
+
scaleBlock(this.heightMap.lineAt(pos, QueryType.ByPos, this.heightOracle, 0, 0), this.scaler);
|
|
5187
5226
|
}
|
|
5188
5227
|
lineBlockAtHeight(height) {
|
|
5189
|
-
return scaleBlock(this.heightMap.lineAt(this.scaler.fromDOM(height), QueryType.ByHeight, this.
|
|
5228
|
+
return scaleBlock(this.heightMap.lineAt(this.scaler.fromDOM(height), QueryType.ByHeight, this.heightOracle, 0, 0), this.scaler);
|
|
5190
5229
|
}
|
|
5191
5230
|
elementAtHeight(height) {
|
|
5192
|
-
return scaleBlock(this.heightMap.blockAt(this.scaler.fromDOM(height), this.
|
|
5231
|
+
return scaleBlock(this.heightMap.blockAt(this.scaler.fromDOM(height), this.heightOracle, 0, 0), this.scaler);
|
|
5193
5232
|
}
|
|
5194
5233
|
get docHeight() {
|
|
5195
5234
|
return this.scaler.toDOM(this.heightMap.height);
|
|
@@ -5263,11 +5302,11 @@ const IdScaler = {
|
|
|
5263
5302
|
// regions outside the viewports so that the total height is
|
|
5264
5303
|
// VP.MaxDOMHeight.
|
|
5265
5304
|
class BigScaler {
|
|
5266
|
-
constructor(
|
|
5305
|
+
constructor(oracle, heightMap, viewports) {
|
|
5267
5306
|
let vpHeight = 0, base = 0, domBase = 0;
|
|
5268
5307
|
this.viewports = viewports.map(({ from, to }) => {
|
|
5269
|
-
let top = heightMap.lineAt(from, QueryType.ByPos,
|
|
5270
|
-
let bottom = heightMap.lineAt(to, QueryType.ByPos,
|
|
5308
|
+
let top = heightMap.lineAt(from, QueryType.ByPos, oracle, 0, 0).top;
|
|
5309
|
+
let bottom = heightMap.lineAt(to, QueryType.ByPos, oracle, 0, 0).bottom;
|
|
5271
5310
|
vpHeight += bottom - top;
|
|
5272
5311
|
return { from, to, top, bottom, domTop: 0, domBottom: 0 };
|
|
5273
5312
|
});
|
|
@@ -5634,7 +5673,7 @@ function applyDOMChange(view, domChange) {
|
|
|
5634
5673
|
};
|
|
5635
5674
|
}
|
|
5636
5675
|
else if ((browser.mac || browser.android) && change && change.from == change.to && change.from == sel.head - 1 &&
|
|
5637
|
-
/^\. ?$/.test(change.insert.toString())) {
|
|
5676
|
+
/^\. ?$/.test(change.insert.toString()) && view.contentDOM.getAttribute("autocorrect") == "off") {
|
|
5638
5677
|
// Detect insert-period-on-double-space Mac and Android behavior,
|
|
5639
5678
|
// and transform it into a regular space insert.
|
|
5640
5679
|
if (newSel && change.insert.length == 2)
|
|
@@ -7048,6 +7087,11 @@ called and the default behavior is prevented.
|
|
|
7048
7087
|
*/
|
|
7049
7088
|
EditorView.inputHandler = inputHandler;
|
|
7050
7089
|
/**
|
|
7090
|
+
This facet can be used to provide functions that create effects
|
|
7091
|
+
to be dispatched when the editor's focus state changes.
|
|
7092
|
+
*/
|
|
7093
|
+
EditorView.focusChangeEffect = focusChangeEffect;
|
|
7094
|
+
/**
|
|
7051
7095
|
By default, the editor assumes all its content has the same
|
|
7052
7096
|
[text direction](https://codemirror.net/6/docs/ref/#view.Direction). Configure this with a `true`
|
|
7053
7097
|
value to make it read the text direction of every (rendered)
|
|
@@ -8363,6 +8407,7 @@ const tooltipConfig = state.Facet.define({
|
|
|
8363
8407
|
});
|
|
8364
8408
|
}
|
|
8365
8409
|
});
|
|
8410
|
+
const knownHeight = new WeakMap();
|
|
8366
8411
|
const tooltipPlugin = ViewPlugin.fromClass(class {
|
|
8367
8412
|
constructor(view) {
|
|
8368
8413
|
this.view = view;
|
|
@@ -8478,6 +8523,7 @@ const tooltipPlugin = ViewPlugin.fromClass(class {
|
|
|
8478
8523
|
};
|
|
8479
8524
|
}
|
|
8480
8525
|
writeMeasure(measured) {
|
|
8526
|
+
var _a;
|
|
8481
8527
|
let { editor, space } = measured;
|
|
8482
8528
|
let others = [];
|
|
8483
8529
|
for (let i = 0; i < this.manager.tooltips.length; i++) {
|
|
@@ -8493,7 +8539,7 @@ const tooltipPlugin = ViewPlugin.fromClass(class {
|
|
|
8493
8539
|
}
|
|
8494
8540
|
let arrow = tooltip.arrow ? tView.dom.querySelector(".cm-tooltip-arrow") : null;
|
|
8495
8541
|
let arrowHeight = arrow ? 7 /* Arrow.Size */ : 0;
|
|
8496
|
-
let width = size.right - size.left, height = size.bottom - size.top;
|
|
8542
|
+
let width = size.right - size.left, height = (_a = knownHeight.get(tView)) !== null && _a !== void 0 ? _a : size.bottom - size.top;
|
|
8497
8543
|
let offset = tView.offset || noOffset, ltr = this.view.textDirection == exports.Direction.LTR;
|
|
8498
8544
|
let left = size.width > space.right - space.left ? (ltr ? space.left : space.right - size.width)
|
|
8499
8545
|
: ltr ? Math.min(pos.left - (arrow ? 14 /* Arrow.Offset */ : 0) + offset.x, space.right - width)
|
|
@@ -8510,6 +8556,7 @@ const tooltipPlugin = ViewPlugin.fromClass(class {
|
|
|
8510
8556
|
dom.style.top = Outside;
|
|
8511
8557
|
continue;
|
|
8512
8558
|
}
|
|
8559
|
+
knownHeight.set(tView, height);
|
|
8513
8560
|
dom.style.height = (height = spaceVert) + "px";
|
|
8514
8561
|
}
|
|
8515
8562
|
else if (dom.style.height) {
|
package/dist/index.d.ts
CHANGED
|
@@ -995,6 +995,11 @@ declare class EditorView {
|
|
|
995
995
|
*/
|
|
996
996
|
static inputHandler: Facet<(view: EditorView, from: number, to: number, text: string) => boolean, readonly ((view: EditorView, from: number, to: number, text: string) => boolean)[]>;
|
|
997
997
|
/**
|
|
998
|
+
This facet can be used to provide functions that create effects
|
|
999
|
+
to be dispatched when the editor's focus state changes.
|
|
1000
|
+
*/
|
|
1001
|
+
static focusChangeEffect: Facet<(state: EditorState, focusing: boolean) => StateEffect<any> | null, readonly ((state: EditorState, focusing: boolean) => StateEffect<any> | null)[]>;
|
|
1002
|
+
/**
|
|
998
1003
|
By default, the editor assumes all its content has the same
|
|
999
1004
|
[text direction](https://codemirror.net/6/docs/ref/#view.Direction). Configure this with a `true`
|
|
1000
1005
|
value to make it read the text direction of every (rendered)
|
package/dist/index.js
CHANGED
|
@@ -1779,6 +1779,7 @@ const mouseSelectionStyle = /*@__PURE__*/Facet.define();
|
|
|
1779
1779
|
const exceptionSink = /*@__PURE__*/Facet.define();
|
|
1780
1780
|
const updateListener = /*@__PURE__*/Facet.define();
|
|
1781
1781
|
const inputHandler = /*@__PURE__*/Facet.define();
|
|
1782
|
+
const focusChangeEffect = /*@__PURE__*/Facet.define();
|
|
1782
1783
|
const perLineTextDirection = /*@__PURE__*/Facet.define({
|
|
1783
1784
|
combine: values => values.some(x => x)
|
|
1784
1785
|
});
|
|
@@ -4028,8 +4029,18 @@ handlers.copy = handlers.cut = (view, event) => {
|
|
|
4028
4029
|
};
|
|
4029
4030
|
function updateForFocusChange(view) {
|
|
4030
4031
|
setTimeout(() => {
|
|
4031
|
-
if (view.hasFocus != view.inputState.notifiedFocused)
|
|
4032
|
-
view.
|
|
4032
|
+
if (view.hasFocus != view.inputState.notifiedFocused) {
|
|
4033
|
+
let effects = [], focus = !view.inputState.notifiedFocused;
|
|
4034
|
+
for (let getEffect of view.state.facet(focusChangeEffect)) {
|
|
4035
|
+
let effect = getEffect(view.state, focus);
|
|
4036
|
+
if (effect)
|
|
4037
|
+
effects.push(effect);
|
|
4038
|
+
}
|
|
4039
|
+
if (effects.length)
|
|
4040
|
+
view.dispatch({ effects });
|
|
4041
|
+
else
|
|
4042
|
+
view.update([]);
|
|
4043
|
+
}
|
|
4033
4044
|
}, 10);
|
|
4034
4045
|
}
|
|
4035
4046
|
handlers.focus = view => {
|
|
@@ -4111,7 +4122,7 @@ class HeightOracle {
|
|
|
4111
4122
|
heightForGap(from, to) {
|
|
4112
4123
|
let lines = this.doc.lineAt(to).number - this.doc.lineAt(from).number + 1;
|
|
4113
4124
|
if (this.lineWrapping)
|
|
4114
|
-
lines += Math.ceil(((to - from) - (lines * this.lineLength * 0.5)) / this.lineLength);
|
|
4125
|
+
lines += Math.max(0, Math.ceil(((to - from) - (lines * this.lineLength * 0.5)) / this.lineLength));
|
|
4115
4126
|
return this.lineHeight * lines;
|
|
4116
4127
|
}
|
|
4117
4128
|
heightForLine(length) {
|
|
@@ -4256,11 +4267,11 @@ class HeightMap {
|
|
|
4256
4267
|
decomposeLeft(_to, result) { result.push(this); }
|
|
4257
4268
|
decomposeRight(_from, result) { result.push(this); }
|
|
4258
4269
|
applyChanges(decorations, oldDoc, oracle, changes) {
|
|
4259
|
-
let me = this;
|
|
4270
|
+
let me = this, doc = oracle.doc;
|
|
4260
4271
|
for (let i = changes.length - 1; i >= 0; i--) {
|
|
4261
4272
|
let { fromA, toA, fromB, toB } = changes[i];
|
|
4262
|
-
let start = me.lineAt(fromA, QueryType.ByPosNoHeight, oldDoc, 0, 0);
|
|
4263
|
-
let end = start.to >= toA ? start : me.lineAt(toA, QueryType.ByPosNoHeight,
|
|
4273
|
+
let start = me.lineAt(fromA, QueryType.ByPosNoHeight, oracle.setDoc(oldDoc), 0, 0);
|
|
4274
|
+
let end = start.to >= toA ? start : me.lineAt(toA, QueryType.ByPosNoHeight, oracle, 0, 0);
|
|
4264
4275
|
toB += end.to - toA;
|
|
4265
4276
|
toA = end.to;
|
|
4266
4277
|
while (i > 0 && start.from <= changes[i - 1].toA) {
|
|
@@ -4268,11 +4279,11 @@ class HeightMap {
|
|
|
4268
4279
|
fromB = changes[i - 1].fromB;
|
|
4269
4280
|
i--;
|
|
4270
4281
|
if (fromA < start.from)
|
|
4271
|
-
start = me.lineAt(fromA, QueryType.ByPosNoHeight,
|
|
4282
|
+
start = me.lineAt(fromA, QueryType.ByPosNoHeight, oracle, 0, 0);
|
|
4272
4283
|
}
|
|
4273
4284
|
fromB += start.from - fromA;
|
|
4274
4285
|
fromA = start.from;
|
|
4275
|
-
let nodes = NodeBuilder.build(oracle, decorations, fromB, toB);
|
|
4286
|
+
let nodes = NodeBuilder.build(oracle.setDoc(doc), decorations, fromB, toB);
|
|
4276
4287
|
me = me.replace(fromA, toA, nodes);
|
|
4277
4288
|
}
|
|
4278
4289
|
return me.updateHeight(oracle, 0);
|
|
@@ -4339,15 +4350,15 @@ class HeightMapBlock extends HeightMap {
|
|
|
4339
4350
|
super(length, height);
|
|
4340
4351
|
this.type = type;
|
|
4341
4352
|
}
|
|
4342
|
-
blockAt(_height,
|
|
4353
|
+
blockAt(_height, _oracle, top, offset) {
|
|
4343
4354
|
return new BlockInfo(offset, this.length, top, this.height, this.type);
|
|
4344
4355
|
}
|
|
4345
|
-
lineAt(_value, _type,
|
|
4346
|
-
return this.blockAt(0,
|
|
4356
|
+
lineAt(_value, _type, oracle, top, offset) {
|
|
4357
|
+
return this.blockAt(0, oracle, top, offset);
|
|
4347
4358
|
}
|
|
4348
|
-
forEachLine(from, to,
|
|
4359
|
+
forEachLine(from, to, oracle, top, offset, f) {
|
|
4349
4360
|
if (from <= offset + this.length && to >= offset)
|
|
4350
|
-
f(this.blockAt(0,
|
|
4361
|
+
f(this.blockAt(0, oracle, top, offset));
|
|
4351
4362
|
}
|
|
4352
4363
|
updateHeight(oracle, offset = 0, _force = false, measured) {
|
|
4353
4364
|
if (measured && measured.from <= offset && measured.more)
|
|
@@ -4393,35 +4404,60 @@ class HeightMapText extends HeightMapBlock {
|
|
|
4393
4404
|
}
|
|
4394
4405
|
class HeightMapGap extends HeightMap {
|
|
4395
4406
|
constructor(length) { super(length, 0); }
|
|
4396
|
-
|
|
4397
|
-
let firstLine = doc.lineAt(offset).number, lastLine = doc.lineAt(offset + this.length).number;
|
|
4398
|
-
|
|
4407
|
+
heightMetrics(oracle, offset) {
|
|
4408
|
+
let firstLine = oracle.doc.lineAt(offset).number, lastLine = oracle.doc.lineAt(offset + this.length).number;
|
|
4409
|
+
let lines = lastLine - firstLine + 1;
|
|
4410
|
+
let perLine, perChar = 0;
|
|
4411
|
+
if (oracle.lineWrapping) {
|
|
4412
|
+
let totalPerLine = Math.min(this.height, oracle.lineHeight * lines);
|
|
4413
|
+
perLine = totalPerLine / lines;
|
|
4414
|
+
perChar = (this.height - totalPerLine) / (this.length - lines - 1);
|
|
4415
|
+
}
|
|
4416
|
+
else {
|
|
4417
|
+
perLine = this.height / lines;
|
|
4418
|
+
}
|
|
4419
|
+
return { firstLine, lastLine, perLine, perChar };
|
|
4399
4420
|
}
|
|
4400
|
-
blockAt(height,
|
|
4401
|
-
let { firstLine, lastLine,
|
|
4402
|
-
|
|
4403
|
-
|
|
4404
|
-
|
|
4421
|
+
blockAt(height, oracle, top, offset) {
|
|
4422
|
+
let { firstLine, lastLine, perLine, perChar } = this.heightMetrics(oracle, offset);
|
|
4423
|
+
if (oracle.lineWrapping) {
|
|
4424
|
+
let guess = offset + Math.round(Math.max(0, Math.min(1, (height - top) / this.height)) * this.length);
|
|
4425
|
+
let line = oracle.doc.lineAt(guess), lineHeight = perLine + line.length * perChar;
|
|
4426
|
+
let lineTop = Math.max(top, height - lineHeight / 2);
|
|
4427
|
+
return new BlockInfo(line.from, line.length, lineTop, lineHeight, BlockType.Text);
|
|
4428
|
+
}
|
|
4429
|
+
else {
|
|
4430
|
+
let line = Math.max(0, Math.min(lastLine - firstLine, Math.floor((height - top) / perLine)));
|
|
4431
|
+
let { from, length } = oracle.doc.line(firstLine + line);
|
|
4432
|
+
return new BlockInfo(from, length, top + perLine * line, perLine, BlockType.Text);
|
|
4433
|
+
}
|
|
4405
4434
|
}
|
|
4406
|
-
lineAt(value, type,
|
|
4435
|
+
lineAt(value, type, oracle, top, offset) {
|
|
4407
4436
|
if (type == QueryType.ByHeight)
|
|
4408
|
-
return this.blockAt(value,
|
|
4437
|
+
return this.blockAt(value, oracle, top, offset);
|
|
4409
4438
|
if (type == QueryType.ByPosNoHeight) {
|
|
4410
|
-
let { from, to } = doc.lineAt(value);
|
|
4439
|
+
let { from, to } = oracle.doc.lineAt(value);
|
|
4411
4440
|
return new BlockInfo(from, to - from, 0, 0, BlockType.Text);
|
|
4412
4441
|
}
|
|
4413
|
-
let { firstLine,
|
|
4414
|
-
let
|
|
4415
|
-
|
|
4416
|
-
|
|
4417
|
-
|
|
4418
|
-
|
|
4419
|
-
|
|
4420
|
-
|
|
4421
|
-
|
|
4422
|
-
|
|
4423
|
-
|
|
4424
|
-
|
|
4442
|
+
let { firstLine, perLine, perChar } = this.heightMetrics(oracle, offset);
|
|
4443
|
+
let line = oracle.doc.lineAt(value), lineHeight = perLine + line.length * perChar;
|
|
4444
|
+
let linesAbove = line.number - firstLine;
|
|
4445
|
+
let lineTop = top + perLine * linesAbove + perChar * (line.from - offset - linesAbove);
|
|
4446
|
+
return new BlockInfo(line.from, line.length, Math.max(top, Math.min(lineTop, top + this.height - lineHeight)), lineHeight, BlockType.Text);
|
|
4447
|
+
}
|
|
4448
|
+
forEachLine(from, to, oracle, top, offset, f) {
|
|
4449
|
+
from = Math.max(from, offset);
|
|
4450
|
+
to = Math.min(to, offset + this.length);
|
|
4451
|
+
let { firstLine, perLine, perChar } = this.heightMetrics(oracle, offset);
|
|
4452
|
+
for (let pos = from, lineTop = top; pos <= to;) {
|
|
4453
|
+
let line = oracle.doc.lineAt(pos);
|
|
4454
|
+
if (pos == from) {
|
|
4455
|
+
let linesAbove = line.number - firstLine;
|
|
4456
|
+
lineTop += perLine * linesAbove + perChar * (from - offset - linesAbove);
|
|
4457
|
+
}
|
|
4458
|
+
let lineHeight = perLine + perChar * line.length;
|
|
4459
|
+
f(new BlockInfo(line.from, line.length, lineTop, lineHeight, BlockType.Text));
|
|
4460
|
+
lineTop += lineHeight;
|
|
4425
4461
|
pos = line.to + 1;
|
|
4426
4462
|
}
|
|
4427
4463
|
}
|
|
@@ -4457,7 +4493,6 @@ class HeightMapGap extends HeightMap {
|
|
|
4457
4493
|
// they would already have been added to the heightmap (gaps
|
|
4458
4494
|
// only contain plain text).
|
|
4459
4495
|
let nodes = [], pos = Math.max(offset, measured.from), singleHeight = -1;
|
|
4460
|
-
let wasChanged = oracle.heightChanged;
|
|
4461
4496
|
if (measured.from > offset)
|
|
4462
4497
|
nodes.push(new HeightMapGap(measured.from - offset - 1).updateHeight(oracle, offset));
|
|
4463
4498
|
while (pos <= end && measured.more) {
|
|
@@ -4477,8 +4512,9 @@ class HeightMapGap extends HeightMap {
|
|
|
4477
4512
|
if (pos <= end)
|
|
4478
4513
|
nodes.push(null, new HeightMapGap(end - pos).updateHeight(oracle, pos));
|
|
4479
4514
|
let result = HeightMap.of(nodes);
|
|
4480
|
-
|
|
4481
|
-
Math.abs(singleHeight - this.
|
|
4515
|
+
if (singleHeight < 0 || Math.abs(result.height - this.height) >= Epsilon ||
|
|
4516
|
+
Math.abs(singleHeight - this.heightMetrics(oracle, offset).perLine) >= Epsilon)
|
|
4517
|
+
oracle.heightChanged = true;
|
|
4482
4518
|
return result;
|
|
4483
4519
|
}
|
|
4484
4520
|
else if (force || this.outdated) {
|
|
@@ -4497,40 +4533,40 @@ class HeightMapBranch extends HeightMap {
|
|
|
4497
4533
|
this.size = left.size + right.size;
|
|
4498
4534
|
}
|
|
4499
4535
|
get break() { return this.flags & 1 /* Flag.Break */; }
|
|
4500
|
-
blockAt(height,
|
|
4536
|
+
blockAt(height, oracle, top, offset) {
|
|
4501
4537
|
let mid = top + this.left.height;
|
|
4502
|
-
return height < mid ? this.left.blockAt(height,
|
|
4503
|
-
: this.right.blockAt(height,
|
|
4538
|
+
return height < mid ? this.left.blockAt(height, oracle, top, offset)
|
|
4539
|
+
: this.right.blockAt(height, oracle, mid, offset + this.left.length + this.break);
|
|
4504
4540
|
}
|
|
4505
|
-
lineAt(value, type,
|
|
4541
|
+
lineAt(value, type, oracle, top, offset) {
|
|
4506
4542
|
let rightTop = top + this.left.height, rightOffset = offset + this.left.length + this.break;
|
|
4507
4543
|
let left = type == QueryType.ByHeight ? value < rightTop : value < rightOffset;
|
|
4508
|
-
let base = left ? this.left.lineAt(value, type,
|
|
4509
|
-
: this.right.lineAt(value, type,
|
|
4544
|
+
let base = left ? this.left.lineAt(value, type, oracle, top, offset)
|
|
4545
|
+
: this.right.lineAt(value, type, oracle, rightTop, rightOffset);
|
|
4510
4546
|
if (this.break || (left ? base.to < rightOffset : base.from > rightOffset))
|
|
4511
4547
|
return base;
|
|
4512
4548
|
let subQuery = type == QueryType.ByPosNoHeight ? QueryType.ByPosNoHeight : QueryType.ByPos;
|
|
4513
4549
|
if (left)
|
|
4514
|
-
return base.join(this.right.lineAt(rightOffset, subQuery,
|
|
4550
|
+
return base.join(this.right.lineAt(rightOffset, subQuery, oracle, rightTop, rightOffset));
|
|
4515
4551
|
else
|
|
4516
|
-
return this.left.lineAt(rightOffset, subQuery,
|
|
4552
|
+
return this.left.lineAt(rightOffset, subQuery, oracle, top, offset).join(base);
|
|
4517
4553
|
}
|
|
4518
|
-
forEachLine(from, to,
|
|
4554
|
+
forEachLine(from, to, oracle, top, offset, f) {
|
|
4519
4555
|
let rightTop = top + this.left.height, rightOffset = offset + this.left.length + this.break;
|
|
4520
4556
|
if (this.break) {
|
|
4521
4557
|
if (from < rightOffset)
|
|
4522
|
-
this.left.forEachLine(from, to,
|
|
4558
|
+
this.left.forEachLine(from, to, oracle, top, offset, f);
|
|
4523
4559
|
if (to >= rightOffset)
|
|
4524
|
-
this.right.forEachLine(from, to,
|
|
4560
|
+
this.right.forEachLine(from, to, oracle, rightTop, rightOffset, f);
|
|
4525
4561
|
}
|
|
4526
4562
|
else {
|
|
4527
|
-
let mid = this.lineAt(rightOffset, QueryType.ByPos,
|
|
4563
|
+
let mid = this.lineAt(rightOffset, QueryType.ByPos, oracle, top, offset);
|
|
4528
4564
|
if (from < mid.from)
|
|
4529
|
-
this.left.forEachLine(from, mid.from - 1,
|
|
4565
|
+
this.left.forEachLine(from, mid.from - 1, oracle, top, offset, f);
|
|
4530
4566
|
if (mid.to >= from && mid.from <= to)
|
|
4531
4567
|
f(mid);
|
|
4532
4568
|
if (to > mid.to)
|
|
4533
|
-
this.right.forEachLine(mid.to + 1, to,
|
|
4569
|
+
this.right.forEachLine(mid.to + 1, to, oracle, rightTop, rightOffset, f);
|
|
4534
4570
|
}
|
|
4535
4571
|
}
|
|
4536
4572
|
replace(from, to, nodes) {
|
|
@@ -4880,11 +4916,11 @@ class ViewState {
|
|
|
4880
4916
|
}
|
|
4881
4917
|
this.viewports = viewports.sort((a, b) => a.from - b.from);
|
|
4882
4918
|
this.scaler = this.heightMap.height <= 7000000 /* VP.MaxDOMHeight */ ? IdScaler :
|
|
4883
|
-
new BigScaler(this.heightOracle
|
|
4919
|
+
new BigScaler(this.heightOracle, this.heightMap, this.viewports);
|
|
4884
4920
|
}
|
|
4885
4921
|
updateViewportLines() {
|
|
4886
4922
|
this.viewportLines = [];
|
|
4887
|
-
this.heightMap.forEachLine(this.viewport.from, this.viewport.to, this.state.doc, 0, 0, block => {
|
|
4923
|
+
this.heightMap.forEachLine(this.viewport.from, this.viewport.to, this.heightOracle.setDoc(this.state.doc), 0, 0, block => {
|
|
4888
4924
|
this.viewportLines.push(this.scaler.scale == 1 ? block : scaleBlock(block, this.scaler));
|
|
4889
4925
|
});
|
|
4890
4926
|
}
|
|
@@ -4924,8 +4960,9 @@ class ViewState {
|
|
|
4924
4960
|
let whiteSpace = style.whiteSpace;
|
|
4925
4961
|
this.defaultTextDirection = style.direction == "rtl" ? Direction.RTL : Direction.LTR;
|
|
4926
4962
|
let refresh = this.heightOracle.mustRefreshForWrapping(whiteSpace);
|
|
4927
|
-
let
|
|
4928
|
-
this.contentDOMHeight
|
|
4963
|
+
let domRect = dom.getBoundingClientRect();
|
|
4964
|
+
let measureContent = refresh || this.mustMeasureContent || this.contentDOMHeight != domRect.height;
|
|
4965
|
+
this.contentDOMHeight = domRect.height;
|
|
4929
4966
|
this.mustMeasureContent = false;
|
|
4930
4967
|
let result = 0, bias = 0;
|
|
4931
4968
|
// Vertical padding
|
|
@@ -4953,9 +4990,9 @@ class ViewState {
|
|
|
4953
4990
|
}
|
|
4954
4991
|
if (!this.inView && !this.scrollTarget)
|
|
4955
4992
|
return 0;
|
|
4956
|
-
let contentWidth =
|
|
4993
|
+
let contentWidth = domRect.width;
|
|
4957
4994
|
if (this.contentDOMWidth != contentWidth || this.editorHeight != view.scrollDOM.clientHeight) {
|
|
4958
|
-
this.contentDOMWidth =
|
|
4995
|
+
this.contentDOMWidth = domRect.width;
|
|
4959
4996
|
this.editorHeight = view.scrollDOM.clientHeight;
|
|
4960
4997
|
result |= 8 /* UpdateFlag.Geometry */;
|
|
4961
4998
|
}
|
|
@@ -4984,7 +5021,8 @@ class ViewState {
|
|
|
4984
5021
|
result |= 2 /* UpdateFlag.Height */;
|
|
4985
5022
|
}
|
|
4986
5023
|
let viewportChange = !this.viewportIsAppropriate(this.viewport, bias) ||
|
|
4987
|
-
this.scrollTarget && (this.scrollTarget.range.head < this.viewport.from ||
|
|
5024
|
+
this.scrollTarget && (this.scrollTarget.range.head < this.viewport.from ||
|
|
5025
|
+
this.scrollTarget.range.head > this.viewport.to);
|
|
4988
5026
|
if (viewportChange)
|
|
4989
5027
|
this.viewport = this.getViewport(bias, this.scrollTarget);
|
|
4990
5028
|
this.updateForViewport();
|
|
@@ -5010,36 +5048,37 @@ class ViewState {
|
|
|
5010
5048
|
// bottom, depending on the bias (the change in viewport position
|
|
5011
5049
|
// since the last update). It'll hold a number between 0 and 1
|
|
5012
5050
|
let marginTop = 0.5 - Math.max(-0.5, Math.min(0.5, bias / 1000 /* VP.Margin */ / 2));
|
|
5013
|
-
let map = this.heightMap,
|
|
5014
|
-
let
|
|
5051
|
+
let map = this.heightMap, oracle = this.heightOracle;
|
|
5052
|
+
let { visibleTop, visibleBottom } = this;
|
|
5053
|
+
let viewport = new Viewport(map.lineAt(visibleTop - marginTop * 1000 /* VP.Margin */, QueryType.ByHeight, oracle, 0, 0).from, map.lineAt(visibleBottom + (1 - marginTop) * 1000 /* VP.Margin */, QueryType.ByHeight, oracle, 0, 0).to);
|
|
5015
5054
|
// If scrollTarget is given, make sure the viewport includes that position
|
|
5016
5055
|
if (scrollTarget) {
|
|
5017
5056
|
let { head } = scrollTarget.range;
|
|
5018
5057
|
if (head < viewport.from || head > viewport.to) {
|
|
5019
5058
|
let viewHeight = Math.min(this.editorHeight, this.pixelViewport.bottom - this.pixelViewport.top);
|
|
5020
|
-
let block = map.lineAt(head, QueryType.ByPos,
|
|
5059
|
+
let block = map.lineAt(head, QueryType.ByPos, oracle, 0, 0), topPos;
|
|
5021
5060
|
if (scrollTarget.y == "center")
|
|
5022
5061
|
topPos = (block.top + block.bottom) / 2 - viewHeight / 2;
|
|
5023
5062
|
else if (scrollTarget.y == "start" || scrollTarget.y == "nearest" && head < viewport.from)
|
|
5024
5063
|
topPos = block.top;
|
|
5025
5064
|
else
|
|
5026
5065
|
topPos = block.bottom - viewHeight;
|
|
5027
|
-
viewport = new Viewport(map.lineAt(topPos - 1000 /* VP.Margin */ / 2, QueryType.ByHeight,
|
|
5066
|
+
viewport = new Viewport(map.lineAt(topPos - 1000 /* VP.Margin */ / 2, QueryType.ByHeight, oracle, 0, 0).from, map.lineAt(topPos + viewHeight + 1000 /* VP.Margin */ / 2, QueryType.ByHeight, oracle, 0, 0).to);
|
|
5028
5067
|
}
|
|
5029
5068
|
}
|
|
5030
5069
|
return viewport;
|
|
5031
5070
|
}
|
|
5032
5071
|
mapViewport(viewport, changes) {
|
|
5033
5072
|
let from = changes.mapPos(viewport.from, -1), to = changes.mapPos(viewport.to, 1);
|
|
5034
|
-
return new Viewport(this.heightMap.lineAt(from, QueryType.ByPos, this.
|
|
5073
|
+
return new Viewport(this.heightMap.lineAt(from, QueryType.ByPos, this.heightOracle, 0, 0).from, this.heightMap.lineAt(to, QueryType.ByPos, this.heightOracle, 0, 0).to);
|
|
5035
5074
|
}
|
|
5036
5075
|
// Checks if a given viewport covers the visible part of the
|
|
5037
5076
|
// document and not too much beyond that.
|
|
5038
5077
|
viewportIsAppropriate({ from, to }, bias = 0) {
|
|
5039
5078
|
if (!this.inView)
|
|
5040
5079
|
return true;
|
|
5041
|
-
let { top } = this.heightMap.lineAt(from, QueryType.ByPos, this.
|
|
5042
|
-
let { bottom } = this.heightMap.lineAt(to, QueryType.ByPos, this.
|
|
5080
|
+
let { top } = this.heightMap.lineAt(from, QueryType.ByPos, this.heightOracle, 0, 0);
|
|
5081
|
+
let { bottom } = this.heightMap.lineAt(to, QueryType.ByPos, this.heightOracle, 0, 0);
|
|
5043
5082
|
let { visibleTop, visibleBottom } = this;
|
|
5044
5083
|
return (from == 0 || top <= visibleTop - Math.max(10 /* VP.MinCoverMargin */, Math.min(-bias, 250 /* VP.MaxCoverMargin */))) &&
|
|
5045
5084
|
(to == this.state.doc.length ||
|
|
@@ -5176,13 +5215,13 @@ class ViewState {
|
|
|
5176
5215
|
}
|
|
5177
5216
|
lineBlockAt(pos) {
|
|
5178
5217
|
return (pos >= this.viewport.from && pos <= this.viewport.to && this.viewportLines.find(b => b.from <= pos && b.to >= pos)) ||
|
|
5179
|
-
scaleBlock(this.heightMap.lineAt(pos, QueryType.ByPos, this.
|
|
5218
|
+
scaleBlock(this.heightMap.lineAt(pos, QueryType.ByPos, this.heightOracle, 0, 0), this.scaler);
|
|
5180
5219
|
}
|
|
5181
5220
|
lineBlockAtHeight(height) {
|
|
5182
|
-
return scaleBlock(this.heightMap.lineAt(this.scaler.fromDOM(height), QueryType.ByHeight, this.
|
|
5221
|
+
return scaleBlock(this.heightMap.lineAt(this.scaler.fromDOM(height), QueryType.ByHeight, this.heightOracle, 0, 0), this.scaler);
|
|
5183
5222
|
}
|
|
5184
5223
|
elementAtHeight(height) {
|
|
5185
|
-
return scaleBlock(this.heightMap.blockAt(this.scaler.fromDOM(height), this.
|
|
5224
|
+
return scaleBlock(this.heightMap.blockAt(this.scaler.fromDOM(height), this.heightOracle, 0, 0), this.scaler);
|
|
5186
5225
|
}
|
|
5187
5226
|
get docHeight() {
|
|
5188
5227
|
return this.scaler.toDOM(this.heightMap.height);
|
|
@@ -5256,11 +5295,11 @@ const IdScaler = {
|
|
|
5256
5295
|
// regions outside the viewports so that the total height is
|
|
5257
5296
|
// VP.MaxDOMHeight.
|
|
5258
5297
|
class BigScaler {
|
|
5259
|
-
constructor(
|
|
5298
|
+
constructor(oracle, heightMap, viewports) {
|
|
5260
5299
|
let vpHeight = 0, base = 0, domBase = 0;
|
|
5261
5300
|
this.viewports = viewports.map(({ from, to }) => {
|
|
5262
|
-
let top = heightMap.lineAt(from, QueryType.ByPos,
|
|
5263
|
-
let bottom = heightMap.lineAt(to, QueryType.ByPos,
|
|
5301
|
+
let top = heightMap.lineAt(from, QueryType.ByPos, oracle, 0, 0).top;
|
|
5302
|
+
let bottom = heightMap.lineAt(to, QueryType.ByPos, oracle, 0, 0).bottom;
|
|
5264
5303
|
vpHeight += bottom - top;
|
|
5265
5304
|
return { from, to, top, bottom, domTop: 0, domBottom: 0 };
|
|
5266
5305
|
});
|
|
@@ -5627,7 +5666,7 @@ function applyDOMChange(view, domChange) {
|
|
|
5627
5666
|
};
|
|
5628
5667
|
}
|
|
5629
5668
|
else if ((browser.mac || browser.android) && change && change.from == change.to && change.from == sel.head - 1 &&
|
|
5630
|
-
/^\. ?$/.test(change.insert.toString())) {
|
|
5669
|
+
/^\. ?$/.test(change.insert.toString()) && view.contentDOM.getAttribute("autocorrect") == "off") {
|
|
5631
5670
|
// Detect insert-period-on-double-space Mac and Android behavior,
|
|
5632
5671
|
// and transform it into a regular space insert.
|
|
5633
5672
|
if (newSel && change.insert.length == 2)
|
|
@@ -7041,6 +7080,11 @@ called and the default behavior is prevented.
|
|
|
7041
7080
|
*/
|
|
7042
7081
|
EditorView.inputHandler = inputHandler;
|
|
7043
7082
|
/**
|
|
7083
|
+
This facet can be used to provide functions that create effects
|
|
7084
|
+
to be dispatched when the editor's focus state changes.
|
|
7085
|
+
*/
|
|
7086
|
+
EditorView.focusChangeEffect = focusChangeEffect;
|
|
7087
|
+
/**
|
|
7044
7088
|
By default, the editor assumes all its content has the same
|
|
7045
7089
|
[text direction](https://codemirror.net/6/docs/ref/#view.Direction). Configure this with a `true`
|
|
7046
7090
|
value to make it read the text direction of every (rendered)
|
|
@@ -8356,6 +8400,7 @@ const tooltipConfig = /*@__PURE__*/Facet.define({
|
|
|
8356
8400
|
});
|
|
8357
8401
|
}
|
|
8358
8402
|
});
|
|
8403
|
+
const knownHeight = /*@__PURE__*/new WeakMap();
|
|
8359
8404
|
const tooltipPlugin = /*@__PURE__*/ViewPlugin.fromClass(class {
|
|
8360
8405
|
constructor(view) {
|
|
8361
8406
|
this.view = view;
|
|
@@ -8471,6 +8516,7 @@ const tooltipPlugin = /*@__PURE__*/ViewPlugin.fromClass(class {
|
|
|
8471
8516
|
};
|
|
8472
8517
|
}
|
|
8473
8518
|
writeMeasure(measured) {
|
|
8519
|
+
var _a;
|
|
8474
8520
|
let { editor, space } = measured;
|
|
8475
8521
|
let others = [];
|
|
8476
8522
|
for (let i = 0; i < this.manager.tooltips.length; i++) {
|
|
@@ -8486,7 +8532,7 @@ const tooltipPlugin = /*@__PURE__*/ViewPlugin.fromClass(class {
|
|
|
8486
8532
|
}
|
|
8487
8533
|
let arrow = tooltip.arrow ? tView.dom.querySelector(".cm-tooltip-arrow") : null;
|
|
8488
8534
|
let arrowHeight = arrow ? 7 /* Arrow.Size */ : 0;
|
|
8489
|
-
let width = size.right - size.left, height = size.bottom - size.top;
|
|
8535
|
+
let width = size.right - size.left, height = (_a = knownHeight.get(tView)) !== null && _a !== void 0 ? _a : size.bottom - size.top;
|
|
8490
8536
|
let offset = tView.offset || noOffset, ltr = this.view.textDirection == Direction.LTR;
|
|
8491
8537
|
let left = size.width > space.right - space.left ? (ltr ? space.left : space.right - size.width)
|
|
8492
8538
|
: ltr ? Math.min(pos.left - (arrow ? 14 /* Arrow.Offset */ : 0) + offset.x, space.right - width)
|
|
@@ -8503,6 +8549,7 @@ const tooltipPlugin = /*@__PURE__*/ViewPlugin.fromClass(class {
|
|
|
8503
8549
|
dom.style.top = Outside;
|
|
8504
8550
|
continue;
|
|
8505
8551
|
}
|
|
8552
|
+
knownHeight.set(tView, height);
|
|
8506
8553
|
dom.style.height = (height = spaceVert) + "px";
|
|
8507
8554
|
}
|
|
8508
8555
|
else if (dom.style.height) {
|