@jsenv/navi 0.29.467 → 0.29.469
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 +149 -117
- package/dist/dev/jsenv_navi.js.map +3 -3
- package/dist/jsenv_navi.js +149 -117
- package/dist/jsenv_navi.js.map +3 -3
- package/package.json +1 -1
package/dist/dev/jsenv_navi.js
CHANGED
|
@@ -34374,85 +34374,6 @@ const warnOnce$1 = (id, message) => {
|
|
|
34374
34374
|
|
|
34375
34375
|
installImportMetaCssBuild(import.meta);
|
|
34376
34376
|
|
|
34377
|
-
/**
|
|
34378
|
-
* The furniture around the pages — the fixed bars, and the popups standing
|
|
34379
|
-
* over them in the top layer — photographed with them for the length of a
|
|
34380
|
-
* route transition, so that a piece of it belonging to ONE of the two states
|
|
34381
|
-
* takes part in the movement instead of appearing or vanishing in a frame.
|
|
34382
|
-
*
|
|
34383
|
-
* Whether a bar is the frame or part of what changes is a fact about the PAIR
|
|
34384
|
-
* of states, never about the bar: the top bar of a list is the frame while one
|
|
34385
|
-
* goes into a row of that list, and part of what changes when the next page
|
|
34386
|
-
* takes the whole screen. So nothing is declared — a name is written on every
|
|
34387
|
-
* bar for the length of the movement, and the browser derives the rest:
|
|
34388
|
-
*
|
|
34389
|
-
* - a bar the two states SHARE is one element wearing one name on both sides.
|
|
34390
|
-
* The browser pairs the two pictures into one group and holds it where it
|
|
34391
|
-
* stands: the frame, and the pages move behind it exactly as before.
|
|
34392
|
-
* - a bar only one state has never meets a counterpart. It belongs to the page
|
|
34393
|
-
* that has it, so it travels with that page — leaving by the keyframes the
|
|
34394
|
-
* page being left leaves by, arriving by the ones the page arriving arrives
|
|
34395
|
-
* by — instead of going out with the render. Over that page, as it is at
|
|
34396
|
-
* rest: the page runs under it, and what it paints outside its box (a button
|
|
34397
|
-
* standing up out of a tab bar) is not cut by its own page. Under the pages
|
|
34398
|
-
* only when its page is covered by the other one — a cover-* movement — so
|
|
34399
|
-
* the sheet comes over it; a popup over everything, standing where it
|
|
34400
|
-
* stands in the document (see the z-order in route_transition.jsx). Which
|
|
34401
|
-
* side a bar is on is said by a class on its group, written here.
|
|
34402
|
-
*
|
|
34403
|
-
* A popup shown in the top layer is furniture of the same kind, and its case
|
|
34404
|
-
* is the sharper one: it is a DOM descendant of the area, yet painted outside
|
|
34405
|
-
* the area's picture, so being captured on its own is the only way it is on
|
|
34406
|
-
* screen at all for those few hundred milliseconds (layout/popup_css.js). One
|
|
34407
|
-
* the two states share holds where it stands, one only a single state has
|
|
34408
|
-
* travels with that state's page — the same two outcomes, derived the same way.
|
|
34409
|
-
*
|
|
34410
|
-
* Which keyframes those are is published by the movement itself
|
|
34411
|
-
* (--navi-route-transition-leave / -enter, see route_transition.jsx): a
|
|
34412
|
-
* selector cannot say "the bars that have no counterpart" — the names are per
|
|
34413
|
-
* element, so there is nothing static to write — so the rule is written for
|
|
34414
|
-
* the length of the movement, over the names this one turned out to have.
|
|
34415
|
-
*
|
|
34416
|
-
* The name is per ELEMENT and kept for the element's whole life, which is what
|
|
34417
|
-
* makes "shared" mean shared: several bars can live on one edge
|
|
34418
|
-
* (layout/fixed_bar/fixed_bar_space.js), so a bar leaving and another one
|
|
34419
|
-
* arriving on that same edge are two names and two movements, not one bar
|
|
34420
|
-
* changing its mind.
|
|
34421
|
-
*
|
|
34422
|
-
* Worn only while a transition of navi's plays: named the rest of the time, a
|
|
34423
|
-
* bar would be captured during every view transition the APPLICATION starts —
|
|
34424
|
-
* dead to the pointer and drawn in the top layer for the length of a movement
|
|
34425
|
-
* that has nothing to do with it. Being unable to answer a press is the price
|
|
34426
|
-
* of being photographed, and a route transition is where it costs nothing:
|
|
34427
|
-
* both pages are pictures for those few hundred milliseconds anyway.
|
|
34428
|
-
*
|
|
34429
|
-
* The WALL of a popup goes the other way round: it is not photographed at
|
|
34430
|
-
* all. The top layer is drawn during a transition only as part of the root's
|
|
34431
|
-
* picture, which is opted out while an area is marked (route_transition.jsx),
|
|
34432
|
-
* and a modal dialog's wall is its ::backdrop — a pseudo-element, which wears
|
|
34433
|
-
* no name; a popover's is a real element, but named it would be a picture the
|
|
34434
|
-
* size of the screen, sliding across the page arriving. Captured on its own,
|
|
34435
|
-
* the popup's box travels; its wall is painted nowhere for the length of the
|
|
34436
|
-
* movement, and the page under it leaves undimmed. So the wall is painted
|
|
34437
|
-
* INTO the page's picture instead: a stand-in laid over the area before each
|
|
34438
|
-
* of the two pictures is taken, painting what the wall paints, and removed
|
|
34439
|
-
* with the movement. Carried by the page's picture, it leaves with the page
|
|
34440
|
-
* being left and arrives with the page arriving, cut at the page's edge — and
|
|
34441
|
-
* under the popup's own picture, which stands over the pages (the z-order in
|
|
34442
|
-
* route_transition.jsx). The bars are under the wall as much as the page is,
|
|
34443
|
-
* and each is a picture of its own: the same stand-in is laid over every bar
|
|
34444
|
-
* outside the area. A bar the two states share is one group with two
|
|
34445
|
-
* pictures — dimmed on the side that has a wall — and its cross-fade is the
|
|
34446
|
-
* wall fading out as the page leaves, or in as it arrives; a bar only one
|
|
34447
|
-
* state has carries the wall with it. What no picture covers — the glass
|
|
34448
|
-
* beside a narrowed app, the window below a page shorter than it — shows the
|
|
34449
|
-
* live document through, and only the live document can paint a wall there:
|
|
34450
|
-
* one fixed stand-in over the window, under the pictures, with a hole cut
|
|
34451
|
-
* where each picture stands, its opacity taken from the state being left to
|
|
34452
|
-
* the state arriving on the movement's own clock. A popup with layer="local"
|
|
34453
|
-
* paints its wall inside the page and needs none of this.
|
|
34454
|
-
*/
|
|
34455
|
-
|
|
34456
34377
|
// The browser's top layer: painted above everything the document paints, so
|
|
34457
34378
|
// outside the area's picture whatever the DOM says.
|
|
34458
34379
|
const TOP_LAYER_SELECTOR = ":modal, :popover-open";
|
|
@@ -34477,6 +34398,11 @@ const FURNITURE_NAME_PREFIX = "navi-transition-furniture-";
|
|
|
34477
34398
|
const TOP_LAYER_WALL_SELECTOR =
|
|
34478
34399
|
".navi_dialog:modal, .navi_popover_backdrop:popover-open, .navi_popup_group:modal";
|
|
34479
34400
|
const WALL_ATTRIBUTE = "data-navi-transition-wall";
|
|
34401
|
+
// Worn by a bar dimmed by a filter of navi's; the property holds the whole
|
|
34402
|
+
// chain, the bar's own filter first (see dimBarPicture).
|
|
34403
|
+
const WALL_FILTER_ATTRIBUTE = "data-navi-transition-wall-filter";
|
|
34404
|
+
const WALL_FILTER_PROPERTY = "--navi-transition-wall-filter";
|
|
34405
|
+
const WALL_FILTERS_ATTRIBUTE = "data-navi-transition-wall-filters";
|
|
34480
34406
|
// Which side of the movement a bar is on, worn by the bar and read by the
|
|
34481
34407
|
// browser as the class of its group (the CSS below): "leaving" from the first
|
|
34482
34408
|
// picture, "arriving" for a bar the state arriving brought, "shared" for one
|
|
@@ -34532,6 +34458,18 @@ const TRANSITION_FURNITURE_CSS = /* css */ `.navi_fixed_bar[data-navi-transition
|
|
|
34532
34458
|
}
|
|
34533
34459
|
}
|
|
34534
34460
|
|
|
34461
|
+
.navi_fixed_bar[data-navi-transition-wall-filter] {
|
|
34462
|
+
filter: var(--navi-transition-wall-filter) !important;
|
|
34463
|
+
}
|
|
34464
|
+
|
|
34465
|
+
[data-navi-transition-wall-filters] {
|
|
34466
|
+
pointer-events: none;
|
|
34467
|
+
width: 0;
|
|
34468
|
+
height: 0;
|
|
34469
|
+
position: fixed;
|
|
34470
|
+
overflow: hidden;
|
|
34471
|
+
}
|
|
34472
|
+
|
|
34535
34473
|
:root:not(:active-view-transition) [data-navi-transition-wall="rest"] {
|
|
34536
34474
|
clip-path: var(--wall-holes-arriving, var(--wall-holes));
|
|
34537
34475
|
}
|
|
@@ -34562,9 +34500,13 @@ let namedElements = new Set();
|
|
|
34562
34500
|
// The rule giving the one-sided bars their movement, written for one movement
|
|
34563
34501
|
// and taken down with it.
|
|
34564
34502
|
let travelStyleElement = null;
|
|
34565
|
-
// The
|
|
34566
|
-
//
|
|
34503
|
+
// The walls open in the top layer, painted for one picture and taken down
|
|
34504
|
+
// before the next: the area's stand-ins, the bars wearing a filter for them,
|
|
34505
|
+
// and the <svg> holding those filters.
|
|
34567
34506
|
let wallElements = [];
|
|
34507
|
+
let dimmedBars = [];
|
|
34508
|
+
let wallFilterSvg = null;
|
|
34509
|
+
let wallFilterCount = 0;
|
|
34568
34510
|
// The stand-ins for what no picture covers, kept for the whole movement, and
|
|
34569
34511
|
// the opacity they are heading to once it plays.
|
|
34570
34512
|
let restWallElements = [];
|
|
@@ -34759,12 +34701,13 @@ const releaseTransitionFurniture = (owner) => {
|
|
|
34759
34701
|
removeRestWalls();
|
|
34760
34702
|
};
|
|
34761
34703
|
|
|
34762
|
-
// One stand-in per open wall
|
|
34763
|
-
//
|
|
34764
|
-
//
|
|
34765
|
-
//
|
|
34766
|
-
//
|
|
34767
|
-
// area's stand-in answers for
|
|
34704
|
+
// One stand-in per open wall over the pages, and one filter per open wall on
|
|
34705
|
+
// every bar outside them, walls in document order: they stack in the top
|
|
34706
|
+
// layer, and what dims the document is all of them. A wall open anywhere
|
|
34707
|
+
// covers everything the document paints, so the sources are looked for in the
|
|
34708
|
+
// whole document — a dialog opened from a bar dims the pages too. A bar inside
|
|
34709
|
+
// the area is part of the pages' picture, and the area's stand-in answers for
|
|
34710
|
+
// it.
|
|
34768
34711
|
const paintTransitionWalls = (areaElement) => {
|
|
34769
34712
|
removeTransitionWalls();
|
|
34770
34713
|
const sources = Array.from(
|
|
@@ -34773,23 +34716,24 @@ const paintTransitionWalls = (areaElement) => {
|
|
|
34773
34716
|
if (sources.length === 0) {
|
|
34774
34717
|
return sources;
|
|
34775
34718
|
}
|
|
34776
|
-
for (const
|
|
34777
|
-
|
|
34778
|
-
|
|
34779
|
-
|
|
34780
|
-
|
|
34781
|
-
|
|
34782
|
-
|
|
34783
|
-
|
|
34784
|
-
|
|
34785
|
-
|
|
34786
|
-
|
|
34787
|
-
|
|
34788
|
-
|
|
34789
|
-
|
|
34790
|
-
|
|
34791
|
-
|
|
34792
|
-
|
|
34719
|
+
for (const source of sources) {
|
|
34720
|
+
const wall = createWall(source);
|
|
34721
|
+
areaElement.appendChild(wall);
|
|
34722
|
+
// The area is not necessarily a containing block (it is a plain box), and
|
|
34723
|
+
// made one for the movement it would move whatever the page positioned
|
|
34724
|
+
// against an ancestor of it: the wall is placed from wherever its
|
|
34725
|
+
// containing block turns out to be, by the offset between that box and
|
|
34726
|
+
// the area's.
|
|
34727
|
+
const areaRect = areaElement.getBoundingClientRect();
|
|
34728
|
+
const wallRect = wall.getBoundingClientRect();
|
|
34729
|
+
wall.style.left = `${areaRect.left - wallRect.left}px`;
|
|
34730
|
+
wall.style.top = `${areaRect.top - wallRect.top}px`;
|
|
34731
|
+
wall.style.width = `${areaRect.width}px`;
|
|
34732
|
+
wall.style.height = `${areaRect.height}px`;
|
|
34733
|
+
wallElements.push(wall);
|
|
34734
|
+
}
|
|
34735
|
+
for (const bar of barsOutside(areaElement)) {
|
|
34736
|
+
dimBarPicture(bar, sources);
|
|
34793
34737
|
}
|
|
34794
34738
|
return sources;
|
|
34795
34739
|
};
|
|
@@ -34799,18 +34743,102 @@ const removeTransitionWalls = () => {
|
|
|
34799
34743
|
wall.remove();
|
|
34800
34744
|
}
|
|
34801
34745
|
wallElements = [];
|
|
34746
|
+
for (const bar of dimmedBars) {
|
|
34747
|
+
bar.removeAttribute(WALL_FILTER_ATTRIBUTE);
|
|
34748
|
+
bar.style.removeProperty(WALL_FILTER_PROPERTY);
|
|
34749
|
+
}
|
|
34750
|
+
dimmedBars = [];
|
|
34751
|
+
if (wallFilterSvg) {
|
|
34752
|
+
wallFilterSvg.remove();
|
|
34753
|
+
wallFilterSvg = null;
|
|
34754
|
+
}
|
|
34802
34755
|
};
|
|
34803
34756
|
|
|
34804
|
-
// What is photographed on its own and
|
|
34757
|
+
// What is photographed on its own and carries the wall in its picture: the
|
|
34805
34758
|
// pages, and every bar outside them.
|
|
34806
34759
|
const pictureTargets = (areaElement) => {
|
|
34807
|
-
|
|
34760
|
+
return [areaElement, ...barsOutside(areaElement)];
|
|
34761
|
+
};
|
|
34762
|
+
|
|
34763
|
+
const barsOutside = (areaElement) => {
|
|
34764
|
+
const bars = [];
|
|
34808
34765
|
for (const bar of document.querySelectorAll(FIXED_BAR_SELECTOR$1)) {
|
|
34809
34766
|
if (!areaElement.contains(bar)) {
|
|
34810
|
-
|
|
34767
|
+
bars.push(bar);
|
|
34811
34768
|
}
|
|
34812
34769
|
}
|
|
34813
|
-
return
|
|
34770
|
+
return bars;
|
|
34771
|
+
};
|
|
34772
|
+
|
|
34773
|
+
// Room around what a bar's picture holds for what paints past every box — a
|
|
34774
|
+
// shadow, the blur of a wall — which no API measures: a filter cuts whatever
|
|
34775
|
+
// falls outside its region.
|
|
34776
|
+
const WALL_FILTER_INK_ROOM = 100;
|
|
34777
|
+
const SVG_NS = "http://www.w3.org/2000/svg";
|
|
34778
|
+
|
|
34779
|
+
// The bar's picture dimmed, not a rectangle over it: each wall's colour is
|
|
34780
|
+
// flooded atop the bar's own pixels (Porter-Duff source-atop, which no blend
|
|
34781
|
+
// mode gives), so what the bar leaves transparent stays so. Composited over
|
|
34782
|
+
// the area's picture and its stand-in, that is the wall over the bar over the
|
|
34783
|
+
// page: the frame at rest. A wall's filter comes before its colour, as its
|
|
34784
|
+
// backdrop-filter does at rest.
|
|
34785
|
+
const dimBarPicture = (bar, sources) => {
|
|
34786
|
+
const box = bar.getBoundingClientRect();
|
|
34787
|
+
// The filter region is in objectBoundingBox units, which measure from the
|
|
34788
|
+
// box: one without an area leaves nothing to measure from.
|
|
34789
|
+
if (box.width === 0 || box.height === 0) {
|
|
34790
|
+
return;
|
|
34791
|
+
}
|
|
34792
|
+
const picture = pictureRect(bar);
|
|
34793
|
+
const region = {
|
|
34794
|
+
x: (picture.left - WALL_FILTER_INK_ROOM - box.left) / box.width,
|
|
34795
|
+
y: (picture.top - WALL_FILTER_INK_ROOM - box.top) / box.height,
|
|
34796
|
+
width:
|
|
34797
|
+
(picture.right - picture.left + 2 * WALL_FILTER_INK_ROOM) / box.width,
|
|
34798
|
+
height:
|
|
34799
|
+
(picture.bottom - picture.top + 2 * WALL_FILTER_INK_ROOM) / box.height,
|
|
34800
|
+
};
|
|
34801
|
+
// Read while the bar wears none of navi's: removeTransitionWalls took it.
|
|
34802
|
+
const ownFilter = getComputedStyle(bar).filter;
|
|
34803
|
+
const chain = ownFilter === "none" ? [] : [ownFilter];
|
|
34804
|
+
for (const source of sources) {
|
|
34805
|
+
const backdropFilter = getComputedStyle(source)
|
|
34806
|
+
.getPropertyValue("--backdrop-filter")
|
|
34807
|
+
.trim();
|
|
34808
|
+
if (backdropFilter && backdropFilter !== "none") {
|
|
34809
|
+
chain.push(backdropFilter);
|
|
34810
|
+
}
|
|
34811
|
+
chain.push(`url(#${createWallFilter(source, region).id})`);
|
|
34812
|
+
}
|
|
34813
|
+
bar.style.setProperty(WALL_FILTER_PROPERTY, chain.join(" "));
|
|
34814
|
+
bar.setAttribute(WALL_FILTER_ATTRIBUTE, "");
|
|
34815
|
+
dimmedBars.push(bar);
|
|
34816
|
+
};
|
|
34817
|
+
|
|
34818
|
+
const createWallFilter = (source, region) => {
|
|
34819
|
+
if (!wallFilterSvg) {
|
|
34820
|
+
wallFilterSvg = document.createElementNS(SVG_NS, "svg");
|
|
34821
|
+
wallFilterSvg.setAttribute(WALL_FILTERS_ATTRIBUTE, "");
|
|
34822
|
+
wallFilterSvg.setAttribute("aria-hidden", "true");
|
|
34823
|
+
document.body.appendChild(wallFilterSvg);
|
|
34824
|
+
}
|
|
34825
|
+
wallFilterCount++;
|
|
34826
|
+
const filter = document.createElementNS(SVG_NS, "filter");
|
|
34827
|
+
filter.id = `navi-transition-wall-${wallFilterCount}`;
|
|
34828
|
+
// linearRGB, the default, floods another colour than the wall's.
|
|
34829
|
+
filter.setAttribute("color-interpolation-filters", "sRGB");
|
|
34830
|
+
filter.setAttribute("x", region.x);
|
|
34831
|
+
filter.setAttribute("y", region.y);
|
|
34832
|
+
filter.setAttribute("width", region.width);
|
|
34833
|
+
filter.setAttribute("height", region.height);
|
|
34834
|
+
const flood = document.createElementNS(SVG_NS, "feFlood");
|
|
34835
|
+
flood.setAttribute("flood-color", readBackdropColor(source));
|
|
34836
|
+
const composite = document.createElementNS(SVG_NS, "feComposite");
|
|
34837
|
+
composite.setAttribute("in2", "SourceGraphic");
|
|
34838
|
+
composite.setAttribute("operator", "atop");
|
|
34839
|
+
filter.append(flood, composite);
|
|
34840
|
+
wallFilterSvg.appendChild(filter);
|
|
34841
|
+
return filter;
|
|
34814
34842
|
};
|
|
34815
34843
|
|
|
34816
34844
|
const createWall = (source) => {
|
|
@@ -34824,8 +34852,8 @@ const createWall = (source) => {
|
|
|
34824
34852
|
};
|
|
34825
34853
|
|
|
34826
34854
|
// One per open wall, over the window, at the opacity of the state they are
|
|
34827
|
-
// painted from. A hole is cut where a picture stands, since the picture
|
|
34828
|
-
//
|
|
34855
|
+
// painted from. A hole is cut where a picture stands, since the picture
|
|
34856
|
+
// carries the wall itself and shows the live document through nowhere — and on
|
|
34829
34857
|
// the frames the live document IS shown, the first and the last, a hole is
|
|
34830
34858
|
// what keeps the two from being painted on top of each other.
|
|
34831
34859
|
const paintRestWalls = (sources, opacity) => {
|
|
@@ -34846,10 +34874,10 @@ const measurePictureRects = (areaElement) => {
|
|
|
34846
34874
|
return rects;
|
|
34847
34875
|
};
|
|
34848
34876
|
|
|
34849
|
-
// What the picture holds
|
|
34850
|
-
//
|
|
34851
|
-
//
|
|
34852
|
-
//
|
|
34877
|
+
// What the picture holds: a bar's picture carries what its content paints
|
|
34878
|
+
// outside its box (a button standing up out of a tab bar), so its rectangle
|
|
34879
|
+
// is taken with its descendants'. The pages' is their own box — the movement
|
|
34880
|
+
// cuts them at it anyway.
|
|
34853
34881
|
const pictureRect = (target) => {
|
|
34854
34882
|
const rect = target.getBoundingClientRect();
|
|
34855
34883
|
let { left, top, right, bottom } = rect;
|
|
@@ -34857,9 +34885,6 @@ const pictureRect = (target) => {
|
|
|
34857
34885
|
return { left, top, right, bottom };
|
|
34858
34886
|
}
|
|
34859
34887
|
for (const descendant of target.querySelectorAll("*")) {
|
|
34860
|
-
if (descendant.hasAttribute(WALL_ATTRIBUTE)) {
|
|
34861
|
-
continue;
|
|
34862
|
-
}
|
|
34863
34888
|
const descendantRect = descendant.getBoundingClientRect();
|
|
34864
34889
|
if (descendantRect.width === 0 || descendantRect.height === 0) {
|
|
34865
34890
|
continue;
|
|
@@ -78846,6 +78871,13 @@ const useListScrollSync = ({
|
|
|
78846
78871
|
// the selected item for as long as the hold takes to put it back.
|
|
78847
78872
|
return;
|
|
78848
78873
|
}
|
|
78874
|
+
if (getScroller() === document.scrollingElement) {
|
|
78875
|
+
// Where the document opens is the arrival's (see scroll_restoration.js),
|
|
78876
|
+
// and a list asks for a place in it through `defaultScrolled`. A box
|
|
78877
|
+
// around the list (a popup's body) has no other owner, so the selected
|
|
78878
|
+
// item is still centered there.
|
|
78879
|
+
return;
|
|
78880
|
+
}
|
|
78849
78881
|
const items = listItems.itemsSignal.peek();
|
|
78850
78882
|
const firstSelected = items.find(i => {
|
|
78851
78883
|
if (i.selected) {
|