@jsenv/dom 0.17.93 → 0.17.95
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.
- package/dist/jsenv_dom.js +109 -48
- package/package.json +1 -1
package/dist/jsenv_dom.js
CHANGED
|
@@ -13253,6 +13253,14 @@ const startDragToTravel = (
|
|
|
13253
13253
|
if (movingAxis && !axesLeft.includes(movingAxis)) {
|
|
13254
13254
|
return null;
|
|
13255
13255
|
}
|
|
13256
|
+
// A link and an image are draggable without anyone asking, and the browser
|
|
13257
|
+
// starts that drag about 3px in, under the threshold below: it cancels the
|
|
13258
|
+
// pointer and keeps the rest of the press, so the travel never forms. Refused
|
|
13259
|
+
// for this press only — one excluded above, or left to a box inside, keeps it.
|
|
13260
|
+
const refuseNativeDrag = (dragStartEvent) => {
|
|
13261
|
+
dragStartEvent.preventDefault();
|
|
13262
|
+
};
|
|
13263
|
+
element.addEventListener("dragstart", refuseNativeDrag);
|
|
13256
13264
|
const startThreshold =
|
|
13257
13265
|
pointerDownEvent.pointerType === "mouse"
|
|
13258
13266
|
? DRAG_START_THRESHOLD
|
|
@@ -13278,6 +13286,7 @@ const startDragToTravel = (
|
|
|
13278
13286
|
clearTimeout(holdTimeout);
|
|
13279
13287
|
document.documentElement.removeAttribute(GESTURE_ATTRIBUTE);
|
|
13280
13288
|
document.documentElement.removeAttribute(WALKING_ATTRIBUTE);
|
|
13289
|
+
element.removeEventListener("dragstart", refuseNativeDrag);
|
|
13281
13290
|
window.removeEventListener("pointerup", onPressOver);
|
|
13282
13291
|
window.removeEventListener("pointercancel", onPressOver);
|
|
13283
13292
|
};
|
|
@@ -14091,10 +14100,11 @@ const findPanZoomSurface = (element) => {
|
|
|
14091
14100
|
* @param {boolean|"kept"} [options.afterHold=false] Whether a FINGER must be held
|
|
14092
14101
|
* still before it pans, the page keeping its scroll until then. For a surface
|
|
14093
14102
|
* standing in something that scrolls; a mouse pans by travelling either way.
|
|
14094
|
-
* `"kept"` asks for the wait once: from the moment
|
|
14095
|
-
* pans on contact, and it asks again only after a pointer
|
|
14096
|
-
* from it. `data-hand-kept` is on the element for as long
|
|
14097
|
-
* that way, a hand touching it or not
|
|
14103
|
+
* `"kept"` asks for the wait once: from the moment a finger has given the
|
|
14104
|
+
* surface the hand it pans on contact, and it asks again only after a pointer
|
|
14105
|
+
* has gone down away from it. `data-hand-kept` is on the element for as long
|
|
14106
|
+
* as it holds the hand that way, a hand touching it or not; a mouse pan never
|
|
14107
|
+
* sets it.
|
|
14098
14108
|
* @param {"auto"|"always"} [options.wheelZoom="auto"] Whether a BARE wheel zooms.
|
|
14099
14109
|
* `"auto"` gives it to whatever scrolls around the surface when there is one,
|
|
14100
14110
|
* and zooms when there is none; `"always"` takes it back, for a surface that
|
|
@@ -14115,8 +14125,8 @@ const installPanZoom = (
|
|
|
14115
14125
|
} = {},
|
|
14116
14126
|
) => {
|
|
14117
14127
|
// Whether a finger still owes the wait. Constant under a plain `afterHold`;
|
|
14118
|
-
// under `"kept"` it is spent the first time the surface
|
|
14119
|
-
// asked for again once the hand has gone elsewhere.
|
|
14128
|
+
// under `"kept"` it is spent the first time a finger gives the surface the hand
|
|
14129
|
+
// and asked for again once the hand has gone elsewhere.
|
|
14120
14130
|
let holdIsOwed = Boolean(afterHold);
|
|
14121
14131
|
const reflectHoldOwed = () => {
|
|
14122
14132
|
// What a touch may do is settled before it lands, so the mode is in the DOM
|
|
@@ -14195,10 +14205,14 @@ const installPanZoom = (
|
|
|
14195
14205
|
|
|
14196
14206
|
const activate = (anchorWhere, event) => {
|
|
14197
14207
|
active = true;
|
|
14198
|
-
if (
|
|
14199
|
-
|
|
14200
|
-
|
|
14201
|
-
|
|
14208
|
+
if (
|
|
14209
|
+
afterHold === "kept" &&
|
|
14210
|
+
[...pointers.values()].some((pointer) => pointer.waitsForHold)
|
|
14211
|
+
) {
|
|
14212
|
+
// Spent by the finger that owed it, whether the hold or a second finger
|
|
14213
|
+
// proved it: the surface is the hand's from here. A mouse never owed the
|
|
14214
|
+
// wait, so it neither spends it nor marks it — and a surface that does not
|
|
14215
|
+
// pan asks no finger to wait, having no pan on contact to keep.
|
|
14202
14216
|
keepTheHand();
|
|
14203
14217
|
}
|
|
14204
14218
|
for (const pointer of pointers.values()) {
|
|
@@ -14379,6 +14393,16 @@ const installPanZoom = (
|
|
|
14379
14393
|
}
|
|
14380
14394
|
};
|
|
14381
14395
|
|
|
14396
|
+
// A link and an image are draggable without anyone asking, and the browser
|
|
14397
|
+
// starts that drag about 3px in, under `threshold`: it cancels the pointer and
|
|
14398
|
+
// keeps the rest of the press, so the pan never forms. Refused only while the
|
|
14399
|
+
// surface reads a press — one yielded to something inside never got here.
|
|
14400
|
+
const refuseNativeDrag = (dragStartEvent) => {
|
|
14401
|
+
if (pointers.size > 0) {
|
|
14402
|
+
dragStartEvent.preventDefault();
|
|
14403
|
+
}
|
|
14404
|
+
};
|
|
14405
|
+
|
|
14382
14406
|
// What the first event of the burst going on settled: a key let go of (or
|
|
14383
14407
|
// pressed) halfway through must not hand a zoom to the page mid-gesture, and
|
|
14384
14408
|
// a burst has no end but a silence.
|
|
@@ -14448,6 +14472,10 @@ const installPanZoom = (
|
|
|
14448
14472
|
element.addEventListener("touchmove", preventTouchScroll, {
|
|
14449
14473
|
passive: false,
|
|
14450
14474
|
});
|
|
14475
|
+
// Without a pan, one pointer is whatever else reads it, its drag included.
|
|
14476
|
+
if (onPan) {
|
|
14477
|
+
element.addEventListener("dragstart", refuseNativeDrag);
|
|
14478
|
+
}
|
|
14451
14479
|
if (onZoom) {
|
|
14452
14480
|
element.addEventListener("wheel", onWheel, { passive: false });
|
|
14453
14481
|
}
|
|
@@ -14459,6 +14487,7 @@ const installPanZoom = (
|
|
|
14459
14487
|
element.removeEventListener("pointerdown", onPointerDown);
|
|
14460
14488
|
element.removeEventListener("lostpointercapture", onLostPointerCapture);
|
|
14461
14489
|
element.removeEventListener("touchmove", preventTouchScroll);
|
|
14490
|
+
element.removeEventListener("dragstart", refuseNativeDrag);
|
|
14462
14491
|
element.removeEventListener("wheel", onWheel);
|
|
14463
14492
|
window.removeEventListener("pointerdown", onPointerDownAway, true);
|
|
14464
14493
|
element.removeAttribute(SURFACE_ATTRIBUTE);
|
|
@@ -16384,62 +16413,94 @@ const areLevel = (a, b) => {
|
|
|
16384
16413
|
|
|
16385
16414
|
/**
|
|
16386
16415
|
* The item the copy is at, and its `side` in the order of the list: "start" for
|
|
16387
|
-
* before it, "end" for after it.
|
|
16388
|
-
*
|
|
16389
|
-
*
|
|
16390
|
-
*
|
|
16391
|
-
* and
|
|
16392
|
-
*
|
|
16393
|
-
*
|
|
16394
|
-
*
|
|
16416
|
+
* before it, "end" for after it.
|
|
16417
|
+
*
|
|
16418
|
+
* Down a list, the item under the copy, read by the copy's leading edge (see
|
|
16419
|
+
* getDropTargetInfo); over no item, above the first one is the start of the
|
|
16420
|
+
* list and below the last one its end.
|
|
16421
|
+
*
|
|
16422
|
+
* Along a row, the copy's middle decides, the way a click puts the caret in a
|
|
16423
|
+
* text: on the nearest line, before the first item whose middle it has not
|
|
16424
|
+
* reached. How high the copy is says which line and nothing more, its size
|
|
16425
|
+
* nothing at all — the leading edge assumes a copy as large as what it passes
|
|
16426
|
+
* over, and items of a row are as wide as their content: read by its edge, one
|
|
16427
|
+
* wider than its neighbour could never be put after it.
|
|
16395
16428
|
*/
|
|
16396
16429
|
const findPlaceInList = (gestureInfo, items, flow) => {
|
|
16397
16430
|
const dragElementRect = gestureInfo.elementImpacted.getBoundingClientRect();
|
|
16431
|
+
if (flow !== "down") {
|
|
16432
|
+
return findPlaceOnNearestLine(dragElementRect, items, flow);
|
|
16433
|
+
}
|
|
16398
16434
|
const dropTargetInfo = getDropTargetInfo(gestureInfo, items);
|
|
16399
16435
|
if (dropTargetInfo) {
|
|
16400
|
-
|
|
16401
|
-
|
|
16402
|
-
|
|
16403
|
-
}
|
|
16404
|
-
const elementRect = element.getBoundingClientRect();
|
|
16405
|
-
const dragMiddle = dragElementRect.left + dragElementRect.width / 2;
|
|
16406
|
-
const elementMiddle = elementRect.left + elementRect.width / 2;
|
|
16407
|
-
const beforeItsMiddle =
|
|
16408
|
-
flow === "right"
|
|
16409
|
-
? dragMiddle < elementMiddle
|
|
16410
|
-
: dragMiddle > elementMiddle;
|
|
16411
|
-
return { element, side: beforeItsMiddle ? "start" : "end" };
|
|
16436
|
+
return {
|
|
16437
|
+
element: dropTargetInfo.element,
|
|
16438
|
+
side: dropTargetInfo.elementSide.y,
|
|
16439
|
+
};
|
|
16412
16440
|
}
|
|
16413
16441
|
const firstItem = items[0];
|
|
16414
16442
|
if (!firstItem) {
|
|
16415
16443
|
return null;
|
|
16416
16444
|
}
|
|
16417
16445
|
const lastItem = items[items.length - 1];
|
|
16418
|
-
|
|
16419
|
-
const lastRect = lastItem.getBoundingClientRect();
|
|
16420
|
-
if (
|
|
16421
|
-
dragElementRect.bottom < firstRect.top ||
|
|
16422
|
-
(flow !== "down" &&
|
|
16423
|
-
areLevel(dragElementRect, firstRect) &&
|
|
16424
|
-
isBeyond(dragElementRect, firstRect, flow === "right" ? "left" : "right"))
|
|
16425
|
-
) {
|
|
16446
|
+
if (dragElementRect.bottom < firstItem.getBoundingClientRect().top) {
|
|
16426
16447
|
return { element: firstItem, side: "start" };
|
|
16427
16448
|
}
|
|
16428
|
-
if (
|
|
16429
|
-
dragElementRect.top > lastRect.bottom ||
|
|
16430
|
-
(flow !== "down" &&
|
|
16431
|
-
areLevel(dragElementRect, lastRect) &&
|
|
16432
|
-
isBeyond(dragElementRect, lastRect, flow))
|
|
16433
|
-
) {
|
|
16449
|
+
if (dragElementRect.top > lastItem.getBoundingClientRect().bottom) {
|
|
16434
16450
|
return { element: lastItem, side: "end" };
|
|
16435
16451
|
}
|
|
16436
16452
|
return null;
|
|
16437
16453
|
};
|
|
16438
16454
|
|
|
16439
|
-
const
|
|
16440
|
-
|
|
16441
|
-
|
|
16442
|
-
|
|
16455
|
+
const findPlaceOnNearestLine = (dragElementRect, items, flow) => {
|
|
16456
|
+
const lines = [];
|
|
16457
|
+
let previousRect;
|
|
16458
|
+
for (const item of items) {
|
|
16459
|
+
const rect = item.getBoundingClientRect();
|
|
16460
|
+
// A box that takes no room stands on no line (see readItemFlow).
|
|
16461
|
+
if (rect.width === 0 && rect.height === 0) {
|
|
16462
|
+
continue;
|
|
16463
|
+
}
|
|
16464
|
+
if (!previousRect || !areLevel(previousRect, rect)) {
|
|
16465
|
+
lines.push({ top: rect.top, bottom: rect.bottom, entries: [] });
|
|
16466
|
+
}
|
|
16467
|
+
const line = lines[lines.length - 1];
|
|
16468
|
+
if (rect.top < line.top) {
|
|
16469
|
+
line.top = rect.top;
|
|
16470
|
+
}
|
|
16471
|
+
if (rect.bottom > line.bottom) {
|
|
16472
|
+
line.bottom = rect.bottom;
|
|
16473
|
+
}
|
|
16474
|
+
line.entries.push({ item, middle: rect.left + rect.width / 2 });
|
|
16475
|
+
previousRect = rect;
|
|
16476
|
+
}
|
|
16477
|
+
const dragMiddleY = dragElementRect.top + dragElementRect.height / 2;
|
|
16478
|
+
let nearestLine;
|
|
16479
|
+
let nearestDistance;
|
|
16480
|
+
for (const line of lines) {
|
|
16481
|
+
const distance =
|
|
16482
|
+
dragMiddleY < line.top
|
|
16483
|
+
? line.top - dragMiddleY
|
|
16484
|
+
: dragMiddleY > line.bottom
|
|
16485
|
+
? dragMiddleY - line.bottom
|
|
16486
|
+
: 0;
|
|
16487
|
+
if (nearestLine === undefined || distance < nearestDistance) {
|
|
16488
|
+
nearestLine = line;
|
|
16489
|
+
nearestDistance = distance;
|
|
16490
|
+
}
|
|
16491
|
+
}
|
|
16492
|
+
if (!nearestLine) {
|
|
16493
|
+
return null;
|
|
16494
|
+
}
|
|
16495
|
+
const dragMiddleX = dragElementRect.left + dragElementRect.width / 2;
|
|
16496
|
+
for (const { item, middle } of nearestLine.entries) {
|
|
16497
|
+
const notReached =
|
|
16498
|
+
flow === "right" ? middle > dragMiddleX : middle < dragMiddleX;
|
|
16499
|
+
if (notReached) {
|
|
16500
|
+
return { element: item, side: "start" };
|
|
16501
|
+
}
|
|
16502
|
+
}
|
|
16503
|
+
return { element: nearestLine.entries.at(-1).item, side: "end" };
|
|
16443
16504
|
};
|
|
16444
16505
|
|
|
16445
16506
|
/**
|