fix: Editeur Excalidraw - diagramme vide (CSS + appState) et auto-save pendant l'edition (BUG-064, BUG-065)
This commit is contained in:
@@ -5,8 +5,11 @@
|
||||
* excalidraw-editor.html. Communication between parent and iframe
|
||||
* via postMessage:
|
||||
*
|
||||
* Parent → Iframe: init {data, theme} | theme {theme} | requestSave
|
||||
* Parent → Iframe: init {data, theme} | theme {theme}
|
||||
* Iframe → Parent: ready | save {data} | modified {dirty}
|
||||
*
|
||||
* Saves are explicit only (in-editor Save button / Ctrl+S): no autosave, so
|
||||
* writing the file never triggers an `index_updated` reload of the viewer.
|
||||
*/
|
||||
|
||||
import { api } from './auth.js';
|
||||
@@ -35,7 +38,15 @@ export function renderExcalidraw(container, data, vaultName, filePath, opts = {}
|
||||
iframe.src = '/static/excalidraw-editor.html?v=' + Date.now();
|
||||
iframe.sandbox.add('allow-scripts');
|
||||
iframe.sandbox.add('allow-same-origin');
|
||||
// Let the editor's own Fullscreen button work (native Fullscreen API inside
|
||||
// the sandboxed iframe).
|
||||
iframe.setAttribute('allow', 'fullscreen');
|
||||
iframe.setAttribute('allowfullscreen', '');
|
||||
iframe.style.cssText = 'width:100%;height:100%;border:none;';
|
||||
// Identify the owning document so sync.js can avoid re-rendering (and thus
|
||||
// reloading) this iframe after its own save triggers an `index_updated`.
|
||||
iframe.dataset.excalidrawVault = vaultName;
|
||||
iframe.dataset.excalidrawPath = filePath;
|
||||
|
||||
// Clean container and insert iframe
|
||||
container.innerHTML = '';
|
||||
@@ -49,7 +60,6 @@ export function renderExcalidraw(container, data, vaultName, filePath, opts = {}
|
||||
path: filePath,
|
||||
isDirty: false,
|
||||
ready: false,
|
||||
saveTimer: null,
|
||||
};
|
||||
_activeEditors.set(editorId, editorState);
|
||||
|
||||
@@ -94,16 +104,11 @@ export function renderExcalidraw(container, data, vaultName, filePath, opts = {}
|
||||
break;
|
||||
|
||||
case 'modified':
|
||||
// No autosave: saving writes the file, which emits `index_updated` and
|
||||
// reloads the viewer (visible page refresh) — and can interrupt the
|
||||
// user mid-drawing. The scene is saved explicitly via the in-editor
|
||||
// Save button or Ctrl+S. We only track the dirty state.
|
||||
editorState.isDirty = msg.dirty === true;
|
||||
// If dirty, start auto-save timer (2s debounce)
|
||||
if (editorState.isDirty) {
|
||||
if (editorState.saveTimer) clearTimeout(editorState.saveTimer);
|
||||
editorState.saveTimer = setTimeout(() => {
|
||||
if (editorState.isDirty && editorState.ready) {
|
||||
iframe.contentWindow.postMessage({ type: 'requestSave' }, '*');
|
||||
}
|
||||
}, 2000);
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
@@ -154,9 +159,7 @@ export function notifyExcalidrawThemeChange(theme) {
|
||||
* Clean up an editor instance (e.g., when tab is closed).
|
||||
*/
|
||||
export function destroyExcalidrawEditor(editorId) {
|
||||
const state = _activeEditors.get(editorId);
|
||||
if (state) {
|
||||
if (state.saveTimer) clearTimeout(state.saveTimer);
|
||||
if (_activeEditors.has(editorId)) {
|
||||
_activeEditors.delete(editorId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -693,6 +693,13 @@ async function reloadExternalWrite(vault, path, force = false) {
|
||||
}
|
||||
// Not editing: refresh the read view when it shows the written document.
|
||||
if (state.currentVault === vault && state.currentPath === path) {
|
||||
// Excalidraw owns its iframe: re-rendering would recreate it (visible page
|
||||
// refresh) and discard the in-editor scene. Its own save already persisted
|
||||
// the file, so there is nothing to reload here.
|
||||
const openExcalidraw = Array.from(
|
||||
document.querySelectorAll("iframe[data-excalidraw-path]")
|
||||
).some((f) => f.dataset.excalidrawVault === vault && f.dataset.excalidrawPath === path);
|
||||
if (openExcalidraw) return;
|
||||
_invalidateActiveTabCache(vault, path);
|
||||
openFile(vault, path);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user