@codemirror/view 6.21.3 → 6.22.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 +24 -0
- package/dist/index.cjs +116 -28
- package/dist/index.d.cts +35 -2
- package/dist/index.d.ts +35 -2
- package/dist/index.js +117 -29
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,27 @@
|
|
|
1
|
+
## 6.22.0 (2023-11-03)
|
|
2
|
+
|
|
3
|
+
### Bug fixes
|
|
4
|
+
|
|
5
|
+
Exceptions raised by update listeners are now routed to the configured exception sink, if any.
|
|
6
|
+
|
|
7
|
+
Fix an issue where passing large scroll margins to `scrollIntoView` would cause the measure loop to fail to terminate.
|
|
8
|
+
|
|
9
|
+
Widgets that are draggable (and allow drag events through in their `ignoreEvent` implementation) can now use the editor's built-in drag/drop behavior.
|
|
10
|
+
|
|
11
|
+
### New features
|
|
12
|
+
|
|
13
|
+
The new `scrollTo` option to `EditorView` allows an initial scroll position to be provided.
|
|
14
|
+
|
|
15
|
+
The new `EditorView.scrollSnapshot` method returns an effect that can be used to reset to a previous scroll position.
|
|
16
|
+
|
|
17
|
+
## 6.21.4 (2023-10-24)
|
|
18
|
+
|
|
19
|
+
### Bug fixes
|
|
20
|
+
|
|
21
|
+
Support the `offset`, `getCoords`, `overlap`, and `resize` properties on hover tooltips, as long as they aren't given conflicting values when there are multiple active hover tooltips.
|
|
22
|
+
|
|
23
|
+
Fix a bug that caused tooltips in the default configuration to be positioned incorrectly on Chrome when the editor was transformed.
|
|
24
|
+
|
|
1
25
|
## 6.21.3 (2023-10-06)
|
|
2
26
|
|
|
3
27
|
### Bug fixes
|
package/dist/index.cjs
CHANGED
|
@@ -1788,15 +1788,28 @@ const nativeSelectionHidden = state.Facet.define({
|
|
|
1788
1788
|
combine: values => values.some(x => x)
|
|
1789
1789
|
});
|
|
1790
1790
|
class ScrollTarget {
|
|
1791
|
-
constructor(range, y = "nearest", x = "nearest", yMargin = 5, xMargin = 5
|
|
1791
|
+
constructor(range, y = "nearest", x = "nearest", yMargin = 5, xMargin = 5,
|
|
1792
|
+
// This data structure is abused to also store precise scroll
|
|
1793
|
+
// snapshots, instead of a `scrollIntoView` request. When this
|
|
1794
|
+
// flag is `true`, `range` points at a position in the reference
|
|
1795
|
+
// line, `yMargin` holds the difference between the top of that
|
|
1796
|
+
// line and the top of the editor, and `xMargin` holds the
|
|
1797
|
+
// editor's `scrollLeft`.
|
|
1798
|
+
isSnapshot = false) {
|
|
1792
1799
|
this.range = range;
|
|
1793
1800
|
this.y = y;
|
|
1794
1801
|
this.x = x;
|
|
1795
1802
|
this.yMargin = yMargin;
|
|
1796
1803
|
this.xMargin = xMargin;
|
|
1804
|
+
this.isSnapshot = isSnapshot;
|
|
1797
1805
|
}
|
|
1798
1806
|
map(changes) {
|
|
1799
|
-
return changes.empty ? this :
|
|
1807
|
+
return changes.empty ? this :
|
|
1808
|
+
new ScrollTarget(this.range.map(changes), this.y, this.x, this.yMargin, this.xMargin, this.isSnapshot);
|
|
1809
|
+
}
|
|
1810
|
+
clip(state$1) {
|
|
1811
|
+
return this.range.to <= state$1.doc.length ? this :
|
|
1812
|
+
new ScrollTarget(state.EditorSelection.cursor(state$1.doc.length), this.y, this.x, this.yMargin, this.xMargin, this.isSnapshot);
|
|
1800
1813
|
}
|
|
1801
1814
|
}
|
|
1802
1815
|
const scrollIntoView = state.StateEffect.define({ map: (t, ch) => t.map(ch) });
|
|
@@ -3090,6 +3103,12 @@ class DocView extends ContentView {
|
|
|
3090
3103
|
];
|
|
3091
3104
|
}
|
|
3092
3105
|
scrollIntoView(target) {
|
|
3106
|
+
if (target.isSnapshot) {
|
|
3107
|
+
let ref = this.view.viewState.lineBlockAt(target.range.head);
|
|
3108
|
+
this.view.scrollDOM.scrollTop = ref.top - target.yMargin;
|
|
3109
|
+
this.view.scrollDOM.scrollLeft = target.xMargin;
|
|
3110
|
+
return;
|
|
3111
|
+
}
|
|
3093
3112
|
let { range } = target;
|
|
3094
3113
|
let rect = this.coordsAt(range.head, range.empty ? range.assoc : range.head > range.anchor ? -1 : 1), other;
|
|
3095
3114
|
if (!rect)
|
|
@@ -3102,7 +3121,8 @@ class DocView extends ContentView {
|
|
|
3102
3121
|
left: rect.left - margins.left, top: rect.top - margins.top,
|
|
3103
3122
|
right: rect.right + margins.right, bottom: rect.bottom + margins.bottom
|
|
3104
3123
|
};
|
|
3105
|
-
|
|
3124
|
+
let { offsetWidth, offsetHeight } = this.view.scrollDOM;
|
|
3125
|
+
scrollRectIntoView(this.view.scrollDOM, targetRect, range.head < range.anchor ? -1 : 1, target.x, target.y, Math.max(Math.min(target.xMargin, offsetWidth), -offsetWidth), Math.max(Math.min(target.yMargin, offsetHeight), -offsetHeight), this.view.textDirection == exports.Direction.LTR);
|
|
3106
3126
|
}
|
|
3107
3127
|
}
|
|
3108
3128
|
function betweenUneditable(pos) {
|
|
@@ -3639,6 +3659,9 @@ class InputState {
|
|
|
3639
3659
|
// the mutation events fire shortly after the compositionend event
|
|
3640
3660
|
this.compositionPendingChange = false;
|
|
3641
3661
|
this.mouseSelection = null;
|
|
3662
|
+
// When a drag from the editor is active, this points at the range
|
|
3663
|
+
// being dragged.
|
|
3664
|
+
this.draggedContent = null;
|
|
3642
3665
|
this.handleEvent = this.handleEvent.bind(this);
|
|
3643
3666
|
this.notifiedFocused = view.hasFocus;
|
|
3644
3667
|
// On Safari adding an input event handler somehow prevents an
|
|
@@ -3755,6 +3778,8 @@ class InputState {
|
|
|
3755
3778
|
update(update) {
|
|
3756
3779
|
if (this.mouseSelection)
|
|
3757
3780
|
this.mouseSelection.update(update);
|
|
3781
|
+
if (this.draggedContent && update.docChanged)
|
|
3782
|
+
this.draggedContent = this.draggedContent.map(update.changes);
|
|
3758
3783
|
if (update.transactions.length)
|
|
3759
3784
|
this.lastKeyCode = this.lastSelectionTime = 0;
|
|
3760
3785
|
}
|
|
@@ -3872,7 +3897,7 @@ class MouseSelection {
|
|
|
3872
3897
|
let doc = this.view.contentDOM.ownerDocument;
|
|
3873
3898
|
doc.removeEventListener("mousemove", this.move);
|
|
3874
3899
|
doc.removeEventListener("mouseup", this.up);
|
|
3875
|
-
this.view.inputState.mouseSelection = null;
|
|
3900
|
+
this.view.inputState.mouseSelection = this.view.inputState.draggedContent = null;
|
|
3876
3901
|
}
|
|
3877
3902
|
setScrollSpeed(sx, sy) {
|
|
3878
3903
|
this.scrollSpeed = { x: sx, y: sy };
|
|
@@ -3930,8 +3955,6 @@ class MouseSelection {
|
|
|
3930
3955
|
this.mustSelect = false;
|
|
3931
3956
|
}
|
|
3932
3957
|
update(update) {
|
|
3933
|
-
if (update.docChanged && this.dragging)
|
|
3934
|
-
this.dragging = this.dragging.map(update.changes);
|
|
3935
3958
|
if (this.style.update(update))
|
|
3936
3959
|
setTimeout(() => this.select(this.lastEvent), 20);
|
|
3937
3960
|
}
|
|
@@ -4159,23 +4182,36 @@ function removeRangeAround(sel, pos) {
|
|
|
4159
4182
|
return null;
|
|
4160
4183
|
}
|
|
4161
4184
|
handlers.dragstart = (view, event) => {
|
|
4162
|
-
let { selection: { main } } = view.state;
|
|
4163
|
-
|
|
4164
|
-
|
|
4165
|
-
|
|
4185
|
+
let { selection: { main: range } } = view.state;
|
|
4186
|
+
if (event.target.draggable) {
|
|
4187
|
+
let cView = view.docView.nearest(event.target);
|
|
4188
|
+
if (cView && cView.isWidget) {
|
|
4189
|
+
let from = cView.posAtStart, to = from + cView.length;
|
|
4190
|
+
if (from >= range.to || to <= range.from)
|
|
4191
|
+
range = state.EditorSelection.range(from, to);
|
|
4192
|
+
}
|
|
4193
|
+
}
|
|
4194
|
+
let { inputState } = view;
|
|
4195
|
+
if (inputState.mouseSelection)
|
|
4196
|
+
inputState.mouseSelection.dragging = true;
|
|
4197
|
+
inputState.draggedContent = range;
|
|
4166
4198
|
if (event.dataTransfer) {
|
|
4167
|
-
event.dataTransfer.setData("Text", view.state.sliceDoc(
|
|
4199
|
+
event.dataTransfer.setData("Text", view.state.sliceDoc(range.from, range.to));
|
|
4168
4200
|
event.dataTransfer.effectAllowed = "copyMove";
|
|
4169
4201
|
}
|
|
4170
4202
|
return false;
|
|
4171
4203
|
};
|
|
4204
|
+
handlers.dragend = view => {
|
|
4205
|
+
view.inputState.draggedContent = null;
|
|
4206
|
+
return false;
|
|
4207
|
+
};
|
|
4172
4208
|
function dropText(view, event, text, direct) {
|
|
4173
4209
|
if (!text)
|
|
4174
4210
|
return;
|
|
4175
4211
|
let dropPos = view.posAtCoords({ x: event.clientX, y: event.clientY }, false);
|
|
4176
|
-
let {
|
|
4177
|
-
let del = direct &&
|
|
4178
|
-
{ from:
|
|
4212
|
+
let { draggedContent } = view.inputState;
|
|
4213
|
+
let del = direct && draggedContent && dragMovesSelection(view, event)
|
|
4214
|
+
? { from: draggedContent.from, to: draggedContent.to } : null;
|
|
4179
4215
|
let ins = { from: dropPos, insert: text };
|
|
4180
4216
|
let changes = view.state.changes(del ? [del, ins] : ins);
|
|
4181
4217
|
view.focus();
|
|
@@ -4184,6 +4220,7 @@ function dropText(view, event, text, direct) {
|
|
|
4184
4220
|
selection: { anchor: changes.mapPos(dropPos, -1), head: changes.mapPos(dropPos, 1) },
|
|
4185
4221
|
userEvent: del ? "move.drop" : "input.drop"
|
|
4186
4222
|
});
|
|
4223
|
+
view.inputState.draggedContent = null;
|
|
4187
4224
|
}
|
|
4188
4225
|
handlers.drop = (view, event) => {
|
|
4189
4226
|
if (!event.dataTransfer)
|
|
@@ -6371,7 +6408,6 @@ class DOMObserver {
|
|
|
6371
6408
|
this.scrollTargets = [];
|
|
6372
6409
|
this.intersection = null;
|
|
6373
6410
|
this.resizeScroll = null;
|
|
6374
|
-
this.resizeContent = null;
|
|
6375
6411
|
this.intersecting = false;
|
|
6376
6412
|
this.gapIntersection = null;
|
|
6377
6413
|
this.gaps = [];
|
|
@@ -6415,8 +6451,6 @@ class DOMObserver {
|
|
|
6415
6451
|
this.onResize();
|
|
6416
6452
|
});
|
|
6417
6453
|
this.resizeScroll.observe(view.scrollDOM);
|
|
6418
|
-
this.resizeContent = new ResizeObserver(() => this.view.requestMeasure());
|
|
6419
|
-
this.resizeContent.observe(view.contentDOM);
|
|
6420
6454
|
}
|
|
6421
6455
|
this.addWindowListeners(this.win = view.win);
|
|
6422
6456
|
this.start();
|
|
@@ -6745,12 +6779,11 @@ class DOMObserver {
|
|
|
6745
6779
|
win.document.removeEventListener("selectionchange", this.onSelectionChange);
|
|
6746
6780
|
}
|
|
6747
6781
|
destroy() {
|
|
6748
|
-
var _a, _b, _c
|
|
6782
|
+
var _a, _b, _c;
|
|
6749
6783
|
this.stop();
|
|
6750
6784
|
(_a = this.intersection) === null || _a === void 0 ? void 0 : _a.disconnect();
|
|
6751
6785
|
(_b = this.gapIntersection) === null || _b === void 0 ? void 0 : _b.disconnect();
|
|
6752
6786
|
(_c = this.resizeScroll) === null || _c === void 0 ? void 0 : _c.disconnect();
|
|
6753
|
-
(_d = this.resizeContent) === null || _d === void 0 ? void 0 : _d.disconnect();
|
|
6754
6787
|
for (let dom of this.scrollTargets)
|
|
6755
6788
|
dom.removeEventListener("scroll", this.onScroll);
|
|
6756
6789
|
this.removeWindowListeners(this.win);
|
|
@@ -6908,6 +6941,8 @@ class EditorView {
|
|
|
6908
6941
|
this.dispatch = this.dispatch.bind(this);
|
|
6909
6942
|
this._root = (config.root || getRoot(config.parent) || document);
|
|
6910
6943
|
this.viewState = new ViewState(config.state || state.EditorState.create(config));
|
|
6944
|
+
if (config.scrollTo && config.scrollTo.is(scrollIntoView))
|
|
6945
|
+
this.viewState.scrollTarget = config.scrollTo.value.clip(this.viewState.state);
|
|
6911
6946
|
this.plugins = this.state.facet(viewPlugin).map(spec => new PluginInstance(spec));
|
|
6912
6947
|
for (let plugin of this.plugins)
|
|
6913
6948
|
plugin.update(this);
|
|
@@ -6995,7 +7030,7 @@ class EditorView {
|
|
|
6995
7030
|
}
|
|
6996
7031
|
for (let e of tr.effects)
|
|
6997
7032
|
if (e.is(scrollIntoView))
|
|
6998
|
-
scrollTarget = e.value;
|
|
7033
|
+
scrollTarget = e.value.clip(this.state);
|
|
6999
7034
|
}
|
|
7000
7035
|
this.viewState.update(update, scrollTarget);
|
|
7001
7036
|
this.bidiCache = CachedOrder.update(this.bidiCache, update.changes);
|
|
@@ -7018,8 +7053,14 @@ class EditorView {
|
|
|
7018
7053
|
if (redrawn || attrsChanged || scrollTarget || this.viewState.mustEnforceCursorAssoc || this.viewState.mustMeasureContent)
|
|
7019
7054
|
this.requestMeasure();
|
|
7020
7055
|
if (!update.empty)
|
|
7021
|
-
for (let listener of this.state.facet(updateListener))
|
|
7022
|
-
|
|
7056
|
+
for (let listener of this.state.facet(updateListener)) {
|
|
7057
|
+
try {
|
|
7058
|
+
listener(update);
|
|
7059
|
+
}
|
|
7060
|
+
catch (e) {
|
|
7061
|
+
logException(this.state, e, "update listener");
|
|
7062
|
+
}
|
|
7063
|
+
}
|
|
7023
7064
|
if (dispatchFocus || domChange)
|
|
7024
7065
|
Promise.resolve().then(() => {
|
|
7025
7066
|
if (dispatchFocus && this.state == dispatchFocus.startState)
|
|
@@ -7601,6 +7642,23 @@ class EditorView {
|
|
|
7601
7642
|
return scrollIntoView.of(new ScrollTarget(typeof pos == "number" ? state.EditorSelection.cursor(pos) : pos, options.y, options.x, options.yMargin, options.xMargin));
|
|
7602
7643
|
}
|
|
7603
7644
|
/**
|
|
7645
|
+
Return an effect that resets the editor to its current (at the
|
|
7646
|
+
time this method was called) scroll position. Note that this
|
|
7647
|
+
only affects the editor's own scrollable element, not parents.
|
|
7648
|
+
See also
|
|
7649
|
+
[`EditorViewConfig.scrollTo`](https://codemirror.net/6/docs/ref/#view.EditorViewConfig.scrollTo).
|
|
7650
|
+
|
|
7651
|
+
The effect should be used with a document identical to the one
|
|
7652
|
+
it was created for. Failing to do so is not an error, but may
|
|
7653
|
+
not scroll to the expected position. You can
|
|
7654
|
+
[map](https://codemirror.net/6/docs/ref/#state.StateEffect.map) the effect to account for changes.
|
|
7655
|
+
*/
|
|
7656
|
+
scrollSnapshot() {
|
|
7657
|
+
let { scrollTop, scrollLeft } = this.scrollDOM;
|
|
7658
|
+
let ref = this.viewState.scrollAnchorAt(scrollTop);
|
|
7659
|
+
return scrollIntoView.of(new ScrollTarget(state.EditorSelection.cursor(ref.from), "start", "start", ref.top - scrollTop, scrollLeft, true));
|
|
7660
|
+
}
|
|
7661
|
+
/**
|
|
7604
7662
|
Returns an extension that can be used to add DOM event handlers.
|
|
7605
7663
|
The value should be an object mapping event names to handler
|
|
7606
7664
|
functions. For any given event, such functions are ordered by
|
|
@@ -9198,6 +9256,7 @@ const tooltipPlugin = ViewPlugin.fromClass(class {
|
|
|
9198
9256
|
}
|
|
9199
9257
|
tooltipView.dom.style.position = this.position;
|
|
9200
9258
|
tooltipView.dom.style.top = Outside;
|
|
9259
|
+
tooltipView.dom.style.left = "0px";
|
|
9201
9260
|
this.container.appendChild(tooltipView.dom);
|
|
9202
9261
|
if (tooltipView.mount)
|
|
9203
9262
|
tooltipView.mount(this.view);
|
|
@@ -9219,12 +9278,24 @@ const tooltipPlugin = ViewPlugin.fromClass(class {
|
|
|
9219
9278
|
let editor = this.view.dom.getBoundingClientRect();
|
|
9220
9279
|
let scaleX = 1, scaleY = 1, makeAbsolute = false;
|
|
9221
9280
|
if (this.position == "fixed" && this.manager.tooltipViews.length) {
|
|
9222
|
-
|
|
9223
|
-
|
|
9224
|
-
|
|
9225
|
-
|
|
9226
|
-
|
|
9227
|
-
|
|
9281
|
+
let { dom } = this.manager.tooltipViews[0];
|
|
9282
|
+
if (browser.gecko) {
|
|
9283
|
+
// Firefox sets the element's `offsetParent` to the
|
|
9284
|
+
// transformed element when a transform interferes with fixed
|
|
9285
|
+
// positioning.
|
|
9286
|
+
makeAbsolute = dom.offsetParent != this.container.ownerDocument.body;
|
|
9287
|
+
}
|
|
9288
|
+
else {
|
|
9289
|
+
// On other browsers, we have to awkwardly try and use other
|
|
9290
|
+
// information to detect a transform.
|
|
9291
|
+
if (this.view.scaleX != 1 || this.view.scaleY != 1) {
|
|
9292
|
+
makeAbsolute = true;
|
|
9293
|
+
}
|
|
9294
|
+
else if (dom.style.top == Outside && dom.style.left == "0px") {
|
|
9295
|
+
let rect = dom.getBoundingClientRect();
|
|
9296
|
+
makeAbsolute = Math.abs(rect.top + 10000) > 1 || Math.abs(rect.left) > 1;
|
|
9297
|
+
}
|
|
9298
|
+
}
|
|
9228
9299
|
}
|
|
9229
9300
|
if (makeAbsolute || this.position == "absolute") {
|
|
9230
9301
|
if (this.parent) {
|
|
@@ -9450,6 +9521,23 @@ class HoverTooltipHost {
|
|
|
9450
9521
|
for (let t of this.manager.tooltipViews)
|
|
9451
9522
|
(_a = t.destroy) === null || _a === void 0 ? void 0 : _a.call(t);
|
|
9452
9523
|
}
|
|
9524
|
+
passProp(name) {
|
|
9525
|
+
let value = undefined;
|
|
9526
|
+
for (let view of this.manager.tooltipViews) {
|
|
9527
|
+
let given = view[name];
|
|
9528
|
+
if (given !== undefined) {
|
|
9529
|
+
if (value === undefined)
|
|
9530
|
+
value = given;
|
|
9531
|
+
else if (value !== given)
|
|
9532
|
+
return undefined;
|
|
9533
|
+
}
|
|
9534
|
+
}
|
|
9535
|
+
return value;
|
|
9536
|
+
}
|
|
9537
|
+
get offset() { return this.passProp("offset"); }
|
|
9538
|
+
get getCoords() { return this.passProp("getCoords"); }
|
|
9539
|
+
get overlap() { return this.passProp("overlap"); }
|
|
9540
|
+
get resize() { return this.passProp("resize"); }
|
|
9453
9541
|
}
|
|
9454
9542
|
const showHoverTooltipHost = showTooltip.compute([showHoverTooltip], state => {
|
|
9455
9543
|
let tooltips = state.facet(showHoverTooltip).filter(t => t);
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as _codemirror_state from '@codemirror/state';
|
|
2
|
-
import { RangeSet, RangeValue, Range, EditorState, Extension, Transaction, ChangeSet, EditorSelection, EditorStateConfig,
|
|
2
|
+
import { RangeSet, RangeValue, Range, EditorState, Extension, Transaction, ChangeSet, SelectionRange, ChangeDesc, EditorSelection, EditorStateConfig, StateEffect, TransactionSpec, Line, Facet } from '@codemirror/state';
|
|
3
3
|
import { StyleModule, StyleSpec } from 'style-mod';
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -361,6 +361,17 @@ apply to the editor, and if it can, perform it as a side effect
|
|
|
361
361
|
transaction) and return `true`.
|
|
362
362
|
*/
|
|
363
363
|
type Command = (target: EditorView) => boolean;
|
|
364
|
+
declare class ScrollTarget {
|
|
365
|
+
readonly range: SelectionRange;
|
|
366
|
+
readonly y: ScrollStrategy;
|
|
367
|
+
readonly x: ScrollStrategy;
|
|
368
|
+
readonly yMargin: number;
|
|
369
|
+
readonly xMargin: number;
|
|
370
|
+
readonly isSnapshot: boolean;
|
|
371
|
+
constructor(range: SelectionRange, y?: ScrollStrategy, x?: ScrollStrategy, yMargin?: number, xMargin?: number, isSnapshot?: boolean);
|
|
372
|
+
map(changes: ChangeDesc): ScrollTarget;
|
|
373
|
+
clip(state: EditorState): ScrollTarget;
|
|
374
|
+
}
|
|
364
375
|
/**
|
|
365
376
|
Log or report an unhandled exception in client code. Should
|
|
366
377
|
probably only be used by extension code that allows client code to
|
|
@@ -633,6 +644,13 @@ interface EditorViewConfig extends EditorStateConfig {
|
|
|
633
644
|
*/
|
|
634
645
|
root?: Document | ShadowRoot;
|
|
635
646
|
/**
|
|
647
|
+
Pass an effect created with
|
|
648
|
+
[`EditorView.scrollIntoView`](https://codemirror.net/6/docs/ref/#view.EditorView^scrollIntoView) or
|
|
649
|
+
[`EditorView.scrollSnapshot`](https://codemirror.net/6/docs/ref/#view.EditorView.scrollSnapshot)
|
|
650
|
+
here to set an initial scroll position.
|
|
651
|
+
*/
|
|
652
|
+
scrollTo?: StateEffect<any>;
|
|
653
|
+
/**
|
|
636
654
|
Override the way transactions are
|
|
637
655
|
[dispatched](https://codemirror.net/6/docs/ref/#view.EditorView.dispatch) for this editor view.
|
|
638
656
|
Your implementation, if provided, should probably call the
|
|
@@ -1032,15 +1050,30 @@ declare class EditorView {
|
|
|
1032
1050
|
/**
|
|
1033
1051
|
Extra vertical distance to add when moving something into
|
|
1034
1052
|
view. Not used with the `"center"` strategy. Defaults to 5.
|
|
1053
|
+
Must be less than the height of the editor.
|
|
1035
1054
|
*/
|
|
1036
1055
|
yMargin?: number;
|
|
1037
1056
|
/**
|
|
1038
1057
|
Extra horizontal distance to add. Not used with the `"center"`
|
|
1039
|
-
strategy. Defaults to 5.
|
|
1058
|
+
strategy. Defaults to 5. Must be less than the width of the
|
|
1059
|
+
editor.
|
|
1040
1060
|
*/
|
|
1041
1061
|
xMargin?: number;
|
|
1042
1062
|
}): StateEffect<unknown>;
|
|
1043
1063
|
/**
|
|
1064
|
+
Return an effect that resets the editor to its current (at the
|
|
1065
|
+
time this method was called) scroll position. Note that this
|
|
1066
|
+
only affects the editor's own scrollable element, not parents.
|
|
1067
|
+
See also
|
|
1068
|
+
[`EditorViewConfig.scrollTo`](https://codemirror.net/6/docs/ref/#view.EditorViewConfig.scrollTo).
|
|
1069
|
+
|
|
1070
|
+
The effect should be used with a document identical to the one
|
|
1071
|
+
it was created for. Failing to do so is not an error, but may
|
|
1072
|
+
not scroll to the expected position. You can
|
|
1073
|
+
[map](https://codemirror.net/6/docs/ref/#state.StateEffect.map) the effect to account for changes.
|
|
1074
|
+
*/
|
|
1075
|
+
scrollSnapshot(): StateEffect<ScrollTarget>;
|
|
1076
|
+
/**
|
|
1044
1077
|
Facet to add a [style
|
|
1045
1078
|
module](https://github.com/marijnh/style-mod#documentation) to
|
|
1046
1079
|
an editor view. The view will ensure that the module is
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as _codemirror_state from '@codemirror/state';
|
|
2
|
-
import { RangeSet, RangeValue, Range, EditorState, Extension, Transaction, ChangeSet, EditorSelection, EditorStateConfig,
|
|
2
|
+
import { RangeSet, RangeValue, Range, EditorState, Extension, Transaction, ChangeSet, SelectionRange, ChangeDesc, EditorSelection, EditorStateConfig, StateEffect, TransactionSpec, Line, Facet } from '@codemirror/state';
|
|
3
3
|
import { StyleModule, StyleSpec } from 'style-mod';
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -361,6 +361,17 @@ apply to the editor, and if it can, perform it as a side effect
|
|
|
361
361
|
transaction) and return `true`.
|
|
362
362
|
*/
|
|
363
363
|
type Command = (target: EditorView) => boolean;
|
|
364
|
+
declare class ScrollTarget {
|
|
365
|
+
readonly range: SelectionRange;
|
|
366
|
+
readonly y: ScrollStrategy;
|
|
367
|
+
readonly x: ScrollStrategy;
|
|
368
|
+
readonly yMargin: number;
|
|
369
|
+
readonly xMargin: number;
|
|
370
|
+
readonly isSnapshot: boolean;
|
|
371
|
+
constructor(range: SelectionRange, y?: ScrollStrategy, x?: ScrollStrategy, yMargin?: number, xMargin?: number, isSnapshot?: boolean);
|
|
372
|
+
map(changes: ChangeDesc): ScrollTarget;
|
|
373
|
+
clip(state: EditorState): ScrollTarget;
|
|
374
|
+
}
|
|
364
375
|
/**
|
|
365
376
|
Log or report an unhandled exception in client code. Should
|
|
366
377
|
probably only be used by extension code that allows client code to
|
|
@@ -633,6 +644,13 @@ interface EditorViewConfig extends EditorStateConfig {
|
|
|
633
644
|
*/
|
|
634
645
|
root?: Document | ShadowRoot;
|
|
635
646
|
/**
|
|
647
|
+
Pass an effect created with
|
|
648
|
+
[`EditorView.scrollIntoView`](https://codemirror.net/6/docs/ref/#view.EditorView^scrollIntoView) or
|
|
649
|
+
[`EditorView.scrollSnapshot`](https://codemirror.net/6/docs/ref/#view.EditorView.scrollSnapshot)
|
|
650
|
+
here to set an initial scroll position.
|
|
651
|
+
*/
|
|
652
|
+
scrollTo?: StateEffect<any>;
|
|
653
|
+
/**
|
|
636
654
|
Override the way transactions are
|
|
637
655
|
[dispatched](https://codemirror.net/6/docs/ref/#view.EditorView.dispatch) for this editor view.
|
|
638
656
|
Your implementation, if provided, should probably call the
|
|
@@ -1032,15 +1050,30 @@ declare class EditorView {
|
|
|
1032
1050
|
/**
|
|
1033
1051
|
Extra vertical distance to add when moving something into
|
|
1034
1052
|
view. Not used with the `"center"` strategy. Defaults to 5.
|
|
1053
|
+
Must be less than the height of the editor.
|
|
1035
1054
|
*/
|
|
1036
1055
|
yMargin?: number;
|
|
1037
1056
|
/**
|
|
1038
1057
|
Extra horizontal distance to add. Not used with the `"center"`
|
|
1039
|
-
strategy. Defaults to 5.
|
|
1058
|
+
strategy. Defaults to 5. Must be less than the width of the
|
|
1059
|
+
editor.
|
|
1040
1060
|
*/
|
|
1041
1061
|
xMargin?: number;
|
|
1042
1062
|
}): StateEffect<unknown>;
|
|
1043
1063
|
/**
|
|
1064
|
+
Return an effect that resets the editor to its current (at the
|
|
1065
|
+
time this method was called) scroll position. Note that this
|
|
1066
|
+
only affects the editor's own scrollable element, not parents.
|
|
1067
|
+
See also
|
|
1068
|
+
[`EditorViewConfig.scrollTo`](https://codemirror.net/6/docs/ref/#view.EditorViewConfig.scrollTo).
|
|
1069
|
+
|
|
1070
|
+
The effect should be used with a document identical to the one
|
|
1071
|
+
it was created for. Failing to do so is not an error, but may
|
|
1072
|
+
not scroll to the expected position. You can
|
|
1073
|
+
[map](https://codemirror.net/6/docs/ref/#state.StateEffect.map) the effect to account for changes.
|
|
1074
|
+
*/
|
|
1075
|
+
scrollSnapshot(): StateEffect<ScrollTarget>;
|
|
1076
|
+
/**
|
|
1044
1077
|
Facet to add a [style
|
|
1045
1078
|
module](https://github.com/marijnh/style-mod#documentation) to
|
|
1046
1079
|
an editor view. The view will ensure that the module is
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Text, RangeSet, MapMode, RangeValue, Facet, StateEffect, ChangeSet,
|
|
1
|
+
import { Text, RangeSet, MapMode, RangeValue, Facet, StateEffect, ChangeSet, EditorSelection, findClusterBreak, findColumn, CharCategory, Annotation, EditorState, Transaction, Prec, codePointAt, codePointSize, combineConfig, StateField, RangeSetBuilder, countColumn } from '@codemirror/state';
|
|
2
2
|
import { StyleModule } from 'style-mod';
|
|
3
3
|
import { keyName, base, shift } from 'w3c-keyname';
|
|
4
4
|
|
|
@@ -1785,15 +1785,28 @@ const nativeSelectionHidden = /*@__PURE__*/Facet.define({
|
|
|
1785
1785
|
combine: values => values.some(x => x)
|
|
1786
1786
|
});
|
|
1787
1787
|
class ScrollTarget {
|
|
1788
|
-
constructor(range, y = "nearest", x = "nearest", yMargin = 5, xMargin = 5
|
|
1788
|
+
constructor(range, y = "nearest", x = "nearest", yMargin = 5, xMargin = 5,
|
|
1789
|
+
// This data structure is abused to also store precise scroll
|
|
1790
|
+
// snapshots, instead of a `scrollIntoView` request. When this
|
|
1791
|
+
// flag is `true`, `range` points at a position in the reference
|
|
1792
|
+
// line, `yMargin` holds the difference between the top of that
|
|
1793
|
+
// line and the top of the editor, and `xMargin` holds the
|
|
1794
|
+
// editor's `scrollLeft`.
|
|
1795
|
+
isSnapshot = false) {
|
|
1789
1796
|
this.range = range;
|
|
1790
1797
|
this.y = y;
|
|
1791
1798
|
this.x = x;
|
|
1792
1799
|
this.yMargin = yMargin;
|
|
1793
1800
|
this.xMargin = xMargin;
|
|
1801
|
+
this.isSnapshot = isSnapshot;
|
|
1794
1802
|
}
|
|
1795
1803
|
map(changes) {
|
|
1796
|
-
return changes.empty ? this :
|
|
1804
|
+
return changes.empty ? this :
|
|
1805
|
+
new ScrollTarget(this.range.map(changes), this.y, this.x, this.yMargin, this.xMargin, this.isSnapshot);
|
|
1806
|
+
}
|
|
1807
|
+
clip(state) {
|
|
1808
|
+
return this.range.to <= state.doc.length ? this :
|
|
1809
|
+
new ScrollTarget(EditorSelection.cursor(state.doc.length), this.y, this.x, this.yMargin, this.xMargin, this.isSnapshot);
|
|
1797
1810
|
}
|
|
1798
1811
|
}
|
|
1799
1812
|
const scrollIntoView = /*@__PURE__*/StateEffect.define({ map: (t, ch) => t.map(ch) });
|
|
@@ -3086,6 +3099,12 @@ class DocView extends ContentView {
|
|
|
3086
3099
|
];
|
|
3087
3100
|
}
|
|
3088
3101
|
scrollIntoView(target) {
|
|
3102
|
+
if (target.isSnapshot) {
|
|
3103
|
+
let ref = this.view.viewState.lineBlockAt(target.range.head);
|
|
3104
|
+
this.view.scrollDOM.scrollTop = ref.top - target.yMargin;
|
|
3105
|
+
this.view.scrollDOM.scrollLeft = target.xMargin;
|
|
3106
|
+
return;
|
|
3107
|
+
}
|
|
3089
3108
|
let { range } = target;
|
|
3090
3109
|
let rect = this.coordsAt(range.head, range.empty ? range.assoc : range.head > range.anchor ? -1 : 1), other;
|
|
3091
3110
|
if (!rect)
|
|
@@ -3098,7 +3117,8 @@ class DocView extends ContentView {
|
|
|
3098
3117
|
left: rect.left - margins.left, top: rect.top - margins.top,
|
|
3099
3118
|
right: rect.right + margins.right, bottom: rect.bottom + margins.bottom
|
|
3100
3119
|
};
|
|
3101
|
-
|
|
3120
|
+
let { offsetWidth, offsetHeight } = this.view.scrollDOM;
|
|
3121
|
+
scrollRectIntoView(this.view.scrollDOM, targetRect, range.head < range.anchor ? -1 : 1, target.x, target.y, Math.max(Math.min(target.xMargin, offsetWidth), -offsetWidth), Math.max(Math.min(target.yMargin, offsetHeight), -offsetHeight), this.view.textDirection == Direction.LTR);
|
|
3102
3122
|
}
|
|
3103
3123
|
}
|
|
3104
3124
|
function betweenUneditable(pos) {
|
|
@@ -3635,6 +3655,9 @@ class InputState {
|
|
|
3635
3655
|
// the mutation events fire shortly after the compositionend event
|
|
3636
3656
|
this.compositionPendingChange = false;
|
|
3637
3657
|
this.mouseSelection = null;
|
|
3658
|
+
// When a drag from the editor is active, this points at the range
|
|
3659
|
+
// being dragged.
|
|
3660
|
+
this.draggedContent = null;
|
|
3638
3661
|
this.handleEvent = this.handleEvent.bind(this);
|
|
3639
3662
|
this.notifiedFocused = view.hasFocus;
|
|
3640
3663
|
// On Safari adding an input event handler somehow prevents an
|
|
@@ -3751,6 +3774,8 @@ class InputState {
|
|
|
3751
3774
|
update(update) {
|
|
3752
3775
|
if (this.mouseSelection)
|
|
3753
3776
|
this.mouseSelection.update(update);
|
|
3777
|
+
if (this.draggedContent && update.docChanged)
|
|
3778
|
+
this.draggedContent = this.draggedContent.map(update.changes);
|
|
3754
3779
|
if (update.transactions.length)
|
|
3755
3780
|
this.lastKeyCode = this.lastSelectionTime = 0;
|
|
3756
3781
|
}
|
|
@@ -3868,7 +3893,7 @@ class MouseSelection {
|
|
|
3868
3893
|
let doc = this.view.contentDOM.ownerDocument;
|
|
3869
3894
|
doc.removeEventListener("mousemove", this.move);
|
|
3870
3895
|
doc.removeEventListener("mouseup", this.up);
|
|
3871
|
-
this.view.inputState.mouseSelection = null;
|
|
3896
|
+
this.view.inputState.mouseSelection = this.view.inputState.draggedContent = null;
|
|
3872
3897
|
}
|
|
3873
3898
|
setScrollSpeed(sx, sy) {
|
|
3874
3899
|
this.scrollSpeed = { x: sx, y: sy };
|
|
@@ -3926,8 +3951,6 @@ class MouseSelection {
|
|
|
3926
3951
|
this.mustSelect = false;
|
|
3927
3952
|
}
|
|
3928
3953
|
update(update) {
|
|
3929
|
-
if (update.docChanged && this.dragging)
|
|
3930
|
-
this.dragging = this.dragging.map(update.changes);
|
|
3931
3954
|
if (this.style.update(update))
|
|
3932
3955
|
setTimeout(() => this.select(this.lastEvent), 20);
|
|
3933
3956
|
}
|
|
@@ -4155,23 +4178,36 @@ function removeRangeAround(sel, pos) {
|
|
|
4155
4178
|
return null;
|
|
4156
4179
|
}
|
|
4157
4180
|
handlers.dragstart = (view, event) => {
|
|
4158
|
-
let { selection: { main } } = view.state;
|
|
4159
|
-
|
|
4160
|
-
|
|
4161
|
-
|
|
4181
|
+
let { selection: { main: range } } = view.state;
|
|
4182
|
+
if (event.target.draggable) {
|
|
4183
|
+
let cView = view.docView.nearest(event.target);
|
|
4184
|
+
if (cView && cView.isWidget) {
|
|
4185
|
+
let from = cView.posAtStart, to = from + cView.length;
|
|
4186
|
+
if (from >= range.to || to <= range.from)
|
|
4187
|
+
range = EditorSelection.range(from, to);
|
|
4188
|
+
}
|
|
4189
|
+
}
|
|
4190
|
+
let { inputState } = view;
|
|
4191
|
+
if (inputState.mouseSelection)
|
|
4192
|
+
inputState.mouseSelection.dragging = true;
|
|
4193
|
+
inputState.draggedContent = range;
|
|
4162
4194
|
if (event.dataTransfer) {
|
|
4163
|
-
event.dataTransfer.setData("Text", view.state.sliceDoc(
|
|
4195
|
+
event.dataTransfer.setData("Text", view.state.sliceDoc(range.from, range.to));
|
|
4164
4196
|
event.dataTransfer.effectAllowed = "copyMove";
|
|
4165
4197
|
}
|
|
4166
4198
|
return false;
|
|
4167
4199
|
};
|
|
4200
|
+
handlers.dragend = view => {
|
|
4201
|
+
view.inputState.draggedContent = null;
|
|
4202
|
+
return false;
|
|
4203
|
+
};
|
|
4168
4204
|
function dropText(view, event, text, direct) {
|
|
4169
4205
|
if (!text)
|
|
4170
4206
|
return;
|
|
4171
4207
|
let dropPos = view.posAtCoords({ x: event.clientX, y: event.clientY }, false);
|
|
4172
|
-
let {
|
|
4173
|
-
let del = direct &&
|
|
4174
|
-
{ from:
|
|
4208
|
+
let { draggedContent } = view.inputState;
|
|
4209
|
+
let del = direct && draggedContent && dragMovesSelection(view, event)
|
|
4210
|
+
? { from: draggedContent.from, to: draggedContent.to } : null;
|
|
4175
4211
|
let ins = { from: dropPos, insert: text };
|
|
4176
4212
|
let changes = view.state.changes(del ? [del, ins] : ins);
|
|
4177
4213
|
view.focus();
|
|
@@ -4180,6 +4216,7 @@ function dropText(view, event, text, direct) {
|
|
|
4180
4216
|
selection: { anchor: changes.mapPos(dropPos, -1), head: changes.mapPos(dropPos, 1) },
|
|
4181
4217
|
userEvent: del ? "move.drop" : "input.drop"
|
|
4182
4218
|
});
|
|
4219
|
+
view.inputState.draggedContent = null;
|
|
4183
4220
|
}
|
|
4184
4221
|
handlers.drop = (view, event) => {
|
|
4185
4222
|
if (!event.dataTransfer)
|
|
@@ -6366,7 +6403,6 @@ class DOMObserver {
|
|
|
6366
6403
|
this.scrollTargets = [];
|
|
6367
6404
|
this.intersection = null;
|
|
6368
6405
|
this.resizeScroll = null;
|
|
6369
|
-
this.resizeContent = null;
|
|
6370
6406
|
this.intersecting = false;
|
|
6371
6407
|
this.gapIntersection = null;
|
|
6372
6408
|
this.gaps = [];
|
|
@@ -6410,8 +6446,6 @@ class DOMObserver {
|
|
|
6410
6446
|
this.onResize();
|
|
6411
6447
|
});
|
|
6412
6448
|
this.resizeScroll.observe(view.scrollDOM);
|
|
6413
|
-
this.resizeContent = new ResizeObserver(() => this.view.requestMeasure());
|
|
6414
|
-
this.resizeContent.observe(view.contentDOM);
|
|
6415
6449
|
}
|
|
6416
6450
|
this.addWindowListeners(this.win = view.win);
|
|
6417
6451
|
this.start();
|
|
@@ -6740,12 +6774,11 @@ class DOMObserver {
|
|
|
6740
6774
|
win.document.removeEventListener("selectionchange", this.onSelectionChange);
|
|
6741
6775
|
}
|
|
6742
6776
|
destroy() {
|
|
6743
|
-
var _a, _b, _c
|
|
6777
|
+
var _a, _b, _c;
|
|
6744
6778
|
this.stop();
|
|
6745
6779
|
(_a = this.intersection) === null || _a === void 0 ? void 0 : _a.disconnect();
|
|
6746
6780
|
(_b = this.gapIntersection) === null || _b === void 0 ? void 0 : _b.disconnect();
|
|
6747
6781
|
(_c = this.resizeScroll) === null || _c === void 0 ? void 0 : _c.disconnect();
|
|
6748
|
-
(_d = this.resizeContent) === null || _d === void 0 ? void 0 : _d.disconnect();
|
|
6749
6782
|
for (let dom of this.scrollTargets)
|
|
6750
6783
|
dom.removeEventListener("scroll", this.onScroll);
|
|
6751
6784
|
this.removeWindowListeners(this.win);
|
|
@@ -6903,6 +6936,8 @@ class EditorView {
|
|
|
6903
6936
|
this.dispatch = this.dispatch.bind(this);
|
|
6904
6937
|
this._root = (config.root || getRoot(config.parent) || document);
|
|
6905
6938
|
this.viewState = new ViewState(config.state || EditorState.create(config));
|
|
6939
|
+
if (config.scrollTo && config.scrollTo.is(scrollIntoView))
|
|
6940
|
+
this.viewState.scrollTarget = config.scrollTo.value.clip(this.viewState.state);
|
|
6906
6941
|
this.plugins = this.state.facet(viewPlugin).map(spec => new PluginInstance(spec));
|
|
6907
6942
|
for (let plugin of this.plugins)
|
|
6908
6943
|
plugin.update(this);
|
|
@@ -6990,7 +7025,7 @@ class EditorView {
|
|
|
6990
7025
|
}
|
|
6991
7026
|
for (let e of tr.effects)
|
|
6992
7027
|
if (e.is(scrollIntoView))
|
|
6993
|
-
scrollTarget = e.value;
|
|
7028
|
+
scrollTarget = e.value.clip(this.state);
|
|
6994
7029
|
}
|
|
6995
7030
|
this.viewState.update(update, scrollTarget);
|
|
6996
7031
|
this.bidiCache = CachedOrder.update(this.bidiCache, update.changes);
|
|
@@ -7013,8 +7048,14 @@ class EditorView {
|
|
|
7013
7048
|
if (redrawn || attrsChanged || scrollTarget || this.viewState.mustEnforceCursorAssoc || this.viewState.mustMeasureContent)
|
|
7014
7049
|
this.requestMeasure();
|
|
7015
7050
|
if (!update.empty)
|
|
7016
|
-
for (let listener of this.state.facet(updateListener))
|
|
7017
|
-
|
|
7051
|
+
for (let listener of this.state.facet(updateListener)) {
|
|
7052
|
+
try {
|
|
7053
|
+
listener(update);
|
|
7054
|
+
}
|
|
7055
|
+
catch (e) {
|
|
7056
|
+
logException(this.state, e, "update listener");
|
|
7057
|
+
}
|
|
7058
|
+
}
|
|
7018
7059
|
if (dispatchFocus || domChange)
|
|
7019
7060
|
Promise.resolve().then(() => {
|
|
7020
7061
|
if (dispatchFocus && this.state == dispatchFocus.startState)
|
|
@@ -7596,6 +7637,23 @@ class EditorView {
|
|
|
7596
7637
|
return scrollIntoView.of(new ScrollTarget(typeof pos == "number" ? EditorSelection.cursor(pos) : pos, options.y, options.x, options.yMargin, options.xMargin));
|
|
7597
7638
|
}
|
|
7598
7639
|
/**
|
|
7640
|
+
Return an effect that resets the editor to its current (at the
|
|
7641
|
+
time this method was called) scroll position. Note that this
|
|
7642
|
+
only affects the editor's own scrollable element, not parents.
|
|
7643
|
+
See also
|
|
7644
|
+
[`EditorViewConfig.scrollTo`](https://codemirror.net/6/docs/ref/#view.EditorViewConfig.scrollTo).
|
|
7645
|
+
|
|
7646
|
+
The effect should be used with a document identical to the one
|
|
7647
|
+
it was created for. Failing to do so is not an error, but may
|
|
7648
|
+
not scroll to the expected position. You can
|
|
7649
|
+
[map](https://codemirror.net/6/docs/ref/#state.StateEffect.map) the effect to account for changes.
|
|
7650
|
+
*/
|
|
7651
|
+
scrollSnapshot() {
|
|
7652
|
+
let { scrollTop, scrollLeft } = this.scrollDOM;
|
|
7653
|
+
let ref = this.viewState.scrollAnchorAt(scrollTop);
|
|
7654
|
+
return scrollIntoView.of(new ScrollTarget(EditorSelection.cursor(ref.from), "start", "start", ref.top - scrollTop, scrollLeft, true));
|
|
7655
|
+
}
|
|
7656
|
+
/**
|
|
7599
7657
|
Returns an extension that can be used to add DOM event handlers.
|
|
7600
7658
|
The value should be an object mapping event names to handler
|
|
7601
7659
|
functions. For any given event, such functions are ordered by
|
|
@@ -9193,6 +9251,7 @@ const tooltipPlugin = /*@__PURE__*/ViewPlugin.fromClass(class {
|
|
|
9193
9251
|
}
|
|
9194
9252
|
tooltipView.dom.style.position = this.position;
|
|
9195
9253
|
tooltipView.dom.style.top = Outside;
|
|
9254
|
+
tooltipView.dom.style.left = "0px";
|
|
9196
9255
|
this.container.appendChild(tooltipView.dom);
|
|
9197
9256
|
if (tooltipView.mount)
|
|
9198
9257
|
tooltipView.mount(this.view);
|
|
@@ -9214,12 +9273,24 @@ const tooltipPlugin = /*@__PURE__*/ViewPlugin.fromClass(class {
|
|
|
9214
9273
|
let editor = this.view.dom.getBoundingClientRect();
|
|
9215
9274
|
let scaleX = 1, scaleY = 1, makeAbsolute = false;
|
|
9216
9275
|
if (this.position == "fixed" && this.manager.tooltipViews.length) {
|
|
9217
|
-
|
|
9218
|
-
|
|
9219
|
-
|
|
9220
|
-
|
|
9221
|
-
|
|
9222
|
-
|
|
9276
|
+
let { dom } = this.manager.tooltipViews[0];
|
|
9277
|
+
if (browser.gecko) {
|
|
9278
|
+
// Firefox sets the element's `offsetParent` to the
|
|
9279
|
+
// transformed element when a transform interferes with fixed
|
|
9280
|
+
// positioning.
|
|
9281
|
+
makeAbsolute = dom.offsetParent != this.container.ownerDocument.body;
|
|
9282
|
+
}
|
|
9283
|
+
else {
|
|
9284
|
+
// On other browsers, we have to awkwardly try and use other
|
|
9285
|
+
// information to detect a transform.
|
|
9286
|
+
if (this.view.scaleX != 1 || this.view.scaleY != 1) {
|
|
9287
|
+
makeAbsolute = true;
|
|
9288
|
+
}
|
|
9289
|
+
else if (dom.style.top == Outside && dom.style.left == "0px") {
|
|
9290
|
+
let rect = dom.getBoundingClientRect();
|
|
9291
|
+
makeAbsolute = Math.abs(rect.top + 10000) > 1 || Math.abs(rect.left) > 1;
|
|
9292
|
+
}
|
|
9293
|
+
}
|
|
9223
9294
|
}
|
|
9224
9295
|
if (makeAbsolute || this.position == "absolute") {
|
|
9225
9296
|
if (this.parent) {
|
|
@@ -9445,6 +9516,23 @@ class HoverTooltipHost {
|
|
|
9445
9516
|
for (let t of this.manager.tooltipViews)
|
|
9446
9517
|
(_a = t.destroy) === null || _a === void 0 ? void 0 : _a.call(t);
|
|
9447
9518
|
}
|
|
9519
|
+
passProp(name) {
|
|
9520
|
+
let value = undefined;
|
|
9521
|
+
for (let view of this.manager.tooltipViews) {
|
|
9522
|
+
let given = view[name];
|
|
9523
|
+
if (given !== undefined) {
|
|
9524
|
+
if (value === undefined)
|
|
9525
|
+
value = given;
|
|
9526
|
+
else if (value !== given)
|
|
9527
|
+
return undefined;
|
|
9528
|
+
}
|
|
9529
|
+
}
|
|
9530
|
+
return value;
|
|
9531
|
+
}
|
|
9532
|
+
get offset() { return this.passProp("offset"); }
|
|
9533
|
+
get getCoords() { return this.passProp("getCoords"); }
|
|
9534
|
+
get overlap() { return this.passProp("overlap"); }
|
|
9535
|
+
get resize() { return this.passProp("resize"); }
|
|
9448
9536
|
}
|
|
9449
9537
|
const showHoverTooltipHost = /*@__PURE__*/showTooltip.compute([showHoverTooltip], state => {
|
|
9450
9538
|
let tooltips = state.facet(showHoverTooltip).filter(t => t);
|