@jsenv/navi 0.29.466 → 0.29.468

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.
@@ -33406,8 +33406,9 @@ const onDocumentClick = (clickEvent) => {
33406
33406
  // application sees ONE click, on the control it was aimed at, rather than
33407
33407
  // two: this one falling through and the one below.
33408
33408
  clickEvent.stopPropagation();
33409
+ const ClickEventConstructor = clickEvent.constructor;
33409
33410
  pressable.dispatchEvent(
33410
- new clickEvent.constructor(clickEvent.type, clickEvent),
33411
+ new ClickEventConstructor(clickEvent.type, clickEvent),
33411
33412
  );
33412
33413
  return;
33413
33414
  }
@@ -33415,85 +33416,6 @@ const onDocumentClick = (clickEvent) => {
33415
33416
 
33416
33417
  installImportMetaCssBuild(import.meta);
33417
33418
 
33418
- /**
33419
- * The furniture around the pages — the fixed bars, and the popups standing
33420
- * over them in the top layer — photographed with them for the length of a
33421
- * route transition, so that a piece of it belonging to ONE of the two states
33422
- * takes part in the movement instead of appearing or vanishing in a frame.
33423
- *
33424
- * Whether a bar is the frame or part of what changes is a fact about the PAIR
33425
- * of states, never about the bar: the top bar of a list is the frame while one
33426
- * goes into a row of that list, and part of what changes when the next page
33427
- * takes the whole screen. So nothing is declared — a name is written on every
33428
- * bar for the length of the movement, and the browser derives the rest:
33429
- *
33430
- * - a bar the two states SHARE is one element wearing one name on both sides.
33431
- * The browser pairs the two pictures into one group and holds it where it
33432
- * stands: the frame, and the pages move behind it exactly as before.
33433
- * - a bar only one state has never meets a counterpart. It belongs to the page
33434
- * that has it, so it travels with that page — leaving by the keyframes the
33435
- * page being left leaves by, arriving by the ones the page arriving arrives
33436
- * by — instead of going out with the render. Over that page, as it is at
33437
- * rest: the page runs under it, and what it paints outside its box (a button
33438
- * standing up out of a tab bar) is not cut by its own page. Under the pages
33439
- * only when its page is covered by the other one — a cover-* movement — so
33440
- * the sheet comes over it; a popup over everything, standing where it
33441
- * stands in the document (see the z-order in route_transition.jsx). Which
33442
- * side a bar is on is said by a class on its group, written here.
33443
- *
33444
- * A popup shown in the top layer is furniture of the same kind, and its case
33445
- * is the sharper one: it is a DOM descendant of the area, yet painted outside
33446
- * the area's picture, so being captured on its own is the only way it is on
33447
- * screen at all for those few hundred milliseconds (layout/popup_css.js). One
33448
- * the two states share holds where it stands, one only a single state has
33449
- * travels with that state's page — the same two outcomes, derived the same way.
33450
- *
33451
- * Which keyframes those are is published by the movement itself
33452
- * (--navi-route-transition-leave / -enter, see route_transition.jsx): a
33453
- * selector cannot say "the bars that have no counterpart" — the names are per
33454
- * element, so there is nothing static to write — so the rule is written for
33455
- * the length of the movement, over the names this one turned out to have.
33456
- *
33457
- * The name is per ELEMENT and kept for the element's whole life, which is what
33458
- * makes "shared" mean shared: several bars can live on one edge
33459
- * (layout/fixed_bar/fixed_bar_space.js), so a bar leaving and another one
33460
- * arriving on that same edge are two names and two movements, not one bar
33461
- * changing its mind.
33462
- *
33463
- * Worn only while a transition of navi's plays: named the rest of the time, a
33464
- * bar would be captured during every view transition the APPLICATION starts —
33465
- * dead to the pointer and drawn in the top layer for the length of a movement
33466
- * that has nothing to do with it. Being unable to answer a press is the price
33467
- * of being photographed, and a route transition is where it costs nothing:
33468
- * both pages are pictures for those few hundred milliseconds anyway.
33469
- *
33470
- * The WALL of a popup goes the other way round: it is not photographed at
33471
- * all. The top layer is drawn during a transition only as part of the root's
33472
- * picture, which is opted out while an area is marked (route_transition.jsx),
33473
- * and a modal dialog's wall is its ::backdrop — a pseudo-element, which wears
33474
- * no name; a popover's is a real element, but named it would be a picture the
33475
- * size of the screen, sliding across the page arriving. Captured on its own,
33476
- * the popup's box travels; its wall is painted nowhere for the length of the
33477
- * movement, and the page under it leaves undimmed. So the wall is painted
33478
- * INTO the page's picture instead: a stand-in laid over the area before each
33479
- * of the two pictures is taken, painting what the wall paints, and removed
33480
- * with the movement. Carried by the page's picture, it leaves with the page
33481
- * being left and arrives with the page arriving, cut at the page's edge — and
33482
- * under the popup's own picture, which stands over the pages (the z-order in
33483
- * route_transition.jsx). The bars are under the wall as much as the page is,
33484
- * and each is a picture of its own: the same stand-in is laid over every bar
33485
- * outside the area. A bar the two states share is one group with two
33486
- * pictures — dimmed on the side that has a wall — and its cross-fade is the
33487
- * wall fading out as the page leaves, or in as it arrives; a bar only one
33488
- * state has carries the wall with it. What no picture covers — the glass
33489
- * beside a narrowed app, the window below a page shorter than it — shows the
33490
- * live document through, and only the live document can paint a wall there:
33491
- * one fixed stand-in over the window, under the pictures, with a hole cut
33492
- * where each picture stands, its opacity taken from the state being left to
33493
- * the state arriving on the movement's own clock. A popup with layer="local"
33494
- * paints its wall inside the page and needs none of this.
33495
- */
33496
-
33497
33419
  // The browser's top layer: painted above everything the document paints, so
33498
33420
  // outside the area's picture whatever the DOM says.
33499
33421
  const TOP_LAYER_SELECTOR = ":modal, :popover-open";
@@ -33518,6 +33440,11 @@ const FURNITURE_NAME_PREFIX = "navi-transition-furniture-";
33518
33440
  const TOP_LAYER_WALL_SELECTOR =
33519
33441
  ".navi_dialog:modal, .navi_popover_backdrop:popover-open, .navi_popup_group:modal";
33520
33442
  const WALL_ATTRIBUTE = "data-navi-transition-wall";
33443
+ // Worn by a bar dimmed by a filter of navi's; the property holds the whole
33444
+ // chain, the bar's own filter first (see dimBarPicture).
33445
+ const WALL_FILTER_ATTRIBUTE = "data-navi-transition-wall-filter";
33446
+ const WALL_FILTER_PROPERTY = "--navi-transition-wall-filter";
33447
+ const WALL_FILTERS_ATTRIBUTE = "data-navi-transition-wall-filters";
33521
33448
  // Which side of the movement a bar is on, worn by the bar and read by the
33522
33449
  // browser as the class of its group (the CSS below): "leaving" from the first
33523
33450
  // picture, "arriving" for a bar the state arriving brought, "shared" for one
@@ -33573,6 +33500,18 @@ const TRANSITION_FURNITURE_CSS = /* css */ `.navi_fixed_bar[data-navi-transition
33573
33500
  }
33574
33501
  }
33575
33502
 
33503
+ .navi_fixed_bar[data-navi-transition-wall-filter] {
33504
+ filter: var(--navi-transition-wall-filter) !important;
33505
+ }
33506
+
33507
+ [data-navi-transition-wall-filters] {
33508
+ pointer-events: none;
33509
+ width: 0;
33510
+ height: 0;
33511
+ position: fixed;
33512
+ overflow: hidden;
33513
+ }
33514
+
33576
33515
  :root:not(:active-view-transition) [data-navi-transition-wall="rest"] {
33577
33516
  clip-path: var(--wall-holes-arriving, var(--wall-holes));
33578
33517
  }
@@ -33603,9 +33542,13 @@ let namedElements = new Set();
33603
33542
  // The rule giving the one-sided bars their movement, written for one movement
33604
33543
  // and taken down with it.
33605
33544
  let travelStyleElement = null;
33606
- // The stand-ins for the walls open in the top layer, painted for one picture
33607
- // and taken down before the next.
33545
+ // The walls open in the top layer, painted for one picture and taken down
33546
+ // before the next: the area's stand-ins, the bars wearing a filter for them,
33547
+ // and the <svg> holding those filters.
33608
33548
  let wallElements = [];
33549
+ let dimmedBars = [];
33550
+ let wallFilterSvg = null;
33551
+ let wallFilterCount = 0;
33609
33552
  // The stand-ins for what no picture covers, kept for the whole movement, and
33610
33553
  // the opacity they are heading to once it plays.
33611
33554
  let restWallElements = [];
@@ -33800,12 +33743,13 @@ const releaseTransitionFurniture = (owner) => {
33800
33743
  removeRestWalls();
33801
33744
  };
33802
33745
 
33803
- // One stand-in per open wall in every picture, walls in document order: they
33804
- // stack in the top layer, and what dims the document is all of them. A wall
33805
- // open anywhere covers everything the document paints, so the sources are
33806
- // looked for in the whole document — a dialog opened from a bar dims the
33807
- // pages too. A bar inside the area is part of the pages' picture, and the
33808
- // area's stand-in answers for it.
33746
+ // One stand-in per open wall over the pages, and one filter per open wall on
33747
+ // every bar outside them, walls in document order: they stack in the top
33748
+ // layer, and what dims the document is all of them. A wall open anywhere
33749
+ // covers everything the document paints, so the sources are looked for in the
33750
+ // whole document — a dialog opened from a bar dims the pages too. A bar inside
33751
+ // the area is part of the pages' picture, and the area's stand-in answers for
33752
+ // it.
33809
33753
  const paintTransitionWalls = (areaElement) => {
33810
33754
  removeTransitionWalls();
33811
33755
  const sources = Array.from(
@@ -33814,23 +33758,24 @@ const paintTransitionWalls = (areaElement) => {
33814
33758
  if (sources.length === 0) {
33815
33759
  return sources;
33816
33760
  }
33817
- for (const target of pictureTargets(areaElement)) {
33818
- for (const source of sources) {
33819
- const wall = createWall(source);
33820
- target.appendChild(wall);
33821
- // The target is not necessarily a containing block (the area is a plain
33822
- // box), and made one for the movement it would move whatever the page
33823
- // positioned against an ancestor of it: the wall is placed from
33824
- // wherever its containing block turns out to be, by the offset between
33825
- // that box and the target's.
33826
- const targetRect = pictureRect(target);
33827
- const wallRect = wall.getBoundingClientRect();
33828
- wall.style.left = `${targetRect.left - wallRect.left}px`;
33829
- wall.style.top = `${targetRect.top - wallRect.top}px`;
33830
- wall.style.width = `${targetRect.right - targetRect.left}px`;
33831
- wall.style.height = `${targetRect.bottom - targetRect.top}px`;
33832
- wallElements.push(wall);
33833
- }
33761
+ for (const source of sources) {
33762
+ const wall = createWall(source);
33763
+ areaElement.appendChild(wall);
33764
+ // The area is not necessarily a containing block (it is a plain box), and
33765
+ // made one for the movement it would move whatever the page positioned
33766
+ // against an ancestor of it: the wall is placed from wherever its
33767
+ // containing block turns out to be, by the offset between that box and
33768
+ // the area's.
33769
+ const areaRect = areaElement.getBoundingClientRect();
33770
+ const wallRect = wall.getBoundingClientRect();
33771
+ wall.style.left = `${areaRect.left - wallRect.left}px`;
33772
+ wall.style.top = `${areaRect.top - wallRect.top}px`;
33773
+ wall.style.width = `${areaRect.width}px`;
33774
+ wall.style.height = `${areaRect.height}px`;
33775
+ wallElements.push(wall);
33776
+ }
33777
+ for (const bar of barsOutside(areaElement)) {
33778
+ dimBarPicture(bar, sources);
33834
33779
  }
33835
33780
  return sources;
33836
33781
  };
@@ -33840,18 +33785,102 @@ const removeTransitionWalls = () => {
33840
33785
  wall.remove();
33841
33786
  }
33842
33787
  wallElements = [];
33788
+ for (const bar of dimmedBars) {
33789
+ bar.removeAttribute(WALL_FILTER_ATTRIBUTE);
33790
+ bar.style.removeProperty(WALL_FILTER_PROPERTY);
33791
+ }
33792
+ dimmedBars = [];
33793
+ if (wallFilterSvg) {
33794
+ wallFilterSvg.remove();
33795
+ wallFilterSvg = null;
33796
+ }
33843
33797
  };
33844
33798
 
33845
- // What is photographed on its own and gets a stand-in in its picture: the
33799
+ // What is photographed on its own and carries the wall in its picture: the
33846
33800
  // pages, and every bar outside them.
33847
33801
  const pictureTargets = (areaElement) => {
33848
- const targets = [areaElement];
33802
+ return [areaElement, ...barsOutside(areaElement)];
33803
+ };
33804
+
33805
+ const barsOutside = (areaElement) => {
33806
+ const bars = [];
33849
33807
  for (const bar of document.querySelectorAll(FIXED_BAR_SELECTOR$1)) {
33850
33808
  if (!areaElement.contains(bar)) {
33851
- targets.push(bar);
33809
+ bars.push(bar);
33852
33810
  }
33853
33811
  }
33854
- return targets;
33812
+ return bars;
33813
+ };
33814
+
33815
+ // Room around what a bar's picture holds for what paints past every box — a
33816
+ // shadow, the blur of a wall — which no API measures: a filter cuts whatever
33817
+ // falls outside its region.
33818
+ const WALL_FILTER_INK_ROOM = 100;
33819
+ const SVG_NS = "http://www.w3.org/2000/svg";
33820
+
33821
+ // The bar's picture dimmed, not a rectangle over it: each wall's colour is
33822
+ // flooded atop the bar's own pixels (Porter-Duff source-atop, which no blend
33823
+ // mode gives), so what the bar leaves transparent stays so. Composited over
33824
+ // the area's picture and its stand-in, that is the wall over the bar over the
33825
+ // page: the frame at rest. A wall's filter comes before its colour, as its
33826
+ // backdrop-filter does at rest.
33827
+ const dimBarPicture = (bar, sources) => {
33828
+ const box = bar.getBoundingClientRect();
33829
+ // The filter region is in objectBoundingBox units, which measure from the
33830
+ // box: one without an area leaves nothing to measure from.
33831
+ if (box.width === 0 || box.height === 0) {
33832
+ return;
33833
+ }
33834
+ const picture = pictureRect(bar);
33835
+ const region = {
33836
+ x: (picture.left - WALL_FILTER_INK_ROOM - box.left) / box.width,
33837
+ y: (picture.top - WALL_FILTER_INK_ROOM - box.top) / box.height,
33838
+ width:
33839
+ (picture.right - picture.left + 2 * WALL_FILTER_INK_ROOM) / box.width,
33840
+ height:
33841
+ (picture.bottom - picture.top + 2 * WALL_FILTER_INK_ROOM) / box.height,
33842
+ };
33843
+ // Read while the bar wears none of navi's: removeTransitionWalls took it.
33844
+ const ownFilter = getComputedStyle(bar).filter;
33845
+ const chain = ownFilter === "none" ? [] : [ownFilter];
33846
+ for (const source of sources) {
33847
+ const backdropFilter = getComputedStyle(source)
33848
+ .getPropertyValue("--backdrop-filter")
33849
+ .trim();
33850
+ if (backdropFilter && backdropFilter !== "none") {
33851
+ chain.push(backdropFilter);
33852
+ }
33853
+ chain.push(`url(#${createWallFilter(source, region).id})`);
33854
+ }
33855
+ bar.style.setProperty(WALL_FILTER_PROPERTY, chain.join(" "));
33856
+ bar.setAttribute(WALL_FILTER_ATTRIBUTE, "");
33857
+ dimmedBars.push(bar);
33858
+ };
33859
+
33860
+ const createWallFilter = (source, region) => {
33861
+ if (!wallFilterSvg) {
33862
+ wallFilterSvg = document.createElementNS(SVG_NS, "svg");
33863
+ wallFilterSvg.setAttribute(WALL_FILTERS_ATTRIBUTE, "");
33864
+ wallFilterSvg.setAttribute("aria-hidden", "true");
33865
+ document.body.appendChild(wallFilterSvg);
33866
+ }
33867
+ wallFilterCount++;
33868
+ const filter = document.createElementNS(SVG_NS, "filter");
33869
+ filter.id = `navi-transition-wall-${wallFilterCount}`;
33870
+ // linearRGB, the default, floods another colour than the wall's.
33871
+ filter.setAttribute("color-interpolation-filters", "sRGB");
33872
+ filter.setAttribute("x", region.x);
33873
+ filter.setAttribute("y", region.y);
33874
+ filter.setAttribute("width", region.width);
33875
+ filter.setAttribute("height", region.height);
33876
+ const flood = document.createElementNS(SVG_NS, "feFlood");
33877
+ flood.setAttribute("flood-color", readBackdropColor(source));
33878
+ const composite = document.createElementNS(SVG_NS, "feComposite");
33879
+ composite.setAttribute("in2", "SourceGraphic");
33880
+ composite.setAttribute("operator", "atop");
33881
+ filter.append(flood, composite);
33882
+ wallFilterSvg.appendChild(filter);
33883
+ return filter;
33855
33884
  };
