@codemirror/view 6.23.0 → 6.24.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 +69 -46
- package/dist/index.d.cts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +69 -46
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,23 @@
|
|
|
1
|
+
## 6.24.0 (2024-02-09)
|
|
2
|
+
|
|
3
|
+
### Bug fixes
|
|
4
|
+
|
|
5
|
+
Fix an issue that broke context-menu select-all on Chrome when the viewport didn't cover the whole document.
|
|
6
|
+
|
|
7
|
+
Make sure tooltips are ordered by extension precedence in the DOM.
|
|
8
|
+
|
|
9
|
+
### New features
|
|
10
|
+
|
|
11
|
+
Hover tooltip sources may now return multiple tooltips.
|
|
12
|
+
|
|
13
|
+
## 6.23.1 (2024-01-24)
|
|
14
|
+
|
|
15
|
+
### Bug fixes
|
|
16
|
+
|
|
17
|
+
Fix a bug that caused `Tooltip.above` to not take effect for tooltips that were already present when the tooltip plugin is initialized.
|
|
18
|
+
|
|
19
|
+
Automatically reposition tooltips when their size changes.
|
|
20
|
+
|
|
1
21
|
## 6.23.0 (2023-12-28)
|
|
2
22
|
|
|
3
23
|
### Bug fixes
|
package/dist/index.cjs
CHANGED
|
@@ -3193,6 +3193,7 @@ class BlockGapWidget extends WidgetType {
|
|
|
3193
3193
|
}
|
|
3194
3194
|
get editable() { return true; }
|
|
3195
3195
|
get estimatedHeight() { return this.height; }
|
|
3196
|
+
ignoreEvent() { return false; }
|
|
3196
3197
|
}
|
|
3197
3198
|
function findCompositionNode(view, headPos) {
|
|
3198
3199
|
let sel = view.observer.selectionRange;
|
|
@@ -6208,12 +6209,16 @@ class DOMChange {
|
|
|
6208
6209
|
!contains(view.contentDOM, domSel.anchorNode)
|
|
6209
6210
|
? view.state.selection.main.anchor
|
|
6210
6211
|
: view.docView.posFromDOM(domSel.anchorNode, domSel.anchorOffset);
|
|
6211
|
-
// iOS will refuse to select the block gaps when doing
|
|
6212
|
+
// iOS will refuse to select the block gaps when doing
|
|
6213
|
+
// select-all.
|
|
6214
|
+
// Chrome will put the selection *inside* them, confusing
|
|
6215
|
+
// posFromDOM
|
|
6212
6216
|
let vp = view.viewport;
|
|
6213
|
-
if (browser.ios && view.state.selection.main.empty && head != anchor &&
|
|
6217
|
+
if ((browser.ios || browser.chrome) && view.state.selection.main.empty && head != anchor &&
|
|
6214
6218
|
(vp.from > 0 || vp.to < view.state.doc.length)) {
|
|
6215
|
-
let
|
|
6216
|
-
|
|
6219
|
+
let from = Math.min(head, anchor), to = Math.max(head, anchor);
|
|
6220
|
+
let offFrom = vp.from - from, offTo = vp.to - to;
|
|
6221
|
+
if ((offFrom == 0 || offFrom == 1 || from == 0) && (offTo == 0 || offTo == -1 || to == view.state.doc.length)) {
|
|
6217
6222
|
head = 0;
|
|
6218
6223
|
anchor = view.state.doc.length;
|
|
6219
6224
|
}
|
|
@@ -9179,12 +9184,14 @@ function crosshairCursor(options = {}) {
|
|
|
9179
9184
|
|
|
9180
9185
|
const Outside = "-10000px";
|
|
9181
9186
|
class TooltipViewManager {
|
|
9182
|
-
constructor(view, facet, createTooltipView) {
|
|
9187
|
+
constructor(view, facet, createTooltipView, removeTooltipView) {
|
|
9183
9188
|
this.facet = facet;
|
|
9184
9189
|
this.createTooltipView = createTooltipView;
|
|
9190
|
+
this.removeTooltipView = removeTooltipView;
|
|
9185
9191
|
this.input = view.state.facet(facet);
|
|
9186
9192
|
this.tooltips = this.input.filter(t => t);
|
|
9187
|
-
|
|
9193
|
+
let prev = null;
|
|
9194
|
+
this.tooltipViews = this.tooltips.map(t => prev = createTooltipView(t, prev));
|
|
9188
9195
|
}
|
|
9189
9196
|
update(update, above) {
|
|
9190
9197
|
var _a;
|
|
@@ -9207,7 +9214,7 @@ class TooltipViewManager {
|
|
|
9207
9214
|
known = i;
|
|
9208
9215
|
}
|
|
9209
9216
|
if (known < 0) {
|
|
9210
|
-
tooltipViews[i] = this.createTooltipView(tip);
|
|
9217
|
+
tooltipViews[i] = this.createTooltipView(tip, i ? tooltipViews[i - 1] : null);
|
|
9211
9218
|
if (newAbove)
|
|
9212
9219
|
newAbove[i] = !!tip.above;
|
|
9213
9220
|
}
|
|
@@ -9221,7 +9228,7 @@ class TooltipViewManager {
|
|
|
9221
9228
|
}
|
|
9222
9229
|
for (let t of this.tooltipViews)
|
|
9223
9230
|
if (tooltipViews.indexOf(t) < 0) {
|
|
9224
|
-
|
|
9231
|
+
this.removeTooltipView(t);
|
|
9225
9232
|
(_a = t.destroy) === null || _a === void 0 ? void 0 : _a.call(t);
|
|
9226
9233
|
}
|
|
9227
9234
|
if (above) {
|
|
@@ -9269,7 +9276,13 @@ const tooltipPlugin = ViewPlugin.fromClass(class {
|
|
|
9269
9276
|
this.classes = view.themeClasses;
|
|
9270
9277
|
this.createContainer();
|
|
9271
9278
|
this.measureReq = { read: this.readMeasure.bind(this), write: this.writeMeasure.bind(this), key: this };
|
|
9272
|
-
this.
|
|
9279
|
+
this.resizeObserver = typeof ResizeObserver == "function" ? new ResizeObserver(() => this.measureSoon()) : null;
|
|
9280
|
+
this.manager = new TooltipViewManager(view, showTooltip, (t, p) => this.createTooltip(t, p), t => {
|
|
9281
|
+
if (this.resizeObserver)
|
|
9282
|
+
this.resizeObserver.unobserve(t.dom);
|
|
9283
|
+
t.dom.remove();
|
|
9284
|
+
});
|
|
9285
|
+
this.above = this.manager.tooltips.map(t => !!t.above);
|
|
9273
9286
|
this.intersectionObserver = typeof IntersectionObserver == "function" ? new IntersectionObserver(entries => {
|
|
9274
9287
|
if (Date.now() > this.lastTransaction - 50 &&
|
|
9275
9288
|
entries.length > 0 && entries[entries.length - 1].intersectionRatio < 1)
|
|
@@ -9333,24 +9346,27 @@ const tooltipPlugin = ViewPlugin.fromClass(class {
|
|
|
9333
9346
|
if (shouldMeasure)
|
|
9334
9347
|
this.maybeMeasure();
|
|
9335
9348
|
}
|
|
9336
|
-
createTooltip(tooltip) {
|
|
9349
|
+
createTooltip(tooltip, prev) {
|
|
9337
9350
|
let tooltipView = tooltip.create(this.view);
|
|
9351
|
+
let before = prev ? prev.dom : null;
|
|
9338
9352
|
tooltipView.dom.classList.add("cm-tooltip");
|
|
9339
9353
|
if (tooltip.arrow && !tooltipView.dom.querySelector(".cm-tooltip > .cm-tooltip-arrow")) {
|
|
9340
9354
|
let arrow = document.createElement("div");
|
|
9341
9355
|
arrow.className = "cm-tooltip-arrow";
|
|
9342
|
-
tooltipView.dom.
|
|
9356
|
+
tooltipView.dom.insertBefore(arrow, before);
|
|
9343
9357
|
}
|
|
9344
9358
|
tooltipView.dom.style.position = this.position;
|
|
9345
9359
|
tooltipView.dom.style.top = Outside;
|
|
9346
9360
|
tooltipView.dom.style.left = "0px";
|
|
9347
|
-
this.container.
|
|
9361
|
+
this.container.insertBefore(tooltipView.dom, before);
|
|
9348
9362
|
if (tooltipView.mount)
|
|
9349
9363
|
tooltipView.mount(this.view);
|
|
9364
|
+
if (this.resizeObserver)
|
|
9365
|
+
this.resizeObserver.observe(tooltipView.dom);
|
|
9350
9366
|
return tooltipView;
|
|
9351
9367
|
}
|
|
9352
9368
|
destroy() {
|
|
9353
|
-
var _a, _b;
|
|
9369
|
+
var _a, _b, _c;
|
|
9354
9370
|
this.view.win.removeEventListener("resize", this.measureSoon);
|
|
9355
9371
|
for (let tooltipView of this.manager.tooltipViews) {
|
|
9356
9372
|
tooltipView.dom.remove();
|
|
@@ -9358,7 +9374,8 @@ const tooltipPlugin = ViewPlugin.fromClass(class {
|
|
|
9358
9374
|
}
|
|
9359
9375
|
if (this.parent)
|
|
9360
9376
|
this.container.remove();
|
|
9361
|
-
(_b = this.
|
|
9377
|
+
(_b = this.resizeObserver) === null || _b === void 0 ? void 0 : _b.disconnect();
|
|
9378
|
+
(_c = this.intersectionObserver) === null || _c === void 0 ? void 0 : _c.disconnect();
|
|
9362
9379
|
clearTimeout(this.measureTimeout);
|
|
9363
9380
|
}
|
|
9364
9381
|
readMeasure() {
|
|
@@ -9561,7 +9578,9 @@ Facet to which an extension can add a value to show a tooltip.
|
|
|
9561
9578
|
const showTooltip = state.Facet.define({
|
|
9562
9579
|
enables: [tooltipPlugin, baseTheme]
|
|
9563
9580
|
});
|
|
9564
|
-
const showHoverTooltip = state.Facet.define(
|
|
9581
|
+
const showHoverTooltip = state.Facet.define({
|
|
9582
|
+
combine: inputs => inputs.reduce((a, i) => a.concat(i), [])
|
|
9583
|
+
});
|
|
9565
9584
|
class HoverTooltipHost {
|
|
9566
9585
|
// Needs to be static so that host tooltip instances always match
|
|
9567
9586
|
static create(view) {
|
|
@@ -9572,12 +9591,12 @@ class HoverTooltipHost {
|
|
|
9572
9591
|
this.mounted = false;
|
|
9573
9592
|
this.dom = document.createElement("div");
|
|
9574
9593
|
this.dom.classList.add("cm-tooltip-hover");
|
|
9575
|
-
this.manager = new TooltipViewManager(view, showHoverTooltip, t => this.createHostedView(t));
|
|
9594
|
+
this.manager = new TooltipViewManager(view, showHoverTooltip, (t, p) => this.createHostedView(t, p), t => t.dom.remove());
|
|
9576
9595
|
}
|
|
9577
|
-
createHostedView(tooltip) {
|
|
9596
|
+
createHostedView(tooltip, prev) {
|
|
9578
9597
|
let hostedView = tooltip.create(this.view);
|
|
9579
9598
|
hostedView.dom.classList.add("cm-tooltip-section");
|
|
9580
|
-
this.dom.
|
|
9599
|
+
this.dom.insertBefore(hostedView.dom, prev ? prev.dom.nextSibling : this.dom.firstChild);
|
|
9581
9600
|
if (this.mounted && hostedView.mount)
|
|
9582
9601
|
hostedView.mount(this.view);
|
|
9583
9602
|
return hostedView;
|
|
@@ -9622,7 +9641,7 @@ class HoverTooltipHost {
|
|
|
9622
9641
|
get resize() { return this.passProp("resize"); }
|
|
9623
9642
|
}
|
|
9624
9643
|
const showHoverTooltipHost = showTooltip.compute([showHoverTooltip], state => {
|
|
9625
|
-
let tooltips = state.facet(showHoverTooltip)
|
|
9644
|
+
let tooltips = state.facet(showHoverTooltip);
|
|
9626
9645
|
if (tooltips.length === 0)
|
|
9627
9646
|
return null;
|
|
9628
9647
|
return {
|
|
@@ -9660,7 +9679,7 @@ class HoverPlugin {
|
|
|
9660
9679
|
}
|
|
9661
9680
|
checkHover() {
|
|
9662
9681
|
this.hoverTimeout = -1;
|
|
9663
|
-
if (this.active)
|
|
9682
|
+
if (this.active.length)
|
|
9664
9683
|
return;
|
|
9665
9684
|
let hovered = Date.now() - this.lastMove.time;
|
|
9666
9685
|
if (hovered < this.hoverTime)
|
|
@@ -9698,13 +9717,13 @@ class HoverPlugin {
|
|
|
9698
9717
|
open.then(result => {
|
|
9699
9718
|
if (this.pending == pending) {
|
|
9700
9719
|
this.pending = null;
|
|
9701
|
-
if (result)
|
|
9702
|
-
view.dispatch({ effects: this.setHover.of(result) });
|
|
9720
|
+
if (result && !(Array.isArray(result) && !result.length))
|
|
9721
|
+
view.dispatch({ effects: this.setHover.of(Array.isArray(result) ? result : [result]) });
|
|
9703
9722
|
}
|
|
9704
9723
|
}, e => logException(view.state, e, "hover tooltip"));
|
|
9705
9724
|
}
|
|
9706
|
-
else if (open) {
|
|
9707
|
-
view.dispatch({ effects: this.setHover.of(open) });
|
|
9725
|
+
else if (open && !(Array.isArray(open) && !open.length)) {
|
|
9726
|
+
view.dispatch({ effects: this.setHover.of(Array.isArray(open) ? open : [open]) });
|
|
9708
9727
|
}
|
|
9709
9728
|
}
|
|
9710
9729
|
get tooltip() {
|
|
@@ -9713,16 +9732,16 @@ class HoverPlugin {
|
|
|
9713
9732
|
return index > -1 ? plugin.manager.tooltipViews[index] : null;
|
|
9714
9733
|
}
|
|
9715
9734
|
mousemove(event) {
|
|
9716
|
-
var _a;
|
|
9735
|
+
var _a, _b;
|
|
9717
9736
|
this.lastMove = { x: event.clientX, y: event.clientY, target: event.target, time: Date.now() };
|
|
9718
9737
|
if (this.hoverTimeout < 0)
|
|
9719
9738
|
this.hoverTimeout = setTimeout(this.checkHover, this.hoverTime);
|
|
9720
9739
|
let { active, tooltip } = this;
|
|
9721
|
-
if (active && tooltip && !isInTooltip(tooltip.dom, event) || this.pending) {
|
|
9722
|
-
let { pos } = active || this.pending, end = (_a = active === null ||
|
|
9740
|
+
if (active.length && tooltip && !isInTooltip(tooltip.dom, event) || this.pending) {
|
|
9741
|
+
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;
|
|
9723
9742
|
if ((pos == end ? this.view.posAtCoords(this.lastMove) != pos
|
|
9724
9743
|
: !isOverRange(this.view, pos, end, event.clientX, event.clientY))) {
|
|
9725
|
-
this.view.dispatch({ effects: this.setHover.of(
|
|
9744
|
+
this.view.dispatch({ effects: this.setHover.of([]) });
|
|
9726
9745
|
this.pending = null;
|
|
9727
9746
|
}
|
|
9728
9747
|
}
|
|
@@ -9731,11 +9750,11 @@ class HoverPlugin {
|
|
|
9731
9750
|
clearTimeout(this.hoverTimeout);
|
|
9732
9751
|
this.hoverTimeout = -1;
|
|
9733
9752
|
let { active } = this;
|
|
9734
|
-
if (active) {
|
|
9753
|
+
if (active.length) {
|
|
9735
9754
|
let { tooltip } = this;
|
|
9736
9755
|
let inTooltip = tooltip && tooltip.dom.contains(event.relatedTarget);
|
|
9737
9756
|
if (!inTooltip)
|
|
9738
|
-
this.view.dispatch({ effects: this.setHover.of(
|
|
9757
|
+
this.view.dispatch({ effects: this.setHover.of([]) });
|
|
9739
9758
|
else
|
|
9740
9759
|
this.watchTooltipLeave(tooltip.dom);
|
|
9741
9760
|
}
|
|
@@ -9743,8 +9762,8 @@ class HoverPlugin {
|
|
|
9743
9762
|
watchTooltipLeave(tooltip) {
|
|
9744
9763
|
let watch = (event) => {
|
|
9745
9764
|
tooltip.removeEventListener("mouseleave", watch);
|
|
9746
|
-
if (this.active && !this.view.dom.contains(event.relatedTarget))
|
|
9747
|
-
this.view.dispatch({ effects: this.setHover.of(
|
|
9765
|
+
if (this.active.length && !this.view.dom.contains(event.relatedTarget))
|
|
9766
|
+
this.view.dispatch({ effects: this.setHover.of([]) });
|
|
9748
9767
|
};
|
|
9749
9768
|
tooltip.addEventListener("mouseleave", watch);
|
|
9750
9769
|
}
|
|
@@ -9784,26 +9803,30 @@ range to be "merged" together without overlapping.
|
|
|
9784
9803
|
function hoverTooltip(source, options = {}) {
|
|
9785
9804
|
let setHover = state.StateEffect.define();
|
|
9786
9805
|
let hoverState = state.StateField.define({
|
|
9787
|
-
create() { return
|
|
9806
|
+
create() { return []; },
|
|
9788
9807
|
update(value, tr) {
|
|
9789
|
-
if (value
|
|
9790
|
-
options.
|
|
9791
|
-
|
|
9792
|
-
|
|
9793
|
-
|
|
9794
|
-
if (
|
|
9795
|
-
|
|
9796
|
-
|
|
9797
|
-
|
|
9798
|
-
|
|
9799
|
-
|
|
9800
|
-
|
|
9808
|
+
if (value.length) {
|
|
9809
|
+
if (options.hideOnChange && (tr.docChanged || tr.selection))
|
|
9810
|
+
value = [];
|
|
9811
|
+
else if (options.hideOn)
|
|
9812
|
+
value = value.filter(v => !options.hideOn(tr, v));
|
|
9813
|
+
if (tr.docChanged) {
|
|
9814
|
+
for (let tooltip of value) {
|
|
9815
|
+
let newPos = tr.changes.mapPos(tooltip.pos, -1, state.MapMode.TrackDel);
|
|
9816
|
+
if (newPos != null) {
|
|
9817
|
+
let copy = Object.assign(Object.create(null), tooltip);
|
|
9818
|
+
copy.pos = newPos;
|
|
9819
|
+
if (copy.end != null)
|
|
9820
|
+
copy.end = tr.changes.mapPos(copy.end);
|
|
9821
|
+
}
|
|
9822
|
+
}
|
|
9823
|
+
}
|
|
9801
9824
|
}
|
|
9802
9825
|
for (let effect of tr.effects) {
|
|
9803
9826
|
if (effect.is(setHover))
|
|
9804
9827
|
value = effect.value;
|
|
9805
9828
|
if (effect.is(closeHoverTooltipEffect))
|
|
9806
|
-
value =
|
|
9829
|
+
value = [];
|
|
9807
9830
|
}
|
|
9808
9831
|
return value;
|
|
9809
9832
|
},
|
package/dist/index.d.cts
CHANGED
|
@@ -1889,6 +1889,7 @@ interface TooltipView {
|
|
|
1889
1889
|
Facet to which an extension can add a value to show a tooltip.
|
|
1890
1890
|
*/
|
|
1891
1891
|
declare const showTooltip: Facet<Tooltip | null, readonly (Tooltip | null)[]>;
|
|
1892
|
+
type HoverSource = (view: EditorView, pos: number, side: -1 | 1) => Tooltip | readonly Tooltip[] | null | Promise<Tooltip | readonly Tooltip[] | null>;
|
|
1892
1893
|
/**
|
|
1893
1894
|
Set up a hover tooltip, which shows up when the pointer hovers
|
|
1894
1895
|
over ranges of text. The callback is called when the mouse hovers
|
|
@@ -1902,7 +1903,7 @@ Note that all hover tooltips are hosted within a single tooltip
|
|
|
1902
1903
|
container element. This allows multiple tooltips over the same
|
|
1903
1904
|
range to be "merged" together without overlapping.
|
|
1904
1905
|
*/
|
|
1905
|
-
declare function hoverTooltip(source:
|
|
1906
|
+
declare function hoverTooltip(source: HoverSource, options?: {
|
|
1906
1907
|
/**
|
|
1907
1908
|
Controls whether a transaction hides the tooltip. The default
|
|
1908
1909
|
is to not hide.
|
package/dist/index.d.ts
CHANGED
|
@@ -1889,6 +1889,7 @@ interface TooltipView {
|
|
|
1889
1889
|
Facet to which an extension can add a value to show a tooltip.
|
|
1890
1890
|
*/
|
|
1891
1891
|
declare const showTooltip: Facet<Tooltip | null, readonly (Tooltip | null)[]>;
|
|
1892
|
+
type HoverSource = (view: EditorView, pos: number, side: -1 | 1) => Tooltip | readonly Tooltip[] | null | Promise<Tooltip | readonly Tooltip[] | null>;
|
|
1892
1893
|
/**
|
|
1893
1894
|
Set up a hover tooltip, which shows up when the pointer hovers
|
|
1894
1895
|
over ranges of text. The callback is called when the mouse hovers
|
|
@@ -1902,7 +1903,7 @@ Note that all hover tooltips are hosted within a single tooltip
|
|
|
1902
1903
|
container element. This allows multiple tooltips over the same
|
|
1903
1904
|
range to be "merged" together without overlapping.
|
|
1904
1905
|
*/
|
|
1905
|
-
declare function hoverTooltip(source:
|
|
1906
|
+
declare function hoverTooltip(source: HoverSource, options?: {
|
|
1906
1907
|
/**
|
|
1907
1908
|
Controls whether a transaction hides the tooltip. The default
|
|
1908
1909
|
is to not hide.
|
package/dist/index.js
CHANGED
|
@@ -3189,6 +3189,7 @@ class BlockGapWidget extends WidgetType {
|
|
|
3189
3189
|
}
|
|
3190
3190
|
get editable() { return true; }
|
|
3191
3191
|
get estimatedHeight() { return this.height; }
|
|
3192
|
+
ignoreEvent() { return false; }
|
|
3192
3193
|
}
|
|
3193
3194
|
function findCompositionNode(view, headPos) {
|
|
3194
3195
|
let sel = view.observer.selectionRange;
|
|
@@ -6203,12 +6204,16 @@ class DOMChange {
|
|
|
6203
6204
|
!contains(view.contentDOM, domSel.anchorNode)
|
|
6204
6205
|
? view.state.selection.main.anchor
|
|
6205
6206
|
: view.docView.posFromDOM(domSel.anchorNode, domSel.anchorOffset);
|
|
6206
|
-
// iOS will refuse to select the block gaps when doing
|
|
6207
|
+
// iOS will refuse to select the block gaps when doing
|
|
6208
|
+
// select-all.
|
|
6209
|
+
// Chrome will put the selection *inside* them, confusing
|
|
6210
|
+
// posFromDOM
|
|
6207
6211
|
let vp = view.viewport;
|
|
6208
|
-
if (browser.ios && view.state.selection.main.empty && head != anchor &&
|
|
6212
|
+
if ((browser.ios || browser.chrome) && view.state.selection.main.empty && head != anchor &&
|
|
6209
6213
|
(vp.from > 0 || vp.to < view.state.doc.length)) {
|
|
6210
|
-
let
|
|
6211
|
-
|
|
6214
|
+
let from = Math.min(head, anchor), to = Math.max(head, anchor);
|
|
6215
|
+
let offFrom = vp.from - from, offTo = vp.to - to;
|
|
6216
|
+
if ((offFrom == 0 || offFrom == 1 || from == 0) && (offTo == 0 || offTo == -1 || to == view.state.doc.length)) {
|
|
6212
6217
|
head = 0;
|
|
6213
6218
|
anchor = view.state.doc.length;
|
|
6214
6219
|
}
|
|
@@ -9174,12 +9179,14 @@ function crosshairCursor(options = {}) {
|
|
|
9174
9179
|
|
|
9175
9180
|
const Outside = "-10000px";
|
|
9176
9181
|
class TooltipViewManager {
|
|
9177
|
-
constructor(view, facet, createTooltipView) {
|
|
9182
|
+
constructor(view, facet, createTooltipView, removeTooltipView) {
|
|
9178
9183
|
this.facet = facet;
|
|
9179
9184
|
this.createTooltipView = createTooltipView;
|
|
9185
|
+
this.removeTooltipView = removeTooltipView;
|
|
9180
9186
|
this.input = view.state.facet(facet);
|
|
9181
9187
|
this.tooltips = this.input.filter(t => t);
|
|
9182
|
-
|
|
9188
|
+
let prev = null;
|
|
9189
|
+
this.tooltipViews = this.tooltips.map(t => prev = createTooltipView(t, prev));
|
|
9183
9190
|
}
|
|
9184
9191
|
update(update, above) {
|
|
9185
9192
|
var _a;
|
|
@@ -9202,7 +9209,7 @@ class TooltipViewManager {
|
|
|
9202
9209
|
known = i;
|
|
9203
9210
|
}
|
|
9204
9211
|
if (known < 0) {
|
|
9205
|
-
tooltipViews[i] = this.createTooltipView(tip);
|
|
9212
|
+
tooltipViews[i] = this.createTooltipView(tip, i ? tooltipViews[i - 1] : null);
|
|
9206
9213
|
if (newAbove)
|
|
9207
9214
|
newAbove[i] = !!tip.above;
|
|
9208
9215
|
}
|
|
@@ -9216,7 +9223,7 @@ class TooltipViewManager {
|
|
|
9216
9223
|
}
|
|
9217
9224
|
for (let t of this.tooltipViews)
|
|
9218
9225
|
if (tooltipViews.indexOf(t) < 0) {
|
|
9219
|
-
|
|
9226
|
+
this.removeTooltipView(t);
|
|
9220
9227
|
(_a = t.destroy) === null || _a === void 0 ? void 0 : _a.call(t);
|
|
9221
9228
|
}
|
|
9222
9229
|
if (above) {
|
|
@@ -9264,7 +9271,13 @@ const tooltipPlugin = /*@__PURE__*/ViewPlugin.fromClass(class {
|
|
|
9264
9271
|
this.classes = view.themeClasses;
|
|
9265
9272
|
this.createContainer();
|
|
9266
9273
|
this.measureReq = { read: this.readMeasure.bind(this), write: this.writeMeasure.bind(this), key: this };
|
|
9267
|
-
this.
|
|
9274
|
+
this.resizeObserver = typeof ResizeObserver == "function" ? new ResizeObserver(() => this.measureSoon()) : null;
|
|
9275
|
+
this.manager = new TooltipViewManager(view, showTooltip, (t, p) => this.createTooltip(t, p), t => {
|
|
9276
|
+
if (this.resizeObserver)
|
|
9277
|
+
this.resizeObserver.unobserve(t.dom);
|
|
9278
|
+
t.dom.remove();
|
|
9279
|
+
});
|
|
9280
|
+
this.above = this.manager.tooltips.map(t => !!t.above);
|
|
9268
9281
|
this.intersectionObserver = typeof IntersectionObserver == "function" ? new IntersectionObserver(entries => {
|
|
9269
9282
|
if (Date.now() > this.lastTransaction - 50 &&
|
|
9270
9283
|
entries.length > 0 && entries[entries.length - 1].intersectionRatio < 1)
|
|
@@ -9328,24 +9341,27 @@ const tooltipPlugin = /*@__PURE__*/ViewPlugin.fromClass(class {
|
|
|
9328
9341
|
if (shouldMeasure)
|
|
9329
9342
|
this.maybeMeasure();
|
|
9330
9343
|
}
|
|
9331
|
-
createTooltip(tooltip) {
|
|
9344
|
+
createTooltip(tooltip, prev) {
|
|
9332
9345
|
let tooltipView = tooltip.create(this.view);
|
|
9346
|
+
let before = prev ? prev.dom : null;
|
|
9333
9347
|
tooltipView.dom.classList.add("cm-tooltip");
|
|
9334
9348
|
if (tooltip.arrow && !tooltipView.dom.querySelector(".cm-tooltip > .cm-tooltip-arrow")) {
|
|
9335
9349
|
let arrow = document.createElement("div");
|
|
9336
9350
|
arrow.className = "cm-tooltip-arrow";
|
|
9337
|
-
tooltipView.dom.
|
|
9351
|
+
tooltipView.dom.insertBefore(arrow, before);
|
|
9338
9352
|
}
|
|
9339
9353
|
tooltipView.dom.style.position = this.position;
|
|
9340
9354
|
tooltipView.dom.style.top = Outside;
|
|
9341
9355
|
tooltipView.dom.style.left = "0px";
|
|
9342
|
-
this.container.
|
|
9356
|
+
this.container.insertBefore(tooltipView.dom, before);
|
|
9343
9357
|
if (tooltipView.mount)
|
|
9344
9358
|
tooltipView.mount(this.view);
|
|
9359
|
+
if (this.resizeObserver)
|
|
9360
|
+
this.resizeObserver.observe(tooltipView.dom);
|
|
9345
9361
|
return tooltipView;
|
|
9346
9362
|
}
|
|
9347
9363
|
destroy() {
|
|
9348
|
-
var _a, _b;
|
|
9364
|
+
var _a, _b, _c;
|
|
9349
9365
|
this.view.win.removeEventListener("resize", this.measureSoon);
|
|
9350
9366
|
for (let tooltipView of this.manager.tooltipViews) {
|
|
9351
9367
|
tooltipView.dom.remove();
|
|
@@ -9353,7 +9369,8 @@ const tooltipPlugin = /*@__PURE__*/ViewPlugin.fromClass(class {
|
|
|
9353
9369
|
}
|
|
9354
9370
|
if (this.parent)
|
|
9355
9371
|
this.container.remove();
|
|
9356
|
-
(_b = this.
|
|
9372
|
+
(_b = this.resizeObserver) === null || _b === void 0 ? void 0 : _b.disconnect();
|
|
9373
|
+
(_c = this.intersectionObserver) === null || _c === void 0 ? void 0 : _c.disconnect();
|
|
9357
9374
|
clearTimeout(this.measureTimeout);
|
|
9358
9375
|
}
|
|
9359
9376
|
readMeasure() {
|
|
@@ -9556,7 +9573,9 @@ Facet to which an extension can add a value to show a tooltip.
|
|
|
9556
9573
|
const showTooltip = /*@__PURE__*/Facet.define({
|
|
9557
9574
|
enables: [tooltipPlugin, baseTheme]
|
|
9558
9575
|
});
|
|
9559
|
-
const showHoverTooltip = /*@__PURE__*/Facet.define(
|
|
9576
|
+
const showHoverTooltip = /*@__PURE__*/Facet.define({
|
|
9577
|
+
combine: inputs => inputs.reduce((a, i) => a.concat(i), [])
|
|
9578
|
+
});
|
|
9560
9579
|
class HoverTooltipHost {
|
|
9561
9580
|
// Needs to be static so that host tooltip instances always match
|
|
9562
9581
|
static create(view) {
|
|
@@ -9567,12 +9586,12 @@ class HoverTooltipHost {
|
|
|
9567
9586
|
this.mounted = false;
|
|
9568
9587
|
this.dom = document.createElement("div");
|
|
9569
9588
|
this.dom.classList.add("cm-tooltip-hover");
|
|
9570
|
-
this.manager = new TooltipViewManager(view, showHoverTooltip, t => this.createHostedView(t));
|
|
9589
|
+
this.manager = new TooltipViewManager(view, showHoverTooltip, (t, p) => this.createHostedView(t, p), t => t.dom.remove());
|
|
9571
9590
|
}
|
|
9572
|
-
createHostedView(tooltip) {
|
|
9591
|
+
createHostedView(tooltip, prev) {
|
|
9573
9592
|
let hostedView = tooltip.create(this.view);
|
|
9574
9593
|
hostedView.dom.classList.add("cm-tooltip-section");
|
|
9575
|
-
this.dom.
|
|
9594
|
+
this.dom.insertBefore(hostedView.dom, prev ? prev.dom.nextSibling : this.dom.firstChild);
|
|
9576
9595
|
if (this.mounted && hostedView.mount)
|
|
9577
9596
|
hostedView.mount(this.view);
|
|
9578
9597
|
return hostedView;
|
|
@@ -9617,7 +9636,7 @@ class HoverTooltipHost {
|
|
|
9617
9636
|
get resize() { return this.passProp("resize"); }
|
|
9618
9637
|
}
|
|
9619
9638
|
const showHoverTooltipHost = /*@__PURE__*/showTooltip.compute([showHoverTooltip], state => {
|
|
9620
|
-
let tooltips = state.facet(showHoverTooltip)
|
|
9639
|
+
let tooltips = state.facet(showHoverTooltip);
|
|
9621
9640
|
if (tooltips.length === 0)
|
|
9622
9641
|
return null;
|
|
9623
9642
|
return {
|
|
@@ -9655,7 +9674,7 @@ class HoverPlugin {
|
|
|
9655
9674
|
}
|
|
9656
9675
|
checkHover() {
|
|
9657
9676
|
this.hoverTimeout = -1;
|
|
9658
|
-
if (this.active)
|
|
9677
|
+
if (this.active.length)
|
|
9659
9678
|
return;
|
|
9660
9679
|
let hovered = Date.now() - this.lastMove.time;
|
|
9661
9680
|
if (hovered < this.hoverTime)
|
|
@@ -9693,13 +9712,13 @@ class HoverPlugin {
|
|
|
9693
9712
|
open.then(result => {
|
|
9694
9713
|
if (this.pending == pending) {
|
|
9695
9714
|
this.pending = null;
|
|
9696
|
-
if (result)
|
|
9697
|
-
view.dispatch({ effects: this.setHover.of(result) });
|
|
9715
|
+
if (result && !(Array.isArray(result) && !result.length))
|
|
9716
|
+
view.dispatch({ effects: this.setHover.of(Array.isArray(result) ? result : [result]) });
|
|
9698
9717
|
}
|
|
9699
9718
|
}, e => logException(view.state, e, "hover tooltip"));
|
|
9700
9719
|
}
|
|
9701
|
-
else if (open) {
|
|
9702
|
-
view.dispatch({ effects: this.setHover.of(open) });
|
|
9720
|
+
else if (open && !(Array.isArray(open) && !open.length)) {
|
|
9721
|
+
view.dispatch({ effects: this.setHover.of(Array.isArray(open) ? open : [open]) });
|
|
9703
9722
|
}
|
|
9704
9723
|
}
|
|
9705
9724
|
get tooltip() {
|
|
@@ -9708,16 +9727,16 @@ class HoverPlugin {
|
|
|
9708
9727
|
return index > -1 ? plugin.manager.tooltipViews[index] : null;
|
|
9709
9728
|
}
|
|
9710
9729
|
mousemove(event) {
|
|
9711
|
-
var _a;
|
|
9730
|
+
var _a, _b;
|
|
9712
9731
|
this.lastMove = { x: event.clientX, y: event.clientY, target: event.target, time: Date.now() };
|
|
9713
9732
|
if (this.hoverTimeout < 0)
|
|
9714
9733
|
this.hoverTimeout = setTimeout(this.checkHover, this.hoverTime);
|
|
9715
9734
|
let { active, tooltip } = this;
|
|
9716
|
-
if (active && tooltip && !isInTooltip(tooltip.dom, event) || this.pending) {
|
|
9717
|
-
let { pos } = active || this.pending, end = (_a = active === null ||
|
|
9735
|
+
if (active.length && tooltip && !isInTooltip(tooltip.dom, event) || this.pending) {
|
|
9736
|
+
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;
|
|
9718
9737
|
if ((pos == end ? this.view.posAtCoords(this.lastMove) != pos
|
|
9719
9738
|
: !isOverRange(this.view, pos, end, event.clientX, event.clientY))) {
|
|
9720
|
-
this.view.dispatch({ effects: this.setHover.of(
|
|
9739
|
+
this.view.dispatch({ effects: this.setHover.of([]) });
|
|
9721
9740
|
this.pending = null;
|
|
9722
9741
|
}
|
|
9723
9742
|
}
|
|
@@ -9726,11 +9745,11 @@ class HoverPlugin {
|
|
|
9726
9745
|
clearTimeout(this.hoverTimeout);
|
|
9727
9746
|
this.hoverTimeout = -1;
|
|
9728
9747
|
let { active } = this;
|
|
9729
|
-
if (active) {
|
|
9748
|
+
if (active.length) {
|
|
9730
9749
|
let { tooltip } = this;
|
|
9731
9750
|
let inTooltip = tooltip && tooltip.dom.contains(event.relatedTarget);
|
|
9732
9751
|
if (!inTooltip)
|
|
9733
|
-
this.view.dispatch({ effects: this.setHover.of(
|
|
9752
|
+
this.view.dispatch({ effects: this.setHover.of([]) });
|
|
9734
9753
|
else
|
|
9735
9754
|
this.watchTooltipLeave(tooltip.dom);
|
|
9736
9755
|
}
|
|
@@ -9738,8 +9757,8 @@ class HoverPlugin {
|
|
|
9738
9757
|
watchTooltipLeave(tooltip) {
|
|
9739
9758
|
let watch = (event) => {
|
|
9740
9759
|
tooltip.removeEventListener("mouseleave", watch);
|
|
9741
|
-
if (this.active && !this.view.dom.contains(event.relatedTarget))
|
|
9742
|
-
this.view.dispatch({ effects: this.setHover.of(
|
|
9760
|
+
if (this.active.length && !this.view.dom.contains(event.relatedTarget))
|
|
9761
|
+
this.view.dispatch({ effects: this.setHover.of([]) });
|
|
9743
9762
|
};
|
|
9744
9763
|
tooltip.addEventListener("mouseleave", watch);
|
|
9745
9764
|
}
|
|
@@ -9779,26 +9798,30 @@ range to be "merged" together without overlapping.
|
|
|
9779
9798
|
function hoverTooltip(source, options = {}) {
|
|
9780
9799
|
let setHover = StateEffect.define();
|
|
9781
9800
|
let hoverState = StateField.define({
|
|
9782
|
-
create() { return
|
|
9801
|
+
create() { return []; },
|
|
9783
9802
|
update(value, tr) {
|
|
9784
|
-
if (value
|
|
9785
|
-
options.
|
|
9786
|
-
|
|
9787
|
-
|
|
9788
|
-
|
|
9789
|
-
if (
|
|
9790
|
-
|
|
9791
|
-
|
|
9792
|
-
|
|
9793
|
-
|
|
9794
|
-
|
|
9795
|
-
|
|
9803
|
+
if (value.length) {
|
|
9804
|
+
if (options.hideOnChange && (tr.docChanged || tr.selection))
|
|
9805
|
+
value = [];
|
|
9806
|
+
else if (options.hideOn)
|
|
9807
|
+
value = value.filter(v => !options.hideOn(tr, v));
|
|
9808
|
+
if (tr.docChanged) {
|
|
9809
|
+
for (let tooltip of value) {
|
|
9810
|
+
let newPos = tr.changes.mapPos(tooltip.pos, -1, MapMode.TrackDel);
|
|
9811
|
+
if (newPos != null) {
|
|
9812
|
+
let copy = Object.assign(Object.create(null), tooltip);
|
|
9813
|
+
copy.pos = newPos;
|
|
9814
|
+
if (copy.end != null)
|
|
9815
|
+
copy.end = tr.changes.mapPos(copy.end);
|
|
9816
|
+
}
|
|
9817
|
+
}
|
|
9818
|
+
}
|
|
9796
9819
|
}
|
|
9797
9820
|
for (let effect of tr.effects) {
|
|
9798
9821
|
if (effect.is(setHover))
|
|
9799
9822
|
value = effect.value;
|
|
9800
9823
|
if (effect.is(closeHoverTooltipEffect))
|
|
9801
|
-
value =
|
|
9824
|
+
value = [];
|
|
9802
9825
|
}
|
|
9803
9826
|
return value;
|
|
9804
9827
|
},
|