@weasel-js/routing 1.10.1 → 1.11.1
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/{chunk-VCEIQ64H.js → chunk-KLBH7VFF.js} +740 -87
- package/dist/chunk-KLBH7VFF.js.map +1 -0
- package/dist/{index-DkOqUxow.d.ts → index-Cb7ehEks.d.ts} +1689 -1177
- package/dist/index.d.ts +6 -3
- package/dist/index.js +85 -17
- package/dist/index.js.map +1 -1
- package/dist/{internal-Boc2I3zn.d.ts → internal-Dcyz_cJv.d.ts} +31 -1
- package/dist/internal.d.ts +8 -5
- package/dist/react.d.ts +61 -29
- package/dist/react.js +467 -232
- package/dist/react.js.map +1 -1
- package/package.json +13 -9
- package/dist/chunk-VCEIQ64H.js.map +0 -1
|
@@ -1,17 +1,53 @@
|
|
|
1
|
+
import { isDev } from '@weasel-js/react';
|
|
1
2
|
import { createEmitter } from '@weasel-js/registry';
|
|
2
|
-
import { RESERVED_ID_PREFIXES, RESERVED_ID_NAMES, routeGestureForSpecKind, getGestureDescriptor, formatRoute, parseTargetSpec, matchSpec, canonicalModifiers, UNKNOWN_MIME, specificity, VALID_MOD_NAMES, stylusOf } from '@weasel-js/gestures';
|
|
3
|
+
import { RESERVED_ID_PREFIXES, RESERVED_ID_NAMES, isApplePlatform, routeGestureForSpecKind, getGestureDescriptor, formatRoute, parseTargetSpec, matchSpec, canonicalModifiers, UNKNOWN_MIME, specificity, VALID_MOD_NAMES, stylusOf } from '@weasel-js/gestures';
|
|
3
4
|
export { GESTURE_DESCRIPTORS, LONG_PRESS_MS, RESERVED_ID_NAMES, RESERVED_ID_PREFIXES, ROUTE_FIELD_DEFINITIONS, ROUTE_TERMS, activatesFocusedControl, canonicalModifiers, collapseShiftPairs, describeRoute, describeRouteParts, focusedControlOwnsKey, formatPhaseAtom, formatRoute, getGestureDescriptor, isEditableTarget, isKnownGestureName, matchKey, matchModifiers, matchPhase, matchSpec, matchTarget, parseRoute, routeGestureForSpecKind, specKindForRouteGesture, specificity } from '@weasel-js/gestures';
|
|
4
5
|
import { activeModeOf, NORMAL, DEFAULT_MODES, capabilitiesAllowed } from '@weasel-js/modes';
|
|
5
6
|
import { resolveCursor } from '@weasel-js/cursor';
|
|
7
|
+
import { prefIsShown, prefIsEnabled, isPrefLeaf, prefAliasTarget, prefLeafAt, prefAliasedLeaf, prefNumberAt, resolvePrefUnit, prefDisplayBounds, prefUnitAccepts, prefValueAtPath } from '@weasel-js/prefs';
|
|
8
|
+
import { endlessAllows } from '@weasel-js/quantity';
|
|
6
9
|
|
|
7
|
-
// src/interactions/actions/
|
|
8
|
-
var
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
// src/interactions/actions/actionItems.ts
|
|
11
|
+
var NO_TAGS = Object.freeze([]);
|
|
12
|
+
function actionItems(action) {
|
|
13
|
+
if (action.invoker?.timing !== "immediate") return [];
|
|
14
|
+
if (!action.variants?.length) {
|
|
15
|
+
return [{ key: action.id, action, label: action.label, icon: action.icon, tags: action.tags ?? NO_TAGS }];
|
|
16
|
+
}
|
|
17
|
+
return action.variants.map((v) => ({
|
|
18
|
+
key: `${action.id}:${v.key}`,
|
|
19
|
+
action,
|
|
20
|
+
label: v.label,
|
|
21
|
+
icon: v.icon ?? action.icon,
|
|
22
|
+
tags: v.tags ? [...action.tags ?? NO_TAGS, ...v.tags] : action.tags ?? NO_TAGS,
|
|
23
|
+
params: v.params
|
|
24
|
+
}));
|
|
25
|
+
}
|
|
26
|
+
function actionItemTitle(item) {
|
|
27
|
+
if (item.key === item.action.id) return item.label;
|
|
28
|
+
const words = (s) => s.toLowerCase().match(/[\p{L}\p{N}]+/gu) ?? [];
|
|
29
|
+
const head = words(item.action.label);
|
|
30
|
+
const label = words(item.label);
|
|
31
|
+
for (let i = 0; i + head.length <= label.length; i++) {
|
|
32
|
+
if (head.every((w, j) => label[i + j] === w)) return item.label;
|
|
33
|
+
}
|
|
34
|
+
return `${item.action.label}: ${item.label}`;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// src/interactions/actions/actionSettings.ts
|
|
38
|
+
var EMPTY = { values: {} };
|
|
39
|
+
function readActionSettings(action, deps) {
|
|
40
|
+
const settings = action.settings;
|
|
41
|
+
if (!settings) return null;
|
|
42
|
+
try {
|
|
43
|
+
return settings.read(deps ?? {});
|
|
44
|
+
} catch {
|
|
45
|
+
return EMPTY;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function actionSettingsParams(settings, path, value) {
|
|
49
|
+
return settings.params ? settings.params(path, value) : { [path]: value };
|
|
50
|
+
}
|
|
15
51
|
|
|
16
52
|
// src/interactions/actions/binding.ts
|
|
17
53
|
function actionBindings(action) {
|
|
@@ -26,22 +62,60 @@ function actionBindings(action) {
|
|
|
26
62
|
});
|
|
27
63
|
}
|
|
28
64
|
|
|
29
|
-
// src/
|
|
30
|
-
function
|
|
31
|
-
|
|
65
|
+
// src/interactions/actions/actionShortcuts.ts
|
|
66
|
+
function keySpecShortcut(spec) {
|
|
67
|
+
if (spec.kind !== "key" && spec.kind !== "key-held") return void 0;
|
|
68
|
+
const key = Array.isArray(spec.key) ? spec.key[0] : spec.key;
|
|
69
|
+
if (typeof key !== "string" || key.length === 0) return void 0;
|
|
70
|
+
const mods = "mods" in spec ? spec.mods : void 0;
|
|
71
|
+
return {
|
|
72
|
+
key,
|
|
73
|
+
mod: mods?.mod === true,
|
|
74
|
+
alt: mods?.alt === true,
|
|
75
|
+
shift: mods?.shift === true
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
function actionShortcuts(action, params) {
|
|
79
|
+
const out = [];
|
|
80
|
+
const seen = /* @__PURE__ */ new Set();
|
|
81
|
+
for (const { spec, opts } of actionBindings(action)) {
|
|
82
|
+
if (params && !paramsMatch(opts?.params, params)) continue;
|
|
83
|
+
const shortcut = keySpecShortcut(spec);
|
|
84
|
+
if (!shortcut) continue;
|
|
85
|
+
const token = `${shortcut.key}|${shortcut.mod}|${shortcut.alt}|${shortcut.shift}`;
|
|
86
|
+
if (seen.has(token)) continue;
|
|
87
|
+
seen.add(token);
|
|
88
|
+
out.push(shortcut);
|
|
89
|
+
}
|
|
90
|
+
return out;
|
|
91
|
+
}
|
|
92
|
+
function paramsMatch(bound, wanted) {
|
|
93
|
+
if (typeof bound !== "object" || bound === null) return false;
|
|
94
|
+
return Object.entries(wanted).every(([k, v]) => bound[k] === v);
|
|
32
95
|
}
|
|
33
96
|
|
|
34
|
-
// src/interactions/actions/
|
|
97
|
+
// src/interactions/actions/action.ts
|
|
98
|
+
var ActionDisabledReason = {
|
|
99
|
+
SelectionRequired: "selection-required",
|
|
100
|
+
SceneEmpty: "scene-empty",
|
|
101
|
+
NotApplicable: "not-applicable",
|
|
102
|
+
/** Sentinel: the predicate threw. Surfaced by `evaluateEnabled`'s catch. */
|
|
103
|
+
PredicateThrew: "predicate-threw"
|
|
104
|
+
};
|
|
105
|
+
function actionCursor(action, params) {
|
|
106
|
+
const c = action?.cursor;
|
|
107
|
+
return typeof c === "function" ? c(params) : c;
|
|
108
|
+
}
|
|
35
109
|
var enabledSlowWarned = /* @__PURE__ */ new Set();
|
|
36
110
|
var enabledThrewWarned = /* @__PURE__ */ new Set();
|
|
37
111
|
var ENABLED_BUDGET_MS = 4;
|
|
38
|
-
function evaluateEnabled(action, deps) {
|
|
112
|
+
function evaluateEnabled(action, deps, at) {
|
|
39
113
|
if (!action.enabled) return { enabled: true };
|
|
40
114
|
const dev = isDev();
|
|
41
115
|
const now = typeof performance !== "undefined" && typeof performance.now === "function" ? () => performance.now() : () => Date.now();
|
|
42
116
|
const start = dev ? now() : 0;
|
|
43
117
|
try {
|
|
44
|
-
const result = action.enabled(deps);
|
|
118
|
+
const result = action.enabled(deps, at);
|
|
45
119
|
if (dev) {
|
|
46
120
|
const elapsed = now() - start;
|
|
47
121
|
if (elapsed > ENABLED_BUDGET_MS && !enabledSlowWarned.has(action.id)) {
|
|
@@ -72,15 +146,7 @@ function evaluateActive(action, deps) {
|
|
|
72
146
|
return false;
|
|
73
147
|
}
|
|
74
148
|
}
|
|
75
|
-
|
|
76
|
-
// src/interactions/actions/buildDeps.ts
|
|
77
|
-
var DEV = (() => {
|
|
78
|
-
try {
|
|
79
|
-
return Boolean(import.meta.env?.DEV);
|
|
80
|
-
} catch {
|
|
81
|
-
return false;
|
|
82
|
-
}
|
|
83
|
-
})();
|
|
149
|
+
var DEV = isDev();
|
|
84
150
|
function buildDepsFromRequires(action, depRegistry) {
|
|
85
151
|
const requires = action.requires ?? [];
|
|
86
152
|
const entries = requires.map((name) => [name, depRegistry.get(name)]);
|
|
@@ -219,13 +285,21 @@ var DepNode = class extends ScopeNode {
|
|
|
219
285
|
};
|
|
220
286
|
},
|
|
221
287
|
get: (name) => {
|
|
288
|
+
const stacks = [...this.start().chain()].map((n) => n.sources.get(name) ?? []);
|
|
289
|
+
return readFrom(stacks, 0, (stacks[0]?.length ?? 0) - 1);
|
|
290
|
+
},
|
|
291
|
+
subscribe: (listener) => this.tree.listeners.subscribe(listener),
|
|
292
|
+
list: () => {
|
|
293
|
+
const found = /* @__PURE__ */ new Map();
|
|
294
|
+
let depth = 0;
|
|
222
295
|
for (const n of this.start().chain()) {
|
|
223
|
-
const
|
|
224
|
-
|
|
296
|
+
for (const [name, stack] of n.sources) {
|
|
297
|
+
if (!found.has(name)) found.set(name, { name, depth, stacked: stack.length });
|
|
298
|
+
}
|
|
299
|
+
depth++;
|
|
225
300
|
}
|
|
226
|
-
return
|
|
301
|
+
return [...found.values()].sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0);
|
|
227
302
|
},
|
|
228
|
-
subscribe: (listener) => this.tree.listeners.subscribe(listener),
|
|
229
303
|
changed: () => this.changed()
|
|
230
304
|
};
|
|
231
305
|
constructor(parent, descends) {
|
|
@@ -233,6 +307,11 @@ var DepNode = class extends ScopeNode {
|
|
|
233
307
|
NODES.set(this.registry, this);
|
|
234
308
|
}
|
|
235
309
|
};
|
|
310
|
+
function readFrom(stacks, scope, index) {
|
|
311
|
+
if (scope >= stacks.length) return void 0;
|
|
312
|
+
if (index < 0) return readFrom(stacks, scope + 1, (stacks[scope + 1]?.length ?? 0) - 1);
|
|
313
|
+
return stacks[scope][index](() => readFrom(stacks, scope, index - 1));
|
|
314
|
+
}
|
|
236
315
|
var NODES = /* @__PURE__ */ new WeakMap();
|
|
237
316
|
function depNodeOf(registry) {
|
|
238
317
|
return registry ? NODES.get(registry) ?? null : null;
|
|
@@ -281,18 +360,50 @@ function resolveParams(params) {
|
|
|
281
360
|
if (params === void 0) return void 0;
|
|
282
361
|
return typeof params === "function" ? params() : params;
|
|
283
362
|
}
|
|
363
|
+
function keysHeld(keys, modifiers, isMac) {
|
|
364
|
+
return keys.some((k) => {
|
|
365
|
+
if (k === "mod") return isMac ? modifiers.meta : modifiers.ctrl;
|
|
366
|
+
return modifiers[k];
|
|
367
|
+
});
|
|
368
|
+
}
|
|
369
|
+
function roleKeysOf(roles, rebinds) {
|
|
370
|
+
if (!roles) return void 0;
|
|
371
|
+
const out = {};
|
|
372
|
+
for (const id of Object.keys(roles)) out[id] = rebinds?.[id] ?? roles[id].keys;
|
|
373
|
+
return out;
|
|
374
|
+
}
|
|
375
|
+
function platformRoleKeys(keys, isMac) {
|
|
376
|
+
const out = {};
|
|
377
|
+
for (const id of Object.keys(keys)) out[id] = keys[id].map((k) => k === "mod" ? isMac ? "meta" : "ctrl" : k);
|
|
378
|
+
return out;
|
|
379
|
+
}
|
|
380
|
+
function resolveRoles(keys, modifiers, isMac) {
|
|
381
|
+
const out = {};
|
|
382
|
+
for (const id of Object.keys(keys)) out[id] = keysHeld(keys[id], modifiers, isMac);
|
|
383
|
+
return out;
|
|
384
|
+
}
|
|
385
|
+
function rebindRoles(roles, rebinds) {
|
|
386
|
+
const out = {};
|
|
387
|
+
for (const id of Object.keys(roles)) {
|
|
388
|
+
out[id] = rebinds[id] ? { ...roles[id], keys: rebinds[id] } : roles[id];
|
|
389
|
+
}
|
|
390
|
+
return out;
|
|
391
|
+
}
|
|
392
|
+
function roleReader(roles) {
|
|
393
|
+
return (ctx, id) => ctx.roles?.[id] ?? keysHeld(roles[id].keys, ctx.modifiers, isApplePlatform());
|
|
394
|
+
}
|
|
284
395
|
|
|
285
396
|
// src/interactions/actions/tuning.ts
|
|
286
397
|
var WRAPS = /* @__PURE__ */ new WeakMap();
|
|
287
398
|
function layered(under, over) {
|
|
288
|
-
if (typeof under !== "function" && typeof over !== "function") return {
|
|
289
|
-
return () => ({
|
|
399
|
+
if (typeof under !== "function" && typeof over !== "function") return tunedParams([{ params: under }], over);
|
|
400
|
+
return () => tunedParams([{ params: under }], resolveParams(over));
|
|
290
401
|
}
|
|
291
402
|
function wrapInvoker(invoker, params) {
|
|
292
403
|
for (let w = invoker; w; w = WRAPS.get(w)?.inner) {
|
|
293
404
|
if (WRAPS.get(w)?.params === params) return invoker;
|
|
294
405
|
}
|
|
295
|
-
const base = (given) => ({
|
|
406
|
+
const base = (given) => tunedParams([{ params }], given);
|
|
296
407
|
const wrapped = invoker.timing === "immediate" ? { timing: "immediate", run: (deps, given) => invoker.run(deps, base(given)) } : {
|
|
297
408
|
timing: "ongoing",
|
|
298
409
|
start: (ctx, opts) => invoker.start(
|
|
@@ -307,16 +418,49 @@ function withBindings(own, added) {
|
|
|
307
418
|
const base = own === void 0 ? [] : Array.isArray(own) ? own : [own];
|
|
308
419
|
return [...base, ...added.filter((b) => !base.includes(b))];
|
|
309
420
|
}
|
|
421
|
+
var CURSOR_WRAPS = /* @__PURE__ */ new WeakMap();
|
|
422
|
+
function wrapCursor(cursor, params) {
|
|
423
|
+
if (typeof cursor !== "function") return cursor;
|
|
424
|
+
for (let w = cursor; typeof w === "function"; w = CURSOR_WRAPS.get(w)?.inner) {
|
|
425
|
+
if (CURSOR_WRAPS.get(w)?.params === params) return cursor;
|
|
426
|
+
}
|
|
427
|
+
const wrapped = (given) => cursor(tunedParams([{ params }], given));
|
|
428
|
+
CURSOR_WRAPS.set(wrapped, { inner: cursor, params });
|
|
429
|
+
return wrapped;
|
|
430
|
+
}
|
|
431
|
+
var PREVIEW_WRAPS = /* @__PURE__ */ new WeakMap();
|
|
432
|
+
function wrapPreview(preview, params) {
|
|
433
|
+
if (!preview) return preview;
|
|
434
|
+
for (let w = preview; w; w = PREVIEW_WRAPS.get(w)?.inner) {
|
|
435
|
+
if (PREVIEW_WRAPS.get(w)?.params === params) return preview;
|
|
436
|
+
}
|
|
437
|
+
const wrapped = (deps, given) => preview(deps, tunedParams([{ params }], given));
|
|
438
|
+
PREVIEW_WRAPS.set(wrapped, { inner: preview, params });
|
|
439
|
+
return wrapped;
|
|
440
|
+
}
|
|
310
441
|
function tuneOnce(action, tuning) {
|
|
311
442
|
const invoker = tuning.params && action.invoker ? wrapInvoker(action.invoker, tuning.params) : action.invoker;
|
|
443
|
+
const cursor = tuning.params ? wrapCursor(action.cursor, tuning.params) : action.cursor;
|
|
444
|
+
const preview = tuning.params ? wrapPreview(action.preview, tuning.params) : action.preview;
|
|
312
445
|
const bindings = tuning.bindings?.length ? withBindings(action.defaultBinding, tuning.bindings) : null;
|
|
313
|
-
|
|
446
|
+
const modifierRoles = tuning.roles && action.modifierRoles ? rebindRoles(action.modifierRoles, tuning.roles) : null;
|
|
447
|
+
if (invoker === action.invoker && cursor === action.cursor && preview === action.preview && bindings === null && modifierRoles === null) {
|
|
448
|
+
return action;
|
|
449
|
+
}
|
|
314
450
|
return {
|
|
315
451
|
...action,
|
|
452
|
+
...modifierRoles ? { modifierRoles } : {},
|
|
316
453
|
...invoker ? { invoker } : {},
|
|
454
|
+
...cursor ? { cursor } : {},
|
|
455
|
+
...preview ? { preview } : {},
|
|
317
456
|
...bindings ? { defaultBinding: bindings } : {}
|
|
318
457
|
};
|
|
319
458
|
}
|
|
459
|
+
function tunedParams(tunings, given) {
|
|
460
|
+
let out = {};
|
|
461
|
+
for (const t of tunings) out = { ...out, ...resolveParams(t.params) };
|
|
462
|
+
return { ...out, ...given };
|
|
463
|
+
}
|
|
320
464
|
function tuneAction(action, tunings) {
|
|
321
465
|
let out = action;
|
|
322
466
|
for (const t of tunings) out = tuneOnce(out, t);
|
|
@@ -404,7 +548,8 @@ function routesForSpec(spec) {
|
|
|
404
548
|
const phases = phaseAtomsForSpec("phase" in spec ? spec.phase : void 0);
|
|
405
549
|
const target = descriptor.hasTarget ? routeTargetForSpec("target" in spec ? spec.target : void 0) ?? "*" : void 0;
|
|
406
550
|
const args = descriptor.arg ? routeArgsForSpec(spec, descriptor.arg.default) : [void 0];
|
|
407
|
-
|
|
551
|
+
const held = spec.kind === "hover" && spec.held !== void 0 ? { held: spec.held === true ? "required" : "optional" } : {};
|
|
552
|
+
return args.map((arg) => formatRoute({ phases, gesture, arg, target, modifiers, ...held }));
|
|
408
553
|
}
|
|
409
554
|
function entryFor(ownerId, spec, actionId) {
|
|
410
555
|
const gesture = routeGestureForSpecKind(spec.kind);
|
|
@@ -555,11 +700,11 @@ function matchSortedWithBarred(e, bindings, isMac, engagedChannels, opts = {}) {
|
|
|
555
700
|
const scopeBarred = [];
|
|
556
701
|
for (const sb of bindings) {
|
|
557
702
|
if (sb.scope !== scope) continue;
|
|
558
|
-
const
|
|
559
|
-
if (!
|
|
703
|
+
const admitted2 = admits(sb);
|
|
704
|
+
if (!admitted2 && !opts.collectBarred) continue;
|
|
560
705
|
const phaseCtx = { selfChannel: sb.ownerId, engagedChannels: engaged };
|
|
561
706
|
if (matchSpec(e, sb.binding.spec, isMac, phaseCtx)) {
|
|
562
|
-
(
|
|
707
|
+
(admitted2 ? scopeMatches : scopeBarred).push({ binding: sb.binding, scope, ownerId: sb.ownerId });
|
|
563
708
|
}
|
|
564
709
|
}
|
|
565
710
|
scopeMatches.sort((a, b) => compareSpecificity(a.binding.spec, b.binding.spec));
|
|
@@ -818,40 +963,13 @@ function buildRuleCtx(args) {
|
|
|
818
963
|
};
|
|
819
964
|
}
|
|
820
965
|
|
|
821
|
-
// src/interactions/dispatcher/dispatchTrace.ts
|
|
822
|
-
var DEV2 = (() => {
|
|
823
|
-
try {
|
|
824
|
-
return Boolean(import.meta.env?.DEV);
|
|
825
|
-
} catch {
|
|
826
|
-
return false;
|
|
827
|
-
}
|
|
828
|
-
})();
|
|
829
|
-
var TRACE_LIMIT = 200;
|
|
830
|
-
var traceLog = DEV2 && typeof window !== "undefined" ? window.__weaselDispatchLog__ ??= [] : [];
|
|
831
|
-
function recordTrace(entry) {
|
|
832
|
-
if (!DEV2) return;
|
|
833
|
-
traceLog.push(entry);
|
|
834
|
-
if (traceLog.length > TRACE_LIMIT) traceLog.shift();
|
|
835
|
-
}
|
|
836
|
-
function publishLiveDispatch(explain2) {
|
|
837
|
-
if (!DEV2 || typeof window === "undefined") return;
|
|
838
|
-
window.__weaselDispatchLive__ = explain2;
|
|
839
|
-
}
|
|
840
|
-
function recordModeSwitch(mode, from, to, detail) {
|
|
841
|
-
recordTrace({
|
|
842
|
-
kind: "mode",
|
|
843
|
-
ts: Date.now(),
|
|
844
|
-
mode,
|
|
845
|
-
from,
|
|
846
|
-
to,
|
|
847
|
-
...detail !== void 0 ? { detail } : {}
|
|
848
|
-
});
|
|
849
|
-
}
|
|
850
|
-
|
|
851
966
|
// src/interactions/dispatcher/gestureIds.ts
|
|
852
967
|
function pointerGestureId(pointerId) {
|
|
853
968
|
return `pointer-${pointerId ?? "mouse"}`;
|
|
854
969
|
}
|
|
970
|
+
function carryGestureId(pointerId) {
|
|
971
|
+
return `carry-${pointerId ?? "mouse"}`;
|
|
972
|
+
}
|
|
855
973
|
function multiTouchGestureId(fingers) {
|
|
856
974
|
return `multitouch-${fingers}`;
|
|
857
975
|
}
|
|
@@ -868,6 +986,9 @@ function gestureIdFor(event) {
|
|
|
868
986
|
if (event.kind === "multitouch") {
|
|
869
987
|
return multiTouchGestureId(event.fingers);
|
|
870
988
|
}
|
|
989
|
+
if (event.kind === "carry") {
|
|
990
|
+
return carryGestureId(event.pointerId);
|
|
991
|
+
}
|
|
871
992
|
return `ongoing-${event.kind}`;
|
|
872
993
|
}
|
|
873
994
|
|
|
@@ -911,6 +1032,51 @@ function assembleEntries(entries, inputs) {
|
|
|
911
1032
|
}
|
|
912
1033
|
};
|
|
913
1034
|
}
|
|
1035
|
+
function createTraceRing(limit = 200, dev = isDev()) {
|
|
1036
|
+
const entries = [];
|
|
1037
|
+
const pushed = createEmitter();
|
|
1038
|
+
let total = 0;
|
|
1039
|
+
let watchers = 0;
|
|
1040
|
+
const recording = () => dev || watchers > 0;
|
|
1041
|
+
return {
|
|
1042
|
+
recording,
|
|
1043
|
+
push(entry) {
|
|
1044
|
+
if (!recording()) return;
|
|
1045
|
+
entries.push(entry);
|
|
1046
|
+
if (entries.length > limit) entries.shift();
|
|
1047
|
+
total++;
|
|
1048
|
+
pushed.emit();
|
|
1049
|
+
},
|
|
1050
|
+
since(cursor) {
|
|
1051
|
+
const first = total - entries.length;
|
|
1052
|
+
return { entries: entries.slice(Math.max(cursor, first) - first), cursor: total };
|
|
1053
|
+
},
|
|
1054
|
+
watch() {
|
|
1055
|
+
watchers++;
|
|
1056
|
+
let released = false;
|
|
1057
|
+
return () => {
|
|
1058
|
+
if (released) return;
|
|
1059
|
+
released = true;
|
|
1060
|
+
watchers--;
|
|
1061
|
+
};
|
|
1062
|
+
},
|
|
1063
|
+
subscribe: pushed.subscribe
|
|
1064
|
+
};
|
|
1065
|
+
}
|
|
1066
|
+
function createDispatchTrace(limit, dev) {
|
|
1067
|
+
const ring = createTraceRing(limit, dev);
|
|
1068
|
+
let explain2 = null;
|
|
1069
|
+
return {
|
|
1070
|
+
...ring,
|
|
1071
|
+
recordModeSwitch(mode, from, to, detail) {
|
|
1072
|
+
ring.push({ kind: "mode", ts: Date.now(), mode, from, to, ...detail !== void 0 ? { detail } : {} });
|
|
1073
|
+
},
|
|
1074
|
+
setLive(next) {
|
|
1075
|
+
explain2 = next;
|
|
1076
|
+
},
|
|
1077
|
+
live: () => explain2?.() ?? null
|
|
1078
|
+
};
|
|
1079
|
+
}
|
|
914
1080
|
|
|
915
1081
|
// src/interactions/dispatcher/inputFacts.ts
|
|
916
1082
|
function modifiersOf(e) {
|
|
@@ -925,11 +1091,14 @@ function worldPointOf(event) {
|
|
|
925
1091
|
case "doubleclick":
|
|
926
1092
|
case "contextmenu":
|
|
927
1093
|
return event.x !== void 0 && event.y !== void 0 ? { x: event.x, y: event.y } : void 0;
|
|
1094
|
+
case "carry":
|
|
1095
|
+
return { x: event.x, y: event.y };
|
|
928
1096
|
default:
|
|
929
1097
|
return void 0;
|
|
930
1098
|
}
|
|
931
1099
|
}
|
|
932
1100
|
function carriedBy(event) {
|
|
1101
|
+
if (event.kind === "carry") return { items: [], carry: { type: event.type, value: event.value } };
|
|
933
1102
|
return event.kind === "drop" || event.kind === "paste" ? { items: event.items } : void 0;
|
|
934
1103
|
}
|
|
935
1104
|
function immediateParams(event, resolved) {
|
|
@@ -965,8 +1134,19 @@ function immediateParams(event, resolved) {
|
|
|
965
1134
|
};
|
|
966
1135
|
// Only a `stage: 'press'` pointerdown reaches an immediate invoker: the
|
|
967
1136
|
// buffered copy matches `drag` specs, which are ongoing.
|
|
968
|
-
case "pointerdown":
|
|
969
1137
|
case "contextmenu":
|
|
1138
|
+
return {
|
|
1139
|
+
worldX: event.x,
|
|
1140
|
+
worldY: event.y,
|
|
1141
|
+
clientX: event.clientX,
|
|
1142
|
+
clientY: event.clientY,
|
|
1143
|
+
affordance: event.affordance,
|
|
1144
|
+
bodyTarget: event.bodyTarget,
|
|
1145
|
+
bodyKind: event.bodyKind,
|
|
1146
|
+
mods: modifiersOf(event),
|
|
1147
|
+
...resolved
|
|
1148
|
+
};
|
|
1149
|
+
case "pointerdown":
|
|
970
1150
|
case "longpress":
|
|
971
1151
|
return {
|
|
972
1152
|
worldX: event.x,
|
|
@@ -985,6 +1165,20 @@ function immediateParams(event, resolved) {
|
|
|
985
1165
|
affordance: event.affordance,
|
|
986
1166
|
bodyTarget: event.bodyTarget,
|
|
987
1167
|
mods: modifiersOf(event),
|
|
1168
|
+
held: event.held === true,
|
|
1169
|
+
...resolved
|
|
1170
|
+
};
|
|
1171
|
+
case "carry":
|
|
1172
|
+
return {
|
|
1173
|
+
worldX: event.x,
|
|
1174
|
+
worldY: event.y,
|
|
1175
|
+
clientX: event.clientX,
|
|
1176
|
+
clientY: event.clientY,
|
|
1177
|
+
carry: { type: event.type, value: event.value },
|
|
1178
|
+
affordance: event.affordance,
|
|
1179
|
+
bodyTarget: event.bodyTarget,
|
|
1180
|
+
bodyKind: event.bodyKind,
|
|
1181
|
+
mods: modifiersOf(event),
|
|
988
1182
|
...resolved
|
|
989
1183
|
};
|
|
990
1184
|
case "drop":
|
|
@@ -1005,16 +1199,20 @@ function liveInView(binding, view) {
|
|
|
1005
1199
|
const views = binding.opts?.views;
|
|
1006
1200
|
return views === void 0 || views.includes(view);
|
|
1007
1201
|
}
|
|
1202
|
+
function liveForKeys(binding, reach) {
|
|
1203
|
+
if (reach === void 0) return true;
|
|
1204
|
+
return binding.opts?.over ? reach.over : reach.held;
|
|
1205
|
+
}
|
|
1008
1206
|
function namesView(binding, view) {
|
|
1009
1207
|
return binding.opts?.views?.includes(view) ?? false;
|
|
1010
1208
|
}
|
|
1011
|
-
function preferViewScoped(
|
|
1209
|
+
function preferViewScoped(matches2, view) {
|
|
1012
1210
|
const named = [];
|
|
1013
1211
|
const rest = [];
|
|
1014
|
-
for (const m of
|
|
1212
|
+
for (const m of matches2) {
|
|
1015
1213
|
(namesView(m.binding, view) ? named : rest).push(m);
|
|
1016
1214
|
}
|
|
1017
|
-
return named.length === 0 ? [...
|
|
1215
|
+
return named.length === 0 ? [...matches2] : [...named, ...rest];
|
|
1018
1216
|
}
|
|
1019
1217
|
function ruleCtxOf(ctx) {
|
|
1020
1218
|
const r = ctx.getRuleCtx?.();
|
|
@@ -1030,7 +1228,7 @@ function isEligible(action, ruleCtx) {
|
|
|
1030
1228
|
function describeEligible(eligible) {
|
|
1031
1229
|
return describeRule(eligibleToRule(eligible));
|
|
1032
1230
|
}
|
|
1033
|
-
function preferContextual(
|
|
1231
|
+
function preferContextual(matches2, actionLookup, holds, view) {
|
|
1034
1232
|
const out = [];
|
|
1035
1233
|
let run = [];
|
|
1036
1234
|
const flush = () => {
|
|
@@ -1041,7 +1239,7 @@ function preferContextual(matches, actionLookup, holds, view) {
|
|
|
1041
1239
|
out.push(...gated, ...run.filter((m) => !gated.includes(m)));
|
|
1042
1240
|
run = [];
|
|
1043
1241
|
};
|
|
1044
|
-
for (const m of
|
|
1242
|
+
for (const m of matches2) {
|
|
1045
1243
|
const head = run[0];
|
|
1046
1244
|
if (head && (head.scope !== m.scope || namesView(head.binding, view) !== namesView(m.binding, view) || !sameSpecificity(head.binding.spec, m.binding.spec))) flush();
|
|
1047
1245
|
run.push(m);
|
|
@@ -1133,8 +1331,10 @@ function createGestureFacts() {
|
|
|
1133
1331
|
const points = /* @__PURE__ */ new Map();
|
|
1134
1332
|
const startSpreads = /* @__PURE__ */ new Map();
|
|
1135
1333
|
const turns = /* @__PURE__ */ new Map();
|
|
1334
|
+
const roles = /* @__PURE__ */ new Map();
|
|
1136
1335
|
return {
|
|
1137
|
-
begin(gestureId, event) {
|
|
1336
|
+
begin(gestureId, event, roleKeys) {
|
|
1337
|
+
if (roleKeys) roles.set(gestureId, roleKeys);
|
|
1138
1338
|
if (event.kind === "pointerdown") {
|
|
1139
1339
|
origins.set(gestureId, {
|
|
1140
1340
|
x: event.x ?? 0,
|
|
@@ -1167,7 +1367,9 @@ function createGestureFacts() {
|
|
|
1167
1367
|
const trail = points.get(gestureId);
|
|
1168
1368
|
const startSpread = startSpreads.get(gestureId);
|
|
1169
1369
|
const turn = turns.get(gestureId);
|
|
1370
|
+
const roleKeys = roles.get(gestureId);
|
|
1170
1371
|
return {
|
|
1372
|
+
...roleKeys !== void 0 ? { roleKeys } : {},
|
|
1171
1373
|
...origin !== void 0 ? { origin } : {},
|
|
1172
1374
|
...trail !== void 0 ? { points: trail } : {},
|
|
1173
1375
|
...startSpread !== void 0 ? { startSpread } : {},
|
|
@@ -1179,12 +1381,14 @@ function createGestureFacts() {
|
|
|
1179
1381
|
points.delete(gestureId);
|
|
1180
1382
|
startSpreads.delete(gestureId);
|
|
1181
1383
|
turns.delete(gestureId);
|
|
1384
|
+
roles.delete(gestureId);
|
|
1182
1385
|
},
|
|
1183
1386
|
clear() {
|
|
1184
1387
|
origins.clear();
|
|
1185
1388
|
points.clear();
|
|
1186
1389
|
startSpreads.clear();
|
|
1187
1390
|
turns.clear();
|
|
1391
|
+
roles.clear();
|
|
1188
1392
|
}
|
|
1189
1393
|
};
|
|
1190
1394
|
}
|
|
@@ -1229,7 +1433,7 @@ function createInFlightGestures() {
|
|
|
1229
1433
|
let cursor = null;
|
|
1230
1434
|
for (const [id, handle] of handles) {
|
|
1231
1435
|
const action = actions.get(id);
|
|
1232
|
-
const spec = handle.cursor?.() ?? action?.activeCursor ?? action
|
|
1436
|
+
const spec = handle.cursor?.() ?? action?.activeCursor ?? actionCursor(action);
|
|
1233
1437
|
if (spec !== void 0 && resolveCursor(spec)) cursor = spec;
|
|
1234
1438
|
}
|
|
1235
1439
|
return cursor;
|
|
@@ -1321,6 +1525,7 @@ function buildInvocationCtx(event, deps, viewId, facts = {}) {
|
|
|
1321
1525
|
};
|
|
1322
1526
|
const screen = clientPoint(event);
|
|
1323
1527
|
if (screen) base.screen = screen;
|
|
1528
|
+
if (facts.roleKeys) base.roles = resolveRoles(facts.roleKeys, base.modifiers, false);
|
|
1324
1529
|
if (event.kind === "key") {
|
|
1325
1530
|
base.key = { key: event.key, repeat: event.repeat ?? false };
|
|
1326
1531
|
} else if (event.kind === "key-held") {
|
|
@@ -1335,6 +1540,9 @@ function buildInvocationCtx(event, deps, viewId, facts = {}) {
|
|
|
1335
1540
|
Object.assign(base, pumpDrag(event, facts));
|
|
1336
1541
|
} else if (event.kind === "multitouch") {
|
|
1337
1542
|
base.multiTouch = multiTouchOf(event, facts);
|
|
1543
|
+
} else if (event.kind === "carry") {
|
|
1544
|
+
base.world = { x: event.x, y: event.y };
|
|
1545
|
+
base.carry = { type: event.type, value: event.value };
|
|
1338
1546
|
}
|
|
1339
1547
|
return base;
|
|
1340
1548
|
}
|
|
@@ -1385,6 +1593,13 @@ function pumpGesture(run, event) {
|
|
|
1385
1593
|
handle.onMove(ctxFor(run, event, {}, gestureId));
|
|
1386
1594
|
return "handled";
|
|
1387
1595
|
}
|
|
1596
|
+
if (event.kind === "wheel") {
|
|
1597
|
+
for (const [gestureId, handle] of [...inFlight.handles].reverse()) {
|
|
1598
|
+
if (handle.onWheel?.(ctxFor(run, event, {}, gestureId)) === true) return "handled";
|
|
1599
|
+
}
|
|
1600
|
+
return void 0;
|
|
1601
|
+
}
|
|
1602
|
+
if (event.kind === "carry") return pumpCarry(run, event);
|
|
1388
1603
|
if (event.kind === "pointerup") return ended("commit");
|
|
1389
1604
|
if (event.kind === "pointercancel") return ended("cancel");
|
|
1390
1605
|
if (event.kind === "multitouch" && event.end !== void 0) {
|
|
@@ -1402,7 +1617,23 @@ function pumpGesture(run, event) {
|
|
|
1402
1617
|
}
|
|
1403
1618
|
return void 0;
|
|
1404
1619
|
}
|
|
1620
|
+
function pumpCarry(run, event) {
|
|
1621
|
+
if (event.stage === "enter") return void 0;
|
|
1622
|
+
const gestureId = gestureIdFor(event);
|
|
1623
|
+
const handle = run.inFlight.handles.get(gestureId);
|
|
1624
|
+
if (!handle) return event.stage === "leave" ? "unhandled" : void 0;
|
|
1625
|
+
if (event.stage === "move") {
|
|
1626
|
+
handle.onMove?.(ctxFor(run, event, {}, gestureId));
|
|
1627
|
+
return "handled";
|
|
1628
|
+
}
|
|
1629
|
+
return endGesture(run, gestureId, event, event.stage === "drop" ? "commit" : "cancel") ? "handled" : "unhandled";
|
|
1630
|
+
}
|
|
1631
|
+
function carryStageFits(event, timing) {
|
|
1632
|
+
if (event.kind !== "carry") return true;
|
|
1633
|
+
return timing === "immediate" ? event.stage === "drop" : event.stage === "enter" || event.stage === "move";
|
|
1634
|
+
}
|
|
1405
1635
|
function invokeAction(run, event, match, action, deps) {
|
|
1636
|
+
if (action.invoker && !carryStageFits(event, action.invoker.timing)) return "empty-handle";
|
|
1406
1637
|
if (action.invoker?.timing === "immediate") {
|
|
1407
1638
|
try {
|
|
1408
1639
|
const params = immediateParams(event, resolveParams(match.binding.opts?.params));
|
|
@@ -1421,7 +1652,8 @@ function invokeAction(run, event, match, action, deps) {
|
|
|
1421
1652
|
return "misbound";
|
|
1422
1653
|
}
|
|
1423
1654
|
const gestureId = gestureIdFor(event);
|
|
1424
|
-
|
|
1655
|
+
const roleKeys = roleKeysOf(action.modifierRoles, match.binding.opts?.roles);
|
|
1656
|
+
run.facts.begin(gestureId, event, roleKeys && platformRoleKeys(roleKeys, run.isMac()));
|
|
1425
1657
|
const handle = action.invoker.start(ctxFor(run, event, deps, gestureId), match.binding.opts);
|
|
1426
1658
|
if (isEmptyOngoingHandle(handle)) {
|
|
1427
1659
|
run.facts.drop(gestureId);
|
|
@@ -1528,16 +1760,20 @@ function assembleScopedBindings(ctx) {
|
|
|
1528
1760
|
...allowedCapabilities ? { allowedCapabilities } : {}
|
|
1529
1761
|
});
|
|
1530
1762
|
const view = ctx.viewId ?? null;
|
|
1531
|
-
const
|
|
1763
|
+
const live = (b) => liveInView(b, view) && liveForKeys(b, ctx.keyReach);
|
|
1764
|
+
const result = scopeBindings(ordered, state).filter((sb) => live(sb.binding));
|
|
1532
1765
|
for (const action of ctx.actions.list()) {
|
|
1533
1766
|
const targetScope = action.scope === "hotkey" ? "hotkey" : "ambient";
|
|
1534
1767
|
for (const binding of actionBindings(action)) {
|
|
1535
|
-
if (!
|
|
1768
|
+
if (!live(binding)) continue;
|
|
1536
1769
|
result.push({ binding, scope: targetScope, ownerId: null });
|
|
1537
1770
|
}
|
|
1538
1771
|
}
|
|
1539
1772
|
return result;
|
|
1540
1773
|
}
|
|
1774
|
+
function anyBinding(ctx, test) {
|
|
1775
|
+
return assembleScopedBindings(ctx).some((sb) => test(sb.binding.spec));
|
|
1776
|
+
}
|
|
1541
1777
|
function buildActionMap(registry) {
|
|
1542
1778
|
const map = /* @__PURE__ */ new Map();
|
|
1543
1779
|
for (const action of registry.list()) {
|
|
@@ -1690,9 +1926,14 @@ function resolveOnly(event, ctx, engaged) {
|
|
|
1690
1926
|
actionId: winner.action.id,
|
|
1691
1927
|
action: winner.action,
|
|
1692
1928
|
scope: winner.match.scope,
|
|
1693
|
-
ownerId: winner.match.ownerId
|
|
1929
|
+
ownerId: winner.match.ownerId,
|
|
1930
|
+
...paramsOf(winner.match.binding)
|
|
1694
1931
|
};
|
|
1695
1932
|
}
|
|
1933
|
+
function paramsOf(binding) {
|
|
1934
|
+
const params = resolveParams(binding.opts?.params);
|
|
1935
|
+
return params ? { params } : {};
|
|
1936
|
+
}
|
|
1696
1937
|
function explain(event, ctx, engaged, opts) {
|
|
1697
1938
|
const r = rank(event, ctx, engaged, true);
|
|
1698
1939
|
const walked = walk(r, event, ctx, null, opts?.evaluateShadowed ?? false);
|
|
@@ -1711,17 +1952,20 @@ function createDispatcher(opts) {
|
|
|
1711
1952
|
}
|
|
1712
1953
|
const uiOngoing = createUiOngoing(inFlight, notify, opts?.getAction);
|
|
1713
1954
|
let routedView;
|
|
1714
|
-
|
|
1955
|
+
let routedIsMac = false;
|
|
1956
|
+
const run = { inFlight, facts, viewId: () => routedView, isMac: () => routedIsMac };
|
|
1715
1957
|
const invoking = (event) => (match, action, deps) => invokeAction(run, event, match, action, deps);
|
|
1716
1958
|
function handleInput(event, ctx) {
|
|
1717
1959
|
routedView = ctx.viewId;
|
|
1960
|
+
routedIsMac = ctx.isMac;
|
|
1718
1961
|
const pumped = pumpGesture(run, event);
|
|
1719
1962
|
if (pumped !== void 0) return pumped;
|
|
1720
1963
|
if (event.kind === "hover") return hover(event, ctx);
|
|
1721
|
-
const
|
|
1964
|
+
const trace = ctx.trace?.recording() ? ctx.trace : null;
|
|
1965
|
+
const r = rank(event, ctx, inFlight.engagedOwners(), trace !== null);
|
|
1722
1966
|
const walked = walk(r, event, ctx, invoking(event), false);
|
|
1723
1967
|
const outcome = walked.stop === "fired" ? "handled" : "unhandled";
|
|
1724
|
-
|
|
1968
|
+
trace?.push(buildDispatchRecord(r, walked, event, ctx, false, outcome));
|
|
1725
1969
|
return outcome;
|
|
1726
1970
|
}
|
|
1727
1971
|
function hover(event, ctx) {
|
|
@@ -1869,6 +2113,75 @@ function openPointerSession(origin, down, cb, opts = {}) {
|
|
|
1869
2113
|
};
|
|
1870
2114
|
}
|
|
1871
2115
|
|
|
2116
|
+
// src/interactions/carry/carry.ts
|
|
2117
|
+
var surfaces = /* @__PURE__ */ new Set();
|
|
2118
|
+
function addCarrySurface(surface) {
|
|
2119
|
+
surfaces.add(surface);
|
|
2120
|
+
return () => {
|
|
2121
|
+
surfaces.delete(surface);
|
|
2122
|
+
};
|
|
2123
|
+
}
|
|
2124
|
+
function contains(r, x, y) {
|
|
2125
|
+
return x >= r.left && x <= r.right && y >= r.top && y <= r.bottom;
|
|
2126
|
+
}
|
|
2127
|
+
function surfaceAt(doc, x, y) {
|
|
2128
|
+
const hit = typeof doc.elementFromPoint === "function" ? doc.elementFromPoint(x, y) : null;
|
|
2129
|
+
let best = null;
|
|
2130
|
+
for (const s of surfaces) {
|
|
2131
|
+
if (!contains(s.element.getBoundingClientRect(), x, y)) continue;
|
|
2132
|
+
if (hit && !s.element.contains(hit)) continue;
|
|
2133
|
+
if (best && s.element.contains(best.element)) continue;
|
|
2134
|
+
best = s;
|
|
2135
|
+
}
|
|
2136
|
+
return best;
|
|
2137
|
+
}
|
|
2138
|
+
function startCarry(origin, down, payload, cb = {}) {
|
|
2139
|
+
const doc = origin.ownerDocument ?? document;
|
|
2140
|
+
const pointerId = down.pointerId;
|
|
2141
|
+
let over = null;
|
|
2142
|
+
const leave = (at) => {
|
|
2143
|
+
const was = over;
|
|
2144
|
+
over = null;
|
|
2145
|
+
if (was && surfaces.has(was)) was.receive("leave", payload, at, pointerId);
|
|
2146
|
+
};
|
|
2147
|
+
const step = (at) => {
|
|
2148
|
+
const next = surfaceAt(doc, at.clientX, at.clientY);
|
|
2149
|
+
if (next === over) {
|
|
2150
|
+
over?.receive("move", payload, at, pointerId);
|
|
2151
|
+
return;
|
|
2152
|
+
}
|
|
2153
|
+
leave(at);
|
|
2154
|
+
over = next;
|
|
2155
|
+
next?.receive("enter", payload, at, pointerId);
|
|
2156
|
+
};
|
|
2157
|
+
let last = down;
|
|
2158
|
+
const session = openPointerSession(origin, down, {
|
|
2159
|
+
onMove: (e) => {
|
|
2160
|
+
last = e;
|
|
2161
|
+
step(e);
|
|
2162
|
+
cb.onMove?.(e);
|
|
2163
|
+
},
|
|
2164
|
+
onEnd: (e) => {
|
|
2165
|
+
step(e);
|
|
2166
|
+
const on = over;
|
|
2167
|
+
over = null;
|
|
2168
|
+
const taken = on !== null && surfaces.has(on) && on.receive("drop", payload, e, pointerId) === "handled";
|
|
2169
|
+
cb.onEnd?.({ taken, event: e });
|
|
2170
|
+
},
|
|
2171
|
+
onCancel: (reason) => {
|
|
2172
|
+
leave(last);
|
|
2173
|
+
cb.onCancel?.(reason);
|
|
2174
|
+
}
|
|
2175
|
+
});
|
|
2176
|
+
return {
|
|
2177
|
+
pointerId,
|
|
2178
|
+
get active() {
|
|
2179
|
+
return session.active;
|
|
2180
|
+
},
|
|
2181
|
+
cancel: () => session.cancel()
|
|
2182
|
+
};
|
|
2183
|
+
}
|
|
2184
|
+
|
|
1872
2185
|
// src/tools/types.ts
|
|
1873
2186
|
function isTool(entry) {
|
|
1874
2187
|
return !!(entry.eligibility?.focus || entry.eligibility?.offhand);
|
|
@@ -2089,6 +2402,20 @@ function normalizeMime(raw) {
|
|
|
2089
2402
|
const bare = raw.split(";")[0].trim().toLowerCase();
|
|
2090
2403
|
return bare || FALLBACK_MIME;
|
|
2091
2404
|
}
|
|
2405
|
+
var admitted = /* @__PURE__ */ new Map();
|
|
2406
|
+
function admitIngestMime(mime) {
|
|
2407
|
+
const key = normalizeMime(mime);
|
|
2408
|
+
admitted.set(key, (admitted.get(key) ?? 0) + 1);
|
|
2409
|
+
let released = false;
|
|
2410
|
+
return () => {
|
|
2411
|
+
if (released) return;
|
|
2412
|
+
released = true;
|
|
2413
|
+
const n = (admitted.get(key) ?? 1) - 1;
|
|
2414
|
+
if (n > 0) admitted.set(key, n);
|
|
2415
|
+
else admitted.delete(key);
|
|
2416
|
+
};
|
|
2417
|
+
}
|
|
2418
|
+
var keepsString = (mime) => INGEST_STRING_MIMES.has(mime) || admitted.has(mime);
|
|
2092
2419
|
function itemsFromFiles(files) {
|
|
2093
2420
|
return files.map((file) => ({ kind: "file", mime: normalizeMime(file.type), file }));
|
|
2094
2421
|
}
|
|
@@ -2102,7 +2429,7 @@ function itemsFromDataTransfer(dt) {
|
|
|
2102
2429
|
if (file) files.push({ kind: "file", mime: normalizeMime(file.type), file });
|
|
2103
2430
|
} else if (item.kind === "string") {
|
|
2104
2431
|
const mime = normalizeMime(item.type);
|
|
2105
|
-
if (
|
|
2432
|
+
if (keepsString(mime)) {
|
|
2106
2433
|
const slot = strings.length;
|
|
2107
2434
|
strings.push(null);
|
|
2108
2435
|
reads.push(
|
|
@@ -2128,7 +2455,7 @@ function itemTypesFromDataTransfer(dt) {
|
|
|
2128
2455
|
for (const item of Array.from(dt.items ?? [])) {
|
|
2129
2456
|
const mime = item.type ? normalizeMime(item.type) : "";
|
|
2130
2457
|
if (item.kind === "file") mimes.push(mime && mime !== "application/x-moz-file" ? mime : UNKNOWN_MIME);
|
|
2131
|
-
else if (
|
|
2458
|
+
else if (keepsString(mime)) mimes.push(mime);
|
|
2132
2459
|
}
|
|
2133
2460
|
if (mimes.length === 0 && Array.from(dt.types ?? []).includes("Files")) mimes.push(UNKNOWN_MIME);
|
|
2134
2461
|
return mimes.map((mime) => ({ mime }));
|
|
@@ -2138,7 +2465,7 @@ function itemsFromClipboardData(cd) {
|
|
|
2138
2465
|
for (const file of Array.from(cd.files ?? [])) {
|
|
2139
2466
|
out.push({ kind: "file", mime: normalizeMime(file.type), file });
|
|
2140
2467
|
}
|
|
2141
|
-
for (const mime of INGEST_STRING_MIMES) {
|
|
2468
|
+
for (const mime of /* @__PURE__ */ new Set([...INGEST_STRING_MIMES, ...admitted.keys()])) {
|
|
2142
2469
|
const text = cd.getData(mime);
|
|
2143
2470
|
if (text) out.push({ kind: "string", mime, text });
|
|
2144
2471
|
}
|
|
@@ -2191,6 +2518,332 @@ function dwarn(namespace, ...args) {
|
|
|
2191
2518
|
console.warn(`[${namespace}]`, ...args);
|
|
2192
2519
|
}
|
|
2193
2520
|
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2521
|
+
// src/menus/pickMenu.ts
|
|
2522
|
+
var oneOf = (want, got) => want === void 0 || (Array.isArray(want) ? want.includes(got) : want === got);
|
|
2523
|
+
function matches(when, hit) {
|
|
2524
|
+
return oneOf(when.bodyTarget, hit.bodyTarget) && oneOf(when.bodyKind, hit.bodyKind);
|
|
2525
|
+
}
|
|
2526
|
+
function mergeMenuDefs(defs, activeTool) {
|
|
2527
|
+
const live = [
|
|
2528
|
+
...defs.filter((d) => d.owner === null),
|
|
2529
|
+
...defs.filter((d) => d.owner !== null && d.owner === activeTool)
|
|
2530
|
+
];
|
|
2531
|
+
const byId = /* @__PURE__ */ new Map();
|
|
2532
|
+
for (const { def } of live) {
|
|
2533
|
+
const prev = byId.get(def.id);
|
|
2534
|
+
if (!prev) {
|
|
2535
|
+
byId.set(def.id, { def: { ...def, menu: { ...def.menu, children: { ...def.menu.children } } }, parts: 1 });
|
|
2536
|
+
continue;
|
|
2537
|
+
}
|
|
2538
|
+
const n = prev.parts++;
|
|
2539
|
+
const children = prev.def.menu.children;
|
|
2540
|
+
children[`~sep${n}`] = { kind: "separator", name: "", description: "", default: void 0 };
|
|
2541
|
+
for (const [k, node] of Object.entries(def.menu.children)) {
|
|
2542
|
+
children[Object.hasOwn(children, k) ? `${k}~${n}` : k] = node;
|
|
2543
|
+
}
|
|
2544
|
+
if (!prev.def.when && def.when) prev.def.when = def.when;
|
|
2545
|
+
}
|
|
2546
|
+
return [...byId.values()].map((m) => m.def);
|
|
2547
|
+
}
|
|
2548
|
+
function pickMenu(defs, hit) {
|
|
2549
|
+
return defs.find((d) => d.when !== void 0 && matches(d.when, hit));
|
|
2550
|
+
}
|
|
2551
|
+
var SUBMENU_AS = /* @__PURE__ */ new Set(["menu", "page", "tab", "panel"]);
|
|
2552
|
+
var noop = () => {
|
|
2553
|
+
};
|
|
2554
|
+
var withAccess = (access) => access ? { access } : {};
|
|
2555
|
+
var sep = (key) => ({ kind: "separator", key });
|
|
2556
|
+
function itemOf(ctx, it, key, label, off, access) {
|
|
2557
|
+
const deps = ctx.src.depsFor(it.action);
|
|
2558
|
+
const point = ctx.at ? { worldX: ctx.at.x, worldY: ctx.at.y } : {};
|
|
2559
|
+
if (it.action.settings) return settingsOf(ctx, it, key, label, off || !evaluateEnabled(it.action, deps, ctx.at).enabled, access);
|
|
2560
|
+
return {
|
|
2561
|
+
kind: "item",
|
|
2562
|
+
key,
|
|
2563
|
+
label,
|
|
2564
|
+
...withAccess(access),
|
|
2565
|
+
icon: it.icon,
|
|
2566
|
+
shortcut: actionShortcuts(it.action, it.params)[0],
|
|
2567
|
+
disabled: off || !evaluateEnabled(it.action, deps, ctx.at).enabled,
|
|
2568
|
+
checked: evaluateActive(it.action, deps),
|
|
2569
|
+
run: () => {
|
|
2570
|
+
ctx.src.trigger(it.action.id, { ...ctx.params, ...it.params, ...point });
|
|
2571
|
+
}
|
|
2572
|
+
};
|
|
2573
|
+
}
|
|
2574
|
+
function settingsOf(ctx, it, key, label, off, access) {
|
|
2575
|
+
const settings = it.action.settings;
|
|
2576
|
+
const state = off ? null : readActionSettings(it.action, ctx.src.depsFor(it.action));
|
|
2577
|
+
const mixed = new Set(state?.mixed ?? []);
|
|
2578
|
+
const values = (path) => mixed.has(path) ? void 0 : prefValueAtPath(state?.values, path);
|
|
2579
|
+
const onChange = (path, value) => {
|
|
2580
|
+
const params = actionSettingsParams(settings, path, value);
|
|
2581
|
+
if (params) ctx.src.trigger(it.action.id, { ...ctx.params, ...it.params, ...params });
|
|
2582
|
+
};
|
|
2583
|
+
const form = {
|
|
2584
|
+
...ctx,
|
|
2585
|
+
src: { ...ctx.src, values, onChange, over: settings.schema },
|
|
2586
|
+
root: settings.schema,
|
|
2587
|
+
read: (path, from) => from === "item" ? void 0 : values(path)
|
|
2588
|
+
};
|
|
2589
|
+
const entries = state ? tidy(groupRows(form, settings.schema, "", false)) : [];
|
|
2590
|
+
return {
|
|
2591
|
+
kind: "submenu",
|
|
2592
|
+
key,
|
|
2593
|
+
label,
|
|
2594
|
+
...it.icon ? { icon: it.icon } : {},
|
|
2595
|
+
...withAccess(access),
|
|
2596
|
+
...entries.length === 0 ? { disabled: true } : {},
|
|
2597
|
+
entries
|
|
2598
|
+
};
|
|
2599
|
+
}
|
|
2600
|
+
function itemsNamed(ctx, name) {
|
|
2601
|
+
const action = ctx.byId.get(name);
|
|
2602
|
+
if (action) return actionItems(action);
|
|
2603
|
+
const colon = name.indexOf(":");
|
|
2604
|
+
const owner = colon > 0 ? ctx.byId.get(name.slice(0, colon)) : void 0;
|
|
2605
|
+
return owner ? actionItems(owner).filter((it) => it.key === name) : [];
|
|
2606
|
+
}
|
|
2607
|
+
function actionRows(ctx, leaf, key, off) {
|
|
2608
|
+
const own = leaf.label || leaf.name;
|
|
2609
|
+
if (leaf.action === void 0) {
|
|
2610
|
+
if (!own) return [];
|
|
2611
|
+
if (isDev()) console.warn(`weasel: menu row "${key}" names no registered action, so it does nothing`);
|
|
2612
|
+
return [{ kind: "item", key, label: own, disabled: true, run: noop }];
|
|
2613
|
+
}
|
|
2614
|
+
const items = itemsNamed(ctx, leaf.action);
|
|
2615
|
+
if (items.length === 1) return [itemOf(ctx, items[0], key, own || items[0].label, off, leaf.access)];
|
|
2616
|
+
return items.map((it) => itemOf(ctx, it, `${key}/${it.key}`, it.label, off));
|
|
2617
|
+
}
|
|
2618
|
+
function siblingsOf(ctx, path) {
|
|
2619
|
+
const dot = path.lastIndexOf(".");
|
|
2620
|
+
const parent = dot < 0 ? void 0 : ctx.src.values(path.slice(0, dot));
|
|
2621
|
+
return parent && typeof parent === "object" ? parent : void 0;
|
|
2622
|
+
}
|
|
2623
|
+
function booleanRows(ctx, leaf, key, path, off) {
|
|
2624
|
+
const { values, onChange } = ctx.src;
|
|
2625
|
+
if (!values || !onChange) return [];
|
|
2626
|
+
const stored = values(path);
|
|
2627
|
+
const on = leaf.encoding ? leaf.encoding.read(stored, siblingsOf(ctx, path)) : stored === true;
|
|
2628
|
+
const write = (v) => leaf.encoding ? leaf.encoding.write(v, siblingsOf(ctx, path)) : v;
|
|
2629
|
+
return [{
|
|
2630
|
+
kind: "item",
|
|
2631
|
+
key,
|
|
2632
|
+
label: leaf.name,
|
|
2633
|
+
...withAccess(leaf.access),
|
|
2634
|
+
checked: on,
|
|
2635
|
+
disabled: off || leaf.readout === true,
|
|
2636
|
+
run: leaf.readout ? noop : () => onChange(path, write(!on))
|
|
2637
|
+
}];
|
|
2638
|
+
}
|
|
2639
|
+
function enumRows(ctx, leaf, key, path, off) {
|
|
2640
|
+
const { values, onChange } = ctx.src;
|
|
2641
|
+
if (!values || !onChange) return [];
|
|
2642
|
+
const stored = values(path);
|
|
2643
|
+
const current = leaf.encoding ? leaf.encoding.read(stored, siblingsOf(ctx, path)) : stored;
|
|
2644
|
+
if (leaf.readout) {
|
|
2645
|
+
const shown = leaf.options.find((o) => o.value === current)?.label ?? "\u2014";
|
|
2646
|
+
return [{ kind: "item", key, label: `${leaf.name}: ${shown}`, disabled: true, run: noop }];
|
|
2647
|
+
}
|
|
2648
|
+
const write = (v) => leaf.encoding ? leaf.encoding.write(v, siblingsOf(ctx, path)) : v;
|
|
2649
|
+
return [
|
|
2650
|
+
sep(`${key}/<`),
|
|
2651
|
+
...leaf.options.map((o) => ({
|
|
2652
|
+
kind: "item",
|
|
2653
|
+
key: `${key}/${o.value}`,
|
|
2654
|
+
label: o.label,
|
|
2655
|
+
checked: o.value === current,
|
|
2656
|
+
disabled: off || o.disabled === true,
|
|
2657
|
+
run: () => onChange(path, write(o.value))
|
|
2658
|
+
})),
|
|
2659
|
+
sep(`${key}/>`)
|
|
2660
|
+
];
|
|
2661
|
+
}
|
|
2662
|
+
function numberRows(ctx, given, key, path, off) {
|
|
2663
|
+
const { values, onChange } = ctx.src;
|
|
2664
|
+
if (!values || !onChange) return [];
|
|
2665
|
+
const leaf = prefNumberAt(given, values);
|
|
2666
|
+
const unit = leaf.unit && resolvePrefUnit(leaf.unit);
|
|
2667
|
+
const stored = values(path);
|
|
2668
|
+
const { min, max, step, endless } = prefDisplayBounds(leaf);
|
|
2669
|
+
const disabled = off || leaf.readout === true;
|
|
2670
|
+
return [{
|
|
2671
|
+
kind: "number",
|
|
2672
|
+
key,
|
|
2673
|
+
label: leaf.name,
|
|
2674
|
+
...withAccess(leaf.access),
|
|
2675
|
+
...leaf.icon ? { icon: leaf.icon } : {},
|
|
2676
|
+
...disabled ? { disabled } : {},
|
|
2677
|
+
value: typeof stored === "number" && (Number.isFinite(stored) || endlessAllows(leaf.endless, stored)) ? unit ? unit.toDisplay(stored) : stored : void 0,
|
|
2678
|
+
...min === void 0 ? {} : { min },
|
|
2679
|
+
...max === void 0 ? {} : { max },
|
|
2680
|
+
step,
|
|
2681
|
+
...unit?.suffix === void 0 ? {} : { suffix: unit.suffix },
|
|
2682
|
+
...leaf.display ? { display: leaf.display } : {},
|
|
2683
|
+
...endless ? { endless } : {},
|
|
2684
|
+
...leaf.infinity === void 0 ? {} : { infinity: leaf.infinity },
|
|
2685
|
+
...unit ? { accepts: prefUnitAccepts(unit) } : {},
|
|
2686
|
+
set: (shown) => onChange(path, unit ? unit.fromDisplay(shown) : shown)
|
|
2687
|
+
}];
|
|
2688
|
+
}
|
|
2689
|
+
var textAt = (ctx, path) => {
|
|
2690
|
+
const v = ctx.src.values?.(path);
|
|
2691
|
+
return typeof v === "string" && v !== "" ? v : void 0;
|
|
2692
|
+
};
|
|
2693
|
+
function colorRows(ctx, leaf, key, path, off) {
|
|
2694
|
+
if (!ctx.src.values) return [];
|
|
2695
|
+
return [{ kind: "color", key, label: leaf.name, ...withAccess(leaf.access), ...off ? { disabled: true } : {}, value: textAt(ctx, path) }];
|
|
2696
|
+
}
|
|
2697
|
+
function stringRows(ctx, leaf, key, path, off) {
|
|
2698
|
+
const { values, onChange } = ctx.src;
|
|
2699
|
+
if (!values) return [];
|
|
2700
|
+
if (leaf.readout || !onChange) {
|
|
2701
|
+
return [{ kind: "item", key, label: `${leaf.name}: ${textAt(ctx, path) ?? "\u2014"}`, ...withAccess(leaf.access), disabled: true, run: noop }];
|
|
2702
|
+
}
|
|
2703
|
+
const stored = values(path);
|
|
2704
|
+
return [{
|
|
2705
|
+
kind: "text",
|
|
2706
|
+
key,
|
|
2707
|
+
label: leaf.name,
|
|
2708
|
+
...withAccess(leaf.access),
|
|
2709
|
+
...leaf.icon ? { icon: leaf.icon } : {},
|
|
2710
|
+
...off ? { disabled: true } : {},
|
|
2711
|
+
value: typeof stored === "string" ? stored : void 0,
|
|
2712
|
+
set: (text) => onChange(path, text)
|
|
2713
|
+
}];
|
|
2714
|
+
}
|
|
2715
|
+
function leafRows(ctx, leaf, key, path, off) {
|
|
2716
|
+
switch (leaf.kind) {
|
|
2717
|
+
case "action":
|
|
2718
|
+
return actionRows(ctx, leaf, key, off);
|
|
2719
|
+
case "actions": {
|
|
2720
|
+
const group = leaf.group;
|
|
2721
|
+
return ctx.src.actions().filter((a) => a.group === group).flatMap((a) => actionItems(a).map((it) => itemOf(ctx, it, `${key}/${it.key}`, it.label, off)));
|
|
2722
|
+
}
|
|
2723
|
+
case "boolean":
|
|
2724
|
+
return booleanRows(ctx, leaf, key, path, off);
|
|
2725
|
+
case "enum":
|
|
2726
|
+
return enumRows(ctx, leaf, key, path, off);
|
|
2727
|
+
case "number":
|
|
2728
|
+
return numberRows(ctx, leaf, key, path, off);
|
|
2729
|
+
case "color":
|
|
2730
|
+
return colorRows(ctx, leaf, key, path, off);
|
|
2731
|
+
case "string":
|
|
2732
|
+
return stringRows(ctx, leaf, key, path, off);
|
|
2733
|
+
case "separator":
|
|
2734
|
+
return [sep(key)];
|
|
2735
|
+
case "label":
|
|
2736
|
+
return [{ kind: "item", key, label: leaf.name, ...withAccess(leaf.access), disabled: true, run: noop }];
|
|
2737
|
+
case "alias": {
|
|
2738
|
+
const alias = leaf;
|
|
2739
|
+
const target = prefAliasTarget(alias, (p) => prefLeafAt(ctx.src.over ?? ctx.root, p));
|
|
2740
|
+
return target ? leafRows(ctx, prefAliasedLeaf(alias, target.leaf), key, target.path, off) : [];
|
|
2741
|
+
}
|
|
2742
|
+
default:
|
|
2743
|
+
return [];
|
|
2744
|
+
}
|
|
2745
|
+
}
|
|
2746
|
+
function groupRows(ctx, group, prefix, off) {
|
|
2747
|
+
const out = [];
|
|
2748
|
+
for (const [k, node] of Object.entries(group.children)) {
|
|
2749
|
+
const path = prefix ? `${prefix}.${k}` : k;
|
|
2750
|
+
if (ctx.read && !prefIsShown(node, ctx.read)) continue;
|
|
2751
|
+
const disabled = off || ctx.read !== void 0 && !prefIsEnabled(node, ctx.read);
|
|
2752
|
+
if (isPrefLeaf(node)) {
|
|
2753
|
+
out.push(...leafRows(ctx, node, path, path, disabled));
|
|
2754
|
+
} else if (node.as !== void 0 && SUBMENU_AS.has(node.as)) {
|
|
2755
|
+
const entries = tidy(groupRows(ctx, node, path, disabled));
|
|
2756
|
+
if (entries.length) {
|
|
2757
|
+
out.push({ kind: "submenu", key: path, label: node.name, ...node.icon ? { icon: node.icon } : {}, ...withAccess(node.access), entries });
|
|
2758
|
+
}
|
|
2759
|
+
} else {
|
|
2760
|
+
out.push(sep(`${path}/<`), ...groupRows(ctx, node, path, disabled), sep(`${path}/>`));
|
|
2761
|
+
}
|
|
2762
|
+
}
|
|
2763
|
+
return out;
|
|
2764
|
+
}
|
|
2765
|
+
function tidy(entries) {
|
|
2766
|
+
const out = [];
|
|
2767
|
+
for (const e of entries) {
|
|
2768
|
+
if (e.kind === "separator" && (!out.length || out[out.length - 1].kind === "separator")) continue;
|
|
2769
|
+
out.push(e);
|
|
2770
|
+
}
|
|
2771
|
+
if (out[out.length - 1]?.kind === "separator") out.pop();
|
|
2772
|
+
return out;
|
|
2773
|
+
}
|
|
2774
|
+
function resolveSchemaMenu(schema, src, at, params) {
|
|
2775
|
+
const values = src.values;
|
|
2776
|
+
const ctx = {
|
|
2777
|
+
src,
|
|
2778
|
+
byId: new Map(src.actions().map((a) => [a.id, a])),
|
|
2779
|
+
root: schema,
|
|
2780
|
+
read: values ? (path, from) => from === "item" ? void 0 : values(path) : void 0,
|
|
2781
|
+
at,
|
|
2782
|
+
params
|
|
2783
|
+
};
|
|
2784
|
+
return tidy(groupRows(ctx, schema, "", false));
|
|
2785
|
+
}
|
|
2786
|
+
function resolveMenu(def, src, at, params) {
|
|
2787
|
+
return resolveSchemaMenu(def.menu, src, at, params);
|
|
2788
|
+
}
|
|
2789
|
+
|
|
2790
|
+
// src/menus/menuHost.ts
|
|
2791
|
+
function createMenuHost(src) {
|
|
2792
|
+
const defs = [];
|
|
2793
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
2794
|
+
let open = null;
|
|
2795
|
+
let seq = 0;
|
|
2796
|
+
const emit = () => {
|
|
2797
|
+
for (const fn of listeners) fn();
|
|
2798
|
+
};
|
|
2799
|
+
const close = () => {
|
|
2800
|
+
if (!open) return;
|
|
2801
|
+
open = null;
|
|
2802
|
+
emit();
|
|
2803
|
+
};
|
|
2804
|
+
const resolve = (req) => {
|
|
2805
|
+
const live = mergeMenuDefs(defs, src.activeTool());
|
|
2806
|
+
const def = req.menu !== void 0 ? live.find((d) => d.id === req.menu) : req.hit ? pickMenu(live, req.hit) : void 0;
|
|
2807
|
+
return def ? resolveMenu(def, src, req.world, req.params) : [];
|
|
2808
|
+
};
|
|
2809
|
+
return {
|
|
2810
|
+
define(def, owner = null) {
|
|
2811
|
+
const entry = { def, owner };
|
|
2812
|
+
defs.push(entry);
|
|
2813
|
+
return () => {
|
|
2814
|
+
const i = defs.indexOf(entry);
|
|
2815
|
+
if (i >= 0) defs.splice(i, 1);
|
|
2816
|
+
};
|
|
2817
|
+
},
|
|
2818
|
+
open(req) {
|
|
2819
|
+
const entries = resolve(req);
|
|
2820
|
+
if (!entries.length) {
|
|
2821
|
+
close();
|
|
2822
|
+
return false;
|
|
2823
|
+
}
|
|
2824
|
+
open = {
|
|
2825
|
+
seq: ++seq,
|
|
2826
|
+
entries,
|
|
2827
|
+
client: req.client,
|
|
2828
|
+
world: req.world,
|
|
2829
|
+
...req.under ? { under: req.under } : {},
|
|
2830
|
+
source: req.source ?? "pointer"
|
|
2831
|
+
};
|
|
2832
|
+
emit();
|
|
2833
|
+
return true;
|
|
2834
|
+
},
|
|
2835
|
+
has: (req) => resolve(req).length > 0,
|
|
2836
|
+
close,
|
|
2837
|
+
current: () => open,
|
|
2838
|
+
subscribe(fn) {
|
|
2839
|
+
listeners.add(fn);
|
|
2840
|
+
return () => {
|
|
2841
|
+
listeners.delete(fn);
|
|
2842
|
+
};
|
|
2843
|
+
}
|
|
2844
|
+
};
|
|
2845
|
+
}
|
|
2846
|
+
|
|
2847
|
+
export { ALWAYS, ActionDisabledReason, COARSE_TARGET_SCALE, DEFAULT_ALLOWED_CAPABILITIES, DEFAULT_DEVICE_PROFILE, DepNode, INGEST_STRING_MIMES, LONG_PRESS_HAPTIC_MS, NEVER, PREDICATE_TARGET, ScopeNode, TOOL_OFFHAND_ID, actionBindings, actionCursor, actionItemTitle, actionItems, actionSettingsParams, actionShortcuts, addCarrySurface, admitIngestMime, anyBinding, assembleEntries, buildDepsFromRequires, buildRouteRegistry, buildRuleCtx, buildToolOffhandBindings, carryGestureId, clientToCanvas, clientToCanvasRect, createDepRegistry, createDispatchTrace, createDispatcher, createLongPressStore, createMenuHost, createTraceRing, depNodeOf, describeRule, dlog, dwarn, evaluate, evaluateActive, evaluateEnabled, findConflicts, heldKeySpec, historyKey, isDebugEnabled, isTool, itemTypesFromDataTransfer, itemsFromClipboardData, itemsFromDataTransfer, itemsFromFiles, keySpecShortcut, keysHeld, liveScope, makeToolOffhandAction, matchBest, matchSorted, matchSortedWithBarred, matchesKeyBinding, mergeMenuDefs, multiTouchGestureId, offhandKeyFor, openPointerSession, pickMenu, pointerGestureId, pushOwner, readActionSettings, reportRouteConflicts, resolveDeviceProfile, resolveMenu, resolveParams, resolveSchemaMenu, roleReader, routesForSpec, ruleCanHoldIn, rulesExclusive, scopeBindings, startCarry, targetConsultsAffordance, tuneAction, tunedParams, validateActionDefaultBinding, validateActionId };
|
|
2848
|
+
//# sourceMappingURL=chunk-KLBH7VFF.js.map
|
|
2849
|
+
//# sourceMappingURL=chunk-KLBH7VFF.js.map
|