@swiftbrowser/web 0.10.3 → 0.10.4
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/package.json +1 -1
- package/src/animation.ts +29 -1
- package/src/renderer.ts +2 -0
package/package.json
CHANGED
package/src/animation.ts
CHANGED
|
@@ -961,12 +961,36 @@ export class Animator {
|
|
|
961
961
|
el.animate([from, to], { ...timing, fill: 'backwards' });
|
|
962
962
|
}
|
|
963
963
|
|
|
964
|
+
/** The exit clones playing, each with the element it left (its parent at removal): `dropExitClonesIn`. */
|
|
965
|
+
private readonly exitClones = new Map<HTMLElement, HTMLElement>();
|
|
966
|
+
|
|
967
|
+
/**
|
|
968
|
+
* Drops the exit clones of elements that left `container` or anything in
|
|
969
|
+
* it: a clone stands in for content of a container that is now going
|
|
970
|
+
* itself, and would play on over whatever takes the container's place. A
|
|
971
|
+
* screen that swaps its content for a placeholder a commit before it is
|
|
972
|
+
* popped (a split view's detail as its selection clears) left its bar
|
|
973
|
+
* group's clone fading over the uncovered screen's bar. (A clone not built
|
|
974
|
+
* yet, its pass still waiting for the frame, is refused in `exit`.)
|
|
975
|
+
*/
|
|
976
|
+
dropExitClonesIn(container: HTMLElement): void {
|
|
977
|
+
for (const [clone, owner] of this.exitClones) {
|
|
978
|
+
if (owner !== container && !container.contains(owner)) continue;
|
|
979
|
+
this.exitClones.delete(clone);
|
|
980
|
+
for (const animation of clone.getAnimations()) animation.cancel();
|
|
981
|
+
clone.remove();
|
|
982
|
+
}
|
|
983
|
+
}
|
|
984
|
+
|
|
964
985
|
/**
|
|
965
986
|
* Re-insert a visual clone of a removed element at its old position and
|
|
966
987
|
* play its transition backwards; the clone is dropped when done.
|
|
967
988
|
*/
|
|
968
989
|
exit(rec: RemovedRecord, animation: Animation | undefined): HTMLElement | null {
|
|
969
990
|
const parent = rec.ancestors[0] ?? null;
|
|
991
|
+
// The element it left has gone itself since (a later pass in the same
|
|
992
|
+
// task popped the screen): nothing is left to leave from.
|
|
993
|
+
if (parent && !parent.isConnected) return null;
|
|
970
994
|
const end = transitionStart(rec.transition ?? implicitTransitionOf(rec.el, parent), true);
|
|
971
995
|
if (isIdentity(end) || !rec.rect) return null;
|
|
972
996
|
const clone = ghostClone(rec.el);
|
|
@@ -999,7 +1023,11 @@ export class Animator {
|
|
|
999
1023
|
}
|
|
1000
1024
|
const timing = baseTiming(timingFor(animation));
|
|
1001
1025
|
const anim = clone.animate([from, to], { ...timing, fill: 'forwards' });
|
|
1002
|
-
|
|
1026
|
+
if (parent) this.exitClones.set(clone, parent);
|
|
1027
|
+
const done = (): void => {
|
|
1028
|
+
this.exitClones.delete(clone);
|
|
1029
|
+
clone.remove();
|
|
1030
|
+
};
|
|
1003
1031
|
anim.finished.then(done, done);
|
|
1004
1032
|
window.setTimeout(done, timing.duration + timing.delay + 100);
|
|
1005
1033
|
return clone;
|
package/src/renderer.ts
CHANGED
|
@@ -2231,6 +2231,8 @@ export class Renderer {
|
|
|
2231
2231
|
const el = this.elements.get(id);
|
|
2232
2232
|
if (!el) throw new RendererError(`Cannot remove unknown element ${id}`, op);
|
|
2233
2233
|
const parent = el.parentElement;
|
|
2234
|
+
// Clones of what left this subtree earlier (a bar group's, src/animation.ts) go with it.
|
|
2235
|
+
this.animator.dropExitClonesIn(el);
|
|
2234
2236
|
const stack = parent?.classList.contains('sb-navstack-screens')
|
|
2235
2237
|
? parent.parentElement
|
|
2236
2238
|
: null;
|