mirror of
https://github.com/jason5ng32/MyIP.git
synced 2026-11-04 08:55:47 +00:00
A pass over every file the branch touched, after the iOS animation hunt left tries and reverts behind it. Removed what nothing reaches: the view-transition rule for a transition no code starts, an unreachable guard in the transition hook, a no-op KeepAlive key branch, a sign-in guard the menu already enforces, usage-dialog wrappers that only forwarded to the store, a duplicated modifier-click check and card filter (isPlainClick / listedTools), a test that hand-rolled listedTools, a drawer-era fixture parameter. auth-flow.js folded into auth-redirect.js. Comments cut to what the code cannot say itself — file headers of a few lines, the measured iOS reasons, non-obvious orderings — and stale ones fixed (Nav under KeepAlive, Home.vue reusing DEFAULT_META, "from Nav", enabledCards). AGENTS.md sections tightened to the code as it is now. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013GbLTGMZ45MV78qd2tHoco
66 lines
2.6 KiB
JavaScript
66 lines
2.6 KiB
JavaScript
// Spec for utils/revive-animations.js: which animations are restarted, that
|
|
// their time is kept, and that only history steps schedule the passes.
|
|
|
|
import assert from 'node:assert/strict';
|
|
import { describe, it } from 'node:test';
|
|
import { reviveAnimations, installAnimationRevival } from '../frontend/utils/revive-animations.js';
|
|
|
|
const fakeAnimation = ({ css = true, playState = 'running', currentTime = 1234 } = {}) => {
|
|
const log = [];
|
|
const animation = {
|
|
playState,
|
|
currentTime,
|
|
cancel: () => log.push('cancel'),
|
|
play: () => log.push('play'),
|
|
log,
|
|
};
|
|
if (css) animation.animationName = 'spin';
|
|
return animation;
|
|
};
|
|
|
|
describe('reviveAnimations()', () => {
|
|
it('cancels, replays and restores the time of running CSS animations only', () => {
|
|
const spin = fakeAnimation();
|
|
const paused = fakeAnimation({ playState: 'paused' });
|
|
const waapi = fakeAnimation({ css: false });
|
|
const doc = { getAnimations: () => [spin, paused, waapi] };
|
|
assert.equal(reviveAnimations(doc), 1);
|
|
assert.deepEqual(spin.log, ['cancel', 'play']);
|
|
assert.equal(spin.currentTime, 1234);
|
|
assert.deepEqual(paused.log, []);
|
|
assert.deepEqual(waapi.log, []);
|
|
});
|
|
|
|
it('tolerates a document without getAnimations', () => {
|
|
assert.equal(reviveAnimations({}), 0);
|
|
assert.equal(reviveAnimations(undefined), 0);
|
|
});
|
|
});
|
|
|
|
describe('installAnimationRevival()', () => {
|
|
const setup = () => {
|
|
const hooks = {};
|
|
const router = { afterEach: (fn) => { hooks.afterEach = fn; } };
|
|
const listeners = {};
|
|
const win = { addEventListener: (type, fn) => { listeners[type] = fn; } };
|
|
const spin = fakeAnimation();
|
|
const doc = { getAnimations: () => [spin] };
|
|
const scheduled = [];
|
|
installAnimationRevival(router, { win, doc, schedule: (fn, delayMs) => scheduled.push({ fn, delayMs }) });
|
|
return { hooks, listeners, spin, scheduled };
|
|
};
|
|
|
|
it('schedules the passes only for a navigation that came from popstate', () => {
|
|
const { hooks, listeners, scheduled, spin } = setup();
|
|
hooks.afterEach();
|
|
assert.equal(scheduled.length, 0, 'a push schedules nothing');
|
|
listeners.popstate();
|
|
hooks.afterEach();
|
|
assert.deepEqual(scheduled.map((s) => s.delayMs), [0, 400, 1200]);
|
|
scheduled.forEach((s) => s.fn());
|
|
assert.equal(spin.log.filter((l) => l === 'play').length, 3);
|
|
hooks.afterEach();
|
|
assert.equal(scheduled.length, 3, 'the flag is consumed');
|
|
});
|
|
});
|