@jsenv/dom 0.17.3 → 0.17.5

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 +52 -17
  2. package/package.json +1 -1
package/dist/jsenv_dom.js CHANGED
@@ -7029,24 +7029,45 @@ const getScrollport = (scrollBox, scrollContainer) => {
7029
7029
  };
7030
7030
  };
7031
7031
 
7032
- // https://davidwalsh.name/detect-scrollbar-width
7032
+ /**
7033
+ * Returns [verticalScrollbarWidth, horizontalScrollbarHeight] as currently
7034
+ * rendered by `scrollableElement`, in px. Returns zeros when the element has no
7035
+ * classic scrollbar: no overflow, overlay scrollbars, `scrollbar-width: none`,
7036
+ * or a `::-webkit-scrollbar { display: none }` rule.
7037
+ *
7038
+ * The measurement is taken on the element itself (its own border box versus its
7039
+ * own content box) rather than on a probe node appended inside it. A probe
7040
+ * cannot answer this question: `scrollbar-width` and `::-webkit-scrollbar` are
7041
+ * not inherited, so a probe reports the platform default scrollbar size even
7042
+ * when the element renders no scrollbar at all.
7043
+ */
7033
7044
  const measureScrollbar = (scrollableElement) => {
7034
- const hasXScrollbar =
7035
- scrollableElement.scrollHeight > scrollableElement.clientHeight;
7036
- const hasYScrollbar =
7037
- scrollableElement.scrollWidth > scrollableElement.clientWidth;
7038
- if (!hasXScrollbar && !hasYScrollbar) {
7039
- return [0, 0];
7040
- }
7041
- const scrollDiv = document.createElement("div");
7042
- scrollDiv.style.cssText = `position: absolute; width: 100px; height: 100px; overflow: scroll; pointer-events: none; visibility: hidden;`;
7043
- scrollableElement.appendChild(scrollDiv);
7044
- const scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth;
7045
- const scrollbarHeight = scrollDiv.offsetHeight - scrollDiv.clientHeight;
7046
- scrollableElement.removeChild(scrollDiv);
7045
+ if (
7046
+ scrollableElement === document.documentElement ||
7047
+ scrollableElement === document.scrollingElement
7048
+ ) {
7049
+ // documentElement.clientWidth/Height report the viewport minus its
7050
+ // scrollbars, not this element's own box (which `max-width` can shrink), so
7051
+ // the border box to compare against is the window itself.
7052
+ return [
7053
+ snapToPixel(window.innerWidth - document.documentElement.clientWidth),
7054
+ snapToPixel(window.innerHeight - document.documentElement.clientHeight),
7055
+ ];
7056
+ }
7057
+ const { left, right, top, bottom } = getBorderSizes(scrollableElement);
7058
+ const scrollbarWidth =
7059
+ scrollableElement.offsetWidth -
7060
+ scrollableElement.clientWidth -
7061
+ left -
7062
+ right;
7063
+ const scrollbarHeight =
7064
+ scrollableElement.offsetHeight -
7065
+ scrollableElement.clientHeight -
7066
+ top -
7067
+ bottom;
7047
7068
  return [
7048
- hasXScrollbar ? snapToPixel(scrollbarWidth) : 0,
7049
- hasYScrollbar ? snapToPixel(scrollbarHeight) : 0,
7069
+ scrollbarWidth > 0 ? snapToPixel(scrollbarWidth) : 0,
7070
+ scrollbarHeight > 0 ? snapToPixel(scrollbarHeight) : 0,
7050
7071
  ];
7051
7072
  };
7052
7073
 
@@ -8781,7 +8802,7 @@ const createDragGestureController = (options = {}) => {
8781
8802
  };
8782
8803
  dragGestureController.grab = grab;
8783
8804
  const initDragByPointer = (grabEvent, dragOptions, initializer) => {
8784
- if (grabEvent.button !== undefined && grabEvent.button !== 0) {
8805
+ if (!isPrimaryButtonEvent(grabEvent)) {
8785
8806
  return null;
8786
8807
  }
8787
8808
  const target = grabEvent.target;
@@ -8877,12 +8898,22 @@ const createDragGestureController = (options = {}) => {
8877
8898
  dragGestureController.grabViaPointer = grabViaPointer;
8878
8899
  return dragGestureController;
8879
8900
  };
8901
+
8902
+ // Only the primary button drags: a right click (or any secondary button) opens
8903
+ // a context menu, it never grabs anything.
8904
+ const isPrimaryButtonEvent = event => event.button === undefined || event.button === 0;
8880
8905
  const dragAfterThreshold = (grabEvent, dragGestureInitializer, threshold) => {
8906
+ if (!isPrimaryButtonEvent(grabEvent)) {
8907
+ return;
8908
+ }
8881
8909
  const target = grabEvent.target;
8882
8910
  const isDedicatedHandle = target.closest && target.closest("[data-drag-handle]");
8883
8911
  if (isDedicatedHandle) {
8884
8912
  // Element is dedicated to drag — skip the threshold and start immediately.
8885
8913
  const dragGesture = dragGestureInitializer();
8914
+ if (!dragGesture) {
8915
+ return;
8916
+ }
8886
8917
  dragGesture.dragViaPointer(grabEvent);
8887
8918
  return;
8888
8919
  }
@@ -11020,6 +11051,10 @@ const startDragToReorder = (event, {
11020
11051
  if (event.target.closest && event.target.closest("[data-drag-ignore]")) {
11021
11052
  return undefined;
11022
11053
  }
11054
+ // A secondary button (right click and friends) is a context menu, not a grab.
11055
+ if (!isPrimaryButtonEvent(event)) {
11056
+ return undefined;
11057
+ }
11023
11058
  event.preventDefault();
11024
11059
  return dragAfterThreshold(event, () => {
11025
11060
  const cloneWrapper = createDragClone(draggedElement, event);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsenv/dom",
3
- "version": "0.17.3",
3
+ "version": "0.17.5",
4
4
  "type": "module",
5
5
  "description": "DOM utilities for writing frontend code",
6
6
  "repository": {