mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-05 10:53:59 +00:00
style: format Cockpit components and pure policies
This commit is contained in:
1 parent
8075c70e6e
commit
e04aefe863
18 files changed
+2227
-1407
No files matched your search
@@ -3,49 +3,115 @@ import assert from 'node:assert/strict';
|
||||
import { CockpitDisplayPortal } from './cockpitDisplayPortal.js';
|
||||
|
||||
function fixture() {
|
||||
const prior = Object.fromEntries(['document', 'window', 'requestAnimationFrame', 'cancelAnimationFrame'].map(key => [key, globalThis[key]]));
|
||||
const prior = Object.fromEntries(
|
||||
['document', 'window', 'requestAnimationFrame', 'cancelAnimationFrame'].map(
|
||||
(key) => [key, globalThis[key]],
|
||||
),
|
||||
);
|
||||
const frames = new Map();
|
||||
let nextFrame = 0;
|
||||
let focusCalls = 0;
|
||||
let layouts = 0;
|
||||
class Node extends EventTarget {
|
||||
constructor(name) {
|
||||
super(); this.name = name; this.children = []; this.parentNode = null; this.scrollTop = 0;
|
||||
super();
|
||||
this.name = name;
|
||||
this.children = [];
|
||||
this.parentNode = null;
|
||||
this.scrollTop = 0;
|
||||
this.classList = { toggle() {} };
|
||||
}
|
||||
append(node) {
|
||||
node.remove(); this.children.push(node); node.parentNode = this;
|
||||
node.remove();
|
||||
this.children.push(node);
|
||||
node.parentNode = this;
|
||||
}
|
||||
remove() {
|
||||
if (this.parentNode) this.parentNode.children.splice(this.parentNode.children.indexOf(this), 1);
|
||||
if (this.parentNode)
|
||||
this.parentNode.children.splice(
|
||||
this.parentNode.children.indexOf(this),
|
||||
1,
|
||||
);
|
||||
this.parentNode = null;
|
||||
}
|
||||
before(node) {
|
||||
node.remove(); const parent = this.parentNode;
|
||||
parent.children.splice(parent.children.indexOf(this), 0, node); node.parentNode = parent;
|
||||
node.remove();
|
||||
const parent = this.parentNode;
|
||||
parent.children.splice(parent.children.indexOf(this), 0, node);
|
||||
node.parentNode = parent;
|
||||
}
|
||||
after(node) {
|
||||
node.remove(); const parent = this.parentNode;
|
||||
parent.children.splice(parent.children.indexOf(this) + 1, 0, node); node.parentNode = parent;
|
||||
node.remove();
|
||||
const parent = this.parentNode;
|
||||
parent.children.splice(parent.children.indexOf(this) + 1, 0, node);
|
||||
node.parentNode = parent;
|
||||
}
|
||||
contains(node) {
|
||||
return (
|
||||
this === node || this.children.some((child) => child.contains(node))
|
||||
);
|
||||
}
|
||||
focus() {
|
||||
focusCalls += 1;
|
||||
document.activeElement = this;
|
||||
}
|
||||
contains(node) { return this === node || this.children.some(child => child.contains(node)); }
|
||||
focus() { focusCalls += 1; document.activeElement = this; }
|
||||
}
|
||||
const standard = new Node('standard'); standard.scrollTop = 71;
|
||||
const cockpit = new Node('cockpit'); cockpit.scrollTop = 19;
|
||||
const group = new Node('group'); const sibling = new Node('sibling');
|
||||
const standard = new Node('standard');
|
||||
standard.scrollTop = 71;
|
||||
const cockpit = new Node('cockpit');
|
||||
cockpit.scrollTop = 19;
|
||||
const group = new Node('group');
|
||||
const sibling = new Node('sibling');
|
||||
const slot = new Node('slot');
|
||||
standard.append(group); standard.append(sibling); cockpit.append(slot);
|
||||
standard.append(group);
|
||||
standard.append(sibling);
|
||||
cockpit.append(slot);
|
||||
cockpit.querySelector = () => slot;
|
||||
globalThis.document = { createComment: name => new Node(name), activeElement: group, body: { classList: { contains: () => false } } };
|
||||
globalThis.document = {
|
||||
createComment: (name) => new Node(name),
|
||||
activeElement: group,
|
||||
body: { classList: { contains: () => false } },
|
||||
};
|
||||
globalThis.window = new EventTarget();
|
||||
globalThis.requestAnimationFrame = fn => { const id = ++nextFrame; frames.set(id, fn); return id; };
|
||||
globalThis.cancelAnimationFrame = id => frames.delete(id);
|
||||
const create = () => new CockpitDisplayPortal({ standardPanel: standard, cockpitPanel: cockpit, groups: [['hud', group]], layout: () => { layouts += 1; } });
|
||||
return { standard, cockpit, group, sibling, slot, frames, create,
|
||||
get focusCalls() { return focusCalls; }, get layouts() { return layouts; },
|
||||
flush() { while (frames.size) { const batch = [...frames.values()]; frames.clear(); batch.forEach(fn => fn()); } },
|
||||
restore() { Object.assign(globalThis, prior); },
|
||||
globalThis.requestAnimationFrame = (fn) => {
|
||||
const id = ++nextFrame;
|
||||
frames.set(id, fn);
|
||||
return id;
|
||||
};
|
||||
globalThis.cancelAnimationFrame = (id) => frames.delete(id);
|
||||
const create = () =>
|
||||
new CockpitDisplayPortal({
|
||||
standardPanel: standard,
|
||||
cockpitPanel: cockpit,
|
||||
groups: [['hud', group]],
|
||||
layout: () => {
|
||||
layouts += 1;
|
||||
},
|
||||
});
|
||||
return {
|
||||
standard,
|
||||
cockpit,
|
||||
group,
|
||||
sibling,
|
||||
slot,
|
||||
frames,
|
||||
create,
|
||||
get focusCalls() {
|
||||
return focusCalls;
|
||||
},
|
||||
get layouts() {
|
||||
return layouts;
|
||||
},
|
||||
flush() {
|
||||
while (frames.size) {
|
||||
const batch = [...frames.values()];
|
||||
frames.clear();
|
||||
batch.forEach((fn) => fn());
|
||||
}
|
||||
},
|
||||
restore() {
|
||||
Object.assign(globalThis, prior);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -66,7 +132,9 @@ test('Display groups return to their exact home with independent scroll position
|
||||
owner.destroy();
|
||||
assert.deepEqual(f.standard.children, [f.group, f.sibling]);
|
||||
assert.equal(f.frames.size, 0);
|
||||
} finally { f.restore(); }
|
||||
} finally {
|
||||
f.restore();
|
||||
}
|
||||
});
|
||||
|
||||
test('superseded portal frames cannot restore obsolete focus or scroll', () => {
|
||||
@@ -77,30 +145,39 @@ test('superseded portal frames cannot restore obsolete focus or scroll', () => {
|
||||
const obsolete = [...f.frames.values()];
|
||||
owner.setActive(false);
|
||||
f.cockpit.scrollTop = 93;
|
||||
obsolete.forEach(callback => callback());
|
||||
obsolete.forEach((callback) => callback());
|
||||
assert.equal(f.focusCalls, 0);
|
||||
assert.equal(f.cockpit.scrollTop, 93);
|
||||
f.flush();
|
||||
assert.equal(f.focusCalls, 1);
|
||||
assert.equal(owner.restoreOwner, null);
|
||||
owner.destroy();
|
||||
} finally { f.restore(); }
|
||||
} finally {
|
||||
f.restore();
|
||||
}
|
||||
});
|
||||
|
||||
test('disposal restores groups and revokes mode listeners and queued focus work', () => {
|
||||
const f = fixture();
|
||||
try {
|
||||
const owner = f.create();
|
||||
window.dispatchEvent(new CustomEvent('gev:cockpit-mode-changed', { detail: { active: true } }));
|
||||
window.dispatchEvent(
|
||||
new CustomEvent('gev:cockpit-mode-changed', { detail: { active: true } }),
|
||||
);
|
||||
assert.equal(f.group.parentNode, f.slot);
|
||||
const obsolete = [...f.frames.values()];
|
||||
owner.destroy(); owner.destroy();
|
||||
obsolete.forEach(callback => callback());
|
||||
window.dispatchEvent(new CustomEvent('gev:cockpit-mode-changed', { detail: { active: true } }));
|
||||
owner.destroy();
|
||||
owner.destroy();
|
||||
obsolete.forEach((callback) => callback());
|
||||
window.dispatchEvent(
|
||||
new CustomEvent('gev:cockpit-mode-changed', { detail: { active: true } }),
|
||||
);
|
||||
owner.setActive(true);
|
||||
assert.deepEqual(f.standard.children, [f.group, f.sibling]);
|
||||
assert.equal(f.frames.size, 0);
|
||||
assert.equal(f.focusCalls, 0);
|
||||
assert.equal(f.layouts, 1);
|
||||
} finally { f.restore(); }
|
||||
} finally {
|
||||
f.restore();
|
||||
}
|
||||
});
|
||||
Reference in new issue
Block a user