diff --git a/src/ExcalidrawAutomate.ts b/src/ExcalidrawAutomate.ts index 95dbcd3..8df4c46 100644 --- a/src/ExcalidrawAutomate.ts +++ b/src/ExcalidrawAutomate.ts @@ -1268,12 +1268,7 @@ export class ExcalidrawAutomate implements ExcalidrawAutomateInterface { */ copyViewElementsToEAforEditing(elements: ExcalidrawElement[]): void { elements.forEach((el) => { - this.elementsDict[el.id] = { - ...el, - version: el.version + 1, - updated: Date.now(), - versionNonce: Math.floor(Math.random() * 1000000000), - }; + this.elementsDict[el.id] = cloneElement(el); }); }; @@ -2312,3 +2307,12 @@ export const getTextElementsMatchingQuery = ( return text.match(q.toLowerCase()); //to distinguish between "# frame" and "# frame 1" https://github.com/zsviczian/obsidian-excalidraw-plugin/issues/530 })); } + +export const cloneElement = (el: ExcalidrawElement):any => { + return { + ...el, + version: el.version + 1, + updated: Date.now(), + versionNonce: Math.floor(Math.random() * 1000000000), + } +} \ No newline at end of file diff --git a/src/ExcalidrawData.ts b/src/ExcalidrawData.ts index 9b184e7..a30e5ee 100644 --- a/src/ExcalidrawData.ts +++ b/src/ExcalidrawData.ts @@ -588,6 +588,7 @@ export class ExcalidrawData { } public async setTextMode(textMode: TextMode, forceupdate: boolean = false) { + if(!this.scene) return; this.textMode = textMode; await this.updateSceneTextElements(forceupdate); } @@ -701,6 +702,7 @@ export class ExcalidrawData { * @returns {boolean} - true if there were changes */ private findNewTextElementsInScene(selectedElementIds: {[key: string]: boolean} = {}): boolean { + return false; //console.log("Excalidraw.Data.findNewTextElementsInScene()"); //get scene text elements this.selectedElementIds = selectedElementIds; @@ -781,11 +783,14 @@ export class ExcalidrawData { this.textElements.delete(key); //if no longer in the scene, delete the text element } else { const text = await this.getText(key, false); + const raw = this.scene.prevTextMode === TextMode.parsed + ? el[0].rawText + : (el[0].originalText ?? el[0].text); if (text !== (el[0].originalText ?? el[0].text)) { const wrapAt = estimateMaxLineLen(el[0].text, el[0].originalText); this.textElements.set(key, { - raw: el[0].originalText ?? el[0].text, - parsed: (await this.parse(el[0].originalText ?? el[0].text)).parsed, + raw, + parsed: (await this.parse(raw)).parsed, wrapAt, }); } diff --git a/src/ExcalidrawView.ts b/src/ExcalidrawView.ts index 59867a0..2f0c209 100644 --- a/src/ExcalidrawView.ts +++ b/src/ExcalidrawView.ts @@ -43,7 +43,7 @@ import { LOCAL_PROTOCOL, } from "./Constants"; import ExcalidrawPlugin from "./main"; -import { repositionElementsToCursor, ExcalidrawAutomate, getTextElementsMatchingQuery } from "./ExcalidrawAutomate"; +import { repositionElementsToCursor, ExcalidrawAutomate, getTextElementsMatchingQuery, cloneElement } from "./ExcalidrawAutomate"; import { t } from "./lang/helpers"; import { ExcalidrawData, @@ -92,14 +92,10 @@ import { ObsidianMenu } from "./menu/ObsidianMenu"; import { ToolsPanel } from "./menu/ToolsPanel"; import { ScriptEngine } from "./Scripts"; import { getTextElementAtPointer, getImageElementAtPointer, getElementWithLinkAtPointer } from "./utils/GetElementAtPointer"; -import { execArgv } from "process"; -import { findLastIndex } from "@zsviczian/excalidraw/types/utils"; -import { fileOpen } from "@zsviczian/excalidraw/types/data/filesystem"; - export enum TextMode { - parsed, - raw, + parsed = "parsed", + raw = "raw", } interface WorkspaceItemExt extends WorkspaceItem { @@ -256,6 +252,7 @@ export default class ExcalidrawView extends TextFileView { public textMode: TextMode = TextMode.raw; private textIsParsed_Element: HTMLElement; private textIsRaw_Element: HTMLElement; + private linkAction_Element: HTMLElement; public compatibilityMode: boolean = false; private obsidianMenu: ObsidianMenu; @@ -1010,7 +1007,7 @@ export default class ExcalidrawView extends TextFileView { () => this.changeTextMode(TextMode.raw), ); - this.addAction("link", t("OPEN_LINK"), (ev) => + this.linkAction_Element = this.addAction("link", t("OPEN_LINK"), (ev) => this.handleLinkClick(this, ev), ); @@ -1148,7 +1145,9 @@ export default class ExcalidrawView extends TextFileView { }); } + private prevTextMode: TextMode; public async changeTextMode(textMode: TextMode, reload: boolean = true) { + if(this.compatibilityMode) return; this.textMode = textMode; if (textMode === TextMode.parsed) { this.textIsRaw_Element.hide(); @@ -1160,15 +1159,13 @@ export default class ExcalidrawView extends TextFileView { if (this.toolsPanelRef && this.toolsPanelRef.current) { this.toolsPanelRef.current.setPreviewMode(textMode === TextMode.parsed); } - if (reload) { + const api = this.excalidrawAPI; + if (api && reload) { await this.save(false, true); - this.updateContainerSize(); - const api = this.excalidrawAPI; - if (!api) { - return; - } + this.updateContainerSize(null,true); api.history.clear(); //to avoid undo replacing links with parsed text } + this.prevTextMode = this.textMode; } public setupAutosaveTimer() { @@ -1413,12 +1410,15 @@ export default class ExcalidrawView extends TextFileView { if (this.compatibilityMode) { this.textIsRaw_Element.hide(); this.textIsParsed_Element.hide(); + this.linkAction_Element.hide(); + this.textMode = TextMode.raw; await this.excalidrawData.loadLegacyData(data, this.file); if (!this.plugin.settings.compatibilityMode) { new Notice(t("COMPATIBILITY_MODE"), 4000); } this.excalidrawData.disableCompression = true; } else { + this.linkAction_Element.show(); this.excalidrawData.disableCompression = false; const textMode = getTextMode(data); this.changeTextMode(textMode, false); @@ -2400,6 +2400,7 @@ export default class ExcalidrawView extends TextFileView { gridSize: st.gridSize, colorPalette: st.colorPalette, }, + prevTextMode: this.prevTextMode, files, }; }; @@ -3000,6 +3001,9 @@ export default class ExcalidrawView extends TextFileView { clearTimeout(this.isEditingTextResetTimer); this.isEditingTextResetTimer = null; this.semaphores.isEditingText = true; //to prevent autoresize on mobile when keyboard pops up + if(this.compatibilityMode) { + return textElement.originalText ?? textElement.text; + } const raw = this.excalidrawData.getRawText(textElement.id); if (!raw) { return textElement.rawText; @@ -3053,14 +3057,26 @@ export default class ExcalidrawView extends TextFileView { textElement.id, text, originalText, - async () => { - await this.save(false); - //save preventReload==false, it will reload and update container sizes + async (wrappedParsedText:string, parsedText:string) => { //this callback function will only be invoked if quick parse fails, i.e. there is a transclusion in the raw text - //thus I only check if TextMode.parsed, text is always != with parseResult - if (this.textMode === TextMode.parsed) { - api.history.clear(); + if(this.textMode === TextMode.raw) return; + + const elements = this.excalidrawAPI.getSceneElements(); + const el = elements.filter((el:ExcalidrawElement)=>el.id === textElement.id); + if(el.length === 1) { + const clone = cloneElement(el[0]); + this.excalidrawData.updateTextElement( + clone, + wrappedParsedText, + parsedText, + true + ); + elements[elements.indexOf(el[0])] = clone; + await this.updateScene({elements}); + if(clone.containerId) this.updateContainerSize(clone.containerId); } + + api.history.clear(); }, ); if (parseResultWrapped) { @@ -3280,6 +3296,7 @@ export default class ExcalidrawView extends TextFileView { } private updateContainerSize(containerId?: string, delay: boolean = false) { + //console.log("updateContainerSize", containerId); const api = this.excalidrawAPI; if (!api) { return; diff --git a/src/main.ts b/src/main.ts index 5e2a0ff..0842ca7 100644 --- a/src/main.ts +++ b/src/main.ts @@ -965,7 +965,7 @@ export default class ExcalidrawPlugin extends Plugin { return false; } const view = this.app.workspace.getActiveViewOfType(ExcalidrawView); - if (view) { + if (view && !view.compatibilityMode) { view.changeTextMode( view.textMode === TextMode.parsed ? TextMode.raw : TextMode.parsed, );