@jsenv/navi 0.29.308 → 0.29.310

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.
@@ -2837,7 +2837,17 @@ const updateActions = ({
2837
2837
  * - willRunSet: actions that will be run
2838
2838
  * - willPromoteSet: prerun actions that become run-requested
2839
2839
  * - stays*Set: actions that remain in their current state
2840
+ *
2841
+ * A proxy in any of the sets stands for the action it currently targets,
2842
+ * exactly as proxy.run()/rerun()/reset() do: what enters activationWeakSet
2843
+ * is always the target. A proxy kept in there would retarget on its own —
2844
+ * to a never-run child once its params go falsy — and getActivationInfo
2845
+ * would then meet an IDLE member on every later update of the document.
2840
2846
  */
2847
+ prerunSet = resolveActionProxies(prerunSet);
2848
+ runSet = resolveActionProxies(runSet);
2849
+ rerunSet = resolveActionProxies(rerunSet);
2850
+ resetSet = resolveActionProxies(resetSet);
2841
2851
 
2842
2852
  const { runningSet, settledSet } = getActivationInfo();
2843
2853
 
@@ -3162,6 +3172,14 @@ ${lines.join("\n")}`);
3162
3172
  };
3163
3173
  };
3164
3174
 
3175
+ const resolveActionProxies = (actionSet) => {
3176
+ const resolvedSet = new Set();
3177
+ for (const action of actionSet) {
3178
+ resolvedSet.add(action.isProxy ? action.getCurrentAction() : action);
3179
+ }
3180
+ return resolvedSet;
3181
+ };
3182
+
3165
3183
  const NO_PARAMS = { __no_params__: true };
3166
3184
  const mergeActionParams = (currentParams, newParams) => {
3167
3185
  // The order of these two checks is load-bearing. Checking `undefined` first
@@ -10192,6 +10210,42 @@ const readNumberFromDom = (element, attribute, defaultValue) => {
10192
10210
  return value;
10193
10211
  };
10194
10212
 
10213
+ /**
10214
+ * Where a press really landed, for an element reading a gesture out of it.
10215
+ *
10216
+ * A popup is painted OVER the page and stays a DOM descendant of whatever it
10217
+ * was written in — a dialog inside the card that opens it, a callout beside the
10218
+ * button it belongs to. Its pointer events therefore bubble through boxes it
10219
+ * covers, and a box reading a gesture off one of them answers for something
10220
+ * nobody aimed at it: a finger held in a sheet opening the card underneath the
10221
+ * sheet, a card the sheet is drawn from and that the finger cannot even reach.
10222
+ *
10223
+ * The same list, read for the same reason, as the drag sources in @jsenv/dom
10224
+ * (see DRAG_IGNORED_SELECTOR in drag_to.js) and as the selection rule in
10225
+ * interaction_press.js: a layer over the element (`[popover]`, `dialog`), and
10226
+ * something saying its press is its own business (`data-drag-ignore`, which is
10227
+ * what a popup outside the top layer says for itself).
10228
+ */
10229
+
10230
+ const LAYER_OVER_SELECTOR = "[data-drag-ignore],[popover],dialog";
10231
+
10232
+ /**
10233
+ * The nearest word wins: a layer INSIDE the element takes the press away from
10234
+ * it, one AROUND it does not — an element that IS the dialog, or that sits in
10235
+ * one, goes on answering its own presses.
10236
+ *
10237
+ * @param {EventTarget} target Where the event says the press landed.
10238
+ * @param {Element} element The element reading a gesture out of that press.
10239
+ * @returns {boolean}
10240
+ */
10241
+ const isPressOnLayerOver = (target, element) => {
10242
+ if (!target || typeof target.closest !== "function") {
10243
+ return false;
10244
+ }
10245
+ const layer = target.closest(LAYER_OVER_SELECTOR);
10246
+ return Boolean(layer) && !layer.contains(element);
10247
+ };
10248
+
10195
10249
  /**
10196
10250
  * The interactions the browser already has an event for.
10197
10251
  *
@@ -10210,6 +10264,11 @@ const readNumberFromDom = (element, attribute, defaultValue) => {
10210
10264
  * refuses what is already `defaultPrevented`. Cancelling first would therefore
10211
10265
  * make the interaction refuse itself, and no right click could ever get through.
10212
10266
  * So: ask, and only cover the browser's menu once something answered.
10267
+ *
10268
+ * They are read off the element and not off whatever bubbles to it: a popup is
10269
+ * a DOM descendant of what it was opened from, so a right click in a sheet
10270
+ * reaches the card the sheet was drawn from, and answering it there answers a
10271
+ * request nobody made (see isPressOnLayerOver).
10213
10272
  */
10214
10273
 
10215
10274
 
@@ -10226,6 +10285,9 @@ defineInteractionDetector({
10226
10285
  setup: (element, trigger, { types }) => {
10227
10286
  const listeners = types.map((type) => {
10228
10287
  const listener = (nativeEvent) => {
10288
+ if (isPressOnLayerOver(nativeEvent.target, element)) {
10289
+ return;
10290
+ }
10229
10291
  const performed = trigger(type, nativeEvent);
10230
10292
  if (type === "contextmenu" && performed) {
10231
10293
  // Something answered the request, so the browser's own menu would only
@@ -10513,6 +10575,11 @@ defineInteractionDetector({
10513
10575
  if (pointerDownEvent.button !== 0) {
10514
10576
  return;
10515
10577
  }
10578
+ // A press aimed at a layer over this element, merely bubbling through it
10579
+ // — the same layers the stylesheet above hands the selection back to.
10580
+ if (isPressOnLayerOver(pointerDownEvent.target, element)) {
10581
+ return;
10582
+ }
10516
10583
  let swipe = null;
10517
10584
  let press = null;
10518
10585
  // Set below, with the hold; a no-op until then so the swipe can call it.