@jsenv/dom 0.17.22 → 0.17.23

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.
Files changed (2) hide show
  1. package/dist/jsenv_dom.js +58 -22
  2. package/package.json +1 -1
package/dist/jsenv_dom.js CHANGED
@@ -4295,41 +4295,77 @@ const createPreviousNodeIterator = (fromNode, rootNode, skipRoot = null) => {
4295
4295
  * link or a button that click means "follow me", which is not what the hand
4296
4296
  * asked for: the press was already answered, by the gesture.
4297
4297
  *
4298
- * So it is swallowed, once, in capture on the document before any handler an
4299
- * element may have, and without anyone having to know which element that is.
4298
+ * So it is swallowed, once, before any other listener sees it. Being first is
4299
+ * earned twice, because both orderings matter:
4300
+ *
4301
+ * - on `window`, the first target of the capture phase — a listener anywhere
4302
+ * lower (document included) comes after, no matter when it was registered.
4303
+ * - registered at module load — among listeners on the same target and phase,
4304
+ * registration order decides. A listener added when the gesture ends would
4305
+ * lose to any window-capture listener registered at startup (@jsenv/navi's
4306
+ * link interception is one), so the listener is permanent and merely armed
4307
+ * by each gesture.
4308
+ *
4309
+ * A window-capture listener that this module's evaluation cannot be proven to
4310
+ * precede must not bet on that order: it checks `clickIsSuppressed()` and
4311
+ * stands aside on its own.
4300
4312
  */
4301
4313
 
4314
+ let suppressing = false;
4315
+ let disarmAtNextPress = false;
4316
+
4317
+ const suppressClick = (clickEvent) => {
4318
+ if (!suppressing) {
4319
+ return;
4320
+ }
4321
+ suppressing = false;
4322
+ disarmAtNextPress = false;
4323
+ clickEvent.preventDefault();
4324
+ clickEvent.stopImmediatePropagation();
4325
+ };
4326
+ const onPointerDown = () => {
4327
+ if (disarmAtNextPress) {
4328
+ suppressing = false;
4329
+ disarmAtNextPress = false;
4330
+ }
4331
+ };
4332
+ window.addEventListener("click", suppressClick, { capture: true });
4333
+ window.addEventListener("pointerdown", onPointerDown, { capture: true });
4334
+
4302
4335
  /**
4303
4336
  * Swallows the next click, for a gesture that has just answered the press.
4304
4337
  *
4305
- * @returns {() => void} the gesture is over. The suppressor cannot be taken
4306
- * down with it — the click is dispatched AFTER the pointerup that ends the
4338
+ * @returns {() => void} the gesture is over. The suppression cannot be lifted
4339
+ * with it — the click is dispatched AFTER the pointerup that ends the
4307
4340
  * gesture, so it would be gone one event too early, and the drag would end on
4308
- * the link it started from being followed. It goes once it has swallowed a
4341
+ * the link it started from being followed. It lifts once it has swallowed a
4309
4342
  * click, or at the next press if the gesture produced none: a click is always
4310
- * preceded by a press, so a suppressor that outlives one press can never
4343
+ * preceded by a press, so a suppression that outlives one press can never
4311
4344
  * reach the click of another.
4312
4345
  */
4313
4346
  const suppressClickAfterGesture = () => {
4314
- const suppressClick = (clickEvent) => {
4315
- clickEvent.stopPropagation();
4316
- clickEvent.preventDefault();
4317
- stopSuppressing();
4318
- };
4319
- const stopSuppressing = () => {
4320
- document.removeEventListener("click", suppressClick, { capture: true });
4321
- document.removeEventListener("pointerdown", stopSuppressing, {
4322
- capture: true,
4323
- });
4324
- };
4325
- document.addEventListener("click", suppressClick, { capture: true });
4347
+ suppressing = true;
4348
+ disarmAtNextPress = false;
4326
4349
  return () => {
4327
- document.addEventListener("pointerdown", stopSuppressing, {
4328
- capture: true,
4329
- });
4350
+ disarmAtNextPress = true;
4330
4351
  };
4331
4352
  };
4332
4353
 
4354
+ /**
4355
+ * Whether the click being dispatched is one a gesture left behind — armed by
4356
+ * `suppressClickAfterGesture`, waiting to be swallowed by this module.
4357
+ *
4358
+ * A last resort, not a convenience. The suppressor already swallows the click
4359
+ * before anyone else sees it; the one listener that legitimately needs to ask
4360
+ * is a `click` listener in capture on `window` whose registration cannot be
4361
+ * proven to come after this module's evaluation — that one may run before the
4362
+ * suppressor and must stand aside on its own. Everywhere else (an element,
4363
+ * `document`, the bubble phase) the click never arrives and checking this is
4364
+ * dead code. Reach for it only when you are sure that is your situation and
4365
+ * no other ordering is available.
4366
+ */
4367
+ const clickIsSuppressed = () => suppressing;
4368
+
4333
4369
  /**
4334
4370
  * A press that says something by NOT moving.
4335
4371
  *
@@ -19623,4 +19659,4 @@ const useResizeStatus = (elementRef, { as = "number" } = {}) => {
19623
19659
  };
19624
19660
  };
19625
19661
 
19626
- export { EASING, ELEMENT_SIZE_CHANGE, activeElementSignal, addActiveElementEffect, addAttributeEffect, allowWheelThrough, appendStyles, applyNewPosition, canScroll, captureScrollState, chainEvent, claimWheelGesture, closestOpenableAncestor, contrastColor, createBackgroundColorTransition, createBackgroundTransition, createBorderRadiusTransition, createBorderTransition, createDragGestureController, createDragToMoveGestureController, createEventGroupLogger, createGroupTransitionController, createHeightTransition, createIterableWeakSet, createOpacityTransition, createPubSub, createStyleController, createTimelineTransition, createTransition, createTranslateXTransition, createValueEffect, createWidthTransition, cubicBezier, dispatchCustomEvent, dispatchInternalCustomEvent, dispatchPublicCustomEvent, dragAfterIntent, elementIsFocusable, elementIsVisibleForFocus, elementIsVisuallyVisible, findAfter, findAncestor, findBefore, findDescendant, findEvent, findFocusDelegateTarget, findFocusable, findSelfOrAncestorFixedPosition, formatEventSideEffect, getAncestorOpenType, getAvailableHeight, getAvailableWidth, getBackground, getBackgroundColor, getBorder, getBorderRadius, getBorderSizes, getContrastRatio, getDefaultStyles, getDragCoordinates, getDropTargetInfo, getElementSignature, getFirstVisuallyVisibleAncestor, getFocusVisibilityInfo, getHeight, getHeightWithoutTransition, getInnerHeight, getInnerWidth, getKeyboardEventDefaultAction, getLuminance, getMarginSizes, getMaxHeight, getMaxWidth, getMinHeight, getMinWidth, getOpacity, getOpacityWithoutTransition, getPaddingSizes, getPositionedParent, getPositioningScrollOffset, getPreferedColorScheme, getScrollBox, getScrollContainer, getScrollContainerSet, getScrollRelativeRect, getSelfAndAncestorScrolls, getStyle, getTranslateX, getTranslateXWithoutTransition, getTranslateY, getVirtualKeyboardOverlayHeight, getVisuallyVisibleInfo, getWidth, getWidthWithoutTransition, hasCSSSizeUnit, initFlexDetailsSet, initFocusGroup, initPositionSticky, isAncestorOpen, isPrimaryButtonEvent, isSameColor, isScrollable, markDragSource, measureLongestVisualLineWidth, measureScrollbar, measureWidestChildRow, mergeOneStyle, mergeTwoStyles, normalizeKeyboardKey, normalizeStyle, normalizeStyles, observeAncestorOpenState, onAncestorReopen, parsePositionArea, parseStyle, performTabNavigation, pickPositionRelativeTo, prefersDarkColors, prefersLightColors, preventFocusNav, preventFocusNavViaKeyboard, preventIntermediateScrollbar, releaseWheelGesture, resolveCSSColor, resolveCSSSize, resolveColorLuminance, resolveOklchLightness, scrollIntoViewScoped, scrollIntoViewWithStickyAwareness, scrollRoomTowards, setAttribute, setAttributes, setStyles, setVirtualKeyboardOverlaysContent, snapToPixel, startDragTo, startDragToResizeGesture, startDragToTravel, stickyAsRelativeCoords, stringifyStyle, subscribeVirtualKeyboardGeometryChange, subscribeVisualViewportResizeSettled, subscribeWindowResizeSettled, suppressClickAfterGesture, trapFocusInside, trapScrollInside, useActiveElement, useAvailableHeight, useAvailableWidth, useMaxHeight, useMaxWidth, useResizeStatus, visibleRectEffect, waitForPressHeld, watchWheelTravel, wheelGestureIsTakenFrom };
19662
+ export { EASING, ELEMENT_SIZE_CHANGE, activeElementSignal, addActiveElementEffect, addAttributeEffect, allowWheelThrough, appendStyles, applyNewPosition, canScroll, captureScrollState, chainEvent, claimWheelGesture, clickIsSuppressed, closestOpenableAncestor, contrastColor, createBackgroundColorTransition, createBackgroundTransition, createBorderRadiusTransition, createBorderTransition, createDragGestureController, createDragToMoveGestureController, createEventGroupLogger, createGroupTransitionController, createHeightTransition, createIterableWeakSet, createOpacityTransition, createPubSub, createStyleController, createTimelineTransition, createTransition, createTranslateXTransition, createValueEffect, createWidthTransition, cubicBezier, dispatchCustomEvent, dispatchInternalCustomEvent, dispatchPublicCustomEvent, dragAfterIntent, elementIsFocusable, elementIsVisibleForFocus, elementIsVisuallyVisible, findAfter, findAncestor, findBefore, findDescendant, findEvent, findFocusDelegateTarget, findFocusable, findSelfOrAncestorFixedPosition, formatEventSideEffect, getAncestorOpenType, getAvailableHeight, getAvailableWidth, getBackground, getBackgroundColor, getBorder, getBorderRadius, getBorderSizes, getContrastRatio, getDefaultStyles, getDragCoordinates, getDropTargetInfo, getElementSignature, getFirstVisuallyVisibleAncestor, getFocusVisibilityInfo, getHeight, getHeightWithoutTransition, getInnerHeight, getInnerWidth, getKeyboardEventDefaultAction, getLuminance, getMarginSizes, getMaxHeight, getMaxWidth, getMinHeight, getMinWidth, getOpacity, getOpacityWithoutTransition, getPaddingSizes, getPositionedParent, getPositioningScrollOffset, getPreferedColorScheme, getScrollBox, getScrollContainer, getScrollContainerSet, getScrollRelativeRect, getSelfAndAncestorScrolls, getStyle, getTranslateX, getTranslateXWithoutTransition, getTranslateY, getVirtualKeyboardOverlayHeight, getVisuallyVisibleInfo, getWidth, getWidthWithoutTransition, hasCSSSizeUnit, initFlexDetailsSet, initFocusGroup, initPositionSticky, isAncestorOpen, isPrimaryButtonEvent, isSameColor, isScrollable, markDragSource, measureLongestVisualLineWidth, measureScrollbar, measureWidestChildRow, mergeOneStyle, mergeTwoStyles, normalizeKeyboardKey, normalizeStyle, normalizeStyles, observeAncestorOpenState, onAncestorReopen, parsePositionArea, parseStyle, performTabNavigation, pickPositionRelativeTo, prefersDarkColors, prefersLightColors, preventFocusNav, preventFocusNavViaKeyboard, preventIntermediateScrollbar, releaseWheelGesture, resolveCSSColor, resolveCSSSize, resolveColorLuminance, resolveOklchLightness, scrollIntoViewScoped, scrollIntoViewWithStickyAwareness, scrollRoomTowards, setAttribute, setAttributes, setStyles, setVirtualKeyboardOverlaysContent, snapToPixel, startDragTo, startDragToResizeGesture, startDragToTravel, stickyAsRelativeCoords, stringifyStyle, subscribeVirtualKeyboardGeometryChange, subscribeVisualViewportResizeSettled, subscribeWindowResizeSettled, suppressClickAfterGesture, trapFocusInside, trapScrollInside, useActiveElement, useAvailableHeight, useAvailableWidth, useMaxHeight, useMaxWidth, useResizeStatus, visibleRectEffect, waitForPressHeld, watchWheelTravel, wheelGestureIsTakenFrom };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsenv/dom",
3
- "version": "0.17.22",
3
+ "version": "0.17.23",
4
4
  "type": "module",
5
5
  "description": "DOM utilities for writing frontend code",
6
6
  "repository": {