@neuroplastio/xterm-addon-hotty 0.1.0-next.1 → 0.1.0-next.2
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/README.md +22 -7
- package/dist/hotty-xterm.js +234 -42
- package/dist/hotty-xterm.js.map +2 -2
- package/dist/types/hostcss.d.ts +6 -0
- package/dist/types/surface.d.ts +53 -1
- package/dist/types/touch.d.ts +45 -6
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -171,11 +171,23 @@ runs programs for whoever connects.
|
|
|
171
171
|
lose the capture. The browser clicks the root on a captured release, so
|
|
172
172
|
the drag reports the click itself when it ends where it began. The host
|
|
173
173
|
stylesheet makes the elements that opt in unselectable, important in its
|
|
174
|
-
layer, whatever the document's CSS.
|
|
174
|
+
layer, whatever the document's CSS.
|
|
175
|
+
|
|
176
|
+
A touch drags such an element only where its `touch-action` allows no
|
|
177
|
+
pan along the touch's first move past 8 px (the larger delta; a tie is a
|
|
178
|
+
pan). The value is the element's own, met with its ancestors' up to the
|
|
179
|
+
nearest one that scrolls, both included, as Pointer Events have it; the
|
|
180
|
+
host's own `touch-action` on the root (below) is not the document's. The
|
|
181
|
+
touch then reports `press` and `dragstart` at the cell where it began,
|
|
182
|
+
and drags from there as a mouse does; the lift reports `dragend`, and the
|
|
183
|
+
click where it began. A second finger ends it with `dragend` and no
|
|
184
|
+
target, and nothing more is heard until every finger lifts. A long press,
|
|
185
|
+
or Alt held at the touch, never drags. Any other touch pans as below.
|
|
175
186
|
- **Presses** (SPEC §5.2, §9: `p=1` on `a=place`). Every primary press of a
|
|
176
187
|
mouse or a pen in the window reports `press` on its pointerdown, before
|
|
177
188
|
the drag and the focus it causes; a tap reports it on the mousedown the
|
|
178
|
-
browser makes for it
|
|
189
|
+
browser makes for it, and a touch that drags when it becomes a drag. A
|
|
190
|
+
touch that pans presses nothing. A press on a hyperlink is the terminal's.
|
|
179
191
|
- **Fit** (SPEC §5.2, §9: `f=1` on `a=place`). The program hears `fit`
|
|
180
192
|
with the rows the document needs at the placement's width whenever they
|
|
181
193
|
differ from the rows it heard last, starting from the placement's own;
|
|
@@ -232,8 +244,8 @@ runs programs for whoever connects.
|
|
|
232
244
|
- It shows no scrollbars, and pans nothing on a touch
|
|
233
245
|
(`touch-action: none`). Any scroll offset the browser sets goes back to
|
|
234
246
|
zero, except a text field's own text.
|
|
235
|
-
- A wheel over a surface goes to the terminal, and so does a touch
|
|
236
|
-
as wheel events at the finger. After the finger lifts, the drag keeps
|
|
247
|
+
- A wheel over a surface goes to the terminal, and so does a touch that
|
|
248
|
+
pans, as wheel events at the finger. After the finger lifts, the drag keeps
|
|
237
249
|
going and slows down.
|
|
238
250
|
- Taps and long presses stay the surface's.
|
|
239
251
|
- On the cells, the addon handles touch too (the `touch` option, on by
|
|
@@ -280,9 +292,12 @@ runs programs for whoever connects.
|
|
|
280
292
|
the pointer that can move that way can (the browser scrolls it), else
|
|
281
293
|
on to the terminal, as over the cells, unless `overscroll-behavior`
|
|
282
294
|
stops it. A gesture begun over the cells stays the terminal's when a
|
|
283
|
-
surface comes under the pointer. A touch
|
|
284
|
-
it has a direction: the browser pans the document, or the
|
|
285
|
-
the terminal as before.
|
|
295
|
+
surface comes under the pointer. A touch that pans decides the same way
|
|
296
|
+
once it has a direction: the browser pans the document, or the touch
|
|
297
|
+
goes to the terminal as before. Where the document's `touch-action`
|
|
298
|
+
would stop the browser's pan (a `none` on a box that doesn't drag), the
|
|
299
|
+
addon pans the box itself, so that only a drag element takes a touch
|
|
300
|
+
from scrolling (SPEC §9.1).
|
|
286
301
|
- **Keys.** While the surface has the keyboard, the keys a browser
|
|
287
302
|
scrolls with that the focused element neither uses nor gives the
|
|
288
303
|
program (SPEC §10.2) scroll the innermost box, from the focused
|
package/dist/hotty-xterm.js
CHANGED
|
@@ -67,14 +67,13 @@ function scrollCss(axes, pageScrolls) {
|
|
|
67
67
|
if (!axes) {
|
|
68
68
|
return [
|
|
69
69
|
"@layer hotty-host {",
|
|
70
|
-
`:root { overflow: hidden; touch-action: ${pageScrolls
|
|
70
|
+
`:root { overflow: hidden; touch-action: ${rootTouchAction(axes, pageScrolls)}; }`,
|
|
71
71
|
"* { scrollbar-width: none !important; }",
|
|
72
72
|
"::-webkit-scrollbar { display: none !important; }",
|
|
73
73
|
"}"
|
|
74
74
|
].join("\n");
|
|
75
75
|
}
|
|
76
|
-
const
|
|
77
|
-
const lines = ["@layer hotty-host {", `:root { touch-action: ${pan}; }`];
|
|
76
|
+
const lines = ["@layer hotty-host {", `:root { touch-action: ${rootTouchAction(axes, pageScrolls)}; }`];
|
|
78
77
|
if (axes !== 3) {
|
|
79
78
|
const clipped = axes === 1 ? "overflow-x" : "overflow-y";
|
|
80
79
|
lines.push(`:root, :root:not([${UNCLIPPED}]) [${CLIP}] { ${clipped}: hidden !important; }`);
|
|
@@ -82,6 +81,10 @@ function scrollCss(axes, pageScrolls) {
|
|
|
82
81
|
lines.push("}");
|
|
83
82
|
return lines.join("\n");
|
|
84
83
|
}
|
|
84
|
+
function rootTouchAction(axes, pageScrolls) {
|
|
85
|
+
if (pageScrolls) return "manipulation";
|
|
86
|
+
return axes === 3 ? "pan-x pan-y" : axes === 1 ? "pan-y" : axes === 2 ? "pan-x" : "none";
|
|
87
|
+
}
|
|
85
88
|
function fontStack(family) {
|
|
86
89
|
const f = family.trim();
|
|
87
90
|
if (!f) return "monospace";
|
|
@@ -515,9 +518,27 @@ var Store = class {
|
|
|
515
518
|
|
|
516
519
|
// src/touch.ts
|
|
517
520
|
var DRAG_SLOP = 8;
|
|
521
|
+
var LONG_PRESS_MS = 500;
|
|
518
522
|
var FLING_DECAY = 0.996;
|
|
519
523
|
var REST_MS = 80;
|
|
524
|
+
function touchPans(value) {
|
|
525
|
+
const v = value.trim();
|
|
526
|
+
if (!v || v === "auto" || v === "manipulation") return [true, true];
|
|
527
|
+
const words = v.split(/\s+/);
|
|
528
|
+
return [words.some((w) => /^pan-(x|left|right)$/.test(w)), words.some((w) => /^pan-(y|up|down)$/.test(w))];
|
|
529
|
+
}
|
|
530
|
+
function panBlocked(pans, dx, dy) {
|
|
531
|
+
const ax = Math.abs(dx), ay = Math.abs(dy);
|
|
532
|
+
return ax > ay ? !pans.x : ay > ax ? !pans.y : false;
|
|
533
|
+
}
|
|
520
534
|
var Touch = class {
|
|
535
|
+
touch = null;
|
|
536
|
+
fling = 0;
|
|
537
|
+
off = [];
|
|
538
|
+
win;
|
|
539
|
+
host;
|
|
540
|
+
exclusive;
|
|
541
|
+
engage;
|
|
521
542
|
/**
|
|
522
543
|
* `exclusive`: every touch here is this Touch's (the cells: xterm.js's own
|
|
523
544
|
* touch handling, which listens on the document, never sees it). Otherwise
|
|
@@ -537,19 +558,12 @@ var Touch = class {
|
|
|
537
558
|
};
|
|
538
559
|
on("touchstart", (e) => this.start(e), true);
|
|
539
560
|
on("touchmove", (e) => this.move(e), false);
|
|
540
|
-
on("touchend", (e) => this.end(e),
|
|
561
|
+
on("touchend", (e) => this.end(e), false);
|
|
541
562
|
on("touchcancel", (e) => {
|
|
542
563
|
this.keep(e);
|
|
543
|
-
this.
|
|
564
|
+
this.drop();
|
|
544
565
|
}, true);
|
|
545
566
|
}
|
|
546
|
-
win;
|
|
547
|
-
host;
|
|
548
|
-
exclusive;
|
|
549
|
-
engage;
|
|
550
|
-
touch = null;
|
|
551
|
-
fling = 0;
|
|
552
|
-
off = [];
|
|
553
567
|
dispose() {
|
|
554
568
|
this.stopFling();
|
|
555
569
|
for (const f of this.off) f();
|
|
@@ -557,32 +571,62 @@ var Touch = class {
|
|
|
557
571
|
keep(e) {
|
|
558
572
|
if (this.exclusive) e.stopPropagation();
|
|
559
573
|
}
|
|
574
|
+
/** The touch under way ends without its lift: a drag the host holds
|
|
575
|
+
* hears it. */
|
|
576
|
+
drop() {
|
|
577
|
+
const s = this.touch;
|
|
578
|
+
this.touch = null;
|
|
579
|
+
if (s?.held) this.host.dragCancel?.();
|
|
580
|
+
}
|
|
560
581
|
start(e) {
|
|
561
582
|
this.keep(e);
|
|
562
583
|
this.stopFling();
|
|
563
584
|
const t = e.touches.length === 1 ? e.touches[0] : void 0;
|
|
564
585
|
if (!t || this.engage && !this.engage(e)) {
|
|
565
|
-
this.
|
|
586
|
+
this.drop();
|
|
566
587
|
return;
|
|
567
588
|
}
|
|
568
589
|
const [x, y] = this.host.toPage(t.clientX, t.clientY);
|
|
569
|
-
|
|
590
|
+
const begin = {
|
|
591
|
+
target: e.target,
|
|
592
|
+
x: t.clientX,
|
|
593
|
+
y: t.clientY,
|
|
594
|
+
time: e.timeStamp,
|
|
595
|
+
shiftKey: e.shiftKey,
|
|
596
|
+
ctrlKey: e.ctrlKey,
|
|
597
|
+
altKey: e.altKey,
|
|
598
|
+
metaKey: e.metaKey
|
|
599
|
+
};
|
|
600
|
+
this.touch = { id: t.identifier, x0: x, y0: y, x, y, t: e.timeStamp, t0: e.timeStamp, vx: 0, vy: 0, dragging: false, held: false, begin };
|
|
570
601
|
}
|
|
571
602
|
move(e) {
|
|
572
603
|
this.keep(e);
|
|
573
604
|
const s = this.touch;
|
|
574
605
|
if (!s) return;
|
|
575
606
|
if (e.touches.length !== 1) {
|
|
576
|
-
this.
|
|
607
|
+
this.drop();
|
|
577
608
|
return;
|
|
578
609
|
}
|
|
579
610
|
const t = [...e.changedTouches].find((c) => c.identifier === s.id);
|
|
580
611
|
if (!t) return;
|
|
612
|
+
if (s.held) {
|
|
613
|
+
e.preventDefault();
|
|
614
|
+
this.host.dragMove?.(t.clientX, t.clientY, e);
|
|
615
|
+
return;
|
|
616
|
+
}
|
|
581
617
|
const [x, y] = this.host.toPage(t.clientX, t.clientY);
|
|
582
618
|
if (!s.dragging && Math.hypot(x - s.x0, y - s.y0) < DRAG_SLOP) return;
|
|
583
|
-
if (!s.dragging && this.host.claim
|
|
584
|
-
this.
|
|
585
|
-
|
|
619
|
+
if (!s.dragging && this.host.claim) {
|
|
620
|
+
const claimed = this.host.claim(s.x0 - x, s.y0 - y, e, s.begin);
|
|
621
|
+
if (!claimed) {
|
|
622
|
+
this.touch = null;
|
|
623
|
+
return;
|
|
624
|
+
}
|
|
625
|
+
if (claimed === "drag") {
|
|
626
|
+
s.held = true;
|
|
627
|
+
e.preventDefault();
|
|
628
|
+
return;
|
|
629
|
+
}
|
|
586
630
|
}
|
|
587
631
|
s.dragging = true;
|
|
588
632
|
e.preventDefault();
|
|
@@ -599,13 +643,19 @@ var Touch = class {
|
|
|
599
643
|
end(e) {
|
|
600
644
|
this.keep(e);
|
|
601
645
|
const s = this.touch;
|
|
602
|
-
|
|
646
|
+
const t = s && [...e.changedTouches].find((c) => c.identifier === s.id);
|
|
647
|
+
if (!s || !t) return;
|
|
603
648
|
this.touch = null;
|
|
649
|
+
if (s.held) {
|
|
650
|
+
e.preventDefault();
|
|
651
|
+
this.host.dragEnd?.(t.clientX, t.clientY, e);
|
|
652
|
+
return;
|
|
653
|
+
}
|
|
604
654
|
if (s.dragging) {
|
|
605
655
|
if (e.timeStamp - s.t < REST_MS) this.startFling(-s.vx, -s.vy, s.x, s.y);
|
|
606
656
|
return;
|
|
607
657
|
}
|
|
608
|
-
if (this.host.tap && e.timeStamp - s.t0 <
|
|
658
|
+
if (this.host.tap && e.timeStamp - s.t0 < LONG_PRESS_MS) {
|
|
609
659
|
e.preventDefault();
|
|
610
660
|
this.host.tap(s.x, s.y);
|
|
611
661
|
}
|
|
@@ -1371,8 +1421,13 @@ var Surface = class {
|
|
|
1371
1421
|
/** The axes the document asked to scroll along (`scroll`, SPEC §5.1): 1
|
|
1372
1422
|
* vertically, 2 horizontally, 3 both; 0, nothing scrolls. */
|
|
1373
1423
|
axes = 0;
|
|
1374
|
-
/** Where the touch drag under way goes, once it has a direction
|
|
1424
|
+
/** Where the touch drag under way goes, once it has a direction: "self",
|
|
1425
|
+
* the document, but scrolled by the surface, since the document's
|
|
1426
|
+
* `touch-action` would stop the browser's own pan (SPEC §9.1: it changes
|
|
1427
|
+
* nothing there). */
|
|
1375
1428
|
touchRoute = "terminal";
|
|
1429
|
+
/** The box a touch drag scrolls itself ("self"). */
|
|
1430
|
+
touchBox = null;
|
|
1376
1431
|
/** The box the wheel gesture under way scrolls, if it went to the
|
|
1377
1432
|
* document: the gesture moves no other (`scrollWheel`). */
|
|
1378
1433
|
wheelBox = null;
|
|
@@ -1727,6 +1782,11 @@ var Surface = class {
|
|
|
1727
1782
|
setTimeout(() => this.auxPress = false, 0);
|
|
1728
1783
|
return;
|
|
1729
1784
|
}
|
|
1785
|
+
this.pressAt(e);
|
|
1786
|
+
}
|
|
1787
|
+
/** What a click (SPEC §10.1) at `e`'s target does to the keyboard: a
|
|
1788
|
+
* press of the primary button, a tap, or a touch that becomes a drag. */
|
|
1789
|
+
pressAt(e) {
|
|
1730
1790
|
const el = this.detachedState ? null : focusTargetAt(e, this.hyper);
|
|
1731
1791
|
if (el) {
|
|
1732
1792
|
this.pressed = el;
|
|
@@ -2292,13 +2352,11 @@ var Surface = class {
|
|
|
2292
2352
|
/** The surface's cell under the pointer, from its top left (the frame's
|
|
2293
2353
|
* origin), counting on past its edges. */
|
|
2294
2354
|
cellOf(e) {
|
|
2295
|
-
return
|
|
2355
|
+
return this.cellAt(e.clientX, e.clientY);
|
|
2296
2356
|
}
|
|
2297
2357
|
/** The element under the pointer, if it is in the window (SPEC §5.2). */
|
|
2298
2358
|
elementAt(e, c, r) {
|
|
2299
|
-
|
|
2300
|
-
if (c < w.x || c >= w.x + w.w || r < w.y || r >= w.y + w.h) return null;
|
|
2301
|
-
return this.doc.elementFromPoint(e.clientX, e.clientY);
|
|
2359
|
+
return this.elementAtPoint(e.clientX, e.clientY, c, r);
|
|
2302
2360
|
}
|
|
2303
2361
|
/** A drag's target: the nearest element with an id and `drag` in its
|
|
2304
2362
|
* `data-on`, from `el` outward; "" where there is none. */
|
|
@@ -2309,6 +2367,139 @@ var Surface = class {
|
|
|
2309
2367
|
}
|
|
2310
2368
|
return "";
|
|
2311
2369
|
}
|
|
2370
|
+
// --- Touch drags (SPEC §9.1) ----------------------------------------------
|
|
2371
|
+
/**
|
|
2372
|
+
* Where a touch that has just gone past the slop, scrolling by dx, dy so
|
|
2373
|
+
* far, goes. A drag, where the touched element opts in and the
|
|
2374
|
+
* touch-action that counts for it allows no pan along the touch's first
|
|
2375
|
+
* move (the larger delta; a tie pans). Otherwise a pan, as §5.3 and §9
|
|
2376
|
+
* have it, whatever touch-action says: where the browser would pan the
|
|
2377
|
+
* document but the document's touch-action stops it, the surface scrolls
|
|
2378
|
+
* the box itself.
|
|
2379
|
+
*/
|
|
2380
|
+
claimTouch(dx, dy, e, begin) {
|
|
2381
|
+
const el = begin.target && isElement(begin.target) ? begin.target : null;
|
|
2382
|
+
const pans = this.allowedPans(el);
|
|
2383
|
+
if (panBlocked(pans, dx, dy) && this.touchDragStart(e, begin)) return "drag";
|
|
2384
|
+
if (!this.axes) {
|
|
2385
|
+
this.touchRoute = "terminal";
|
|
2386
|
+
return true;
|
|
2387
|
+
}
|
|
2388
|
+
const to = this.gestureTarget(el, dx, dy);
|
|
2389
|
+
if (typeof to === "string") {
|
|
2390
|
+
this.touchRoute = to;
|
|
2391
|
+
return true;
|
|
2392
|
+
}
|
|
2393
|
+
if (pans.x && pans.y) {
|
|
2394
|
+
this.touchRoute = "doc";
|
|
2395
|
+
return false;
|
|
2396
|
+
}
|
|
2397
|
+
this.touchRoute = "self";
|
|
2398
|
+
this.touchBox = to;
|
|
2399
|
+
return true;
|
|
2400
|
+
}
|
|
2401
|
+
/** Whether the touch-action that counts at `target` allows every pan. */
|
|
2402
|
+
pansFreely(target) {
|
|
2403
|
+
const p = this.allowedPans(target && isElement(target) ? target : null);
|
|
2404
|
+
return p.x && p.y;
|
|
2405
|
+
}
|
|
2406
|
+
/**
|
|
2407
|
+
* The pans the document's touch-action allows a touch on `el`, as Pointer
|
|
2408
|
+
* Events determine them: its own, with its ancestors' up to the nearest
|
|
2409
|
+
* element that scrolls (SPEC §5.3), both included. The root's is the
|
|
2410
|
+
* document's only where it differs from the host's (`rootTouchAction`),
|
|
2411
|
+
* which is there for the browser's own panning.
|
|
2412
|
+
*/
|
|
2413
|
+
allowedPans(el) {
|
|
2414
|
+
let x = true;
|
|
2415
|
+
let y = true;
|
|
2416
|
+
const root = this.doc.documentElement;
|
|
2417
|
+
const host = rootTouchAction(this.axes, this.host.pageScrolls);
|
|
2418
|
+
for (let n = el; n; n = n.parentElement) {
|
|
2419
|
+
const s = n.ownerDocument.defaultView.getComputedStyle(n);
|
|
2420
|
+
const value = n === root && s.touchAction === host ? "auto" : s.touchAction;
|
|
2421
|
+
const [px, py] = touchPans(value);
|
|
2422
|
+
x &&= px;
|
|
2423
|
+
y &&= py;
|
|
2424
|
+
if (n !== root && this.scrolls(s)) break;
|
|
2425
|
+
}
|
|
2426
|
+
return { x, y };
|
|
2427
|
+
}
|
|
2428
|
+
/** Whether an element with this style scrolls (SPEC §5.3): its overflow is
|
|
2429
|
+
* `auto` or `scroll` along an axis the document asked to scroll. */
|
|
2430
|
+
scrolls(s) {
|
|
2431
|
+
return !!(this.axes & 1) && /auto|scroll/.test(s.overflowY) || !!(this.axes & 2) && /auto|scroll/.test(s.overflowX);
|
|
2432
|
+
}
|
|
2433
|
+
/**
|
|
2434
|
+
* A touch becomes a drag (SPEC §9.1), if it can: one that began without
|
|
2435
|
+
* Alt and was not held still past a long press, on an element that opts
|
|
2436
|
+
* in and has an id, in a surface not detached. It presses at this moment
|
|
2437
|
+
* as a mouse does: `press`, then `dragstart`, both for where it began,
|
|
2438
|
+
* then what the press causes; then a `drag` if the finger is by now over
|
|
2439
|
+
* another element.
|
|
2440
|
+
*/
|
|
2441
|
+
touchDragStart(e, begin) {
|
|
2442
|
+
if (this.detachedState || begin.altKey || e.timeStamp - begin.time >= LONG_PRESS_MS) return false;
|
|
2443
|
+
const el = begin.target && isElement(begin.target) ? begin.target : null;
|
|
2444
|
+
let start = null;
|
|
2445
|
+
for (let n = el; n; n = n.parentElement) {
|
|
2446
|
+
if (listens(n, "drag")) {
|
|
2447
|
+
start = n;
|
|
2448
|
+
break;
|
|
2449
|
+
}
|
|
2450
|
+
}
|
|
2451
|
+
const id = start?.getAttribute("id");
|
|
2452
|
+
if (!id) return false;
|
|
2453
|
+
this.cancelDrag();
|
|
2454
|
+
const [c, r] = this.cellAt(begin.x, begin.y);
|
|
2455
|
+
const keys = keysOf(begin);
|
|
2456
|
+
this.reportPress(e);
|
|
2457
|
+
this.drag = { pointer: NaN, start: id, target: id, c, r, keys };
|
|
2458
|
+
this.emit("dragstart", id, { c, r, keys });
|
|
2459
|
+
this.pressAt(e);
|
|
2460
|
+
const t = [...e.changedTouches][0];
|
|
2461
|
+
if (t) this.touchDragMove(t.clientX, t.clientY, e);
|
|
2462
|
+
return true;
|
|
2463
|
+
}
|
|
2464
|
+
/** A touch drag's finger moved to (x, y) of the document: as a pointer's
|
|
2465
|
+
* move (`onDragMove`). */
|
|
2466
|
+
touchDragMove(x, y, e) {
|
|
2467
|
+
const d = this.drag;
|
|
2468
|
+
if (!d) return;
|
|
2469
|
+
const [c, r] = this.cellAt(x, y);
|
|
2470
|
+
const target = this.dragTarget(this.elementAtPoint(x, y, c, r));
|
|
2471
|
+
const keys = keysOf(e);
|
|
2472
|
+
if (target !== d.target || target === "" && (c !== d.c || r !== d.r)) {
|
|
2473
|
+
this.emit("drag", target, { c, r, keys });
|
|
2474
|
+
}
|
|
2475
|
+
Object.assign(d, { target, c, r, keys });
|
|
2476
|
+
}
|
|
2477
|
+
/** A touch drag's finger lifted at (x, y): as a pointer's release
|
|
2478
|
+
* (`onDragUp`), a click where it began. */
|
|
2479
|
+
touchDragEnd(x, y, e) {
|
|
2480
|
+
const d = this.drag;
|
|
2481
|
+
if (!d) return;
|
|
2482
|
+
this.drag = null;
|
|
2483
|
+
const [c, r] = this.cellAt(x, y);
|
|
2484
|
+
const at = this.elementAtPoint(x, y, c, r);
|
|
2485
|
+
const target = this.dragTarget(at);
|
|
2486
|
+
this.emit("dragend", target, { c, r, keys: keysOf(e) });
|
|
2487
|
+
this.dragReleased = true;
|
|
2488
|
+
setTimeout(() => this.dragReleased = false, 0);
|
|
2489
|
+
if (target === d.start && at) this.reportClick(ancestry(at));
|
|
2490
|
+
}
|
|
2491
|
+
/** The surface's cell at (x, y) of the document, counting on past its
|
|
2492
|
+
* edges. */
|
|
2493
|
+
cellAt(x, y) {
|
|
2494
|
+
return [Math.floor(x / this.cellW), Math.floor(y / this.cellH)];
|
|
2495
|
+
}
|
|
2496
|
+
/** The element at (x, y) of the document, if cell (c, r) is in the
|
|
2497
|
+
* window (SPEC §5.2). */
|
|
2498
|
+
elementAtPoint(x, y, c, r) {
|
|
2499
|
+
const w = this.win;
|
|
2500
|
+
if (c < w.x || c >= w.x + w.w || r < w.y || r >= w.y + w.h) return null;
|
|
2501
|
+
return this.doc.elementFromPoint(x, y);
|
|
2502
|
+
}
|
|
2312
2503
|
// --- Presses with Alt (SPEC §9.2) ---------------------------------------
|
|
2313
2504
|
/**
|
|
2314
2505
|
* A press of a mouse's or a pen's primary button with Alt held is the
|
|
@@ -2455,26 +2646,27 @@ var Surface = class {
|
|
|
2455
2646
|
const r = this.frame.getBoundingClientRect();
|
|
2456
2647
|
return [r.left + x, r.top + y];
|
|
2457
2648
|
};
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
{ scroll: (dx, dy) => this.host.scrollPage(dx, dy), toPage },
|
|
2463
|
-
false,
|
|
2464
|
-
(e) => !this.axes && this.inScroller(e.target)
|
|
2465
|
-
);
|
|
2466
|
-
} else {
|
|
2467
|
-
new Touch(d, this.frame.ownerDocument.defaultView, {
|
|
2649
|
+
new Touch(
|
|
2650
|
+
d,
|
|
2651
|
+
this.frame.ownerDocument.defaultView,
|
|
2652
|
+
{
|
|
2468
2653
|
scroll: (dx, dy, x, y) => {
|
|
2469
|
-
if (this.touchRoute === "
|
|
2654
|
+
if (this.touchRoute === "self") this.touchBox?.scrollBy(dx, dy);
|
|
2655
|
+
else if (this.touchRoute !== "terminal") return;
|
|
2656
|
+
else if (this.host.pageScrolls) this.host.scrollPage(dx, dy);
|
|
2657
|
+
else this.host.wheel(new WheelEvent("wheel", { deltaX: dx, deltaY: dy, deltaMode: 0, clientX: x, clientY: y }), x, y);
|
|
2470
2658
|
},
|
|
2471
2659
|
toPage,
|
|
2472
|
-
claim: (dx, dy, e) =>
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
}
|
|
2477
|
-
|
|
2660
|
+
claim: (dx, dy, e, begin) => this.claimTouch(dx, dy, e, begin),
|
|
2661
|
+
dragMove: (x, y, e) => this.touchDragMove(x, y, e),
|
|
2662
|
+
dragEnd: (x, y, e) => this.touchDragEnd(x, y, e),
|
|
2663
|
+
dragCancel: () => this.cancelDrag()
|
|
2664
|
+
},
|
|
2665
|
+
false,
|
|
2666
|
+
// Where the page scrolls, the browser pans it from a touch the
|
|
2667
|
+
// surface leaves alone.
|
|
2668
|
+
this.host.pageScrolls ? (e) => !this.axes && this.inScroller(e.target) || !this.pansFreely(e.target) : void 0
|
|
2669
|
+
);
|
|
2478
2670
|
win.addEventListener("focus", () => {
|
|
2479
2671
|
if (!this.programFocus && !this.auxPress && !this.keyboard) this.settle();
|
|
2480
2672
|
});
|