fix(street-level): /revmain cleanup after the slim rebuild

- Google 3D: the OPEN button re-measures a ground whose tiles are still
  loading (a few times, a second apart) and on a map change, not only
  after the next camera move.
- Mapillary: two mounts on one host during the first download share one
  build instead of leaking a second WebGL viewer.
- Retired floating-panel keys (v8 panelPos, panelFloatHintShown) are
  dropped from localStorage; dead inline-position resets, the drag JSDoc
  and the dead qa-ui-disposal observer branch are gone.
- Docs: z ladder, panel chrome, position storage and the fixture gate's
  actual coverage; changelog fragment for #974 (old .gev-cache/mapillary
  can be deleted).
- ru/es: the layer is named as everywhere else in the UI.
- Fixtures and test fakes: unused exports removed; a fake credit removal
  of an absent credit no longer drops another one; the tile test reset
  frees upstream slots.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
German KhokhlovandClaude Opus 5.5 committed 2026-10-20 14:02:09 +04:00
1 parent 00e8e3b997
commit 28e0ba7104
22 files changed
+220 -74

No files matched your search

+61 -2
View File
@@ -352,8 +352,11 @@ function fakeViewer() {
},
creditDisplay: {
addStaticCredit: (credit) => credits.push(credit),
removeStaticCredit: (credit) =>
credits.splice(credits.indexOf(credit), 1),
removeStaticCredit: (credit) => {
// Cesium ignores a credit it does not hold.
const at = credits.indexOf(credit);
if (at !== -1) credits.splice(at, 1);
},
},
};
}
@@ -786,6 +789,62 @@ test('Street View appears only on the Google 3D map: chip, credit, source and im
assert.deepEqual(listed(), ['mapillary']);
});
test('under Google 3D the ground is measured again once its tiles load, without a move', async (t) => {
const saved = globalThis.document;
globalThis.document = new EventTarget();
t.after(() => {
globalThis.document = saved;
});
t.mock.timers.enable({ apis: ['setTimeout'] });
const viewer = fakeViewer();
// 4 km up the ellipsoid, 2 km over a city whose tiles are still loading.
let ground;
viewer.camera.positionCartographic = { height: 4000 };
viewer.scene.globe = { show: false };
viewer.scene.sampleHeightSupported = true;
viewer.scene.sampleHeight = () => ground;
const layer = createStreetLevelLayer({ providers: [fakeProvider()] });
layer.init(viewer);
layer.enable(viewer);
t.after(() => layer.destroy());
assert.equal(layer.getUIState().groundClickReady, false);
ground = 2000;
t.mock.timers.tick(1000);
assert.equal(layer.getUIState().groundClickReady, true);
});
test('an unknown ground is measured only a few times, and not after the layer is off', (t) => {
const saved = globalThis.document;
globalThis.document = new EventTarget();
t.after(() => {
globalThis.document = saved;
});
t.mock.timers.enable({ apis: ['setTimeout'] });
const viewer = fakeViewer();
let samples = 0;
viewer.camera.positionCartographic = { height: 4000 };
viewer.scene.globe = { show: false };
viewer.scene.sampleHeightSupported = true;
viewer.scene.sampleHeight = () => {
samples++;
return undefined;
};
const layer = createStreetLevelLayer({ providers: [fakeProvider()] });
layer.init(viewer);
layer.enable(viewer);
t.after(() => layer.destroy());
t.mock.timers.tick(60_000);
const measured = samples;
assert.ok(measured > 1 && measured <= 12, `measured ${measured} times`);
viewer.camera.moveEnd.raiseEvent();
layer.disable();
const atDisable = samples;
t.mock.timers.tick(60_000);
assert.equal(samples, atDisable, 'no measuring once the layer is off');
});
test('the UI state says when a click (or the button) can open Street View here', async (t) => {
const { layer } = await withStreetView(t);
assert.equal(typeof layer.getUIState().groundClickReady, 'boolean');