@jsenv/dom 0.17.14 → 0.17.16

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 +100 -6
  2. package/package.json +1 -1
package/dist/jsenv_dom.js CHANGED
@@ -8951,6 +8951,26 @@ installImportMetaCssBuild(import.meta);/**
8951
8951
  *
8952
8952
  * Whichever trigger fired, it has established the intent: the gesture then
8953
8953
  * starts at the first pixel, without a second threshold to cross.
8954
+ *
8955
+ * WHEN A FINGER MAY TRAVEL TOO: [data-drag-on-contact].
8956
+ *
8957
+ * The wait a finger is asked for is not a rule about fingers, it is the answer to
8958
+ * an ambiguity — travel means scroll as much as it means drag, so the two have to
8959
+ * be told apart. Where nothing scrolls the ambiguity does not exist, and the wait
8960
+ * is asking the hand to prove something nothing else could have meant: inside a
8961
+ * dialog that holds the page still, a finger travelling on a piece can only be
8962
+ * carrying it.
8963
+ *
8964
+ * So the attribute says that place, not that element — put on the dialog, every
8965
+ * source inside it reads by distance like a mouse does, at the same few pixels.
8966
+ * A tap is left alone by that: a press that goes nowhere is still a press, which
8967
+ * is what a piece that is also a link or a card needs.
8968
+ *
8969
+ * It is opt-in and cannot be anything else. Nothing here can see whether the
8970
+ * surroundings scroll — a page scrolls by default, an overflow is one CSS
8971
+ * property away, and getting it wrong the wrong way means the list runs away
8972
+ * under the finger that meant to reorder it. Only the application knows it has
8973
+ * taken the scroll away.
8954
8974
  */
8955
8975
 
8956
8976
  /* At module scope, and on the markers rather than on the pressed element: both
@@ -8993,6 +9013,13 @@ const css$4 = /* css */`
8993
9013
  knows which way what surrounds the source scrolls. */
8994
9014
  touch-action: pan-x pinch-zoom;
8995
9015
  }
9016
+ [data-drag-on-contact] [data-drag-source],
9017
+ [data-drag-source][data-drag-on-contact] {
9018
+ /* Nothing scrolls here, so there is no pan to leave to anyone — the finger
9019
+ may travel from the first pixel. Zoom is kept: it belongs to the reader,
9020
+ not to the gesture, and two fingers are never a drag. */
9021
+ touch-action: pinch-zoom;
9022
+ }
8996
9023
  [data-drag-ignore] {
8997
9024
  -webkit-touch-callout: default;
8998
9025
  touch-action: auto;
@@ -9060,6 +9087,8 @@ const markDragSource = (element, axes) => {
9060
9087
  * distance-based.
9061
9088
  * @param {boolean|"if-touch"} [options.longPress="if-touch"]
9062
9089
  * Which pointers start a drag by holding still instead of by travelling.
9090
+ * `"if-touch"` excepts what stands inside a `[data-drag-on-contact]`, where
9091
+ * nothing scrolls and a finger resolves by distance like a mouse.
9063
9092
  * @param {number} [options.longPressDelay=400]
9064
9093
  * How long (ms) the pointer must stay down. Kept under the system context-menu
9065
9094
  * delay so the object is picked up before the menu would have opened.
@@ -9091,7 +9120,10 @@ const dragAfterIntent = (grabEvent, dragGestureInitializer, {
9091
9120
  startDragGesture(dragGestureInitializer);
9092
9121
  return;
9093
9122
  }
9094
- const startsOnLongPress = longPress === true || longPress === "if-touch" && grabEvent.pointerType === "touch";
9123
+ const startsOnLongPress = longPress === true || longPress === "if-touch" && grabEvent.pointerType === "touch" &&
9124
+ // The wait tells a scroll from a drag, and here there is no scroll to tell
9125
+ // it from — see [data-drag-on-contact] at the top of this file.
9126
+ !(target.closest && target.closest("[data-drag-on-contact]"));
9095
9127
  if (startsOnLongPress) {
9096
9128
  dragAfterLongPress(grabEvent, dragGestureInitializer, {
9097
9129
  longPressDelay,
@@ -12759,15 +12791,77 @@ import.meta.css = [/* css */`
12759
12791
 
12760
12792
  !important because this is not a preference: a box that travels cannot let
12761
12793
  the page travel with it, and the rule has to win over whatever an
