@jsenv/navi 0.30.12 → 0.30.14
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/dev/jsenv_navi.js +108 -30
- package/dist/dev/jsenv_navi.js.map +5 -5
- package/dist/jsenv_navi.js +108 -30
- package/dist/jsenv_navi.js.map +5 -5
- package/package.json +1 -1
package/dist/jsenv_navi.js
CHANGED
|
@@ -16341,7 +16341,91 @@ PSEUDO_CLASSES[":-navi-has-value"] = {
|
|
|
16341
16341
|
},
|
|
16342
16342
|
};
|
|
16343
16343
|
{
|
|
16344
|
-
|
|
16344
|
+
// How long a press stays drawn, at least, from the frame that first painted
|
|
16345
|
+
// it (Android's PRESSED_STATE_DURATION). An ordinary tap lasts 30 to 80ms,
|
|
16346
|
+
// and its pointerup can be handled right after its pointerdown when the main
|
|
16347
|
+
// thread was busy: released at once, a press shows on 0 to 3 frames, which
|
|
16348
|
+
// is no press at all to the eye.
|
|
16349
|
+
const PRESS_SHOWN_AT_LEAST = 64;
|
|
16350
|
+
// element → the press going on there, until the element stops being drawn
|
|
16351
|
+
// pressed. Keyed by the element, not held by its tracker: Box re-runs its
|
|
16352
|
+
// tracking whenever the element's state changes, which is what pressing it
|
|
16353
|
+
// often does (a nav entry becoming current), and the press, finger down or
|
|
16354
|
+
// held on screen, goes on across that re-run.
|
|
16355
|
+
const pressWeakMap = new WeakMap();
|
|
16356
|
+
const startPress = (el) => {
|
|
16357
|
+
const pressBefore = pressWeakMap.get(el);
|
|
16358
|
+
if (pressBefore) {
|
|
16359
|
+
// Released, still held on screen: the new press takes over the drawing.
|
|
16360
|
+
pressBefore.abandon();
|
|
16361
|
+
}
|
|
16362
|
+
// When the frame painting the press began.
|
|
16363
|
+
let shownAt = null;
|
|
16364
|
+
let released = false;
|
|
16365
|
+
let timeout = null;
|
|
16366
|
+
let frame = requestAnimationFrame(() => {
|
|
16367
|
+
frame = null;
|
|
16368
|
+
shownAt = performance.now();
|
|
16369
|
+
if (released) {
|
|
16370
|
+
endOnceShown();
|
|
16371
|
+
}
|
|
16372
|
+
});
|
|
16373
|
+
const end = () => {
|
|
16374
|
+
pressWeakMap.delete(el);
|
|
16375
|
+
// Asked of the element rather than of the tracker that saw the press go
|
|
16376
|
+
// down: that one may have been torn down since.
|
|
16377
|
+
dispatchInternalCustomEvent(el, "navi_pseudo_state_request_check");
|
|
16378
|
+
};
|
|
16379
|
+
const endOnceShown = () => {
|
|
16380
|
+
const remaining = shownAt + PRESS_SHOWN_AT_LEAST - performance.now();
|
|
16381
|
+
if (remaining <= 0) {
|
|
16382
|
+
end();
|
|
16383
|
+
return;
|
|
16384
|
+
}
|
|
16385
|
+
timeout = setTimeout(end, remaining);
|
|
16386
|
+
};
|
|
16387
|
+
const stopListening = () => {
|
|
16388
|
+
document.removeEventListener("pointercancel", onCancel, true);
|
|
16389
|
+
document.removeEventListener("pointerup", onRelease, true);
|
|
16390
|
+
document.removeEventListener("contextmenu", onContextMenu, true);
|
|
16391
|
+
};
|
|
16392
|
+
const onRelease = () => {
|
|
16393
|
+
stopListening();
|
|
16394
|
+
released = true;
|
|
16395
|
+
if (shownAt === null) {
|
|
16396
|
+
// No frame has painted it yet: the first one ends it.
|
|
16397
|
+
return;
|
|
16398
|
+
}
|
|
16399
|
+
endOnceShown();
|
|
16400
|
+
};
|
|
16401
|
+
// Not an activation (a scroll took the touch, a context menu opened): no
|
|
16402
|
+
// press to make seen, it ends at once.
|
|
16403
|
+
const onCancel = () => {
|
|
16404
|
+
stopListening();
|
|
16405
|
+
cancelAnimationFrame(frame);
|
|
16406
|
+
end();
|
|
16407
|
+
};
|
|
16408
|
+
const onContextMenu = (e) => {
|
|
16409
|
+
// On touch devices, a long-press triggers the context menu.
|
|
16410
|
+
// If the context menu is not prevented, it means it will open and the
|
|
16411
|
+
// pointer events (pointerup, lostpointercapture) won't fire normally,
|
|
16412
|
+
// leaving the element stuck in pressed state. We clear it manually.
|
|
16413
|
+
// e.button === -1 means the event was synthesized from a long-press (not a real mouse click).
|
|
16414
|
+
if (e.button === -1 && !e.defaultPrevented) {
|
|
16415
|
+
onCancel();
|
|
16416
|
+
}
|
|
16417
|
+
};
|
|
16418
|
+
document.addEventListener("pointercancel", onCancel, true);
|
|
16419
|
+
document.addEventListener("pointerup", onRelease, true);
|
|
16420
|
+
document.addEventListener("contextmenu", onContextMenu, true);
|
|
16421
|
+
pressWeakMap.set(el, {
|
|
16422
|
+
abandon: () => {
|
|
16423
|
+
stopListening();
|
|
16424
|
+
cancelAnimationFrame(frame);
|
|
16425
|
+
clearTimeout(timeout);
|
|
16426
|
+
},
|
|
16427
|
+
});
|
|
16428
|
+
};
|
|
16345
16429
|
PSEUDO_CLASSES[":-navi-pressed"] = {
|
|
16346
16430
|
attribute: "data-pressed",
|
|
16347
16431
|
setup: (el, callback) => {
|
|
@@ -16368,40 +16452,15 @@ PSEUDO_CLASSES[":-navi-has-value"] = {
|
|
|
16368
16452
|
// only left pointer (mouse left click, touch, pen)
|
|
16369
16453
|
return;
|
|
16370
16454
|
}
|
|
16371
|
-
|
|
16372
|
-
const onRelease = () => {
|
|
16373
|
-
pressedElements.delete(el);
|
|
16374
|
-
document.removeEventListener("pointercancel", onRelease, true);
|
|
16375
|
-
document.removeEventListener("pointerup", onRelease, true);
|
|
16376
|
-
document.removeEventListener("contextmenu", onContextMenu, true);
|
|
16377
|
-
callback();
|
|
16378
|
-
};
|
|
16379
|
-
const onContextMenu = (e) => {
|
|
16380
|
-
// On touch devices, a long-press triggers the context menu.
|
|
16381
|
-
// If the context menu is not prevented, it means it will open and the
|
|
16382
|
-
// pointer events (pointerup, lostpointercapture) won't fire normally,
|
|
16383
|
-
// leaving the element stuck in pressed state. We clear it manually.
|
|
16384
|
-
// e.button === -1 means the event was synthesized from a long-press (not a real mouse click).
|
|
16385
|
-
if (e.button === -1 && !e.defaultPrevented) {
|
|
16386
|
-
pressedElements.delete(el);
|
|
16387
|
-
document.removeEventListener("pointercancel", onRelease, true);
|
|
16388
|
-
document.removeEventListener("pointerup", onRelease, true);
|
|
16389
|
-
document.removeEventListener("contextmenu", onContextMenu, true);
|
|
16390
|
-
callback();
|
|
16391
|
-
}
|
|
16392
|
-
};
|
|
16393
|
-
document.addEventListener("pointercancel", onRelease, true);
|
|
16394
|
-
document.addEventListener("pointerup", onRelease, true);
|
|
16395
|
-
document.addEventListener("contextmenu", onContextMenu, true);
|
|
16455
|
+
startPress(el);
|
|
16396
16456
|
callback();
|
|
16397
16457
|
};
|
|
16398
16458
|
el.addEventListener("pointerdown", onPointerDown);
|
|
16399
16459
|
return () => {
|
|
16400
16460
|
el.removeEventListener("pointerdown", onPointerDown);
|
|
16401
|
-
pressedElements.delete(el);
|
|
16402
16461
|
};
|
|
16403
16462
|
},
|
|
16404
|
-
test: (el) =>
|
|
16463
|
+
test: (el) => pressWeakMap.has(el),
|
|
16405
16464
|
};
|
|
16406
16465
|
}
|
|
16407
16466
|
|
|
@@ -54483,6 +54542,7 @@ const TextAnchor = ({
|
|
|
54483
54542
|
lineLayout
|
|
54484
54543
|
}) => {
|
|
54485
54544
|
import.meta.css = [css$11, "@jsenv/navi/src/text/text_anchor.jsx"];
|
|
54545
|
+
const fontArrival = fontArrivalSignal.value;
|
|
54486
54546
|
const anchorRef = useRef();
|
|
54487
54547
|
// The correction reads the layout, with the other reads of the commit (see
|
|
54488
54548
|
// layout_batch.js) — an anchor per icon, each measured between two writes,
|
|
@@ -54552,7 +54612,7 @@ const TextAnchor = ({
|
|
|
54552
54612
|
};
|
|
54553
54613
|
};
|
|
54554
54614
|
});
|
|
54555
|
-
}, [textAnchor, textKey, textSize, lineLayout?.size, lineLayout?.verticalAlign]);
|
|
54615
|
+
}, [textAnchor, textKey, textSize, lineLayout?.size, lineLayout?.verticalAlign, fontArrival]);
|
|
54556
54616
|
return jsxs(Fragment, {
|
|
54557
54617
|
children: [children, jsx("span", {
|
|
54558
54618
|
ref: anchorRef,
|
|
@@ -54633,6 +54693,23 @@ const computeTopOffset = ({
|
|
|
54633
54693
|
};
|
|
54634
54694
|
const charTopCanvas = document.createElement("canvas");
|
|
54635
54695
|
|
|
54696
|
+
// Bumped each time the document finishes loading fonts. A correction measured
|
|
54697
|
+
// while a web font is still loading is made of the fallback face's line box,
|
|
54698
|
+
// baseline and capitals, and every one of them moves when the font arrives.
|
|
54699
|
+
// One listener for every anchor, held while one is mounted: the anchors re-render
|
|
54700
|
+
// together and their reads join the same layout round.
|
|
54701
|
+
const onFontsLoaded = () => {
|
|
54702
|
+
fontArrivalSignal.value++;
|
|
54703
|
+
};
|
|
54704
|
+
const fontArrivalSignal = /*#__PURE__*/signal(0, {
|
|
54705
|
+
watched: () => {
|
|
54706
|
+
document.fonts.addEventListener("loadingdone", onFontsLoaded);
|
|
54707
|
+
},
|
|
54708
|
+
unwatched: () => {
|
|
54709
|
+
document.fonts.removeEventListener("loadingdone", onFontsLoaded);
|
|
54710
|
+
}
|
|
54711
|
+
});
|
|
54712
|
+
|
|
54636
54713
|
const useInitialTextSelection = (ref, textSelection) => {
|
|
54637
54714
|
const deps = [];
|
|
54638
54715
|
if (Array.isArray(textSelection)) {
|
|
@@ -61615,6 +61692,7 @@ a.navi_button {
|
|
|
61615
61692
|
|
|
61616
61693
|
&[data-pressed] {
|
|
61617
61694
|
& .navi_button_content {
|
|
61695
|
+
transition-duration: 0s;
|
|
61618
61696
|
transform: scale(.9);
|
|
61619
61697
|
}
|
|
61620
61698
|
}
|
|
@@ -84122,7 +84200,7 @@ const css$w = /* css */`@property --list-group-label-height {
|
|
|
84122
84200
|
scroll-margin-top: var(--x-list-scroll-spacing-top);
|
|
84123
84201
|
}
|
|
84124
84202
|
|
|
84125
|
-
|
|
84203
|
+
&:not([data-continued]) .navi_list_item_group_list > .navi_list_item:first-child {
|
|
84126
84204
|
scroll-margin-top: calc(var(--x-list-scroll-spacing-top) + var(--list-group-label-height));
|
|
84127
84205
|
}
|
|
84128
84206
|
|