@codemirror/view 6.41.1 → 6.42.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 +12 -0
- package/dist/index.cjs +88 -31
- package/dist/index.d.cts +24 -2
- package/dist/index.d.ts +24 -2
- package/dist/index.js +87 -32
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
## 6.42.0 (2026-05-06)
|
|
2
|
+
|
|
3
|
+
### Bug fixes
|
|
4
|
+
|
|
5
|
+
Make sure `posAtCoords` doesn't recurse endlessly.
|
|
6
|
+
|
|
7
|
+
### New features
|
|
8
|
+
|
|
9
|
+
The new `activateHover` function can be used to explicitly activate hover tooltips at a given position.
|
|
10
|
+
|
|
11
|
+
`closeHoverTooltip` now allows you to close a specific hover tooltip.
|
|
12
|
+
|
|
1
13
|
## 6.41.1 (2026-04-18)
|
|
2
14
|
|
|
3
15
|
### Bug fixes
|
package/dist/index.cjs
CHANGED
|
@@ -3835,7 +3835,7 @@ class InlineCoordsScan {
|
|
|
3835
3835
|
// (including the position after the last piece). For a text tile,
|
|
3836
3836
|
// these will be character clusters, for a composite tile, these
|
|
3837
3837
|
// will be child tiles.
|
|
3838
|
-
scan(positions, getRects) {
|
|
3838
|
+
scan(positions, getRects, recursed = false) {
|
|
3839
3839
|
let lo = 0, hi = positions.length - 1, seen = new Set();
|
|
3840
3840
|
let bidi = this.bidiIn(positions[0], positions[hi]);
|
|
3841
3841
|
let above, below;
|
|
@@ -3908,19 +3908,19 @@ class InlineCoordsScan {
|
|
|
3908
3908
|
if (!closestRect) {
|
|
3909
3909
|
let side = above && (!below || (this.y - above.bottom < below.top - this.y)) ? above : below;
|
|
3910
3910
|
this.y = (side.top + side.bottom) / 2;
|
|
3911
|
-
return this.scan(positions, getRects);
|
|
3911
|
+
return this.scan(positions, getRects, true);
|
|
3912
3912
|
}
|
|
3913
3913
|
// Handle the case where closest matched a higher element on the
|
|
3914
3914
|
// same line as an element below/above the coords
|
|
3915
|
-
if (closestDx) {
|
|
3915
|
+
if (closestDx && !recursed) {
|
|
3916
3916
|
let { top, bottom } = closestRect;
|
|
3917
3917
|
if (above && above.bottom > (top + top + bottom) / 3) {
|
|
3918
3918
|
this.y = above.bottom - 1;
|
|
3919
|
-
return this.scan(positions, getRects);
|
|
3919
|
+
return this.scan(positions, getRects, true);
|
|
3920
3920
|
}
|
|
3921
3921
|
if (below && below.top < (top + bottom + bottom) / 3) {
|
|
3922
3922
|
this.y = below.top + 1;
|
|
3923
|
-
return this.scan(positions, getRects);
|
|
3923
|
+
return this.scan(positions, getRects, true);
|
|
3924
3924
|
}
|
|
3925
3925
|
}
|
|
3926
3926
|
let ltr = (bidi ? this.dirAt(positions[closestI], 1) : this.baseDir) == exports.Direction.LTR;
|
|
@@ -5214,7 +5214,7 @@ observers.compositionend = view => {
|
|
|
5214
5214
|
view.inputState.compositionFirstChange = null;
|
|
5215
5215
|
if (browser.chrome && browser.android) {
|
|
5216
5216
|
// Delay flushing for a bit on Android because it'll often fire a
|
|
5217
|
-
// bunch of contradictory changes in a row at end of
|
|
5217
|
+
// bunch of contradictory changes in a row at end of composition
|
|
5218
5218
|
view.observer.flushSoon();
|
|
5219
5219
|
}
|
|
5220
5220
|
else if (view.inputState.compositionPendingChange) {
|
|
@@ -10638,11 +10638,13 @@ const showHoverTooltipHost = showTooltip.compute([showHoverTooltip], state => {
|
|
|
10638
10638
|
arrow: tooltips.some(t => t.arrow),
|
|
10639
10639
|
};
|
|
10640
10640
|
});
|
|
10641
|
+
const hoverPlugin = state.Facet.define();
|
|
10641
10642
|
class HoverPlugin {
|
|
10642
|
-
constructor(view, source, field, setHover, hoverTime) {
|
|
10643
|
+
constructor(view, source, field, locked, setHover, hoverTime) {
|
|
10643
10644
|
this.view = view;
|
|
10644
10645
|
this.source = source;
|
|
10645
10646
|
this.field = field;
|
|
10647
|
+
this.locked = locked;
|
|
10646
10648
|
this.setHover = setHover;
|
|
10647
10649
|
this.hoverTime = hoverTime;
|
|
10648
10650
|
this.hoverTimeout = -1;
|
|
@@ -10653,7 +10655,7 @@ class HoverPlugin {
|
|
|
10653
10655
|
view.dom.addEventListener("mouseleave", this.mouseleave = this.mouseleave.bind(this));
|
|
10654
10656
|
view.dom.addEventListener("mousemove", this.mousemove = this.mousemove.bind(this));
|
|
10655
10657
|
}
|
|
10656
|
-
update() {
|
|
10658
|
+
update(update) {
|
|
10657
10659
|
if (this.pending) {
|
|
10658
10660
|
this.pending = null;
|
|
10659
10661
|
clearTimeout(this.restartTimeout);
|
|
@@ -10697,19 +10699,29 @@ class HoverPlugin {
|
|
|
10697
10699
|
let rtl = bidi && bidi.dir == exports.Direction.RTL ? -1 : 1;
|
|
10698
10700
|
side = (lastMove.x < posCoords.left ? -rtl : rtl);
|
|
10699
10701
|
}
|
|
10702
|
+
this.activateHover(view, pos, side);
|
|
10703
|
+
}
|
|
10704
|
+
activateHover(view, pos, side, locked) {
|
|
10700
10705
|
let open = this.source(view, pos, side);
|
|
10701
|
-
|
|
10706
|
+
let done = (value) => {
|
|
10707
|
+
if (value && !(Array.isArray(value) && !value.length)) {
|
|
10708
|
+
let tooltips = Array.isArray(value) ? value : [value];
|
|
10709
|
+
if (locked)
|
|
10710
|
+
this.locked.set(tooltips, locked);
|
|
10711
|
+
view.dispatch({ effects: this.setHover.of(tooltips) });
|
|
10712
|
+
}
|
|
10713
|
+
};
|
|
10714
|
+
if (open && "then" in open) {
|
|
10702
10715
|
let pending = this.pending = { pos };
|
|
10703
10716
|
open.then(result => {
|
|
10704
10717
|
if (this.pending == pending) {
|
|
10705
10718
|
this.pending = null;
|
|
10706
|
-
|
|
10707
|
-
view.dispatch({ effects: this.setHover.of(Array.isArray(result) ? result : [result]) });
|
|
10719
|
+
done(result);
|
|
10708
10720
|
}
|
|
10709
10721
|
}, e => logException(view.state, e, "hover tooltip"));
|
|
10710
10722
|
}
|
|
10711
|
-
else
|
|
10712
|
-
|
|
10723
|
+
else {
|
|
10724
|
+
done(open);
|
|
10713
10725
|
}
|
|
10714
10726
|
}
|
|
10715
10727
|
get tooltip() {
|
|
@@ -10723,7 +10735,7 @@ class HoverPlugin {
|
|
|
10723
10735
|
if (this.hoverTimeout < 0)
|
|
10724
10736
|
this.hoverTimeout = setTimeout(this.checkHover, this.hoverTime);
|
|
10725
10737
|
let { active, tooltip } = this;
|
|
10726
|
-
if (active.length && tooltip && !isInTooltip(tooltip.dom, event) || this.pending) {
|
|
10738
|
+
if (active.length && !this.locked.has(active) && tooltip && !isInTooltip(tooltip.dom, event) || this.pending) {
|
|
10727
10739
|
let { pos } = active[0] || this.pending, end = (_b = (_a = active[0]) === null || _a === void 0 ? void 0 : _a.end) !== null && _b !== void 0 ? _b : pos;
|
|
10728
10740
|
if ((pos == end ? this.view.posAtCoords(this.lastMove) != pos
|
|
10729
10741
|
: !isOverRange(this.view, pos, end, event.clientX, event.clientY))) {
|
|
@@ -10736,7 +10748,7 @@ class HoverPlugin {
|
|
|
10736
10748
|
clearTimeout(this.hoverTimeout);
|
|
10737
10749
|
this.hoverTimeout = -1;
|
|
10738
10750
|
let { active } = this;
|
|
10739
|
-
if (active.length) {
|
|
10751
|
+
if (active.length && !this.locked.has(active)) {
|
|
10740
10752
|
let { tooltip } = this;
|
|
10741
10753
|
let inTooltip = tooltip && tooltip.dom.contains(event.relatedTarget);
|
|
10742
10754
|
if (!inTooltip)
|
|
@@ -10748,7 +10760,8 @@ class HoverPlugin {
|
|
|
10748
10760
|
watchTooltipLeave(tooltip) {
|
|
10749
10761
|
let watch = (event) => {
|
|
10750
10762
|
tooltip.removeEventListener("mouseleave", watch);
|
|
10751
|
-
|
|
10763
|
+
let { active } = this;
|
|
10764
|
+
if (active.length && !this.locked.has(active) && !this.view.dom.contains(event.relatedTarget))
|
|
10752
10765
|
this.view.dispatch({ effects: this.setHover.of([]) });
|
|
10753
10766
|
};
|
|
10754
10767
|
tooltip.addEventListener("mouseleave", watch);
|
|
@@ -10799,49 +10812,85 @@ extension.
|
|
|
10799
10812
|
*/
|
|
10800
10813
|
function hoverTooltip(source, options = {}) {
|
|
10801
10814
|
let setHover = state.StateEffect.define();
|
|
10815
|
+
// This would be better stored in the state field, but we've set
|
|
10816
|
+
// down the type of the field in our interface, so it's indirectly
|
|
10817
|
+
// stored by array identity.
|
|
10818
|
+
let locked = new WeakMap();
|
|
10802
10819
|
let hoverState = state.StateField.define({
|
|
10803
10820
|
create() { return []; },
|
|
10804
10821
|
update(value, tr) {
|
|
10822
|
+
let lock = locked.get(value);
|
|
10805
10823
|
if (value.length) {
|
|
10806
10824
|
if (options.hideOnChange && (tr.docChanged || tr.selection))
|
|
10807
10825
|
value = [];
|
|
10826
|
+
else if (lock && lock(tr))
|
|
10827
|
+
value = [];
|
|
10808
10828
|
else if (options.hideOn)
|
|
10809
10829
|
value = value.filter(v => !options.hideOn(tr, v));
|
|
10810
|
-
|
|
10811
|
-
|
|
10812
|
-
|
|
10813
|
-
|
|
10814
|
-
|
|
10815
|
-
|
|
10816
|
-
|
|
10817
|
-
|
|
10818
|
-
|
|
10819
|
-
|
|
10820
|
-
|
|
10830
|
+
}
|
|
10831
|
+
if (tr.docChanged && value.length) {
|
|
10832
|
+
let mapped = [];
|
|
10833
|
+
for (let tooltip of value) {
|
|
10834
|
+
let newPos = tr.changes.mapPos(tooltip.pos, -1, state.MapMode.TrackDel);
|
|
10835
|
+
if (newPos != null) {
|
|
10836
|
+
let copy = Object.assign(Object.create(null), tooltip);
|
|
10837
|
+
copy.pos = newPos;
|
|
10838
|
+
if (copy.end != null)
|
|
10839
|
+
copy.end = tr.changes.mapPos(copy.end);
|
|
10840
|
+
mapped.push(copy);
|
|
10821
10841
|
}
|
|
10822
|
-
value = mapped;
|
|
10823
10842
|
}
|
|
10843
|
+
value = mapped;
|
|
10824
10844
|
}
|
|
10825
10845
|
for (let effect of tr.effects) {
|
|
10826
|
-
if (effect.is(setHover))
|
|
10846
|
+
if (effect.is(setHover)) {
|
|
10827
10847
|
value = effect.value;
|
|
10828
|
-
|
|
10848
|
+
lock = undefined;
|
|
10849
|
+
}
|
|
10850
|
+
if (effect.is(closeHoverTooltipEffect) && !effect.value || effect.value == hoverState)
|
|
10829
10851
|
value = [];
|
|
10830
10852
|
}
|
|
10853
|
+
if (value.length && lock)
|
|
10854
|
+
locked.set(value, lock);
|
|
10831
10855
|
return value;
|
|
10832
10856
|
},
|
|
10833
10857
|
provide: f => showHoverTooltip.from(f)
|
|
10834
10858
|
});
|
|
10859
|
+
const plugin = ViewPlugin.define(view => new HoverPlugin(view, source, hoverState, locked, setHover, options.hoverTime || 300 /* Hover.Time */));
|
|
10835
10860
|
return {
|
|
10836
10861
|
active: hoverState,
|
|
10837
10862
|
extension: [
|
|
10838
10863
|
hoverState,
|
|
10839
|
-
|
|
10864
|
+
plugin,
|
|
10865
|
+
hoverPlugin.of(plugin),
|
|
10840
10866
|
showHoverTooltipHost
|
|
10841
10867
|
]
|
|
10842
10868
|
};
|
|
10843
10869
|
}
|
|
10844
10870
|
/**
|
|
10871
|
+
Activate hover tooltips for the given position and side. If you
|
|
10872
|
+
provide a specific hover tooltip (the value returned from
|
|
10873
|
+
[`hoverTooltip`](https://codemirror.net/6/docs/ref/#view.hoverTooltip)), only that one will be
|
|
10874
|
+
activated. If not given, all hover tooltips at the given position
|
|
10875
|
+
are triggered.
|
|
10876
|
+
|
|
10877
|
+
Note that tooltips opened this way don't close automatically, and
|
|
10878
|
+
you'll want to pass an `until` callback or use
|
|
10879
|
+
[`closeHoverTooltip`](https://codemirror.net/6/docs/ref/#view.closeHoverTooltip)/[`closeHoverTooltips`](https://codemirror.net/6/docs/ref/#view.closeHoverTooltips)
|
|
10880
|
+
to deactivate them.
|
|
10881
|
+
*/
|
|
10882
|
+
function activateHover(view, pos, side, options = {}) {
|
|
10883
|
+
var _a;
|
|
10884
|
+
let plugins = view.state.facet(hoverPlugin).map(p => view.plugin(p)).filter((p) => !!p);
|
|
10885
|
+
if (options.tooltip && options.tooltip.active) {
|
|
10886
|
+
let found = plugins.find(p => p.field == options.tooltip.active);
|
|
10887
|
+
if (found)
|
|
10888
|
+
plugins = [found];
|
|
10889
|
+
}
|
|
10890
|
+
for (let plugin of plugins)
|
|
10891
|
+
plugin.activateHover(view, pos, side, (_a = options.until) !== null && _a !== void 0 ? _a : (() => false));
|
|
10892
|
+
}
|
|
10893
|
+
/**
|
|
10845
10894
|
Get the active tooltip view for a given tooltip, if available.
|
|
10846
10895
|
*/
|
|
10847
10896
|
function getTooltip(view, tooltip) {
|
|
@@ -10863,6 +10912,12 @@ Transaction effect that closes all hover tooltips.
|
|
|
10863
10912
|
*/
|
|
10864
10913
|
const closeHoverTooltips = closeHoverTooltipEffect.of(null);
|
|
10865
10914
|
/**
|
|
10915
|
+
Transaction effect that closes a specific hover tooltip.
|
|
10916
|
+
*/
|
|
10917
|
+
function closeHoverTooltip(tooltip) {
|
|
10918
|
+
return closeHoverTooltipEffect.of(tooltip.active);
|
|
10919
|
+
}
|
|
10920
|
+
/**
|
|
10866
10921
|
Tell the tooltip extension to recompute the position of the active
|
|
10867
10922
|
tooltips. This can be useful when something happens (such as a
|
|
10868
10923
|
re-positioning or CSS change affecting the editor) that could
|
|
@@ -11760,6 +11815,8 @@ exports.ViewPlugin = ViewPlugin;
|
|
|
11760
11815
|
exports.ViewUpdate = ViewUpdate;
|
|
11761
11816
|
exports.WidgetType = WidgetType;
|
|
11762
11817
|
exports.__test = __test;
|
|
11818
|
+
exports.activateHover = activateHover;
|
|
11819
|
+
exports.closeHoverTooltip = closeHoverTooltip;
|
|
11763
11820
|
exports.closeHoverTooltips = closeHoverTooltips;
|
|
11764
11821
|
exports.crosshairCursor = crosshairCursor;
|
|
11765
11822
|
exports.drawSelection = drawSelection;
|
package/dist/index.d.cts
CHANGED
|
@@ -2090,6 +2090,22 @@ declare function hoverTooltip(source: HoverTooltipSource, options?: {
|
|
|
2090
2090
|
active: StateField<readonly Tooltip[]>;
|
|
2091
2091
|
};
|
|
2092
2092
|
/**
|
|
2093
|
+
Activate hover tooltips for the given position and side. If you
|
|
2094
|
+
provide a specific hover tooltip (the value returned from
|
|
2095
|
+
[`hoverTooltip`](https://codemirror.net/6/docs/ref/#view.hoverTooltip)), only that one will be
|
|
2096
|
+
activated. If not given, all hover tooltips at the given position
|
|
2097
|
+
are triggered.
|
|
2098
|
+
|
|
2099
|
+
Note that tooltips opened this way don't close automatically, and
|
|
2100
|
+
you'll want to pass an `until` callback or use
|
|
2101
|
+
[`closeHoverTooltip`](https://codemirror.net/6/docs/ref/#view.closeHoverTooltip)/[`closeHoverTooltips`](https://codemirror.net/6/docs/ref/#view.closeHoverTooltips)
|
|
2102
|
+
to deactivate them.
|
|
2103
|
+
*/
|
|
2104
|
+
declare function activateHover(view: EditorView, pos: number, side: -1 | 1, options?: {
|
|
2105
|
+
tooltip?: Extension;
|
|
2106
|
+
until?: (tr: Transaction) => boolean;
|
|
2107
|
+
}): void;
|
|
2108
|
+
/**
|
|
2093
2109
|
Get the active tooltip view for a given tooltip, if available.
|
|
2094
2110
|
*/
|
|
2095
2111
|
declare function getTooltip(view: EditorView, tooltip: Tooltip): TooltipView | null;
|
|
@@ -2100,7 +2116,13 @@ declare function hasHoverTooltips(state: EditorState): boolean;
|
|
|
2100
2116
|
/**
|
|
2101
2117
|
Transaction effect that closes all hover tooltips.
|
|
2102
2118
|
*/
|
|
2103
|
-
declare const closeHoverTooltips: StateEffect<
|
|
2119
|
+
declare const closeHoverTooltips: StateEffect<unknown>;
|
|
2120
|
+
/**
|
|
2121
|
+
Transaction effect that closes a specific hover tooltip.
|
|
2122
|
+
*/
|
|
2123
|
+
declare function closeHoverTooltip(tooltip: Extension & {
|
|
2124
|
+
active: StateField<readonly Tooltip[]>;
|
|
2125
|
+
}): StateEffect<unknown>;
|
|
2104
2126
|
/**
|
|
2105
2127
|
Tell the tooltip extension to recompute the position of the active
|
|
2106
2128
|
tooltips. This can be useful when something happens (such as a
|
|
@@ -2386,4 +2408,4 @@ trailing whitespace.
|
|
|
2386
2408
|
*/
|
|
2387
2409
|
declare function highlightTrailingWhitespace(): Extension;
|
|
2388
2410
|
|
|
2389
|
-
export { BidiSpan, BlockInfo, BlockType, BlockWrapper, type Command, type DOMEventHandlers, type DOMEventMap, Decoration, type DecorationSet, Direction, EditorView, type EditorViewConfig, GutterMarker, type HoverTooltipSource, type KeyBinding, type LayerMarker, MatchDecorator, type MouseSelectionStyle, type Panel, type PanelConstructor, type PluginSpec, type PluginValue, type Rect, RectangleMarker, type Tooltip, type TooltipView, ViewPlugin, ViewUpdate, WidgetType, closeHoverTooltips, crosshairCursor, drawSelection, dropCursor, getDialog, getDrawSelectionConfig, getPanel, getTooltip, gutter, gutterLineClass, gutterWidgetClass, gutters, hasHoverTooltips, highlightActiveLine, highlightActiveLineGutter, highlightSpecialChars, highlightTrailingWhitespace, highlightWhitespace, hoverTooltip, keymap, layer, lineNumberMarkers, lineNumberWidgetMarker, lineNumbers, logException, panels, placeholder, rectangularSelection, repositionTooltips, runScopeHandlers, scrollPastEnd, showDialog, showPanel, showTooltip, tooltips };
|
|
2411
|
+
export { BidiSpan, BlockInfo, BlockType, BlockWrapper, type Command, type DOMEventHandlers, type DOMEventMap, Decoration, type DecorationSet, Direction, EditorView, type EditorViewConfig, GutterMarker, type HoverTooltipSource, type KeyBinding, type LayerMarker, MatchDecorator, type MouseSelectionStyle, type Panel, type PanelConstructor, type PluginSpec, type PluginValue, type Rect, RectangleMarker, type Tooltip, type TooltipView, ViewPlugin, ViewUpdate, WidgetType, activateHover, closeHoverTooltip, closeHoverTooltips, crosshairCursor, drawSelection, dropCursor, getDialog, getDrawSelectionConfig, getPanel, getTooltip, gutter, gutterLineClass, gutterWidgetClass, gutters, hasHoverTooltips, highlightActiveLine, highlightActiveLineGutter, highlightSpecialChars, highlightTrailingWhitespace, highlightWhitespace, hoverTooltip, keymap, layer, lineNumberMarkers, lineNumberWidgetMarker, lineNumbers, logException, panels, placeholder, rectangularSelection, repositionTooltips, runScopeHandlers, scrollPastEnd, showDialog, showPanel, showTooltip, tooltips };
|
package/dist/index.d.ts
CHANGED
|
@@ -2090,6 +2090,22 @@ declare function hoverTooltip(source: HoverTooltipSource, options?: {
|
|
|
2090
2090
|
active: StateField<readonly Tooltip[]>;
|
|
2091
2091
|
};
|
|
2092
2092
|
/**
|
|
2093
|
+
Activate hover tooltips for the given position and side. If you
|
|
2094
|
+
provide a specific hover tooltip (the value returned from
|
|
2095
|
+
[`hoverTooltip`](https://codemirror.net/6/docs/ref/#view.hoverTooltip)), only that one will be
|
|
2096
|
+
activated. If not given, all hover tooltips at the given position
|
|
2097
|
+
are triggered.
|
|
2098
|
+
|
|
2099
|
+
Note that tooltips opened this way don't close automatically, and
|
|
2100
|
+
you'll want to pass an `until` callback or use
|
|
2101
|
+
[`closeHoverTooltip`](https://codemirror.net/6/docs/ref/#view.closeHoverTooltip)/[`closeHoverTooltips`](https://codemirror.net/6/docs/ref/#view.closeHoverTooltips)
|
|
2102
|
+
to deactivate them.
|
|
2103
|
+
*/
|
|
2104
|
+
declare function activateHover(view: EditorView, pos: number, side: -1 | 1, options?: {
|
|
2105
|
+
tooltip?: Extension;
|
|
2106
|
+
until?: (tr: Transaction) => boolean;
|
|
2107
|
+
}): void;
|
|
2108
|
+
/**
|
|
2093
2109
|
Get the active tooltip view for a given tooltip, if available.
|
|
2094
2110
|
*/
|
|
2095
2111
|
declare function getTooltip(view: EditorView, tooltip: Tooltip): TooltipView | null;
|
|
@@ -2100,7 +2116,13 @@ declare function hasHoverTooltips(state: EditorState): boolean;
|
|
|
2100
2116
|
/**
|
|
2101
2117
|
Transaction effect that closes all hover tooltips.
|
|
2102
2118
|
*/
|
|
2103
|
-
declare const closeHoverTooltips: StateEffect<
|
|
2119
|
+
declare const closeHoverTooltips: StateEffect<unknown>;
|
|
2120
|
+
/**
|
|
2121
|
+
Transaction effect that closes a specific hover tooltip.
|
|
2122
|
+
*/
|
|
2123
|
+
declare function closeHoverTooltip(tooltip: Extension & {
|
|
2124
|
+
active: StateField<readonly Tooltip[]>;
|
|
2125
|
+
}): StateEffect<unknown>;
|
|
2104
2126
|
/**
|
|
2105
2127
|
Tell the tooltip extension to recompute the position of the active
|
|
2106
2128
|
tooltips. This can be useful when something happens (such as a
|
|
@@ -2386,4 +2408,4 @@ trailing whitespace.
|
|
|
2386
2408
|
*/
|
|
2387
2409
|
declare function highlightTrailingWhitespace(): Extension;
|
|
2388
2410
|
|
|
2389
|
-
export { BidiSpan, BlockInfo, BlockType, BlockWrapper, type Command, type DOMEventHandlers, type DOMEventMap, Decoration, type DecorationSet, Direction, EditorView, type EditorViewConfig, GutterMarker, type HoverTooltipSource, type KeyBinding, type LayerMarker, MatchDecorator, type MouseSelectionStyle, type Panel, type PanelConstructor, type PluginSpec, type PluginValue, type Rect, RectangleMarker, type Tooltip, type TooltipView, ViewPlugin, ViewUpdate, WidgetType, closeHoverTooltips, crosshairCursor, drawSelection, dropCursor, getDialog, getDrawSelectionConfig, getPanel, getTooltip, gutter, gutterLineClass, gutterWidgetClass, gutters, hasHoverTooltips, highlightActiveLine, highlightActiveLineGutter, highlightSpecialChars, highlightTrailingWhitespace, highlightWhitespace, hoverTooltip, keymap, layer, lineNumberMarkers, lineNumberWidgetMarker, lineNumbers, logException, panels, placeholder, rectangularSelection, repositionTooltips, runScopeHandlers, scrollPastEnd, showDialog, showPanel, showTooltip, tooltips };
|
|
2411
|
+
export { BidiSpan, BlockInfo, BlockType, BlockWrapper, type Command, type DOMEventHandlers, type DOMEventMap, Decoration, type DecorationSet, Direction, EditorView, type EditorViewConfig, GutterMarker, type HoverTooltipSource, type KeyBinding, type LayerMarker, MatchDecorator, type MouseSelectionStyle, type Panel, type PanelConstructor, type PluginSpec, type PluginValue, type Rect, RectangleMarker, type Tooltip, type TooltipView, ViewPlugin, ViewUpdate, WidgetType, activateHover, closeHoverTooltip, closeHoverTooltips, crosshairCursor, drawSelection, dropCursor, getDialog, getDrawSelectionConfig, getPanel, getTooltip, gutter, gutterLineClass, gutterWidgetClass, gutters, hasHoverTooltips, highlightActiveLine, highlightActiveLineGutter, highlightSpecialChars, highlightTrailingWhitespace, highlightWhitespace, hoverTooltip, keymap, layer, lineNumberMarkers, lineNumberWidgetMarker, lineNumbers, logException, panels, placeholder, rectangularSelection, repositionTooltips, runScopeHandlers, scrollPastEnd, showDialog, showPanel, showTooltip, tooltips };
|
package/dist/index.js
CHANGED
|
@@ -3831,7 +3831,7 @@ class InlineCoordsScan {
|
|
|
3831
3831
|
// (including the position after the last piece). For a text tile,
|
|
3832
3832
|
// these will be character clusters, for a composite tile, these
|
|
3833
3833
|
// will be child tiles.
|
|
3834
|
-
scan(positions, getRects) {
|
|
3834
|
+
scan(positions, getRects, recursed = false) {
|
|
3835
3835
|
let lo = 0, hi = positions.length - 1, seen = new Set();
|
|
3836
3836
|
let bidi = this.bidiIn(positions[0], positions[hi]);
|
|
3837
3837
|
let above, below;
|
|
@@ -3904,19 +3904,19 @@ class InlineCoordsScan {
|
|
|
3904
3904
|
if (!closestRect) {
|
|
3905
3905
|
let side = above && (!below || (this.y - above.bottom < below.top - this.y)) ? above : below;
|
|
3906
3906
|
this.y = (side.top + side.bottom) / 2;
|
|
3907
|
-
return this.scan(positions, getRects);
|
|
3907
|
+
return this.scan(positions, getRects, true);
|
|
3908
3908
|
}
|
|
3909
3909
|
// Handle the case where closest matched a higher element on the
|
|
3910
3910
|
// same line as an element below/above the coords
|
|
3911
|
-
if (closestDx) {
|
|
3911
|
+
if (closestDx && !recursed) {
|
|
3912
3912
|
let { top, bottom } = closestRect;
|
|
3913
3913
|
if (above && above.bottom > (top + top + bottom) / 3) {
|
|
3914
3914
|
this.y = above.bottom - 1;
|
|
3915
|
-
return this.scan(positions, getRects);
|
|
3915
|
+
return this.scan(positions, getRects, true);
|
|
3916
3916
|
}
|
|
3917
3917
|
if (below && below.top < (top + bottom + bottom) / 3) {
|
|
3918
3918
|
this.y = below.top + 1;
|
|
3919
|
-
return this.scan(positions, getRects);
|
|
3919
|
+
return this.scan(positions, getRects, true);
|
|
3920
3920
|
}
|
|
3921
3921
|
}
|
|
3922
3922
|
let ltr = (bidi ? this.dirAt(positions[closestI], 1) : this.baseDir) == Direction.LTR;
|
|
@@ -5210,7 +5210,7 @@ observers.compositionend = view => {
|
|
|
5210
5210
|
view.inputState.compositionFirstChange = null;
|
|
5211
5211
|
if (browser.chrome && browser.android) {
|
|
5212
5212
|
// Delay flushing for a bit on Android because it'll often fire a
|
|
5213
|
-
// bunch of contradictory changes in a row at end of
|
|
5213
|
+
// bunch of contradictory changes in a row at end of composition
|
|
5214
5214
|
view.observer.flushSoon();
|
|
5215
5215
|
}
|
|
5216
5216
|
else if (view.inputState.compositionPendingChange) {
|
|
@@ -10633,11 +10633,13 @@ const showHoverTooltipHost = /*@__PURE__*/showTooltip.compute([showHoverTooltip]
|
|
|
10633
10633
|
arrow: tooltips.some(t => t.arrow),
|
|
10634
10634
|
};
|
|
10635
10635
|
});
|
|
10636
|
+
const hoverPlugin = /*@__PURE__*/Facet.define();
|
|
10636
10637
|
class HoverPlugin {
|
|
10637
|
-
constructor(view, source, field, setHover, hoverTime) {
|
|
10638
|
+
constructor(view, source, field, locked, setHover, hoverTime) {
|
|
10638
10639
|
this.view = view;
|
|
10639
10640
|
this.source = source;
|
|
10640
10641
|
this.field = field;
|
|
10642
|
+
this.locked = locked;
|
|
10641
10643
|
this.setHover = setHover;
|
|
10642
10644
|
this.hoverTime = hoverTime;
|
|
10643
10645
|
this.hoverTimeout = -1;
|
|
@@ -10648,7 +10650,7 @@ class HoverPlugin {
|
|
|
10648
10650
|
view.dom.addEventListener("mouseleave", this.mouseleave = this.mouseleave.bind(this));
|
|
10649
10651
|
view.dom.addEventListener("mousemove", this.mousemove = this.mousemove.bind(this));
|
|
10650
10652
|
}
|
|
10651
|
-
update() {
|
|
10653
|
+
update(update) {
|
|
10652
10654
|
if (this.pending) {
|
|
10653
10655
|
this.pending = null;
|
|
10654
10656
|
clearTimeout(this.restartTimeout);
|
|
@@ -10692,19 +10694,29 @@ class HoverPlugin {
|
|
|
10692
10694
|
let rtl = bidi && bidi.dir == Direction.RTL ? -1 : 1;
|
|
10693
10695
|
side = (lastMove.x < posCoords.left ? -rtl : rtl);
|
|
10694
10696
|
}
|
|
10697
|
+
this.activateHover(view, pos, side);
|
|
10698
|
+
}
|
|
10699
|
+
activateHover(view, pos, side, locked) {
|
|
10695
10700
|
let open = this.source(view, pos, side);
|
|
10696
|
-
|
|
10701
|
+
let done = (value) => {
|
|
10702
|
+
if (value && !(Array.isArray(value) && !value.length)) {
|
|
10703
|
+
let tooltips = Array.isArray(value) ? value : [value];
|
|
10704
|
+
if (locked)
|
|
10705
|
+
this.locked.set(tooltips, locked);
|
|
10706
|
+
view.dispatch({ effects: this.setHover.of(tooltips) });
|
|
10707
|
+
}
|
|
10708
|
+
};
|
|
10709
|
+
if (open && "then" in open) {
|
|
10697
10710
|
let pending = this.pending = { pos };
|
|
10698
10711
|
open.then(result => {
|
|
10699
10712
|
if (this.pending == pending) {
|
|
10700
10713
|
this.pending = null;
|
|
10701
|
-
|
|
10702
|
-
view.dispatch({ effects: this.setHover.of(Array.isArray(result) ? result : [result]) });
|
|
10714
|
+
done(result);
|
|
10703
10715
|
}
|
|
10704
10716
|
}, e => logException(view.state, e, "hover tooltip"));
|
|
10705
10717
|
}
|
|
10706
|
-
else
|
|
10707
|
-
|
|
10718
|
+
else {
|
|
10719
|
+
done(open);
|
|
10708
10720
|
}
|
|
10709
10721
|
}
|
|
10710
10722
|
get tooltip() {
|
|
@@ -10718,7 +10730,7 @@ class HoverPlugin {
|
|
|
10718
10730
|
if (this.hoverTimeout < 0)
|
|
10719
10731
|
this.hoverTimeout = setTimeout(this.checkHover, this.hoverTime);
|
|
10720
10732
|
let { active, tooltip } = this;
|
|
10721
|
-
if (active.length && tooltip && !isInTooltip(tooltip.dom, event) || this.pending) {
|
|
10733
|
+
if (active.length && !this.locked.has(active) && tooltip && !isInTooltip(tooltip.dom, event) || this.pending) {
|
|
10722
10734
|
let { pos } = active[0] || this.pending, end = (_b = (_a = active[0]) === null || _a === void 0 ? void 0 : _a.end) !== null && _b !== void 0 ? _b : pos;
|
|
10723
10735
|
if ((pos == end ? this.view.posAtCoords(this.lastMove) != pos
|
|
10724
10736
|
: !isOverRange(this.view, pos, end, event.clientX, event.clientY))) {
|
|
@@ -10731,7 +10743,7 @@ class HoverPlugin {
|
|
|
10731
10743
|
clearTimeout(this.hoverTimeout);
|
|
10732
10744
|
this.hoverTimeout = -1;
|
|
10733
10745
|
let { active } = this;
|
|
10734
|
-
if (active.length) {
|
|
10746
|
+
if (active.length && !this.locked.has(active)) {
|
|
10735
10747
|
let { tooltip } = this;
|
|
10736
10748
|
let inTooltip = tooltip && tooltip.dom.contains(event.relatedTarget);
|
|
10737
10749
|
if (!inTooltip)
|
|
@@ -10743,7 +10755,8 @@ class HoverPlugin {
|
|
|
10743
10755
|
watchTooltipLeave(tooltip) {
|
|
10744
10756
|
let watch = (event) => {
|
|
10745
10757
|
tooltip.removeEventListener("mouseleave", watch);
|
|
10746
|
-
|
|
10758
|
+
let { active } = this;
|
|
10759
|
+
if (active.length && !this.locked.has(active) && !this.view.dom.contains(event.relatedTarget))
|
|
10747
10760
|
this.view.dispatch({ effects: this.setHover.of([]) });
|
|
10748
10761
|
};
|
|
10749
10762
|
tooltip.addEventListener("mouseleave", watch);
|
|
@@ -10794,49 +10807,85 @@ extension.
|
|
|
10794
10807
|
*/
|
|
10795
10808
|
function hoverTooltip(source, options = {}) {
|
|
10796
10809
|
let setHover = StateEffect.define();
|
|
10810
|
+
// This would be better stored in the state field, but we've set
|
|
10811
|
+
// down the type of the field in our interface, so it's indirectly
|
|
10812
|
+
// stored by array identity.
|
|
10813
|
+
let locked = new WeakMap();
|
|
10797
10814
|
let hoverState = StateField.define({
|
|
10798
10815
|
create() { return []; },
|
|
10799
10816
|
update(value, tr) {
|
|
10817
|
+
let lock = locked.get(value);
|
|
10800
10818
|
if (value.length) {
|
|
10801
10819
|
if (options.hideOnChange && (tr.docChanged || tr.selection))
|
|
10802
10820
|
value = [];
|
|
10821
|
+
else if (lock && lock(tr))
|
|
10822
|
+
value = [];
|
|
10803
10823
|
else if (options.hideOn)
|
|
10804
10824
|
value = value.filter(v => !options.hideOn(tr, v));
|
|
10805
|
-
|
|
10806
|
-
|
|
10807
|
-
|
|
10808
|
-
|
|
10809
|
-
|
|
10810
|
-
|
|
10811
|
-
|
|
10812
|
-
|
|
10813
|
-
|
|
10814
|
-
|
|
10815
|
-
|
|
10825
|
+
}
|
|
10826
|
+
if (tr.docChanged && value.length) {
|
|
10827
|
+
let mapped = [];
|
|
10828
|
+
for (let tooltip of value) {
|
|
10829
|
+
let newPos = tr.changes.mapPos(tooltip.pos, -1, MapMode.TrackDel);
|
|
10830
|
+
if (newPos != null) {
|
|
10831
|
+
let copy = Object.assign(Object.create(null), tooltip);
|
|
10832
|
+
copy.pos = newPos;
|
|
10833
|
+
if (copy.end != null)
|
|
10834
|
+
copy.end = tr.changes.mapPos(copy.end);
|
|
10835
|
+
mapped.push(copy);
|
|
10816
10836
|
}
|
|
10817
|
-
value = mapped;
|
|
10818
10837
|
}
|
|
10838
|
+
value = mapped;
|
|
10819
10839
|
}
|
|
10820
10840
|
for (let effect of tr.effects) {
|
|
10821
|
-
if (effect.is(setHover))
|
|
10841
|
+
if (effect.is(setHover)) {
|
|
10822
10842
|
value = effect.value;
|
|
10823
|
-
|
|
10843
|
+
lock = undefined;
|
|
10844
|
+
}
|
|
10845
|
+
if (effect.is(closeHoverTooltipEffect) && !effect.value || effect.value == hoverState)
|
|
10824
10846
|
value = [];
|
|
10825
10847
|
}
|
|
10848
|
+
if (value.length && lock)
|
|
10849
|
+
locked.set(value, lock);
|
|
10826
10850
|
return value;
|
|
10827
10851
|
},
|
|
10828
10852
|
provide: f => showHoverTooltip.from(f)
|
|
10829
10853
|
});
|
|
10854
|
+
const plugin = ViewPlugin.define(view => new HoverPlugin(view, source, hoverState, locked, setHover, options.hoverTime || 300 /* Hover.Time */));
|
|
10830
10855
|
return {
|
|
10831
10856
|
active: hoverState,
|
|
10832
10857
|
extension: [
|
|
10833
10858
|
hoverState,
|
|
10834
|
-
|
|
10859
|
+
plugin,
|
|
10860
|
+
hoverPlugin.of(plugin),
|
|
10835
10861
|
showHoverTooltipHost
|
|
10836
10862
|
]
|
|
10837
10863
|
};
|
|
10838
10864
|
}
|
|
10839
10865
|
/**
|
|
10866
|
+
Activate hover tooltips for the given position and side. If you
|
|
10867
|
+
provide a specific hover tooltip (the value returned from
|
|
10868
|
+
[`hoverTooltip`](https://codemirror.net/6/docs/ref/#view.hoverTooltip)), only that one will be
|
|
10869
|
+
activated. If not given, all hover tooltips at the given position
|
|
10870
|
+
are triggered.
|
|
10871
|
+
|
|
10872
|
+
Note that tooltips opened this way don't close automatically, and
|
|
10873
|
+
you'll want to pass an `until` callback or use
|
|
10874
|
+
[`closeHoverTooltip`](https://codemirror.net/6/docs/ref/#view.closeHoverTooltip)/[`closeHoverTooltips`](https://codemirror.net/6/docs/ref/#view.closeHoverTooltips)
|
|
10875
|
+
to deactivate them.
|
|
10876
|
+
*/
|
|
10877
|
+
function activateHover(view, pos, side, options = {}) {
|
|
10878
|
+
var _a;
|
|
10879
|
+
let plugins = view.state.facet(hoverPlugin).map(p => view.plugin(p)).filter((p) => !!p);
|
|
10880
|
+
if (options.tooltip && options.tooltip.active) {
|
|
10881
|
+
let found = plugins.find(p => p.field == options.tooltip.active);
|
|
10882
|
+
if (found)
|
|
10883
|
+
plugins = [found];
|
|
10884
|
+
}
|
|
10885
|
+
for (let plugin of plugins)
|
|
10886
|
+
plugin.activateHover(view, pos, side, (_a = options.until) !== null && _a !== void 0 ? _a : (() => false));
|
|
10887
|
+
}
|
|
10888
|
+
/**
|
|
10840
10889
|
Get the active tooltip view for a given tooltip, if available.
|
|
10841
10890
|
*/
|
|
10842
10891
|
function getTooltip(view, tooltip) {
|
|
@@ -10858,6 +10907,12 @@ Transaction effect that closes all hover tooltips.
|
|
|
10858
10907
|
*/
|
|
10859
10908
|
const closeHoverTooltips = /*@__PURE__*/closeHoverTooltipEffect.of(null);
|
|
10860
10909
|
/**
|
|
10910
|
+
Transaction effect that closes a specific hover tooltip.
|
|
10911
|
+
*/
|
|
10912
|
+
function closeHoverTooltip(tooltip) {
|
|
10913
|
+
return closeHoverTooltipEffect.of(tooltip.active);
|
|
10914
|
+
}
|
|
10915
|
+
/**
|
|
10861
10916
|
Tell the tooltip extension to recompute the position of the active
|
|
10862
10917
|
tooltips. This can be useful when something happens (such as a
|
|
10863
10918
|
re-positioning or CSS change affecting the editor) that could
|
|
@@ -11743,4 +11798,4 @@ function highlightTrailingWhitespace() {
|
|
|
11743
11798
|
const __test = { HeightMap, HeightOracle, MeasuredHeights, QueryType, ChangedRange, computeOrder,
|
|
11744
11799
|
moveVisually, clearHeightChangeFlag, getHeightChangeFlag: () => heightChangeFlag };
|
|
11745
11800
|
|
|
11746
|
-
export { BidiSpan, BlockInfo, BlockType, BlockWrapper, Decoration, Direction, EditorView, GutterMarker, MatchDecorator, RectangleMarker, ViewPlugin, ViewUpdate, WidgetType, __test, closeHoverTooltips, crosshairCursor, drawSelection, dropCursor, getDialog, getDrawSelectionConfig, getPanel, getTooltip, gutter, gutterLineClass, gutterWidgetClass, gutters, hasHoverTooltips, highlightActiveLine, highlightActiveLineGutter, highlightSpecialChars, highlightTrailingWhitespace, highlightWhitespace, hoverTooltip, keymap, layer, lineNumberMarkers, lineNumberWidgetMarker, lineNumbers, logException, panels, placeholder, rectangularSelection, repositionTooltips, runScopeHandlers, scrollPastEnd, showDialog, showPanel, showTooltip, tooltips };
|
|
11801
|
+
export { BidiSpan, BlockInfo, BlockType, BlockWrapper, Decoration, Direction, EditorView, GutterMarker, MatchDecorator, RectangleMarker, ViewPlugin, ViewUpdate, WidgetType, __test, activateHover, closeHoverTooltip, closeHoverTooltips, crosshairCursor, drawSelection, dropCursor, getDialog, getDrawSelectionConfig, getPanel, getTooltip, gutter, gutterLineClass, gutterWidgetClass, gutters, hasHoverTooltips, highlightActiveLine, highlightActiveLineGutter, highlightSpecialChars, highlightTrailingWhitespace, highlightWhitespace, hoverTooltip, keymap, layer, lineNumberMarkers, lineNumberWidgetMarker, lineNumbers, logException, panels, placeholder, rectangularSelection, repositionTooltips, runScopeHandlers, scrollPastEnd, showDialog, showPanel, showTooltip, tooltips };
|