@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/dev/jsenv_navi.js
CHANGED
|
@@ -17086,7 +17086,91 @@ PSEUDO_CLASSES[":-navi-has-value"] = {
|
|
|
17086
17086
|
},
|
|
17087
17087
|
};
|
|
17088
17088
|
{
|
|
17089
|
-
|
|
17089
|
+
// How long a press stays drawn, at least, from the frame that first painted
|
|
17090
|
+
// it (Android's PRESSED_STATE_DURATION). An ordinary tap lasts 30 to 80ms,
|
|
17091
|
+
// and its pointerup can be handled right after its pointerdown when the main
|
|
17092
|
+
// thread was busy: released at once, a press shows on 0 to 3 frames, which
|
|
17093
|
+
// is no press at all to the eye.
|
|
17094
|
+
const PRESS_SHOWN_AT_LEAST = 64;
|
|
17095
|
+
// element → the press going on there, until the element stops being drawn
|
|
17096
|
+
// pressed. Keyed by the element, not held by its tracker: Box re-runs its
|
|
17097
|
+
// tracking whenever the element's state changes, which is what pressing it
|
|
17098
|
+
// often does (a nav entry becoming current), and the press, finger down or
|
|
17099
|
+
// held on screen, goes on across that re-run.
|
|
17100
|
+
const pressWeakMap = new WeakMap();
|
|
17101
|
+
const startPress = (el) => {
|
|
17102
|
+
const pressBefore = pressWeakMap.get(el);
|
|
17103
|
+
if (pressBefore) {
|
|
17104
|
+
// Released, still held on screen: the new press takes over the drawing.
|
|
17105
|
+
pressBefore.abandon();
|
|
17106
|
+
}
|
|
17107
|
+
// When the frame painting the press began.
|
|
17108
|
+
let shownAt = null;
|
|
17109
|
+
let released = false;
|
|
17110
|
+
let timeout = null;
|
|
17111
|
+
let frame = requestAnimationFrame(() => {
|
|
17112
|
+
frame = null;
|
|
17113
|
+
shownAt = performance.now();
|
|
17114
|
+
if (released) {
|
|
17115
|
+
endOnceShown();
|
|
17116
|
+
}
|
|
17117
|
+
});
|
|
17118
|
+
const end = () => {
|
|
17119
|
+
pressWeakMap.delete(el);
|
|
17120
|
+
// Asked of the element rather than of the tracker that saw the press go
|
|
17121
|
+
// down: that one may have been torn down since.
|
|
17122
|
+
dispatchInternalCustomEvent(el, "navi_pseudo_state_request_check");
|
|
17123
|
+
};
|
|
17124
|
+
const endOnceShown = () => {
|
|
17125
|
+
const remaining = shownAt + PRESS_SHOWN_AT_LEAST - performance.now();
|
|
17126
|
+
if (remaining <= 0) {
|
|
17127
|
+
end();
|
|
17128
|
+
return;
|
|
17129
|
+
}
|
|
17130
|
+
timeout = setTimeout(end, remaining);
|
|
17131
|
+
};
|
|
17132
|
+
const stopListening = () => {
|
|
17133
|
+
document.removeEventListener("pointercancel", onCancel, true);
|
|
17134
|
+
document.removeEventListener("pointerup", onRelease, true);
|
|
17135
|
+
document.removeEventListener("contextmenu", onContextMenu, true);
|
|
17136
|
+
};
|
|
17137
|
+
const onRelease = () => {
|
|
17138
|
+
stopListening();
|
|
17139
|
+
released = true;
|
|
17140
|
+
if (shownAt === null) {
|
|
17141
|
+
// No frame has painted it yet: the first one ends it.
|
|
17142
|
+
return;
|
|
17143
|
+
}
|
|
17144
|
+
endOnceShown();
|
|
17145
|
+
};
|
|
17146
|
+
// Not an activation (a scroll took the touch, a context menu opened): no
|
|
17147
|
+
// press to make seen, it ends at once.
|
|
17148
|
+
const onCancel = () => {
|
|
17149
|
+
stopListening();
|
|
17150
|
+
cancelAnimationFrame(frame);
|
|
17151
|
+
end();
|
|
17152
|
+
};
|
|
17153
|
+
const onContextMenu = (e) => {
|
|
17154
|
+
// On touch devices, a long-press triggers the context menu.
|
|
17155
|
+
// If the context menu is not prevented, it means it will open and the
|
|
17156
|
+
// pointer events (pointerup, lostpointercapture) won't fire normally,
|
|
17157
|
+
// leaving the element stuck in pressed state. We clear it manually.
|
|
17158
|
+
// e.button === -1 means the event was synthesized from a long-press (not a real mouse click).
|
|
17159
|
+
if (e.button === -1 && !e.defaultPrevented) {
|
|
17160
|
+
onCancel();
|
|
17161
|
+
}
|
|
17162
|
+
};
|
|
17163
|
+
document.addEventListener("pointercancel", onCancel, true);
|
|
17164
|
+
document.addEventListener("pointerup", onRelease, true);
|
|
17165
|
+
document.addEventListener("contextmenu", onContextMenu, true);
|
|
17166
|
+
pressWeakMap.set(el, {
|
|
17167
|
+
abandon: () => {
|
|
17168
|
+
stopListening();
|
|
17169
|
+
cancelAnimationFrame(frame);
|
|
17170
|
+
clearTimeout(timeout);
|
|
17171
|
+
},
|
|
17172
|
+
});
|
|
17173
|
+
};
|
|
17090
17174
|
PSEUDO_CLASSES[":-navi-pressed"] = {
|
|
17091
17175
|
attribute: "data-pressed",
|
|
17092
17176
|
setup: (el, callback) => {
|
|
@@ -17113,40 +17197,15 @@ PSEUDO_CLASSES[":-navi-has-value"] = {
|
|
|
17113
17197
|
// only left pointer (mouse left click, touch, pen)
|
|
17114
17198
|
return;
|
|
17115
17199
|
}
|
|
17116
|
-
|
|
17117
|
-
const onRelease = () => {
|
|
17118
|
-
pressedElements.delete(el);
|
|
17119
|
-
document.removeEventListener("pointercancel", onRelease, true);
|
|
17120
|
-
document.removeEventListener("pointerup", onRelease, true);
|
|
17121
|
-
document.removeEventListener("contextmenu", onContextMenu, true);
|
|
17122
|
-
callback();
|
|
17123
|
-
};
|
|
17124
|
-
const onContextMenu = (e) => {
|
|
17125
|
-
// On touch devices, a long-press triggers the context menu.
|
|
17126
|
-
// If the context menu is not prevented, it means it will open and the
|
|
17127
|
-
// pointer events (pointerup, lostpointercapture) won't fire normally,
|
|
17128
|
-
// leaving the element stuck in pressed state. We clear it manually.
|
|
17129
|
-
// e.button === -1 means the event was synthesized from a long-press (not a real mouse click).
|
|
17130
|
-
if (e.button === -1 && !e.defaultPrevented) {
|
|
17131
|
-
pressedElements.delete(el);
|
|
17132
|
-
document.removeEventListener("pointercancel", onRelease, true);
|
|
17133
|
-
document.removeEventListener("pointerup", onRelease, true);
|
|
17134
|
-
document.removeEventListener("contextmenu", onContextMenu, true);
|
|
17135
|
-
callback();
|
|
17136
|
-
}
|
|
17137
|
-
};
|
|
17138
|
-
document.addEventListener("pointercancel", onRelease, true);
|
|
17139
|
-
document.addEventListener("pointerup", onRelease, true);
|
|
17140
|
-
document.addEventListener("contextmenu", onContextMenu, true);
|
|
17200
|
+
startPress(el);
|
|
17141
17201
|
callback();
|
|
17142
17202
|
};
|
|
17143
17203
|
el.addEventListener("pointerdown", onPointerDown);
|
|
17144
17204
|
return () => {
|
|
17145
17205
|
el.removeEventListener("pointerdown", onPointerDown);
|
|
17146
|
-
pressedElements.delete(el);
|
|
17147
17206
|
};
|
|
17148
17207
|
},
|
|
17149
|
-
test: (el) =>
|
|
17208
|
+
test: (el) => pressWeakMap.has(el),
|
|
17150
17209
|
};
|
|
17151
17210
|
}
|
|
17152
17211
|
|
|
@@ -56014,6 +56073,7 @@ const TextAnchor = ({
|
|
|
56014
56073
|
lineLayout
|
|
56015
56074
|
}) => {
|
|
56016
56075
|
import.meta.css = [css$11, "@jsenv/navi/src/text/text_anchor.jsx"];
|
|
56076
|
+
const fontArrival = fontArrivalSignal.value;
|
|
56017
56077
|
const anchorRef = useRef();
|
|
56018
56078
|
// The correction reads the layout, with the other reads of the commit (see
|
|
56019
56079
|
// layout_batch.js) — an anchor per icon, each measured between two writes,
|
|
@@ -56083,7 +56143,7 @@ const TextAnchor = ({
|
|
|
56083
56143
|
};
|
|
56084
56144
|
};
|
|
56085
56145
|
});
|
|
56086
|
-
}, [textAnchor, textKey, textSize, lineLayout?.size, lineLayout?.verticalAlign]);
|
|
56146
|
+
}, [textAnchor, textKey, textSize, lineLayout?.size, lineLayout?.verticalAlign, fontArrival]);
|
|
56087
56147
|
return jsxs(Fragment, {
|
|
56088
56148
|
children: [children, jsx("span", {
|
|
56089
56149
|
ref: anchorRef,
|
|
@@ -56164,6 +56224,23 @@ const computeTopOffset = ({
|
|
|
56164
56224
|
};
|
|
56165
56225
|
const charTopCanvas = document.createElement("canvas");
|
|
56166
56226
|
|
|
56227
|
+
// Bumped each time the document finishes loading fonts. A correction measured
|
|
56228
|
+
// while a web font is still loading is made of the fallback face's line box,
|
|
56229
|
+
// baseline and capitals, and every one of them moves when the font arrives.
|
|
56230
|
+
// One listener for every anchor, held while one is mounted: the anchors re-render
|
|
56231
|
+
// together and their reads join the same layout round.
|
|
56232
|
+
const onFontsLoaded = () => {
|
|
56233
|
+
fontArrivalSignal.value++;
|
|
56234
|
+
};
|
|
56235
|
+
const fontArrivalSignal = /*#__PURE__*/signal(0, {
|
|
56236
|
+
watched: () => {
|
|
56237
|
+
document.fonts.addEventListener("loadingdone", onFontsLoaded);
|
|
56238
|
+
},
|
|
56239
|
+
unwatched: () => {
|
|
56240
|
+
document.fonts.removeEventListener("loadingdone", onFontsLoaded);
|
|
56241
|
+
}
|
|
56242
|
+
});
|
|
56243
|
+
|
|
56167
56244
|
const useInitialTextSelection = (ref, textSelection) => {
|
|
56168
56245
|
const deps = [];
|
|
56169
56246
|
if (Array.isArray(textSelection)) {
|
|
@@ -63162,6 +63239,7 @@ a.navi_button {
|
|
|
63162
63239
|
|
|
63163
63240
|
&[data-pressed] {
|
|
63164
63241
|
& .navi_button_content {
|
|
63242
|
+
transition-duration: 0s;
|
|
63165
63243
|
transform: scale(.9);
|
|
63166
63244
|
}
|
|
63167
63245
|
}
|
|
@@ -85917,7 +85995,7 @@ const css$w = /* css */`@property --list-group-label-height {
|
|
|
85917
85995
|
scroll-margin-top: var(--x-list-scroll-spacing-top);
|
|
85918
85996
|
}
|
|
85919
85997
|
|
|
85920
|
-
|
|
85998
|
+
&:not([data-continued]) .navi_list_item_group_list > .navi_list_item:first-child {
|
|
85921
85999
|
scroll-margin-top: calc(var(--x-list-scroll-spacing-top) + var(--list-group-label-height));
|
|
85922
86000
|
}
|
|
85923
86001
|
|