33856
33885
 
33857
33886
  const createWall = (source) => {
@@ -33865,8 +33894,8 @@ const createWall = (source) => {
33865
33894
  };
33866
33895
 
33867
33896
  // One per open wall, over the window, at the opacity of the state they are
33868
- // painted from. A hole is cut where a picture stands, since the picture has
33869
- // a stand-in of its own and shows the live document through nowhere — and on
33897
+ // painted from. A hole is cut where a picture stands, since the picture
33898
+ // carries the wall itself and shows the live document through nowhere — and on
33870
33899
  // the frames the live document IS shown, the first and the last, a hole is
33871
33900
  // what keeps the two from being painted on top of each other.
33872
33901
  const paintRestWalls = (sources, opacity) => {
@@ -33887,10 +33916,10 @@ const measurePictureRects = (areaElement) => {
33887
33916
  return rects;
33888
33917
  };
33889
33918
 
33890
- // What the picture holds, which is what the wall covers at rest: a bar's
33891
- // picture carries what its content paints outside its box (a button standing
33892
- // up out of a tab bar), so its rectangle is taken with its descendants'. The
33893
- // pages' is their own box — the movement cuts them at it anyway.
33919
+ // What the picture holds: a bar's picture carries what its content paints
33920
+ // outside its box (a button standing up out of a tab bar), so its rectangle
33921
+ // is taken with its descendants'. The pages' is their own box — the movement
33922
+ // cuts them at it anyway.
33894
33923
  const pictureRect = (target) => {
33895
33924
  const rect = target.getBoundingClientRect();
33896
33925
  let { left, top, right, bottom } = rect;
@@ -33898,9 +33927,6 @@ const pictureRect = (target) => {
33898
33927
  return { left, top, right, bottom };
33899
33928
  }
33900
33929
  for (const descendant of target.querySelectorAll("*")) {
33901
- if (descendant.hasAttribute(WALL_ATTRIBUTE)) {
33902
- continue;
33903
- }
33904
33930
  const descendantRect = descendant.getBoundingClientRect();
33905
33931
  if (descendantRect.width === 0 || descendantRect.height === 0) {
33906
33932
  continue;
@@ -79718,8 +79744,14 @@ const UnorderedList = ({
79718
79744
  value: null,
79719
79745
  children: jsx(ListItemColumnsContext.Provider, {
79720
79746
  value: columns ? null : itemColumns || null,
79721
- children: jsx(ListDeclaredChildren, {
79722
- children: children
79747
+ children: jsx(ListSlotContext.Provider, {
79748
+ value: null,
79749
+ children: jsx(ListGroupContext.Provider, {
79750
+ value: undefined,
79751
+ children: jsx(ListDeclaredChildren, {
79752
+ children: children
79753
+ })
79754
+ })
79723
79755
  })
79724
79756
  })
79725
79757
  })