12762
- application says about its own scrollers. */
12763
- [data-drag-travel*="x"],
12764
- [data-drag-travel*="x"] * {
12794
+ application says about its own scrollers.
12795
+
12796
+ Said on the box, where it is a statement about the box and not about what
12797
+ it happens to hold — and read only where a browser asks the box at all:
12798
+ one that CLIPS is asked (it is a scroll container, which is what "asked"
12799
+ means to a browser), one that does not is walked past. A box that travels
12800
+ usually clips, because moving something in and out of a box is what
12801
+ clipping is for. One that does not still travels — what an inner scroller
12802
+ has left over reaches the page there, and the rule below says why that is
12803
+ the lesser of the two prices. An application that knows which of ITS
12804
+ elements scroll can contain those itself, on the element every engine
12805
+ reads; nothing in here can know that from a stylesheet. */
12806
+ [data-drag-travel*="x"] {
12765
12807
  overscroll-behavior-x: contain !important;
12766
12808
  }
12767
- [data-drag-travel*="y"],
12768
- [data-drag-travel*="y"] * {
12809
+ [data-drag-travel*="y"] {
12769
12810
  overscroll-behavior-y: contain !important;
12770
12811
  }
12812
+ /* The scrollers a browser makes on its own, wherever they are inside the box:
12813
+ a textarea and a list of options scroll their own content by nature, and
12814
+ nobody had to say so for them — no stylesheet declared them, so nothing
12815
+ else here can find them, and they would hand what is left of a gesture to
12816
+ the page like any undeclared scroller does.
12817
+
12818
+ Named rather than found, because being native is exactly what makes them
12819
+ nameable. An input is NOT in the list: it is the one form control that has
12820
+ nothing to scroll on the axis anything travels on, and containing it is how
12821
+ a row-wide invisible checkbox becomes a hole under the wheel.
12822
+
12823
+ A textarea with nothing in it, or a list of options short enough to fit, is
12824
+ contained too — a browser cannot be asked "only if it scrolls". On Blink
12825
+ that costs a wheel over an empty textarea, which then moves nothing rather
12826
+ than the list around it; elsewhere the engine already only asks what
12827
+ scrolls. Worth the page not moving behind a travel. */
12828
+ [data-drag-travel*="x"] :is(textarea, select[multiple], select[size]) {
12829
+ overscroll-behavior-x: contain !important;
12830
+ }
12831
+ [data-drag-travel*="y"] :is(textarea, select[multiple], select[size]) {
12832
+ overscroll-behavior-y: contain !important;
12833
+ }
12834
+ /* The same thing said again to everything inside — and only where saying it
12835
+ is what works.
12836
+
12837
+ Two readings of "contain" are out there, and the rule above lands in only
12838
+ one of them. Blink walks EVERY scroll container between the pointer and the
12839
+ page and asks each one whether the gesture may go past it, whether or not
12840
+ it had anything to scroll: the box above is asked, and containing it is the
12841
+ whole answer. Gecko and WebKit ask only the ones that actually scroll: the
12842
+ box is skipped (it travels, it does not scroll), and what is left of a
12843
+ list's gesture reaches the page unless the LIST itself was told — which is
12844
+ what this does, to everything, because which descendant scrolls is not
12845
+ something a stylesheet can know.
12846
+
12847
+ Not said to Blink, where it is not needed and does harm: an element that
12848
+ clips is a scroll container to a browser (a line of text with an ellipsis,
12849
+ a rounded card, an invisible checkbox covering a row), and Blink asking one
12850
+ of those with nothing to scroll gets "no further" for an answer — the wheel
12851
+ stops there and the list right above it never moves. A dead zone under the
12852
+ pointer, wherever something inside the box happens to clip.
12853
+
12854
+ Blink is told apart by a property only it has, rather than by reading a user
12855
+ agent: the split above is between engines, and -webkit-app-region is one of
12856
+ the few things that names one. */
12857
+ @supports not (-webkit-app-region: none) {
12858
+ [data-drag-travel*="x"] * {
12859
+ overscroll-behavior-x: contain !important;
12860
+ }
12861
+ [data-drag-travel*="y"] * {
12862
+ overscroll-behavior-y: contain !important;
12863
+ }
12864
+ }
12771
12865
  `, "@jsenv/dom/src/interaction/drag/drag_to_travel.js"];
12772
12866
 
12773
12867
  // How far a pointer goes before it is a travel rather than a click: below this
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsenv/dom",
3
- "version": "0.17.14",
3
+ "version": "0.17.16",
4
4
  "type": "module",
5
5
  "description": "DOM utilities for writing frontend code",
6
6
  "repository": {