@jsenv/navi 0.29.370 → 0.29.372

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.
@@ -29091,8 +29091,13 @@ installImportMetaCssBuild(import.meta);
29091
29091
  * outside the area. A bar the two states share is one group with two
29092
29092
  * pictures — dimmed on the side that has a wall — and its cross-fade is the
29093
29093
  * wall fading out as the page leaves, or in as it arrives; a bar only one
29094
- * state has carries the wall with it. A popup with layer="local" paints its
29095
- * wall inside the page and needs none of this.
29094
+ * state has carries the wall with it. What no picture covers — the glass
29095
+ * beside a narrowed app, the window below a page shorter than it — shows the
29096
+ * live document through, and only the live document can paint a wall there:
29097
+ * one fixed stand-in over the window, under the pictures, with a hole cut
29098
+ * where each picture stands, its opacity taken from the state being left to
29099
+ * the state arriving on the movement's own clock. A popup with layer="local"
29100
+ * paints its wall inside the page and needs none of this.
29096
29101
  */
29097
29102
 
29098
29103
  // The browser's top layer: painted above everything the document paints, so
@@ -29134,10 +29139,24 @@ const TRANSITION_WALL_CSS = /* css */ `[data-navi-transition-wall] {
29134
29139
  position: absolute;
29135
29140
  top: 0;
29136
29141
  left: 0;
29142
+
29143
+ &[data-navi-transition-wall="rest"] {
29144
+ clip-path: var(--wall-holes);
29145
+ transition: opacity var(--navi-route-transition-duration, .3s) ease;
29146
+ position: fixed;
29147
+ inset: 0;
29148
+ }
29137
29149
  }
29138
29150
 
29139
- :root:not(:active-view-transition) [data-navi-transition-wall] {
29140
- display: none;
29151
+ :root:not(:active-view-transition) [data-navi-transition-wall="rest"] {
29152
+ clip-path: var(--wall-holes-arriving, var(--wall-holes));
29153
+ }
29154
+
29155
+ :root[data-navi-route-transition] {
29156
+ & .navi_dialog::backdrop, & .navi_popover_backdrop {
29157
+ backdrop-filter: none;
29158
+ background: none;
29159
+ }
29141
29160
  }
29142
29161
  `;
29143
29162
 
@@ -29162,6 +29181,14 @@ let travelStyleElement = null;
29162
29181
  // The stand-ins for the walls open in the top layer, painted for one picture
29163
29182
  // and taken down before the next.
29164
29183
  let wallElements = [];
29184
+ // The stand-ins for what no picture covers, kept for the whole movement, and
29185
+ // the opacity they are heading to once it plays.
29186
+ let restWallElements = [];
29187
+ let restWallOpacity = "0";
29188
+ // Where each picture stood in the state being left, by element: a hole in
29189
+ // the rest walls is cut only where a picture stands at EVERY moment of the
29190
+ // movement, which takes both states' rectangles.
29191
+ let leavingRects = new Map();
29165
29192
 
