fix: editor
This commit is contained in:
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user