@bicharts/chart-host 0.6.107 → 0.6.109
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/dist/adapters.mjs +3 -3
- package/dist/card.mjs +2 -2
- package/dist/{chunk-PA5V6J6K.mjs → chunk-3EQOJHRA.mjs} +1 -1
- package/dist/{chunk-P2DLK7WZ.mjs → chunk-3ER4C7TG.mjs} +1 -1
- package/dist/{chunk-IE426WU6.mjs → chunk-4DOKJ3R3.mjs} +2 -2
- package/dist/{chunk-MU4BWWO6.mjs → chunk-G4CKILIL.mjs} +1 -1
- package/dist/{chunk-CPLWAW3Z.mjs → chunk-GQLEU3VC.mjs} +1 -1
- package/dist/{chunk-BWR35DEK.mjs → chunk-JQ7FFCOE.mjs} +420 -17
- package/dist/{chunk-TLIBO5PT.mjs → chunk-QAPZIFOB.mjs} +35 -43
- package/dist/{chunk-SYUJ4TPX.mjs → chunk-TH577JHI.mjs} +23 -23
- package/dist/{chunk-IE7TM6DX.mjs → chunk-TN5JRULV.mjs} +1 -1
- package/dist/{chunk-7XRQUFVH.mjs → chunk-USZSHKIB.mjs} +5 -1
- package/dist/index.mjs +31 -9
- package/dist/legend-fit.mjs +3 -3
- package/dist/page.mjs +4 -4
- package/dist/provinces.mjs +1 -1
- package/dist/react.mjs +13 -9
- package/dist/testing.mjs +1 -1
- package/dist/types/annotations.d.ts +3 -1
- package/dist/types/contract.d.ts +25 -1
- package/dist/types/defaults.d.ts +2 -1
- package/dist/types/filterScope.d.ts +5 -5
- package/dist/types/focusKeep.d.ts +12 -0
- package/dist/types/host.d.ts +22 -1
- package/dist/types/index.d.ts +5 -3
- package/dist/types/keyboardMarks.d.ts +43 -0
- package/dist/types/react.d.ts +1 -1
- package/dist/zoom-memory.mjs +1 -1
- package/package.json +1 -1
|
@@ -4,11 +4,11 @@ import {
|
|
|
4
4
|
claimParkedLasso,
|
|
5
5
|
installLasso,
|
|
6
6
|
lassoEffect
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-4DOKJ3R3.mjs";
|
|
8
8
|
import {
|
|
9
9
|
censusHitBands,
|
|
10
10
|
ensureCrossfilterHitTargets
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-GQLEU3VC.mjs";
|
|
12
12
|
import {
|
|
13
13
|
clearPress,
|
|
14
14
|
clearSelectionGlyphs,
|
|
@@ -25,14 +25,14 @@ import {
|
|
|
25
25
|
selectionRuleOf,
|
|
26
26
|
trackPress,
|
|
27
27
|
validRowSet
|
|
28
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-3ER4C7TG.mjs";
|
|
29
29
|
import {
|
|
30
30
|
clipWindowOf,
|
|
31
31
|
fitRenderedChart,
|
|
32
32
|
rememberScroll,
|
|
33
33
|
takeScroll,
|
|
34
34
|
unpinScrolledAxis
|
|
35
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-TN5JRULV.mjs";
|
|
36
36
|
import {
|
|
37
37
|
geoFromCache
|
|
38
38
|
} from "./chunk-5WTQN5DL.mjs";
|
|
@@ -43,7 +43,7 @@ import {
|
|
|
43
43
|
Rr,
|
|
44
44
|
Yn,
|
|
45
45
|
tt
|
|
46
|
-
} from "./chunk-
|
|
46
|
+
} from "./chunk-TH577JHI.mjs";
|
|
47
47
|
import {
|
|
48
48
|
ACTIVE_TICK_CLASS,
|
|
49
49
|
ANIM_LOOP_DELAY_DEFAULT,
|
|
@@ -61,6 +61,7 @@ import {
|
|
|
61
61
|
COLOR_SCALE_SELF_CLAMP_PCT_MIN,
|
|
62
62
|
CONTAINER_SLOT_ANIM_STOP,
|
|
63
63
|
CONTAINER_SLOT_CLICKED_MARKS,
|
|
64
|
+
CONTAINER_SLOT_HOST_SELECTION,
|
|
64
65
|
CONTAINER_SLOT_INITIAL_XF_MARK,
|
|
65
66
|
CONTAINER_SLOT_UI_STATE,
|
|
66
67
|
CONTAINER_SLOT_XF_CLEAR,
|
|
@@ -74,6 +75,7 @@ import {
|
|
|
74
75
|
HOST_CONTRACT_VERSION,
|
|
75
76
|
LEGEND_MARK_CLASS,
|
|
76
77
|
LIFT_SELECTED_CLASS,
|
|
78
|
+
MARKS_INERT_CLASS,
|
|
77
79
|
MARK_CLASS,
|
|
78
80
|
MARK_SELECTED_CLASS,
|
|
79
81
|
MAX_MAP_POINTS_DEFAULT,
|
|
@@ -86,7 +88,7 @@ import {
|
|
|
86
88
|
XFILTER_REFRESH_EVENT,
|
|
87
89
|
chartOwnsTimeline,
|
|
88
90
|
periodTickSuppressesFeedback
|
|
89
|
-
} from "./chunk-
|
|
91
|
+
} from "./chunk-USZSHKIB.mjs";
|
|
90
92
|
|
|
91
93
|
// src/labelContrast.ts
|
|
92
94
|
function parseRGBA(c) {
|
|
@@ -1057,6 +1059,18 @@ function themedLand(p) {
|
|
|
1057
1059
|
const fg = toRGBA(p.themeFg) ?? [255, 255, 255, 1];
|
|
1058
1060
|
return "#" + compositeOver([fg[0], fg[1], fg[2], 0.18], [bg[0], bg[1], bg[2]]).map((v) => v.toString(16).padStart(2, "0")).join("");
|
|
1059
1061
|
}
|
|
1062
|
+
function cleanHostSelection(v) {
|
|
1063
|
+
if (!v || typeof v !== "object" || !Array.isArray(v.rows)) return void 0;
|
|
1064
|
+
const raw = v.rows;
|
|
1065
|
+
const rows = Array.from(new Set(raw.filter((n2) => typeof n2 === "number" && Number.isInteger(n2) && n2 >= 0))).sort((a, b) => a - b);
|
|
1066
|
+
const h = Number(v.hidden);
|
|
1067
|
+
const out = { rows, hidden: Number.isFinite(h) && h > 0 ? Math.floor(h) : 0 };
|
|
1068
|
+
const n = v.narrowed;
|
|
1069
|
+
if (n && typeof n === "object" && Number.isInteger(n.published) && Number.isInteger(n.kept) && n.kept >= 0 && n.kept < n.published) {
|
|
1070
|
+
out.narrowed = { published: n.published, kept: n.kept };
|
|
1071
|
+
}
|
|
1072
|
+
return out;
|
|
1073
|
+
}
|
|
1060
1074
|
var clamp = (n, lo, hi) => Math.max(lo, Math.min(hi, n));
|
|
1061
1075
|
var numberOr = (raw, dflt) => {
|
|
1062
1076
|
const n = raw == null || raw === "" ? NaN : Number(raw);
|
|
@@ -1089,6 +1103,8 @@ function resolveOptions(p) {
|
|
|
1089
1103
|
dataComplete: p.dataComplete,
|
|
1090
1104
|
rowsWithheld: p.rowsWithheld,
|
|
1091
1105
|
rowsFilteredOut: p.rowsFilteredOut,
|
|
1106
|
+
// A host FACT about its selection (contract 1.21.0), cleaned, never invented: absent stays absent.
|
|
1107
|
+
hostSelection: cleanHostSelection(p.hostSelection),
|
|
1092
1108
|
// Host services (contract 1.18.0): a FUNCTION or nothing, so a junk value never reaches a chart as something
|
|
1093
1109
|
// it would try to call. Passed through untouched otherwise: the host owns what opening or copying means.
|
|
1094
1110
|
openUrl: typeof p.openUrl === "function" ? p.openUrl : void 0,
|
|
@@ -1144,6 +1160,8 @@ function resolveOptions(p) {
|
|
|
1144
1160
|
})(),
|
|
1145
1161
|
// A host FACT from the generate answer, true only for a literal true: silence never suppresses anything.
|
|
1146
1162
|
suppressSelectionGlyph: p.suppressSelectionGlyph === true ? true : void 0,
|
|
1163
|
+
// A host FACT (1.22.0): the chart works from the keyboard. True only for a literal true, like the one above.
|
|
1164
|
+
keyboardMarks: p.keyboardMarks === true ? true : void 0,
|
|
1147
1165
|
onSelect: p.onSelect,
|
|
1148
1166
|
// Control gestures (1.10.0). Passed straight through like onSelect: the host owns what a gesture MEANS,
|
|
1149
1167
|
// and a host that supplies nothing leaves every control behaving exactly as before.
|
|
@@ -2307,7 +2325,7 @@ var DOT = 8;
|
|
|
2307
2325
|
var RING = 1.5;
|
|
2308
2326
|
var DOT_HALF = DOT / 2 + RING;
|
|
2309
2327
|
var DOT_IN = 8;
|
|
2310
|
-
function createAnnotationLayer(container, onClick) {
|
|
2328
|
+
function createAnnotationLayer(container, onClick, opts) {
|
|
2311
2329
|
let list = [];
|
|
2312
2330
|
let report = { shown: 0, notShown: 0 };
|
|
2313
2331
|
let last = null;
|
|
@@ -2431,7 +2449,7 @@ function createAnnotationLayer(container, onClick) {
|
|
|
2431
2449
|
const after = own.filter((t) => t.b.l >= run.r && t.b.b > run.t && t.b.t < run.b).map((t) => t.b.l);
|
|
2432
2450
|
return { r: Math.min(run.r, seen), y: (run.t + run.b) / 2, next: after.length ? Math.min(...after) : v.r };
|
|
2433
2451
|
};
|
|
2434
|
-
const clear = (v, len, mark) => {
|
|
2452
|
+
const clear = (v, len, mark, whole = v) => {
|
|
2435
2453
|
const hw = Math.max(16, len * 6 + 8) / 2, hh = 8, g = 2;
|
|
2436
2454
|
const cx = (v.l + v.r) / 2, cy = (v.t + v.b) / 2;
|
|
2437
2455
|
const at = (x, y) => ({ l: x - hw, t: y - hh, r: x + hw, b: y + hh });
|
|
@@ -2444,6 +2462,7 @@ function createAnnotationLayer(container, onClick) {
|
|
|
2444
2462
|
const tries = [];
|
|
2445
2463
|
const add = (x, y, px = x, py = y) => tries.push({ x: clampX(x, hw), y: clampY(y, hh), px, py });
|
|
2446
2464
|
const label = rowLabel(v, mark);
|
|
2465
|
+
if (!label && whole !== v && rowLabel(whole, mark)) return null;
|
|
2447
2466
|
if (label) {
|
|
2448
2467
|
const x = label.r + g + hw;
|
|
2449
2468
|
if (x + hw <= label.next - g || label.next >= v.r) add(x, label.y, Math.min(x, v.r - 1), label.y);
|
|
@@ -2508,7 +2527,7 @@ function createAnnotationLayer(container, onClick) {
|
|
|
2508
2527
|
}
|
|
2509
2528
|
}
|
|
2510
2529
|
const dot = wantsDot(bestMark ?? hits2.values().next().value ?? null);
|
|
2511
|
-
const pt = !best ? null : dot ? dotSpot(best, bestWhole) : clear(best, (a.label ?? "\u2022").length, bestMark);
|
|
2530
|
+
const pt = !best ? null : dot ? dotSpot(best, bestWhole) : clear(best, (a.label ?? "\u2022").length, bestMark, bestWhole ?? best);
|
|
2512
2531
|
if (laidOut && !pt) continue;
|
|
2513
2532
|
shown++;
|
|
2514
2533
|
const badge = doc.createElement("div");
|
|
@@ -2549,6 +2568,15 @@ function createAnnotationLayer(container, onClick) {
|
|
|
2549
2568
|
e.stopPropagation();
|
|
2550
2569
|
onClick?.(a);
|
|
2551
2570
|
});
|
|
2571
|
+
if (opts?.keyboard?.()) {
|
|
2572
|
+
badge.setAttribute("tabindex", "0");
|
|
2573
|
+
badge.addEventListener("keydown", (e) => {
|
|
2574
|
+
if (e.key !== "Enter" && e.key !== " " && e.key !== "Spacebar") return;
|
|
2575
|
+
e.preventDefault();
|
|
2576
|
+
e.stopPropagation();
|
|
2577
|
+
onClick?.(a);
|
|
2578
|
+
});
|
|
2579
|
+
}
|
|
2552
2580
|
layer.appendChild(badge);
|
|
2553
2581
|
}
|
|
2554
2582
|
report = { shown, notShown: list.length - shown };
|
|
@@ -2575,6 +2603,222 @@ function createAnnotationLayer(container, onClick) {
|
|
|
2575
2603
|
};
|
|
2576
2604
|
}
|
|
2577
2605
|
|
|
2606
|
+
// src/focusKeep.ts
|
|
2607
|
+
function signatureOf(el) {
|
|
2608
|
+
const a = (n) => el.getAttribute(n) ?? "";
|
|
2609
|
+
const cls = Array.from(el.classList ?? []).filter((c) => !/^lch-|^bic-/.test(c)).sort().join(" ");
|
|
2610
|
+
return [el.localName, a("type"), cls, a("name"), a("placeholder"), a("aria-label"), a("role")].join("|");
|
|
2611
|
+
}
|
|
2612
|
+
function alike(container, sig) {
|
|
2613
|
+
const tag = sig.split("|", 1)[0];
|
|
2614
|
+
if (!tag) return [];
|
|
2615
|
+
return Array.from(container.querySelectorAll(tag)).filter((e) => signatureOf(e) === sig);
|
|
2616
|
+
}
|
|
2617
|
+
function rememberFocus(container) {
|
|
2618
|
+
try {
|
|
2619
|
+
const active = container.ownerDocument?.activeElement;
|
|
2620
|
+
if (!active || active === container || !container.contains(active)) return null;
|
|
2621
|
+
const sig = signatureOf(active);
|
|
2622
|
+
const nth = alike(container, sig).indexOf(active);
|
|
2623
|
+
const t = active;
|
|
2624
|
+
let start = null, end = null, dir = null;
|
|
2625
|
+
try {
|
|
2626
|
+
if (typeof t.selectionStart === "number") {
|
|
2627
|
+
start = t.selectionStart;
|
|
2628
|
+
end = t.selectionEnd;
|
|
2629
|
+
dir = t.selectionDirection ?? null;
|
|
2630
|
+
}
|
|
2631
|
+
} catch {
|
|
2632
|
+
}
|
|
2633
|
+
return { sig, nth: Math.max(0, nth), start, end, dir };
|
|
2634
|
+
} catch {
|
|
2635
|
+
return null;
|
|
2636
|
+
}
|
|
2637
|
+
}
|
|
2638
|
+
function restoreFocus(container, memory) {
|
|
2639
|
+
if (!memory) return false;
|
|
2640
|
+
try {
|
|
2641
|
+
const active = container.ownerDocument?.activeElement;
|
|
2642
|
+
if (active && active !== container && container.contains(active)) return false;
|
|
2643
|
+
const list = alike(container, memory.sig);
|
|
2644
|
+
const el = list[memory.nth] ?? (list.length === 1 ? list[0] : null);
|
|
2645
|
+
if (!el || typeof el.focus !== "function") return false;
|
|
2646
|
+
el.focus({ preventScroll: true });
|
|
2647
|
+
const t = el;
|
|
2648
|
+
if (memory.start != null && typeof t.setSelectionRange === "function") {
|
|
2649
|
+
const len = typeof t.value === "string" ? t.value.length : 0;
|
|
2650
|
+
try {
|
|
2651
|
+
t.setSelectionRange(Math.min(memory.start, len), Math.min(memory.end ?? memory.start, len), memory.dir ?? void 0);
|
|
2652
|
+
} catch {
|
|
2653
|
+
}
|
|
2654
|
+
}
|
|
2655
|
+
return container.ownerDocument?.activeElement === el;
|
|
2656
|
+
} catch {
|
|
2657
|
+
return false;
|
|
2658
|
+
}
|
|
2659
|
+
}
|
|
2660
|
+
|
|
2661
|
+
// src/keyboardMarks.ts
|
|
2662
|
+
var KEYBOARD_STAMP = "// bic:keyboard-marks";
|
|
2663
|
+
var STAMP_RE = /^[ \t]*\/\/[ \t]*bic:keyboard-marks\b/;
|
|
2664
|
+
var STAMP_HEAD_LINES = 12;
|
|
2665
|
+
function codeHasKeyboardStamp(code) {
|
|
2666
|
+
if (typeof code !== "string" || !code) return false;
|
|
2667
|
+
let start = 0;
|
|
2668
|
+
for (let n = 0; n < STAMP_HEAD_LINES && start <= code.length; n++) {
|
|
2669
|
+
const end = code.indexOf("\n", start);
|
|
2670
|
+
const line = code.slice(start, end < 0 ? code.length : end);
|
|
2671
|
+
if (STAMP_RE.test(line)) return true;
|
|
2672
|
+
if (end < 0) break;
|
|
2673
|
+
start = end + 1;
|
|
2674
|
+
}
|
|
2675
|
+
return false;
|
|
2676
|
+
}
|
|
2677
|
+
var KEYBOARD_CLASS = "lch-keyboard";
|
|
2678
|
+
var WIRED_ATTR = "data-lch-kb";
|
|
2679
|
+
function rowNameOf(columns, row, culture) {
|
|
2680
|
+
if (!row) return null;
|
|
2681
|
+
const parts = [];
|
|
2682
|
+
(columns || []).forEach((c, i) => {
|
|
2683
|
+
const name = typeof c === "string" ? c : c?.name;
|
|
2684
|
+
const v = row[i];
|
|
2685
|
+
if (parts.length >= 4 || v == null || v === "" || typeof name === "string" && name.startsWith("__")) return;
|
|
2686
|
+
parts.push(typeof v === "number" ? v.toLocaleString(culture || void 0, { maximumFractionDigits: 2 }) : String(v));
|
|
2687
|
+
});
|
|
2688
|
+
return parts.length ? parts.join(", ") : null;
|
|
2689
|
+
}
|
|
2690
|
+
var isClearChord = (e) => !!e.ctrlKey && !!e.shiftKey && (e.key === "C" || e.key === "c");
|
|
2691
|
+
var NATIVE = /* @__PURE__ */ new Set(["input", "select", "textarea", "button", "a"]);
|
|
2692
|
+
var isNative = (el) => NATIVE.has((el.localName || "").toLowerCase()) || el.isContentEditable === true;
|
|
2693
|
+
function installKeyboard(env) {
|
|
2694
|
+
const { container } = env;
|
|
2695
|
+
let rovingKey = null;
|
|
2696
|
+
let destroyed = false;
|
|
2697
|
+
const marksNow = () => {
|
|
2698
|
+
if (env.inert()) return [];
|
|
2699
|
+
return Array.from(container.querySelectorAll(env.markSelector)).filter((m) => !m.closest(env.skipSelector) && (m.getAttribute("data-row-idx") ?? "") !== "");
|
|
2700
|
+
};
|
|
2701
|
+
const wired = (el) => el.hasAttribute(WIRED_ATTR);
|
|
2702
|
+
const wire = (el, tabindex, role) => {
|
|
2703
|
+
if (el.hasAttribute("tabindex") && !wired(el)) return false;
|
|
2704
|
+
el.setAttribute(WIRED_ATTR, "");
|
|
2705
|
+
el.setAttribute("tabindex", tabindex);
|
|
2706
|
+
if (!el.hasAttribute("role")) el.setAttribute("role", role);
|
|
2707
|
+
return true;
|
|
2708
|
+
};
|
|
2709
|
+
const setRoving = (list, to) => {
|
|
2710
|
+
for (const m of list) if (wired(m)) m.setAttribute("tabindex", m === to ? "0" : "-1");
|
|
2711
|
+
rovingKey = env.keyOf(to);
|
|
2712
|
+
};
|
|
2713
|
+
const refresh = () => {
|
|
2714
|
+
if (destroyed) return;
|
|
2715
|
+
try {
|
|
2716
|
+
container.classList?.add(KEYBOARD_CLASS);
|
|
2717
|
+
const list = marksNow();
|
|
2718
|
+
for (const m of list) {
|
|
2719
|
+
if (!wire(m, "-1", "button")) continue;
|
|
2720
|
+
m.setAttribute("aria-pressed", env.isSelected(m) ? "true" : "false");
|
|
2721
|
+
if (!m.hasAttribute("aria-label") && !m.querySelector(":scope > title")) {
|
|
2722
|
+
const name = env.labelOf(m);
|
|
2723
|
+
if (name) m.setAttribute("aria-label", name);
|
|
2724
|
+
}
|
|
2725
|
+
}
|
|
2726
|
+
if (!list.length) {
|
|
2727
|
+
for (const m of Array.from(container.querySelectorAll(`[${WIRED_ATTR}]`)))
|
|
2728
|
+
if (m.matches(env.markSelector)) {
|
|
2729
|
+
m.removeAttribute("tabindex");
|
|
2730
|
+
m.removeAttribute(WIRED_ATTR);
|
|
2731
|
+
}
|
|
2732
|
+
}
|
|
2733
|
+
const own = list.filter(wired);
|
|
2734
|
+
if (own.length) {
|
|
2735
|
+
const keep = own.find((m) => env.keyOf(m) === rovingKey) ?? own.find((m) => env.isSelected(m)) ?? own[0];
|
|
2736
|
+
setRoving(own, keep);
|
|
2737
|
+
}
|
|
2738
|
+
for (const c of Array.from(container.querySelectorAll(env.pressSelector))) {
|
|
2739
|
+
if (isNative(c)) continue;
|
|
2740
|
+
wire(c, "0", "button");
|
|
2741
|
+
}
|
|
2742
|
+
} catch {
|
|
2743
|
+
}
|
|
2744
|
+
};
|
|
2745
|
+
const onKey = (e) => {
|
|
2746
|
+
if (destroyed || e.defaultPrevented) return;
|
|
2747
|
+
const t = e.target;
|
|
2748
|
+
if (!t || !container.contains(t)) return;
|
|
2749
|
+
const k = e.key;
|
|
2750
|
+
if (isClearChord(e)) {
|
|
2751
|
+
e.preventDefault();
|
|
2752
|
+
env.clear();
|
|
2753
|
+
return;
|
|
2754
|
+
}
|
|
2755
|
+
const press = t.closest?.(env.pressSelector);
|
|
2756
|
+
if (press && wired(press) && container.contains(press)) {
|
|
2757
|
+
if (k === "Enter" || k === " " || k === "Spacebar") {
|
|
2758
|
+
e.preventDefault();
|
|
2759
|
+
const ME = container.ownerDocument.defaultView?.MouseEvent ?? MouseEvent;
|
|
2760
|
+
press.dispatchEvent(new ME("click", { bubbles: true, cancelable: true }));
|
|
2761
|
+
} else if (k === "Escape" && env.escapeClears !== false) env.clear();
|
|
2762
|
+
return;
|
|
2763
|
+
}
|
|
2764
|
+
const mark = t.closest?.(env.markSelector);
|
|
2765
|
+
if (!mark || !wired(mark) || !container.contains(mark)) return;
|
|
2766
|
+
const list = marksNow().filter(wired);
|
|
2767
|
+
const at = list.indexOf(mark);
|
|
2768
|
+
const go = (i) => {
|
|
2769
|
+
const to = list[Math.max(0, Math.min(list.length - 1, i))];
|
|
2770
|
+
if (!to) return;
|
|
2771
|
+
setRoving(list, to);
|
|
2772
|
+
try {
|
|
2773
|
+
to.focus({ preventScroll: false });
|
|
2774
|
+
} catch {
|
|
2775
|
+
}
|
|
2776
|
+
};
|
|
2777
|
+
switch (k) {
|
|
2778
|
+
case "ArrowRight":
|
|
2779
|
+
case "ArrowDown":
|
|
2780
|
+
e.preventDefault();
|
|
2781
|
+
go(at + 1);
|
|
2782
|
+
break;
|
|
2783
|
+
case "ArrowLeft":
|
|
2784
|
+
case "ArrowUp":
|
|
2785
|
+
e.preventDefault();
|
|
2786
|
+
go(at - 1);
|
|
2787
|
+
break;
|
|
2788
|
+
case "Home":
|
|
2789
|
+
e.preventDefault();
|
|
2790
|
+
go(0);
|
|
2791
|
+
break;
|
|
2792
|
+
case "End":
|
|
2793
|
+
e.preventDefault();
|
|
2794
|
+
go(list.length - 1);
|
|
2795
|
+
break;
|
|
2796
|
+
case "Enter":
|
|
2797
|
+
case " ":
|
|
2798
|
+
case "Spacebar":
|
|
2799
|
+
e.preventDefault();
|
|
2800
|
+
rovingKey = env.keyOf(mark);
|
|
2801
|
+
env.select(mark, { ctrl: !!(e.ctrlKey || e.metaKey), shift: !!e.shiftKey });
|
|
2802
|
+
break;
|
|
2803
|
+
case "Escape":
|
|
2804
|
+
if (env.escapeClears !== false) env.clear();
|
|
2805
|
+
break;
|
|
2806
|
+
}
|
|
2807
|
+
};
|
|
2808
|
+
container.addEventListener("keydown", onKey);
|
|
2809
|
+
return {
|
|
2810
|
+
refresh,
|
|
2811
|
+
destroy() {
|
|
2812
|
+
destroyed = true;
|
|
2813
|
+
container.removeEventListener("keydown", onKey);
|
|
2814
|
+
try {
|
|
2815
|
+
container.classList?.remove(KEYBOARD_CLASS);
|
|
2816
|
+
} catch {
|
|
2817
|
+
}
|
|
2818
|
+
}
|
|
2819
|
+
};
|
|
2820
|
+
}
|
|
2821
|
+
|
|
2578
2822
|
// src/host.ts
|
|
2579
2823
|
function sessionViewStateProvider(container) {
|
|
2580
2824
|
const holder = container;
|
|
@@ -2723,6 +2967,9 @@ function createChartHost(container, config) {
|
|
|
2723
2967
|
}
|
|
2724
2968
|
}
|
|
2725
2969
|
let lassoClaimed = false;
|
|
2970
|
+
let ownBag = null;
|
|
2971
|
+
const seedKey = (s) => s && typeof s === "object" ? JSON.stringify(s) : void 0;
|
|
2972
|
+
let lastSeed = seedKey(raw.uiState);
|
|
2726
2973
|
if (typeof raw.setUiState !== "function") {
|
|
2727
2974
|
const provider = config.viewState ?? sessionViewStateProvider(container);
|
|
2728
2975
|
let bag;
|
|
@@ -2736,6 +2983,7 @@ function createChartHost(container, config) {
|
|
|
2736
2983
|
if (raw.uiState && typeof raw.uiState === "object" && Object.keys(bag).length === 0)
|
|
2737
2984
|
Object.assign(bag, raw.uiState);
|
|
2738
2985
|
raw.uiState = bag;
|
|
2986
|
+
ownBag = { bag, provider };
|
|
2739
2987
|
raw.setUiState = (s) => {
|
|
2740
2988
|
if (!s || typeof s !== "object") return;
|
|
2741
2989
|
try {
|
|
@@ -2744,6 +2992,26 @@ function createChartHost(container, config) {
|
|
|
2744
2992
|
}
|
|
2745
2993
|
};
|
|
2746
2994
|
}
|
|
2995
|
+
const takeSeed = (partial) => {
|
|
2996
|
+
if (typeof partial.setUiState === "function") {
|
|
2997
|
+
ownBag = null;
|
|
2998
|
+
return partial;
|
|
2999
|
+
}
|
|
3000
|
+
if (!ownBag || !("uiState" in partial)) return partial;
|
|
3001
|
+
const { uiState: seed, ...rest } = partial;
|
|
3002
|
+
const key = seedKey(seed);
|
|
3003
|
+
if (key !== void 0 && key !== lastSeed) {
|
|
3004
|
+
lastSeed = key;
|
|
3005
|
+
const { bag, provider } = ownBag;
|
|
3006
|
+
for (const k of Object.keys(bag)) delete bag[k];
|
|
3007
|
+
Object.assign(bag, seed);
|
|
3008
|
+
try {
|
|
3009
|
+
provider.save({ ...bag });
|
|
3010
|
+
} catch {
|
|
3011
|
+
}
|
|
3012
|
+
}
|
|
3013
|
+
return rest;
|
|
3014
|
+
};
|
|
2747
3015
|
const resolveForHost = (input) => {
|
|
2748
3016
|
const out = resolveOptions(input);
|
|
2749
3017
|
return out.allowTooltips == null ? { ...out, allowTooltips: true } : out;
|
|
@@ -2758,7 +3026,9 @@ function createChartHost(container, config) {
|
|
|
2758
3026
|
let warnedLassoNoFilter = false;
|
|
2759
3027
|
const idScope = newIdScope();
|
|
2760
3028
|
let renderSeq = 0;
|
|
2761
|
-
const
|
|
3029
|
+
const keyboardOn = codeHasKeyboardStamp(config.code);
|
|
3030
|
+
let keyboard = null;
|
|
3031
|
+
const annotationLayer = createAnnotationLayer(container, (a) => config.onAnnotationClick?.(a), { keyboard: () => keyboardOn });
|
|
2762
3032
|
const drawAnnotations = () => annotationLayer.draw(
|
|
2763
3033
|
{ columns: data.columns, rows: data.rows },
|
|
2764
3034
|
{
|
|
@@ -2802,6 +3072,21 @@ function createChartHost(container, config) {
|
|
|
2802
3072
|
}
|
|
2803
3073
|
};
|
|
2804
3074
|
const subs = /* @__PURE__ */ new Set();
|
|
3075
|
+
let hiddenHeld = 0;
|
|
3076
|
+
let factFresh = true;
|
|
3077
|
+
const selectionFact = () => {
|
|
3078
|
+
const n = Array.isArray(data?.rows) ? data.rows.length : 0;
|
|
3079
|
+
const rows = Array.from(new Set((current ?? []).filter((r) => Number.isInteger(r) && r >= 0 && r < n))).sort((a, b) => a - b);
|
|
3080
|
+
return { rows, hidden: hiddenHeld };
|
|
3081
|
+
};
|
|
3082
|
+
const tellSelection = () => {
|
|
3083
|
+
const slot = container[CONTAINER_SLOT_HOST_SELECTION];
|
|
3084
|
+
if (typeof slot !== "function") return;
|
|
3085
|
+
try {
|
|
3086
|
+
slot(selectionFact());
|
|
3087
|
+
} catch {
|
|
3088
|
+
}
|
|
3089
|
+
};
|
|
2805
3090
|
const ensureAffordanceStyles = () => {
|
|
2806
3091
|
try {
|
|
2807
3092
|
if (!doc || doc.getElementById("bic-chart-host-affordances")) return;
|
|
@@ -2827,7 +3112,18 @@ function createChartHost(container, config) {
|
|
|
2827
3112
|
anomaly badge, a highlight stroke) and must keep dimming with its datum. */
|
|
2828
3113
|
.${HOST_CONTAINER_CLASS} .${MARK_CLASS} { cursor: pointer; transition: opacity 120ms ease-in-out, filter 100ms ease-in-out; }
|
|
2829
3114
|
.${HOST_CONTAINER_CLASS} .${MARK_CLASS}:not([${ROW_IDX_ATTR}=""]):hover { filter: brightness(1.1) drop-shadow(0 0 1.5px rgba(0,0,0,0.5)) !important; }
|
|
2830
|
-
.${HOST_CONTAINER_CLASS}:has(.${MARK_CLASS}:not([${ROW_IDX_ATTR}=""]):hover) .${MARK_CLASS}:not(:hover):not([${ROW_IDX_ATTR}=""]) { opacity: 0.55; }
|
|
3115
|
+
.${HOST_CONTAINER_CLASS}:not(.${MARKS_INERT_CLASS}):has(.${MARK_CLASS}:not([${ROW_IDX_ATTR}=""]):hover) .${MARK_CLASS}:not(:hover):not([${ROW_IDX_ATTR}=""]) { opacity: 0.55; }
|
|
3116
|
+
/* A MARK THAT SELECTS NOTHING DOESN'T LOOK CLICKABLE: no pointer, over the inline cursor generated code
|
|
3117
|
+
sets on its marks, and no dimming of the others on hover (the rule above). A control the chart draws keeps its own. */
|
|
3118
|
+
.${HOST_CONTAINER_CLASS}.${MARKS_INERT_CLASS} .${MARK_CLASS} { cursor: default !important; }
|
|
3119
|
+
/* THE KEYBOARD'S FOCUS: a ring on the mark, control or badge that holds keyboard focus, in the colour the
|
|
3120
|
+
chart's text is drawn in, so it reads in either theme. A pointer's focus shows none. */
|
|
3121
|
+
.${HOST_CONTAINER_CLASS}.${KEYBOARD_CLASS} [${WIRED_ATTR}]:focus:not(:focus-visible) { outline: none; }
|
|
3122
|
+
.${HOST_CONTAINER_CLASS}.${KEYBOARD_CLASS} [${WIRED_ATTR}]:focus-visible,
|
|
3123
|
+
.${HOST_CONTAINER_CLASS} .bic-annotation:focus-visible { outline: 2px solid var(--lch-focus-ring, currentColor) !important; outline-offset: 2px; }
|
|
3124
|
+
/* A dimmed mark that takes keyboard focus is drawn at full strength while it has it, ring included: the dim would
|
|
3125
|
+
otherwise fade the ring with the mark. */
|
|
3126
|
+
.${HOST_CONTAINER_CLASS}.${KEYBOARD_CLASS}.${SELECTION_ACTIVE_CLASS} .${MARK_CLASS}[${WIRED_ATTR}]:focus-visible:not(.${MARK_SELECTED_CLASS}) { opacity: 1 !important; }
|
|
2831
3127
|
.${HOST_CONTAINER_CLASS}.${SELECTION_ACTIVE_CLASS} .${MARK_CLASS}:not(.${MARK_SELECTED_CLASS}):not([${ROW_IDX_ATTR}=""]) {
|
|
2832
3128
|
opacity: var(${DIM_OPACITY_VAR}, ${DIM_OPACITY_DEFAULT}) !important;
|
|
2833
3129
|
}
|
|
@@ -2860,9 +3156,18 @@ function createChartHost(container, config) {
|
|
|
2860
3156
|
} catch {
|
|
2861
3157
|
}
|
|
2862
3158
|
};
|
|
3159
|
+
const marksInert = () => {
|
|
3160
|
+
if (typeof config.marksSelect !== "function") return false;
|
|
3161
|
+
try {
|
|
3162
|
+
return config.marksSelect() === false;
|
|
3163
|
+
} catch {
|
|
3164
|
+
return false;
|
|
3165
|
+
}
|
|
3166
|
+
};
|
|
2863
3167
|
const paintSelection = () => {
|
|
2864
3168
|
if (destroyed) return;
|
|
2865
3169
|
try {
|
|
3170
|
+
container.classList?.[marksInert() ? "add" : "remove"](MARKS_INERT_CLASS);
|
|
2866
3171
|
const sel = current;
|
|
2867
3172
|
const active = !!sel && sel.length > 0;
|
|
2868
3173
|
const dim = active && !selectionIsPeriod;
|
|
@@ -3120,22 +3425,25 @@ function createChartHost(container, config) {
|
|
|
3120
3425
|
}
|
|
3121
3426
|
}
|
|
3122
3427
|
};
|
|
3123
|
-
const notify = (rowIdxs, source, tick, fromChart = false, publish = true) => {
|
|
3428
|
+
const notify = (rowIdxs, source, tick, fromChart = false, publish = true, meta) => {
|
|
3124
3429
|
if (destroyed) return;
|
|
3125
3430
|
current = rowIdxs;
|
|
3126
3431
|
selectionFromChart = rowIdxs.length > 0 && fromChart;
|
|
3127
3432
|
selectionPublished = publish;
|
|
3128
3433
|
activeTickEl = rowIdxs.length ? tick ?? null : null;
|
|
3129
3434
|
selectionIsPeriod = rowIdxs.length > 0 && periodTickSuppressesFeedback(!!tick, chartOwnsTimeline(container));
|
|
3435
|
+
if (!rowIdxs.length && !meta?.keepHidden) hiddenHeld = 0;
|
|
3436
|
+
factFresh = true;
|
|
3130
3437
|
paintSelection();
|
|
3131
3438
|
paintGlyphLayer();
|
|
3132
|
-
|
|
3133
|
-
for (const cb of subs) {
|
|
3439
|
+
keyboard?.refresh();
|
|
3440
|
+
if (publish) for (const cb of subs) {
|
|
3134
3441
|
try {
|
|
3135
|
-
cb(rowIdxs, source);
|
|
3442
|
+
cb(rowIdxs, source, meta);
|
|
3136
3443
|
} catch {
|
|
3137
3444
|
}
|
|
3138
3445
|
}
|
|
3446
|
+
tellSelection();
|
|
3139
3447
|
};
|
|
3140
3448
|
const selectFromLasso = (rows) => {
|
|
3141
3449
|
if (lassoEffect(resolved.lasso) === "highlight") {
|
|
@@ -3164,8 +3472,9 @@ function createChartHost(container, config) {
|
|
|
3164
3472
|
const d = e?.detail || {};
|
|
3165
3473
|
xfAt = Date.now();
|
|
3166
3474
|
if (d.clear) notify([], d.source || "chart", void 0, false, selectionPublished || !(current && current.length));
|
|
3475
|
+
else if (marksInert()) return;
|
|
3167
3476
|
else if (d.mark) notify(parseRowIdxs(d.mark.getAttribute?.(ROW_IDX_ATTR)), d.source || "chart", d.mark, true);
|
|
3168
|
-
else if (Array.isArray(d.rows)) notify(validRowSet(d.rows), d.source || "chart", null, true);
|
|
3477
|
+
else if (Array.isArray(d.rows)) notify(validRowSet(d.rows), d.source || "chart", null, true, true, d.keepHidden === true ? { keepHidden: true } : void 0);
|
|
3169
3478
|
};
|
|
3170
3479
|
const resolver = createMarkResolver({
|
|
3171
3480
|
root: container,
|
|
@@ -3199,6 +3508,9 @@ function createChartHost(container, config) {
|
|
|
3199
3508
|
const wasDrag = clickWasDrag(container, e);
|
|
3200
3509
|
clearPress(container);
|
|
3201
3510
|
if (wasDrag) return;
|
|
3511
|
+
const inert = marksInert();
|
|
3512
|
+
container.classList?.[inert ? "add" : "remove"](MARKS_INERT_CLASS);
|
|
3513
|
+
if (inert) return;
|
|
3202
3514
|
if (Date.now() - xfAt < XF_ECHO_MS) return;
|
|
3203
3515
|
if (isInsideControl(e?.target, container)) return;
|
|
3204
3516
|
let el = resolver.findMark(e?.target, clickSel, e);
|
|
@@ -3226,6 +3538,27 @@ function createChartHost(container, config) {
|
|
|
3226
3538
|
container.addEventListener(XFILTER_REFRESH_EVENT, onXf);
|
|
3227
3539
|
const untrackPress = trackPress(container);
|
|
3228
3540
|
container.addEventListener("click", onClick);
|
|
3541
|
+
if (keyboardOn) {
|
|
3542
|
+
const nameOfRow = (m) => {
|
|
3543
|
+
const r = parseRowIdxs(m.getAttribute(ROW_IDX_ATTR))[0];
|
|
3544
|
+
return rowNameOf(data.columns || [], r == null ? null : data.rows?.[r], resolved.cultureCode);
|
|
3545
|
+
};
|
|
3546
|
+
keyboard = installKeyboard({
|
|
3547
|
+
container,
|
|
3548
|
+
markSelector: clickSel,
|
|
3549
|
+
pressSelector: `.${CONTROL_CLASS}`,
|
|
3550
|
+
skipSelector: `.${ANNOTATION_LAYER_CLASS}, .${GLYPH_LAYER_CLASS}, .${LASSO_OUTLINE_CLASS}`,
|
|
3551
|
+
inert: marksInert,
|
|
3552
|
+
select: (m, mods) => {
|
|
3553
|
+
const ME = win?.MouseEvent ?? MouseEvent;
|
|
3554
|
+
m.dispatchEvent(new ME("click", { bubbles: true, cancelable: true, ctrlKey: mods.ctrl, shiftKey: mods.shift }));
|
|
3555
|
+
},
|
|
3556
|
+
clear: clearFromGesture,
|
|
3557
|
+
isSelected: (m) => !!m.classList?.contains(MARK_SELECTED_CLASS),
|
|
3558
|
+
labelOf: nameOfRow,
|
|
3559
|
+
keyOf: (m) => m.getAttribute(ROW_IDX_ATTR) ?? ""
|
|
3560
|
+
});
|
|
3561
|
+
}
|
|
3229
3562
|
container.classList?.add(HOST_CONTAINER_CLASS);
|
|
3230
3563
|
ensureAffordanceStyles();
|
|
3231
3564
|
const fitOpts = config.fit ?? true;
|
|
@@ -3373,6 +3706,15 @@ function createChartHost(container, config) {
|
|
|
3373
3706
|
} catch {
|
|
3374
3707
|
}
|
|
3375
3708
|
paintGlyphLayer();
|
|
3709
|
+
installLassoHere();
|
|
3710
|
+
keyboard?.refresh();
|
|
3711
|
+
const fw = focusWas;
|
|
3712
|
+
focusWas = null;
|
|
3713
|
+
restoreFocus(container, fw);
|
|
3714
|
+
selfRedraw?.takeRecords();
|
|
3715
|
+
watchSelfRedraw();
|
|
3716
|
+
};
|
|
3717
|
+
function installLassoHere() {
|
|
3376
3718
|
try {
|
|
3377
3719
|
lasso = installLasso({
|
|
3378
3720
|
container,
|
|
@@ -3383,7 +3725,38 @@ function createChartHost(container, config) {
|
|
|
3383
3725
|
});
|
|
3384
3726
|
} catch {
|
|
3385
3727
|
}
|
|
3728
|
+
}
|
|
3729
|
+
let selfRedraw = null;
|
|
3730
|
+
let focusWas = null;
|
|
3731
|
+
let notesHeld = (config.annotations ?? []).length > 0;
|
|
3732
|
+
const takesMarks = (n) => n.nodeType === 1 && (!!n.classList?.contains(MARK_CLASS) || !!n.querySelector?.(`.${MARK_CLASS}`));
|
|
3733
|
+
const lassoLost = () => !!lasso?.surface && !lasso.surface.isConnected;
|
|
3734
|
+
const repaintAfterChart = () => {
|
|
3735
|
+
if (destroyed) return;
|
|
3736
|
+
try {
|
|
3737
|
+
ensureCrossfilterHitTargets(container, doc);
|
|
3738
|
+
} catch {
|
|
3739
|
+
}
|
|
3740
|
+
paintSelection();
|
|
3741
|
+
try {
|
|
3742
|
+
drawAnnotations();
|
|
3743
|
+
} catch {
|
|
3744
|
+
}
|
|
3745
|
+
paintGlyphLayer(false);
|
|
3746
|
+
if (lassoLost()) installLassoHere();
|
|
3747
|
+
keyboard?.refresh();
|
|
3748
|
+
selfRedraw?.takeRecords();
|
|
3386
3749
|
};
|
|
3750
|
+
function watchSelfRedraw() {
|
|
3751
|
+
const MO = win?.MutationObserver;
|
|
3752
|
+
if (selfRedraw || !MO || destroyed) return;
|
|
3753
|
+
selfRedraw = new MO((records) => {
|
|
3754
|
+
if (destroyed || !records.some((r) => Array.from(r.removedNodes).some(takesMarks))) return;
|
|
3755
|
+
if (!(current && current.length) && !notesHeld && !lassoLost()) return;
|
|
3756
|
+
repaintAfterChart();
|
|
3757
|
+
});
|
|
3758
|
+
selfRedraw.observe(container, { childList: true, subtree: true });
|
|
3759
|
+
}
|
|
3387
3760
|
const renderFailure = (err) => {
|
|
3388
3761
|
const message = String(err?.message ?? err ?? "");
|
|
3389
3762
|
if (config.onInvalidSentinel && isInvalidSentinelError(message)) {
|
|
@@ -3403,7 +3776,9 @@ function createChartHost(container, config) {
|
|
|
3403
3776
|
disposeLasso();
|
|
3404
3777
|
flushZoom();
|
|
3405
3778
|
if (hasRendered && keepScroll) rememberScroll(container, scrollKey());
|
|
3779
|
+
focusWas = rememberFocus(container);
|
|
3406
3780
|
container.innerHTML = "";
|
|
3781
|
+
selfRedraw?.takeRecords();
|
|
3407
3782
|
hasRendered = true;
|
|
3408
3783
|
if (!renderFn) {
|
|
3409
3784
|
if (!config.code) throw new Error("createChartHost: provide code or renderFn");
|
|
@@ -3429,6 +3804,7 @@ function createChartHost(container, config) {
|
|
|
3429
3804
|
if (resolved.dateCellsAreUtcDays === void 0 && data.dateCellsAreUtcDays) resolved = { ...resolved, dateCellsAreUtcDays: true };
|
|
3430
3805
|
if (resolved.suppressSelectionGlyph === void 0 && data.meta?.suppressSelectionGlyph === true)
|
|
3431
3806
|
resolved = { ...resolved, suppressSelectionGlyph: true };
|
|
3807
|
+
if (keyboardOn) resolved = { ...resolved, keyboardMarks: true };
|
|
3432
3808
|
let outcome;
|
|
3433
3809
|
zoomCap = null;
|
|
3434
3810
|
if (zoomMemory && config.code && !config.renderFn) {
|
|
@@ -3443,6 +3819,7 @@ function createChartHost(container, config) {
|
|
|
3443
3819
|
zoomCap = null;
|
|
3444
3820
|
}
|
|
3445
3821
|
}
|
|
3822
|
+
if (raw.hostSelection == null) resolved.hostSelection = factFresh ? selectionFact() : void 0;
|
|
3446
3823
|
try {
|
|
3447
3824
|
try {
|
|
3448
3825
|
outcome = renderFn(container, { columns: data.columns, rows: data.rows }, resolved);
|
|
@@ -3503,13 +3880,14 @@ function createChartHost(container, config) {
|
|
|
3503
3880
|
// callback) must not clear, stop or annotate the chart that is on screen now.
|
|
3504
3881
|
setOptions(partial) {
|
|
3505
3882
|
if (destroyed) return;
|
|
3506
|
-
raw = { ...raw, ...partial };
|
|
3883
|
+
raw = { ...raw, ...takeSeed(partial ?? {}) };
|
|
3507
3884
|
resolved = resolveForHost(raw);
|
|
3508
3885
|
host.render();
|
|
3509
3886
|
},
|
|
3510
3887
|
setData(next) {
|
|
3511
3888
|
if (destroyed) return;
|
|
3512
3889
|
data = next;
|
|
3890
|
+
factFresh = false;
|
|
3513
3891
|
host.render();
|
|
3514
3892
|
},
|
|
3515
3893
|
get options() {
|
|
@@ -3517,6 +3895,7 @@ function createChartHost(container, config) {
|
|
|
3517
3895
|
},
|
|
3518
3896
|
setAnnotations(list) {
|
|
3519
3897
|
if (destroyed) return;
|
|
3898
|
+
notesHeld = (list ?? []).length > 0;
|
|
3520
3899
|
annotationLayer.set(list);
|
|
3521
3900
|
try {
|
|
3522
3901
|
drawAnnotations();
|
|
@@ -3555,6 +3934,15 @@ function createChartHost(container, config) {
|
|
|
3555
3934
|
if (lasso && lasso.rows().length && !sameRowSet(rows, lasso.rows())) lasso.clear({ publish: false, source: "host" });
|
|
3556
3935
|
notify(rows, "host");
|
|
3557
3936
|
},
|
|
3937
|
+
setHidden(count) {
|
|
3938
|
+
if (destroyed) return;
|
|
3939
|
+
const n = Number(count);
|
|
3940
|
+
const next = Number.isFinite(n) && n > 0 ? Math.floor(n) : 0;
|
|
3941
|
+
if (next === hiddenHeld && factFresh) return;
|
|
3942
|
+
hiddenHeld = next;
|
|
3943
|
+
factFresh = true;
|
|
3944
|
+
tellSelection();
|
|
3945
|
+
},
|
|
3558
3946
|
get current() {
|
|
3559
3947
|
return current;
|
|
3560
3948
|
}
|
|
@@ -3569,6 +3957,12 @@ function createChartHost(container, config) {
|
|
|
3569
3957
|
if (destroyed) return;
|
|
3570
3958
|
destroyed = true;
|
|
3571
3959
|
stopAnim();
|
|
3960
|
+
if (selfRedraw) {
|
|
3961
|
+
selfRedraw.disconnect();
|
|
3962
|
+
selfRedraw = null;
|
|
3963
|
+
}
|
|
3964
|
+
keyboard?.destroy();
|
|
3965
|
+
keyboard = null;
|
|
3572
3966
|
container.removeEventListener(XFILTER_REFRESH_EVENT, onXf);
|
|
3573
3967
|
container.removeEventListener("click", onClick);
|
|
3574
3968
|
untrackPress();
|
|
@@ -3792,6 +4186,7 @@ export {
|
|
|
3792
4186
|
exportFormatsFor,
|
|
3793
4187
|
exportTableService,
|
|
3794
4188
|
browserSaveFile,
|
|
4189
|
+
cleanHostSelection,
|
|
3795
4190
|
resolveOptions,
|
|
3796
4191
|
buildRenderPayload,
|
|
3797
4192
|
stripJsComments,
|
|
@@ -3814,6 +4209,14 @@ export {
|
|
|
3814
4209
|
invalidSentinelReason,
|
|
3815
4210
|
ANNOTATION_LAYER_CLASS,
|
|
3816
4211
|
ANNOTATION_CLASS,
|
|
4212
|
+
rememberFocus,
|
|
4213
|
+
restoreFocus,
|
|
4214
|
+
KEYBOARD_STAMP,
|
|
4215
|
+
codeHasKeyboardStamp,
|
|
4216
|
+
KEYBOARD_CLASS,
|
|
4217
|
+
WIRED_ATTR,
|
|
4218
|
+
rowNameOf,
|
|
4219
|
+
installKeyboard,
|
|
3817
4220
|
sessionViewStateProvider,
|
|
3818
4221
|
noopViewStateProvider,
|
|
3819
4222
|
assembleD3,
|