77ebe9e3e4
PLAN.md + 5 subplans + CONTEXT.md Strategy: Incremental | Mode: Automated | Execution: Direct Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
71 lines
2.9 KiB
Markdown
71 lines
2.9 KiB
Markdown
# Phase 4: Hash-router для sim deep-links
|
||
|
||
**Status:** ⬜ Not Started
|
||
**Parent plan:** [PLAN.md](./PLAN.md)
|
||
**Domain:** frontend
|
||
|
||
## Objective
|
||
|
||
Сделать `#sim/projectile`, `#sim/newton`, `#sim/chemsandbox` etc. → открывают конкретный sim в lab. F5 на любом deep-link восстанавливает sim. Browser back/forward переключают между симуляциями. По образцу admin-redesign Phase 1 router.
|
||
|
||
## Tasks
|
||
|
||
- [ ] В `frontend/js/labs/lab-glue.js` (или новый `frontend/js/labs/lab-router.js`):
|
||
- На load: прочитать `location.hash`, parsr `#sim/<name>`, активировать соответствующий sim
|
||
- Listen `hashchange`: при изменении hash → переключить sim
|
||
- При программном переключении sim (через sim-switcher UI) → обновить hash без recursion (флаг `_routerNavigating`)
|
||
- [ ] Map sim-name → sim-id:
|
||
- `#sim/projectile` → activate `<div id="sim-proj">`
|
||
- `#sim/newton` → activate `<div id="sim-dynamics">` (или какой-там)
|
||
- Полный mapping из существующих sim-ID
|
||
- [ ] Fallback: unknown hash → ignore (показать default sim)
|
||
- [ ] Verify: F5 на `/lab#sim/projectile` восстанавливает projectile sim
|
||
|
||
## Files to Modify
|
||
|
||
- `frontend/js/labs/lab-glue.js` — добавить router code (~50-100L)
|
||
- `frontend/lab.html` — без изменений (или + 1 script tag если делаем отдельный lab-router.js)
|
||
|
||
## Acceptance Criteria
|
||
|
||
- F5 на `/lab#sim/X` восстанавливает соответствующий sim
|
||
- Browser back/forward переключают между sims
|
||
- Click на sim-switcher обновляет URL (`#sim/X` в адресной строке)
|
||
- Unknown hash (`#sim/nonexistent`) → console.warn + fallback на default
|
||
- 5 deep-link проверены вручную (projectile, newton, chemsandbox, gas, mirror)
|
||
|
||
## Notes
|
||
|
||
### Recursion guard pattern (из admin-redesign Phase 1)
|
||
|
||
```js
|
||
let _navigating = false;
|
||
function navigateTo(simId) {
|
||
_navigating = true;
|
||
location.hash = '#sim/' + simId;
|
||
setTimeout(() => { _navigating = false; }, 0);
|
||
activateSim(simId);
|
||
}
|
||
window.addEventListener('hashchange', () => {
|
||
if (_navigating) return;
|
||
const m = location.hash.match(/^#sim\/([\w-]+)/);
|
||
if (m) activateSim(m[1]);
|
||
});
|
||
```
|
||
|
||
### Reference
|
||
|
||
`frontend/js/admin/router.js` (admin-redesign Phase 1) — read for inspiration. Adapt to lab context.
|
||
|
||
## Review Checklist
|
||
|
||
- [ ] Hash deep-link работает для 5 проверенных симов
|
||
- [ ] Browser back/forward работают
|
||
- [ ] No console errors
|
||
- [ ] No infinite-loop при программной активации
|
||
- [ ] Pre-commit hook passes
|
||
|
||
## Handoff to Next Phase
|
||
|
||
<!-- Implementer: full mapping #sim/X → sim-ID для Phase 5 (template lazy). -->
|