@jsenv/navi 0.29.307 → 0.29.309

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.
@@ -10451,6 +10451,42 @@ const readNumberFromDom = (element, attribute, defaultValue) => {
10451
10451
  return value;
10452
10452
  };
10453
10453
 
10454
+ /**
10455
+ * Where a press really landed, for an element reading a gesture out of it.
10456
+ *
10457
+ * A popup is painted OVER the page and stays a DOM descendant of whatever it
10458
+ * was written in — a dialog inside the card that opens it, a callout beside the
10459
+ * button it belongs to. Its pointer events therefore bubble through boxes it
10460
+ * covers, and a box reading a gesture off one of them answers for something
10461
+ * nobody aimed at it: a finger held in a sheet opening the card underneath the
10462
+ * sheet, a card the sheet is drawn from and that the finger cannot even reach.
10463
+ *
10464
+ * The same list, read for the same reason, as the drag sources in @jsenv/dom
10465
+ * (see DRAG_IGNORED_SELECTOR in drag_to.js) and as the selection rule in
10466
+ * interaction_press.js: a layer over the element (`[popover]`, `dialog`), and
10467
+ * something saying its press is its own business (`data-drag-ignore`, which is
10468
+ * what a popup outside the top layer says for itself).
10469
+ */
10470
+
10471
+ const LAYER_OVER_SELECTOR = "[data-drag-ignore],[popover],dialog";
10472
+
10473
+ /**
10474
+ * The nearest word wins: a layer INSIDE the element takes the press away from
10475
+ * it, one AROUND it does not — an element that IS the dialog, or that sits in
10476
+ * one, goes on answering its own presses.
10477
+ *
10478
+ * @param {EventTarget} target Where the event says the press landed.
10479
+ * @param {Element} element The element reading a gesture out of that press.
10480
+ * @returns {boolean}
10481
+ */
10482
+ const isPressOnLayerOver = (target, element) => {
10483
+ if (!target || typeof target.closest !== "function") {
10484
+ return false;
10485
+ }
10486
+ const layer = target.closest(LAYER_OVER_SELECTOR);
10487
+ return Boolean(layer) && !layer.contains(element);
10488
+ };
10489
+
10454
10490
  /**
10455
10491
  * The interactions the browser already has an event for.
10456
10492
  *
@@ -10469,6 +10505,11 @@ const readNumberFromDom = (element, attribute, defaultValue) => {
10469
10505
  * refuses what is already `defaultPrevented`. Cancelling first would therefore
10470
10506
  * make the interaction refuse itself, and no right click could ever get through.
10471
10507
  * So: ask, and only cover the browser's menu once something answered.
10508
+ *
10509
+ * They are read off the element and not off whatever bubbles to it: a popup is
10510
+ * a DOM descendant of what it was opened from, so a right click in a sheet
10511
+ * reaches the card the sheet was drawn from, and answering it there answers a
10512
+ * request nobody made (see isPressOnLayerOver).
10472
10513
  */
10473
10514
 
10474
10515
 
@@ -10485,6 +10526,9 @@ defineInteractionDetector({
10485
10526
  setup: (element, trigger, { types }) => {
10486
10527
  const listeners = types.map((type) => {
10487
10528
  const listener = (nativeEvent) => {
10529
+ if (isPressOnLayerOver(nativeEvent.target, element)) {
10530
+ return;
10531
+ }
10488
10532
  const performed = trigger(type, nativeEvent);
10489
10533
  if (type === "contextmenu" && performed) {
10490
10534
  // Something answered the request, so the browser's own menu would only
@@ -10777,6 +10821,11 @@ defineInteractionDetector({
10777
10821
  if (pointerDownEvent.button !== 0) {
10778
10822
  return;
10779
10823
  }
10824
+ // A press aimed at a layer over this element, merely bubbling through it
10825
+ // — the same layers the stylesheet above hands the selection back to.
10826
+ if (isPressOnLayerOver(pointerDownEvent.target, element)) {
10827
+ return;
10828
+ }
10780
10829
  let swipe = null;
10781
10830
  let press = null;
10782
10831
  // Set below, with the hold; a no-op until then so the swipe can call it.
@@ -40670,7 +40719,15 @@ const LoadingRectangleSvg = ({
40670
40719
  strokeWidth,
40671
40720
  networkSpeed: networkSpeedForced
40672
40721
  }) => {
40673
- const margin = Math.max(2, Math.min(width, height) * 0.03);
40722
+ // The stroke is centered on the path, so half of it falls outside: drawing
40723
+ // at half the stroke width puts its outer edge exactly on the box, whatever
40724
+ // the box. It used to be a share of the smaller dimension (3%, floored at
40725
+ // 2px), which held the line further and further inside as the box grew — a
40726
+ // caller placing the outline with `inset` got the distance it asked for on a
40727
+ // field and something several pixels inward on a card. Nothing needs the
40728
+ // extra room: the svg is `overflow: visible` and whoever positions the
40729
+ // wrapper already reserves the half stroke.
40730
+ const margin = strokeWidth / 2;
40674
40731
 
40675
40732
  // Calculate the drawable area
40676
40733
  const drawableWidth = width - margin * 2;