29166
29193
  /**
29167
29194
  * Name what stands around the area, before the picture of the state being left
@@ -29174,7 +29201,14 @@ const nameTransitionFurniture = (owner, areaElement) => {
29174
29201
  namedElements = new Set();
29175
29202
  }
29176
29203
  nameFurnitureAround(areaElement);
29177
- paintTransitionWalls(areaElement);
29204
+ const sources = paintTransitionWalls(areaElement);
29205
+ // The state being left has walls: what no picture covers starts dimmed.
29206
+ // The frame the first picture is taken on shows the live document, so the
29207
+ // holes are this state's rectangles, stand-ins inside.
29208
+ removeRestWalls();
29209
+ leavingRects = measurePictureRects(areaElement);
29210
+ paintRestWalls(sources, "1");
29211
+ cutRestWalls([...leavingRects.values()]);
29178
29212
  };
29179
29213
 
29180
29214
  /**
@@ -29195,7 +29229,44 @@ const holdTransitionFurniture = (owner, areaElement) => {
29195
29229
  }
29196
29230
  }
29197
29231
  const namesArriving = nameFurnitureAround(areaElement);
29198
- paintTransitionWalls(areaElement);
29232
+ const sources = paintTransitionWalls(areaElement);
29233
+ // The state arriving has walls: what no picture covers ends dimmed. Painted
29234
+ // from the state being left when that one had walls (they stay up if both
29235
+ // have), from the state arriving otherwise (they come up from nothing).
29236
+ restWallOpacity = sources.length > 0 ? "1" : "0";
29237
+ if (restWallElements.length === 0) {
29238
+ paintRestWalls(sources, "0");
29239
+ }
29240
+ // For the length of the movement a picture is only ever where the two
29241
+ // states' rectangles meet: the pages' pictures slide, and a taller page
29242
+ // arriving does not make the one leaving any taller. A picture only one
29243
+ // state has travels away from where it stood, so it gets no hole at all.
29244
+ const arrivingRects = measurePictureRects(areaElement);
29245
+ const holes = [];
29246
+ for (const [target, arrivingRect] of arrivingRects) {
29247
+ const leavingRect = leavingRects.get(target);
29248
+ if (!leavingRect) {
29249
+ continue;
29250
+ }
29251
+ const left =
29252
+ leavingRect.left > arrivingRect.left
29253
+ ? leavingRect.left
29254
+ : arrivingRect.left;
29255
+ const top =
29256
+ leavingRect.top > arrivingRect.top ? leavingRect.top : arrivingRect.top;
29257
+ const right =
29258
+ leavingRect.right < arrivingRect.right
29259
+ ? leavingRect.right
29260
+ : arrivingRect.right;
29261
+ const bottom =
29262
+ leavingRect.bottom < arrivingRect.bottom
29263
+ ? leavingRect.bottom
29264
+ : arrivingRect.bottom;
29265
+ if (right > left && bottom > top) {
29266
+ holes.push({ left, top, right, bottom });
29267
+ }
29268
+ }
29269
+ cutRestWalls(holes, [...arrivingRects.values()]);
29199
29270
  const cssText = `${travelRule("old", namesLeaving, "--navi-route-transition-leave")}${travelRule("new", namesArriving, "--navi-route-transition-enter")}`;
29200
29271
  if (!cssText) {
29201
29272
  return;
@@ -29265,6 +29336,19 @@ const travelRule = (side, names, movementProperty) => {
29265
29336
  return `${selector}{animation-name:${animationName};animation-timing-function:ease;animation-fill-mode:both}`;
29266
29337
  };
29267
29338
 
29339
+ /**
29340
+ * The pictures are up and about to move: what no picture covers heads to the
29341
+ * state arriving, on the same clock.
29342
+ */
29343
+ const startTransitionFurniture = (owner) => {
29344
+ if (owner !== furnitureOwner) {
29345
+ return;
29346
+ }
29347
+ for (const restWall of restWallElements) {
29348
+ restWall.style.opacity = restWallOpacity;
29349
+ }
29350
+ };
29351
+
29268
29352
  const releaseTransitionFurniture = (owner) => {
29269
29353
  if (owner !== furnitureOwner) {
29270
29354
  return;
@@ -29279,6 +29363,7 @@ const releaseTransitionFurniture = (owner) => {
29279
29363
  travelStyleElement = null;
29280
29364
  }
29281
29365
  removeTransitionWalls();
29366
+ removeRestWalls();
29282
29367
  };
29283
29368
 
29284
29369
  // One stand-in per open wall in every picture, walls in document order: they
@@ -29291,25 +29376,11 @@ const paintTransitionWalls = (areaElement) => {
29291
29376
  removeTransitionWalls();
29292
29377
  const sources = document.querySelectorAll(TOP_LAYER_WALL_SELECTOR);
29293
29378
  if (sources.length === 0) {
29294
- return;
29295
- }
29296
- const targets = [areaElement];
29297
- for (const bar of document.querySelectorAll(FIXED_BAR_SELECTOR$1)) {
29298
- if (!areaElement.contains(bar)) {
29299
- targets.push(bar);
29300
- }
29379
+ return sources;
29301
29380
  }
29302
- for (const target of targets) {
29381
+ for (const target of pictureTargets(areaElement)) {
29303
29382
  for (const source of sources) {
29304
- const sourceStyle = getComputedStyle(source);
29305
- const wall = document.createElement("div");
29306
- wall.setAttribute(WALL_ATTRIBUTE, "");
29307
- for (const property of WALL_PROPERTIES) {
29308
- wall.style.setProperty(
29309
- property,
29310
- sourceStyle.getPropertyValue(property),
29311
- );
29312
- }
29383
+ const wall = createWall(source);
29313
29384
  target.appendChild(wall);
29314
29385
  // The target is not necessarily a containing block (the area is a plain
29315
29386
  // box), and made one for the movement it would move whatever the page
@@ -29325,6 +29396,7 @@ const paintTransitionWalls = (areaElement) => {
29325
29396
  wallElements.push(wall);
29326
29397
  }
29327
29398
  }
29399
+ return sources;
29328
29400
  };
29329
29401
 
29330
29402
  const removeTransitionWalls = () => {
@@ -29334,6 +29406,83 @@ const removeTransitionWalls = () => {
29334
29406
  wallElements = [];
29335
29407
  };
29336
29408
 
29409
+ // What is photographed on its own and gets a stand-in in its picture: the
29410
+ // pages, and every bar outside them.
29411
+ const pictureTargets = (areaElement) => {
29412
+ const targets = [areaElement];
29413
+ for (const bar of document.querySelectorAll(FIXED_BAR_SELECTOR$1)) {
29414
+ if (!areaElement.contains(bar)) {
29415
+ targets.push(bar);
29416
+ }
29417
+ }
29418
+ return targets;
29419
+ };
29420
+
29421
+ const createWall = (source) => {
29422
+ const sourceStyle = getComputedStyle(source);
29423
+ const wall = document.createElement("div");
29424
+ wall.setAttribute(WALL_ATTRIBUTE, "");
29425
+ for (const property of WALL_PROPERTIES) {
29426
+ wall.style.setProperty(property, sourceStyle.getPropertyValue(property));
29427
+ }
29428
+ return wall;
29429
+ };
29430
+
29431
+ // One per open wall, over the window, at the opacity of the state they are
29432
+ // painted from. A hole is cut where a picture stands, since the picture has
29433
+ // a stand-in of its own and shows the live document through nowhere — and on
29434
+ // the frames the live document IS shown, the first and the last, a hole is
29435
+ // what keeps the two from being painted on top of each other.
29436
+ const paintRestWalls = (sources, opacity) => {
29437
+ for (const source of sources) {
29438
+ const restWall = createWall(source);
29439
+ restWall.setAttribute(WALL_ATTRIBUTE, "rest");
29440
+ restWall.style.opacity = opacity;
29441
+ document.body.appendChild(restWall);
29442
+ restWallElements.push(restWall);
29443
+ }
29444
+ };
29445
+
29446
+ const measurePictureRects = (areaElement) => {
29447
+ const rects = new Map();
29448
+ for (const target of pictureTargets(areaElement)) {
29449
+ rects.set(target, target.getBoundingClientRect());
29450
+ }
29451
+ return rects;
29452
+ };
29453
+
29454
+ // The holes for the movement, and the ones for its last frame (see the CSS).
29455
+ const cutRestWalls = (holes, holesArriving = null) => {
29456
+ for (const restWall of restWallElements) {
29457
+ restWall.style.setProperty("--wall-holes", holesPolygon(holes));
29458
+ if (holesArriving) {
29459
+ restWall.style.setProperty(
29460
+ "--wall-holes-arriving",
29461
+ holesPolygon(holesArriving),
29462
+ );
29463
+ }
29464
+ }
29465
+ };
29466
+
29467
+ // One evenodd polygon: the window, then each hole entered from and left by
29468
+ // the window's origin, so the bridges between them have no area.
29469
+ const holesPolygon = (holes) => {
29470
+ let polygon = "0 0, 100% 0, 100% 100%, 0 100%, 0 0";
29471
+ for (const { left, top, right, bottom } of holes) {
29472
+ polygon += `, ${left}px ${top}px, ${right}px ${top}px, ${right}px ${bottom}px, ${left}px ${bottom}px, ${left}px ${top}px, 0 0`;
29473
+ }
29474
+ return `polygon(evenodd, ${polygon})`;
29475
+ };
29476
+
29477
+ const removeRestWalls = () => {
29478
+ for (const restWall of restWallElements) {
29479
+ restWall.remove();
29480
+ }
29481
+ restWallElements = [];
29482
+ restWallOpacity = "0";
29483
+ leavingRects = new Map();
29484
+ };
29485
+
29337
29486
  installImportMetaCssBuild(import.meta);
29338
29487
 
29339
29488
  const TRANSITION_WINDOW_CSS = /* css */ `@property --navi-transition-cover-top {
@@ -30930,6 +31079,7 @@ const beginTransition = ({
30930
31079
  // the only place the silent misconfigurations show. They are all about the
30931
31080
  // same thing — a movement playing on pictures that are not the pages.
30932
31081
  const viewTransitionReady = () => {
31082
+ startTransitionFurniture(transition);
30933
31083
  const capturedNames = capturedViewTransitionNames();
30934
31084
  if (areaElements.length > 0) {
30935
31085
  if (!capturedNames.has(AREA_NAME)) {