@jsenv/dom 0.17.32 → 0.17.33
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 +61 -21
- package/package.json +1 -1
package/dist/jsenv_dom.js
CHANGED
|
@@ -15686,7 +15686,7 @@ const visibleRectEffect = (
|
|
|
15686
15686
|
onNaviPositionChange,
|
|
15687
15687
|
);
|
|
15688
15688
|
// Dispatched by applyNewPosition's own notifyPositionTransition
|
|
15689
|
-
// around this ancestor's own
|
|
15689
|
+
// around this ancestor's own placement animation (distinct from
|
|
15690
15690
|
// navi_position_change, fired once with the final target, not per
|
|
15691
15691
|
// frame). The anchor this element is positioned against may live
|
|
15692
15692
|
// inside that ancestor and be moving right now — rather than hiding
|
|
@@ -16008,7 +16008,10 @@ const toContainerAlignedPosition = (value) => {
|
|
|
16008
16008
|
* axis never reads the attribute back itself (`positionAreaFixed` always wins).
|
|
16009
16009
|
*
|
|
16010
16010
|
* @param {HTMLElement} element - The element to position (position: absolute or
|
|
16011
|
-
* fixed — detected from its own computed style, see the scroll offset comment below)
|
|
16011
|
+
* fixed — detected from its own computed style, see the scroll offset comment below),
|
|
16012
|
+
* laid out at its containing block's own origin: the returned `left`/`top` are meant
|
|
16013
|
+
* to be applied as a translate from there, see `applyNewPosition` for the whole
|
|
16014
|
+
* contract and for why the placement may not go through `left`/`top` themselves
|
|
16012
16015
|
* @param {HTMLElement} [anchor] - The anchor element to position against. Omit (or pass
|
|
16013
16016
|
* `null`/`undefined`) when there's no real anchor to dock `element` against a *container*
|
|
16014
16017
|
* instead — see `container` below; in that mode, "top"/"bottom"/"left"/"right" are
|
|
@@ -16206,12 +16209,12 @@ const pickPositionRelativeTo = (
|
|
|
16206
16209
|
const clampLeftBound = availableLeft;
|
|
16207
16210
|
const clampRightBound = availableRight;
|
|
16208
16211
|
// offsetWidth/offsetHeight (layout box), not getBoundingClientRect() (the
|
|
16209
|
-
// painted/transformed box): the element being positioned
|
|
16210
|
-
//
|
|
16211
|
-
//
|
|
16212
|
-
// instant
|
|
16213
|
-
//
|
|
16214
|
-
//
|
|
16212
|
+
// painted/transformed box): the element being positioned is moved by
|
|
16213
|
+
// transforms — its own placement translate (see applyNewPosition), plus
|
|
16214
|
+
// whatever `scale` an entrance animation happens to be playing at that
|
|
16215
|
+
// instant (a popover using animation="scaling"/"expand-*") — so
|
|
16216
|
+
// getBoundingClientRect() answers where it is painted, at its *shrunk*
|
|
16217
|
+
// mid-animation size, instead of the box being measured here.
|
|
16215
16218
|
const elementWidth = element.offsetWidth;
|
|
16216
16219
|
const elementHeight = element.offsetHeight;
|
|
16217
16220
|
const anchorWidth = anchorRight - anchorLeft;
|
|
@@ -16720,11 +16723,32 @@ const notifyPositionTransition = (element, animation) => {
|
|
|
16720
16723
|
};
|
|
16721
16724
|
|
|
16722
16725
|
/**
|
|
16723
|
-
* Applies a `pickPositionRelativeTo` result to `element
|
|
16724
|
-
*
|
|
16725
|
-
*
|
|
16726
|
-
*
|
|
16727
|
-
*
|
|
16726
|
+
* Applies a `pickPositionRelativeTo` result to `element`, as a `translate`.
|
|
16727
|
+
*
|
|
16728
|
+
* The two halves of that contract, which a caller must honor:
|
|
16729
|
+
*
|
|
16730
|
+
* 1. `element` stays laid out at its containing block's own origin — its CSS
|
|
16731
|
+
* must say `left: 0; top: 0` (and leave right/bottom `auto`). The computed
|
|
16732
|
+
* `left`/`top` are then applied as a translate from there, which lands the
|
|
16733
|
+
* box in exactly the same place `left: Npx` would have. The reason to go
|
|
16734
|
+
* through a transform at all is the *measuring*: an out-of-flow box with a
|
|
16735
|
+
* shrink-to-fit width can never be wider than "containing block width -
|
|
16736
|
+
* left", so a box placed with `left` reports a width that depends on where
|
|
16737
|
+
* it currently stands — and `pickPositionRelativeTo` decides which side to
|
|
16738
|
+
* place it on from that very width. Feeding a placement back into the
|
|
16739
|
+
* decision that produced it makes the element alternate sides forever, one
|
|
16740
|
+
* flip per reposition. Laid out at the origin, the measured width only ever
|
|
16741
|
+
* depends on the content and on the size caps below.
|
|
16742
|
+
* 2. The `translate` property belongs to this function alone. An animation on
|
|
16743
|
+
* the same element uses `scale` (which composes: individual transform
|
|
16744
|
+
* properties apply translate, then rotate, then scale, then `transform`, so
|
|
16745
|
+
* a scale never rescales the placement) or `transform` — see popup_css.js,
|
|
16746
|
+
* whose slide entrances translate through `transform` for that reason.
|
|
16747
|
+
*
|
|
16748
|
+
* The translate is set instantly (a scroll-triggered reposition should never
|
|
16749
|
+
* lag its target); when `shouldTransition` is set (a resize-triggered
|
|
16750
|
+
* reposition), the visual move is played out via `element.animate()` instead —
|
|
16751
|
+
* kept independent of Popover/Dialog/Callout's own opacity/scale/display CSS
|
|
16728
16752
|
* transition on the same element, so neither can clobber the other (see
|
|
16729
16753
|
* notifyPositionTransition's own doc for why a dedicated Animation over a
|
|
16730
16754
|
* CSS one). Duration comes from `--popup-position-transition-duration`
|
|
@@ -16796,18 +16820,19 @@ const applyNewPosition = (
|
|
|
16796
16820
|
// A single implicit keyframe turned out not to work here: the WAAPI
|
|
16797
16821
|
// "neutral" start keyframe isn't frozen at `animate()` call time, it's
|
|
16798
16822
|
// resolved from the underlying value when the animation is first
|
|
16799
|
-
// *sampled* (the next frame) — by then `element.style.
|
|
16823
|
+
// *sampled* (the next frame) — by then `element.style.translate` below
|
|
16800
16824
|
// has already been overwritten with the new target, so start === end and
|
|
16801
16825
|
// nothing visibly moves (observed as the dialog just jumping). Reading
|
|
16802
16826
|
// the previous value ourselves, before overwriting it, and passing both
|
|
16803
16827
|
// keyframes explicitly sidesteps that entirely.
|
|
16804
|
-
const
|
|
16805
|
-
const
|
|
16828
|
+
const previousTranslate = parseTranslate(element.style.translate);
|
|
16829
|
+
const previousLeft = previousTranslate ? previousTranslate.x : left;
|
|
16830
|
+
const previousTop = previousTranslate ? previousTranslate.y : top;
|
|
16806
16831
|
if (shouldTransition) {
|
|
16807
16832
|
const animation = element.animate(
|
|
16808
16833
|
[
|
|
16809
|
-
{
|
|
16810
|
-
{
|
|
16834
|
+
{ translate: `${previousLeft}px ${previousTop}px` },
|
|
16835
|
+
{ translate: `${left}px ${top}px` },
|
|
16811
16836
|
],
|
|
16812
16837
|
{
|
|
16813
16838
|
duration: parseTransitionDurationMs(
|
|
@@ -16820,16 +16845,31 @@ const applyNewPosition = (
|
|
|
16820
16845
|
);
|
|
16821
16846
|
notifyPositionTransition(element, animation);
|
|
16822
16847
|
}
|
|
16823
|
-
// The specified
|
|
16848
|
+
// The specified translate is set to its final target right away,
|
|
16824
16849
|
// regardless of `shouldTransition` — the animation above only plays the
|
|
16825
16850
|
// visual move from the old position, it never becomes the actual
|
|
16826
16851
|
// specified style (see notifyPositionTransition's own commitStyles for
|
|
16827
16852
|
// why that matters once it ends).
|
|
16828
|
-
element.style.
|
|
16829
|
-
element.style.top = `${top}px`;
|
|
16853
|
+
element.style.translate = `${left}px ${top}px`;
|
|
16830
16854
|
dispatchCustomEvent(element, "navi_position_change");
|
|
16831
16855
|
};
|
|
16832
16856
|
|
|
16857
|
+
// "42px 100px" as { x, y }. Anything else — unset, "none", a single-value
|
|
16858
|
+
// shorthand — reads as "never placed yet" (null), so a first placement has no
|
|
16859
|
+
// stale point to be animated from.
|
|
16860
|
+
const parseTranslate = (translate) => {
|
|
16861
|
+
if (!translate) {
|
|
16862
|
+
return null;
|
|
16863
|
+
}
|
|
16864
|
+
const [x, y] = translate.split(" ");
|
|
16865
|
+
const xNumber = parseFloat(x);
|
|
16866
|
+
const yNumber = parseFloat(y);
|
|
16867
|
+
if (Number.isNaN(xNumber) || Number.isNaN(yNumber)) {
|
|
16868
|
+
return null;
|
|
16869
|
+
}
|
|
16870
|
+
return { x: xNumber, y: yNumber };
|
|
16871
|
+
};
|
|
16872
|
+
|
|
16833
16873
|
const [publishDebugger, subscribeDebugger] = createPubSub();
|
|
16834
16874
|
|
|
16835
16875
|
const notifyDebuggerStart = () => {
|