fix: editor

This commit is contained in:
2026-04-22 20:20:09 +07:00
parent c828bf7767
commit 994a13da52
8 changed files with 286 additions and 127 deletions
+70
View File
@@ -127,12 +127,82 @@ http://localhost:3300/tasks/{type}/editor.html?file={docId}
4. Server computes diff → writes `temp/{docId}.diff.json`
5. Server runs `generate.mjs` → regenerates output.html + screenshots
**Browser-sync reload protection:** Editor pages are not reloaded when `output.html` changes (removed from watch list). The server also deduplicates rapid-fire save requests (browser-sync quirk: may relay POSTs twice).
**Claude reviewing editor changes:**
```bash
cat tasks/{type}/temp/{docId}.diff.json # see what changed
# Read screenshot PNGs from tasks/{type}/temp/{docId}-page-{N}.png to verify visually
```
### Building a New Editor
Reference implementation: `tasks/asteroid-splitting/editor.html` (simplest, cleanest pattern).
**1. HTML scaffold** — copy toolbar/statusbar/container from asteroid-splitting editor:
- `#toolbar` with btn-prev, btn-next, btn-reset, btn-copy, btn-copy-changes, btn-save
- `#worksheet-container` (EditorCore fills this)
- `#statusbar`, `#toast`, `#coord-tooltip`
- CSS for `.editor-selected`, `.editor-changed`, toolbar, page labels
**2. Load editor-core.js:**
```html
<script src="../../src/editor/editor-core.js"></script>
```
**3. Initialize EditorCore** (wrap everything in IIFE):
```javascript
(function() {
'use strict';
const core = EditorCore.init({
taskType: 'your-type-name',
serialize: buildConfig, // required: (changesOnly) => data object
onReset: resetCurrentPage, // optional: (pageNum) => void
onReady(pages, mmToPx) { // setup DOM refs, event handlers
findElements(pages);
setupClickHandlers();
setupKeyboard();
},
onDataLoaded(data) { // apply saved data.json to DOM
if (data) applyData(data);
}
});
// ... function implementations
})();
```
**4. State management pattern:**
- Store original element state in a `Map` on init (for change detection + reset)
- Track in-memory references to editable elements in arrays
- Read current state from DOM when serializing
- Use `markChanged(el)` to toggle `.editor-changed` class by comparing to original
**5. Serialization:**
- `buildConfig(changesOnly)` returns `{ pages: [{ page: N, ...task-specific fields }] }`
- When `changesOnly=true`, skip elements matching original state
- EditorCore calls this for Save and Copy
**6. Do NOT:**
- Use synchronous XHR (use EditorCore's async save)
- Bypass EditorCore's save (no manual fetch to `/api/save-edits`)
- Add duplicate event listeners for Save/Copy buttons (core wires them)
- Use `var` (use `const`/`let`)
- Store state only in DOM without in-memory backup
**7. Element identification in templates:**
- For complex/reorderable elements: use `data-*` attributes (see space-route `data-node-id`)
- For simple sequential elements: index-based matching is fine
- Match the strategy in your `generate.mjs`
**8. Mandatory e2e verification** (use Chrome DevTools MCP):
1. Open editor → verify worksheet loads and sections are found
2. Click element → verify selection highlight and status info
3. Modify via keyboard → verify DOM and info update
4. Click Save → verify toast "Saved!" and no page reload
5. Read `data.json` → verify saved values match editor state
6. Run `generate.mjs` → verify transforms in `output.html`
7. Reload editor → verify saved state restored via `onDataLoaded`
## Preview Pages Structure
Three-level navigation hierarchy, maintained manually by Claude: