diff --git a/manifest.json b/manifest.json index 0bf454d..38b01f7 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "id": "obsidian-excalidraw-plugin", "name": "Excalidraw", - "version": "2.1.7", + "version": "2.1.8", "minAppVersion": "1.1.6", "description": "An Obsidian plugin to edit and view Excalidraw drawings", "author": "Zsolt Viczian", diff --git a/src/ExcalidrawAutomate.ts b/src/ExcalidrawAutomate.ts index 65c90e9..6206cb4 100644 --- a/src/ExcalidrawAutomate.ts +++ b/src/ExcalidrawAutomate.ts @@ -51,7 +51,6 @@ import { getSVG, isMaskFile, isVersionNewerThanOther, - log, scaleLoadedImage, wrapTextAtCharLength, } from "src/utils/Utils"; @@ -91,9 +90,8 @@ import { extractCodeBlocks as _extractCodeBlocks, } from "./utils/AIUtils"; import { EXCALIDRAW_AUTOMATE_INFO, EXCALIDRAW_SCRIPTENGINE_INFO } from "./dialogs/SuggesterInfo"; -import { CropImage } from "./utils/CropImage"; -import { has } from "./svgToExcalidraw/attributes"; import { getFrameBasedOnFrameNameOrId } from "./utils/ExcalidrawViewUtils"; +import { log } from "./utils/DebugHelper"; extendPlugins([ HarmonyPlugin, @@ -134,7 +132,7 @@ export class ExcalidrawAutomate { public help(target: Function | string) { if (!target) { - console.log("Usage: ea.help(ea.functionName) or ea.help('propertyName') or ea.help('utils.functionName') - notice property name and utils function name is in quotes"); + log("Usage: ea.help(ea.functionName) or ea.help('propertyName') or ea.help('utils.functionName') - notice property name and utils function name is in quotes"); return; } @@ -153,14 +151,14 @@ export class ExcalidrawAutomate { } if(!funcInfo) { - console.log("Usage: ea.help(ea.functionName) or ea.help('propertyName') or ea.help('utils.functionName') - notice property name and utils function name is in quotes"); + log("Usage: ea.help(ea.functionName) or ea.help('propertyName') or ea.help('utils.functionName') - notice property name and utils function name is in quotes"); return; } let isMissing = true; if (funcInfo.code) { isMissing = false; - console.log(`Declaration: ${funcInfo.code}`); + log(`Declaration: ${funcInfo.code}`); } if (funcInfo.desc) { isMissing = false; @@ -171,10 +169,10 @@ export class ExcalidrawAutomate { .replace(/(.*?)<\/a>/g, (_, href, text) => `%c\u200b${text}%c\u200b (link: ${href})`); // Zero-width non-joiner const styles = Array.from({ length: (formattedDesc.match(/%c/g) || []).length }, (_, i) => i % 2 === 0 ? 'color: #007bff;' : ''); - console.log(`Description: ${formattedDesc}`, ...styles); + log(`Description: ${formattedDesc}`, ...styles); } if (isMissing) { - console.log("Description not available for this function."); + log("Description not available for this function."); } } @@ -2645,7 +2643,7 @@ export class ExcalidrawAutomate { importSVG(svgString:string):boolean { const res:ConversionResult = svgToExcalidraw(svgString); if(res.hasErrors) { - new Notice (`There were errors while parsing the given SVG:\n${[...res.errors].map((el) => el.innerHTML)}`); + new Notice (`There were errors while parsing the given SVG:\n${res.errors}`); return false; } this.copyViewElementsToEAforEditing(res.content); diff --git a/src/ExcalidrawData.ts b/src/ExcalidrawData.ts index 4f1a23a..a930aeb 100644 --- a/src/ExcalidrawData.ts +++ b/src/ExcalidrawData.ts @@ -28,7 +28,6 @@ import { TextMode } from "./ExcalidrawView"; import { addAppendUpdateCustomData, compress, - debug, decompress, //getBakPath, getBinaryFileFromDataURL, @@ -51,7 +50,7 @@ import { BinaryFiles, DataURL, SceneData } from "@zsviczian/excalidraw/types/exc import { EmbeddedFile, MimeType } from "./EmbeddedFileLoader"; import { ConfirmationPrompt } from "./dialogs/Prompt"; import { getMermaidImageElements, getMermaidText, shouldRenderMermaid } from "./utils/MermaidUtils"; -import { add } from "@zsviczian/excalidraw/types/excalidraw/ga"; +import { debug } from "./utils/DebugHelper"; type SceneDataWithFiles = SceneData & { files: BinaryFiles }; @@ -904,7 +903,7 @@ export class ExcalidrawData { container?.type, ); //(await this.getText(te.id))??te.text serves the case when the whole #Text Elements section is deleted by accident } catch(e) { - debug({where: "ExcalidrawData.updateSceneTextElements", fn: this.updateSceneTextElements, textElement: te}); + debug(`ExcalidrawData.updateSceneTextElements, textElement: ${te?.id}`, te, this.updateSceneTextElements); } } } diff --git a/src/ExcalidrawView.ts b/src/ExcalidrawView.ts index 0bb2349..3ed630c 100644 --- a/src/ExcalidrawView.ts +++ b/src/ExcalidrawView.ts @@ -132,7 +132,7 @@ import { useDefaultExcalidrawFrame } from "./utils/CustomEmbeddableUtils"; import { UniversalInsertFileModal } from "./dialogs/UniversalInsertFileModal"; import { getMermaidText, shouldRenderMermaid } from "./utils/MermaidUtils"; import { nanoid } from "nanoid"; -import { CustomMutationObserver, isDebugMode } from "./utils/DebugHelper"; +import { CustomMutationObserver, debug, log} from "./utils/DebugHelper"; import { extractCodeBlocks, postOpenAI } from "./utils/AIUtils"; import { Mutable } from "@zsviczian/excalidraw/types/excalidraw/utility-types"; import { SelectCard } from "./dialogs/SelectCard"; @@ -681,7 +681,7 @@ export default class ExcalidrawView extends TextFileView { try { const allowSave = this.isDirty() || forcesave; //removed this.semaphores.autosaving - if(isDebugMode) console.log({allowSave, isDirty: this.isDirty(), autosaving: this.semaphores.autosaving, forcesave}); + debug({where: "ExcalidrawView.save", allowSave, isDirty: this.isDirty(), autosaving: this.semaphores.autosaving, forcesave}); if (allowSave) { const scene = this.getScene(); @@ -800,7 +800,7 @@ export default class ExcalidrawView extends TextFileView { const header = getExcalidrawMarkdownHeaderSection(this.data, keys); if (!this.excalidrawData.disableCompression) { - this.excalidrawData.disableCompression = + this.excalidrawData.disableCompression = this.plugin.settings.decompressForMDView && this.isEditedAsMarkdownInOtherView(); } const result = header + this.excalidrawData.generateMD( @@ -1303,8 +1303,13 @@ export default class ExcalidrawView extends TextFileView { ); const self = this; - app.workspace.onLayoutReady(async () => { - this.canvasNodeFactory.initialize(); + this.app.workspace.onLayoutReady(async () => { + debug(`ExcalidrawView.onload app.workspace.onLayoutReady, file: ${self.file?.name}, isActiveLeaf: ${self.app.workspace.activeLeaf === self.leaf}, is activeExcalidrawView set: ${Boolean(self.plugin.activeExcalidrawView)}`); + //implemented to overcome issue that activeLeafChangeEventHandler is not called when view is initialized from a saved workspace, since Obsidian 1.6.0 + if (self.app.workspace.activeLeaf === self.leaf) { + self.plugin.activeLeafChangeEventHandler(self.leaf); + } + self.canvasNodeFactory.initialize(); self.contentEl.addClass("excalidraw-view"); //https://github.com/zsviczian/excalibrain/issues/28 await self.addSlidingPanesListner(); //awaiting this because when using workspaces, onLayoutReady comes too early @@ -1320,7 +1325,7 @@ export default class ExcalidrawView extends TextFileView { }; self.onKeyDown = (e: KeyboardEvent) => { - this.modifierKeyDown = { + self.modifierKeyDown = { shiftKey: e.shiftKey, ctrlKey: e.ctrlKey, altKey: e.altKey, @@ -1396,7 +1401,7 @@ export default class ExcalidrawView extends TextFileView { self.offsetTop = offsetTop; } }; - this.parentMoveObserver = isDebugMode + this.parentMoveObserver = this.plugin.settings.isDebugMode ? new CustomMutationObserver(observerFn, "parentMoveObserver") : new MutationObserver(observerFn) @@ -1833,7 +1838,11 @@ export default class ExcalidrawView extends TextFileView { this.lastSaveTimestamp = this.file.stat.mtime; this.lastLoadedFile = this.file; data = this.data = data.replaceAll("\r\n", "\n").replaceAll("\r", "\n"); - app.workspace.onLayoutReady(async () => { + this.app.workspace.onLayoutReady(async () => { + debug(`ExcalidrawView.setViewData app.workspace.onLayoutReady, file: ${this.file?.name}, isActiveLeaf: ${this.app.workspace.activeLeaf === this.leaf}`); + let counter = 0; + while (!this.file && counter++<50) await sleep(50); + if(!this.file) return; this.compatibilityMode = this.file.extension === "excalidraw"; await this.plugin.loadSettings(); if (this.compatibilityMode) { @@ -2263,9 +2272,9 @@ export default class ExcalidrawView extends TextFileView { this.initializeToolsIconPanelAfterLoading(); } - public setDirty(debug?:number) { + public setDirty(location?:number) { if(this.semaphores.saving) return; //do not set dirty if saving - if(isDebugMode) console.log(debug); + debug(`ExcalidrawView.setDirty location:${location}`); this.semaphores.dirty = this.file?.path; this.diskIcon.querySelector("svg").addClass("excalidraw-dirty"); if(!this.semaphores.viewunload && this.toolsPanelRef?.current) { @@ -2354,7 +2363,7 @@ export default class ExcalidrawView extends TextFileView { } public async openAsMarkdown(eState?: any) { - if (this.plugin.settings.compress === true) { + if (this.plugin.settings.compress && this.plugin.settings.decompressForMDView) { this.excalidrawData.disableCompression = true; await this.save(true, true); } @@ -4547,17 +4556,17 @@ export default class ExcalidrawView extends TextFileView { } const json = response.json; - if (isDebugMode) console.log(response); + debug("ExcalidrawView.ttdDialog", response); if (json?.error) { - console.log(response); + log(response); return { error: new Error(json.error.message), }; } if(!json?.choices?.[0]?.message?.content) { - console.log(response); + log(response); return { error: new Error("Generation failed... see console log for details"), }; @@ -4566,7 +4575,7 @@ export default class ExcalidrawView extends TextFileView { let generatedResponse = extractCodeBlocks(json.choices[0]?.message?.content)[0]?.data; if(!generatedResponse) { - console.log(response); + log(response); return { error: new Error("Generation failed... see console log for details"), }; diff --git a/src/MarkdownPostProcessor.ts b/src/MarkdownPostProcessor.ts index 6a397ee..5c2ccf8 100644 --- a/src/MarkdownPostProcessor.ts +++ b/src/MarkdownPostProcessor.ts @@ -714,7 +714,7 @@ const tmpObsidianWYSIWYG = async ( internalEmbedDiv.appendChild(imgDiv); }, 500); } - const observer = isDebugMode + const observer = isDebugMode() ? new CustomMutationObserver(markdownObserverFn, "markdowPostProcessorObserverFn") : new MutationObserver(markdownObserverFn); observer.observe(internalEmbedDiv, { @@ -848,7 +848,7 @@ const legacyExcalidrawPopoverObserverFn: MutationCallback = async (m) => { node.appendChild(div); }; -export const legacyExcalidrawPopoverObserver = isDebugMode +export const legacyExcalidrawPopoverObserver = isDebugMode() ? new CustomMutationObserver(legacyExcalidrawPopoverObserverFn, "legacyExcalidrawPopoverObserverFn") : new MutationObserver(legacyExcalidrawPopoverObserverFn); diff --git a/src/dialogs/Messages.ts b/src/dialogs/Messages.ts index ee60a29..8cd57a0 100644 --- a/src/dialogs/Messages.ts +++ b/src/dialogs/Messages.ts @@ -17,6 +17,17 @@ I develop this plugin as a hobby, spending my free time doing this. If you find
`, +"2.1.8":` +## Fixed +- Fixing issues that surfaced after upgrading to Obsidian 1.6.0 + - Fixed Excalidraw hover previews + - Cursor for editing links, text elements, and frame names became virtually invisible if Obsidian was in dark mode and Excalidraw in light mode and vica versa. + - Rendering Excalidraw drawings in Markdown views, right after Obsidian loaded did not work. +- I implemented more graceful fail if you submitted a malformed SVG for SVG to Excalidraw conversation. [#1768](https://github.com/zsviczian/obsidian-excalidraw-plugin/issues/1768) + +## New +- New setting under "Save" in plugin settings to NOT decompress JSON when switching to Markdown view mode. For details see description under "Save" settings. The benefit is smaller file size and fewer results in the Obsidian search. If you want to edit the JSON, you can always manually decompress JSON in markdown view mode with the command palette action "Excalidraw: Decompress JSON". +`, "2.1.7:":`
diff --git a/src/dialogs/ScriptInstallPrompt.ts b/src/dialogs/ScriptInstallPrompt.ts index 81fa698..bb229d9 100644 --- a/src/dialogs/ScriptInstallPrompt.ts +++ b/src/dialogs/ScriptInstallPrompt.ts @@ -1,6 +1,7 @@ import { MarkdownRenderer, Modal, Notice, request } from "obsidian"; import ExcalidrawPlugin from "../main"; -import { errorlog, escapeRegExp, log } from "../utils/Utils"; +import { errorlog, escapeRegExp } from "../utils/Utils"; +import { log } from "src/utils/DebugHelper"; const URL = "https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/ea-scripts/index-new.md"; diff --git a/src/lang/locale/en.ts b/src/lang/locale/en.ts index f57460f..3893a66 100644 --- a/src/lang/locale/en.ts +++ b/src/lang/locale/en.ts @@ -217,6 +217,14 @@ export default { "once you switch back to Excalidraw view. " + "The setting only has effect 'point forward', meaning, existing drawings will not be affected by the setting " + "until you open them and save them.
Toggle ON: Compress drawing JSON
Toggle OFF: Leave drawing JSON uncompressed", + DECOMPRESS_FOR_MD_NAME: "Decompress Excalidraw JSON in Markdown View", + DECOMPRESS_FOR_MD_DESC: + "By enabling this feature Excalidraw will automatically decompress the drawing JSON when you switch to Markdown view. " + + "This will allow you to easily read and edit the JSON string. The drawing will be compressed again " + + "once you switch back to Excalidraw view and save the drawing (CTRL+S).
" + + "I recommend switching this feature off as it will result in smaller file sizes and avoiding unnecessary results in Obsidian search. " + + "You can always use the 'Excalidraw: Decompress current Excalidraw file' command from the command palette "+ + "to manually decompress the drawing JSON when you need to read or edit it.", AUTOSAVE_INTERVAL_DESKTOP_NAME: "Interval for autosave on Desktop", AUTOSAVE_INTERVAL_DESKTOP_DESC: "The time interval between saves. Autosave will skip if there are no changes in the drawing. " + @@ -565,6 +573,9 @@ FILENAME_HEAD: "Filename", "Double files will be exported both if auto-export SVG or PNG (or both) are enabled, as well as when clicking export on a single image.", COMPATIBILITY_HEAD: "Compatibility features", COMPATIBILITY_DESC: "You should only enable these features if you have a strong reason for wanting to work with excalidraw.com files instead of markdown files. Many of the plugin features are not supported on legacy files. Typical usecase would be if you use set your vault up on top of a Visual Studio Code project folder and you have .excalidraw drawings you want to access from Visual Studio Code as well. Another usecase might be using Excalidraw in Logseq and Obsidian in parallel.", + DEBUGMODE_NAME: "Enable debug messages", + DEBUGMODE_DESC: "I recommend restarting Obsidian after enabling/disabling this setting. This enable debug messages in the console. This is useful for troubleshooting issues. " + + "If you are experiencing problems with the plugin, please enable this setting, reproduce the issue, and include the console log in the issue you raise on GitHub", SLIDING_PANES_NAME: "Sliding panes plugin support", SLIDING_PANES_DESC: "Need to restart Obsidian for this change to take effect.
" + diff --git a/src/main.ts b/src/main.ts index 9f8d1b6..cb89cad 100644 --- a/src/main.ts +++ b/src/main.ts @@ -20,6 +20,7 @@ import { Editor, MarkdownFileInfo, loadMermaid, + requireApiVersion, } from "obsidian"; import { BLANK_DRAWING, @@ -96,7 +97,6 @@ import { import { getFontDataURL, errorlog, - log, setLeftHandedMode, sleep, isVersionNewerThanOther, @@ -133,10 +133,11 @@ import { processLinkText } from "./utils/CustomEmbeddableUtils"; import { getEA } from "src"; import { ExcalidrawImperativeAPI } from "@zsviczian/excalidraw/types/excalidraw/types"; import { Mutable } from "@zsviczian/excalidraw/types/excalidraw/utility-types"; -import { CustomMutationObserver, durationTreshold, isDebugMode } from "./utils/DebugHelper"; +import { CustomMutationObserver, debug, durationTreshold, log } from "./utils/DebugHelper"; import { carveOutImage, carveOutPDF, createImageCropperFile, CROPPED_PREFIX } from "./utils/CarveOut"; import { ExcalidrawConfig } from "./utils/ExcalidrawConfig"; import { EditorHandler } from "./CodeMirrorExtension/EditorHandler"; +import de from "./lang/locale/de"; declare const EXCALIDRAW_PACKAGES:string; declare const react:any; @@ -186,6 +187,7 @@ export default class ExcalidrawPlugin extends Plugin { private stylesManager:StylesManager; private textMeasureDiv:HTMLDivElement = null; public editorHandler: EditorHandler; + public activeLeafChangeEventHandler: (leaf: WorkspaceLeaf) => Promise; constructor(app: App, manifest: PluginManifest) { super(app, manifest); @@ -229,7 +231,7 @@ export default class ExcalidrawPlugin extends Plugin { } public registerEvent(event: any) { - if(!isDebugMode) { + if(!this.settings.isDebugMode) { super.registerEvent(event); return; } @@ -320,6 +322,7 @@ export default class ExcalidrawPlugin extends Plugin { const self = this; this.app.workspace.onLayoutReady(() => { + debug(`ExcalidrawPlugin.onload.app.workspace.onLayoutReady`); this.scriptEngine = new ScriptEngine(self); imageCache.initializeDB(self); }); @@ -329,6 +332,7 @@ export default class ExcalidrawPlugin extends Plugin { private setPropertyTypes() { const app = this.app; this.app.workspace.onLayoutReady(() => { + debug(`ExcalidrawPlugin.setPropertyTypes app.workspace.onLayoutReady`); Object.keys(FRONTMATTER_KEYS).forEach((key) => { if(FRONTMATTER_KEYS[key].depricated === true) return; const {name, type} = FRONTMATTER_KEYS[key]; @@ -339,6 +343,7 @@ export default class ExcalidrawPlugin extends Plugin { public initializeFonts() { this.app.workspace.onLayoutReady(async () => { + debug(`ExcalidrawPlugin.initializeFonts app.workspace.onLayoutReady`); const font = await getFontDataURL( this.app, this.settings.experimantalFourthFont, @@ -393,6 +398,7 @@ export default class ExcalidrawPlugin extends Plugin { private switchToExcalidarwAfterLoad() { const self = this; this.app.workspace.onLayoutReady(() => { + debug(`ExcalidrawPlugin.switchToExcalidarwAfterLoad app.workspace.onLayoutReady`); let leaf: WorkspaceLeaf; for (leaf of this.app.workspace.getLeavesOfType("markdown")) { if ( @@ -620,16 +626,19 @@ export default class ExcalidrawPlugin extends Plugin { * Displays a transcluded .excalidraw image in markdown preview mode */ private addMarkdownPostProcessor() { + //Licat: Are you registering your post processors in onLayoutReady? You should register them in onload instead + initializeMarkdownPostProcessor(this); + this.registerMarkdownPostProcessor(markdownPostProcessor); + const self = this; this.app.workspace.onLayoutReady(() => { - initializeMarkdownPostProcessor(self); - self.registerMarkdownPostProcessor(markdownPostProcessor); + debug(`ExcalidrawPlugin.addMarkdownPostProcessor app.workspace.onLayoutReady`); // internal-link quick preview self.registerEvent(self.app.workspace.on("hover-link", hoverEvent)); //only add the legacy file observer if there are legacy files in the vault - if(this.app.vault.getFiles().some(f=>f.extension === "excalidraw")) { + if(self.app.vault.getFiles().some(f=>f.extension === "excalidraw")) { self.enableLegacyFilePopoverObserver(); } }); @@ -672,7 +681,7 @@ export default class ExcalidrawPlugin extends Plugin { }); }; - this.themeObserver = isDebugMode + this.themeObserver = this.settings.isDebugMode ? new CustomMutationObserver(themeObserverFn, "themeObserver") : new MutationObserver(themeObserverFn); @@ -738,12 +747,13 @@ export default class ExcalidrawPlugin extends Plugin { }); }; - this.fileExplorerObserver = isDebugMode + this.fileExplorerObserver = this.settings.isDebugMode ? new CustomMutationObserver(fileExplorerObserverFn, "fileExplorerObserver") : new MutationObserver(fileExplorerObserverFn); const self = this; this.app.workspace.onLayoutReady(() => { + debug(`ExcalidrawPlugin.experimentalFileTypeDisplay app.workspace.onLayoutReady`); document.querySelectorAll(".nav-file-title").forEach(insertFiletype); //apply filetype to files already displayed const container = document.querySelector(".nav-files-container"); if (container) { @@ -868,9 +878,9 @@ export default class ExcalidrawPlugin extends Plugin { (async () => { const data = await this.app.vault.read(activeFile); - const parts = data.split("%%\n# Drawing\n```compressed-json\n"); + const parts = data.split("\n# Drawing\n```compressed-json\n"); if(parts.length!==2) return; - const header = parts[0] + "%%\n# Drawing\n```json\n"; + const header = parts[0] + "\n# Drawing\n```json\n"; const compressed = parts[1].split("\n```\n%%"); if(compressed.length!==2) return; const decompressed = decompress(compressed[0]); @@ -2413,6 +2423,7 @@ export default class ExcalidrawPlugin extends Plugin { } const self = this; this.app.workspace.onLayoutReady(async () => { + debug(`ExcalidrawPlugin.runStartupScript app.workspace.onLayoutReady: ${self.settings?.startupScriptPath}`); const path = self.settings.startupScriptPath.endsWith(".md") ? self.settings.startupScriptPath : `${self.settings.startupScriptPath}.md`; @@ -2435,6 +2446,7 @@ export default class ExcalidrawPlugin extends Plugin { private registerEventListeners() { const self: ExcalidrawPlugin = this; this.app.workspace.onLayoutReady(async () => { + debug("ExcalidrawPlugin.registerEventListeners app.workspace.onLayoutReady"); const onPasteHandler = ( evt: ClipboardEvent, editor: Editor, @@ -2701,7 +2713,7 @@ export default class ExcalidrawPlugin extends Plugin { const scope = self.app.keymap.getRootScope(); const handler_ctrlEnter = scope.register(["Mod"], "Enter", () => true); scope.keys.unshift(scope.keys.pop()); // Force our handler to the front of the list - const handler_ctrlK = scope.register(["Mod"], "k", () => {return true}); + const handler_ctrlK = scope.register(["Mod"], "k", () => true); scope.keys.unshift(scope.keys.pop()); // Force our handler to the front of the list const handler_ctrlF = scope.register(["Mod"], "f", () => { const view = this.app.workspace.getActiveViewOfType(ExcalidrawView); @@ -2731,8 +2743,9 @@ export default class ExcalidrawPlugin extends Plugin { } } }; + this.activeLeafChangeEventHandler = activeLeafChangeEventHandler; self.registerEvent( - app.workspace.on( + this.app.workspace.on( "active-leaf-change", activeLeafChangeEventHandler, ), @@ -2740,7 +2753,7 @@ export default class ExcalidrawPlugin extends Plugin { self.addFileSaveTriggerEventHandlers(); - const metaCache: MetadataCache = app.metadataCache; + const metaCache: MetadataCache = this.app.metadataCache; //@ts-ignore metaCache.getCachedFiles().forEach((filename: string) => { const fm = metaCache.getCache(filename)?.frontmatter; @@ -2749,7 +2762,7 @@ export default class ExcalidrawPlugin extends Plugin { filename.match(/\.excalidraw$/) ) { self.updateFileCache( - app.vault.getAbstractFileByPath(filename) as TFile, + this.app.vault.getAbstractFileByPath(filename) as TFile, fm, ); } @@ -2822,14 +2835,14 @@ export default class ExcalidrawPlugin extends Plugin { }; if (leftWorkspaceDrawer) { - this.workspaceDrawerLeftObserver = isDebugMode + this.workspaceDrawerLeftObserver = this.settings.isDebugMode ? new CustomMutationObserver(action, "slidingDrawerLeftObserver") : new MutationObserver(action); this.workspaceDrawerLeftObserver.observe(leftWorkspaceDrawer, options); } if (rightWorkspaceDrawer) { - this.workspaceDrawerRightObserver = isDebugMode + this.workspaceDrawerRightObserver = this.settings.isDebugMode ? new CustomMutationObserver(action, "slidingDrawerRightObserver") : new MutationObserver(action); this.workspaceDrawerRightObserver.observe( @@ -2863,7 +2876,7 @@ export default class ExcalidrawPlugin extends Plugin { this.activeExcalidrawView.save(); }; - this.modalContainerObserver = isDebugMode + this.modalContainerObserver = this.settings.isDebugMode ? new CustomMutationObserver(modalContainerObserverFn, "modalContainerObserver") : new MutationObserver(modalContainerObserverFn); this.activeViewDoc = this.activeExcalidrawView.ownerDocument; diff --git a/src/ocr/Taskbone.ts b/src/ocr/Taskbone.ts index 40fade0..e70467c 100644 --- a/src/ocr/Taskbone.ts +++ b/src/ocr/Taskbone.ts @@ -1,13 +1,13 @@ import { ExcalidrawAutomate, createPNG } from "../ExcalidrawAutomate"; import {Notice, requestUrl} from "obsidian" import ExcalidrawPlugin from "../main" -import {log} from "../utils/Utils" import ExcalidrawView, { ExportSettings } from "../ExcalidrawView" import FrontmatterEditor from "src/utils/Frontmatter"; import { ExcalidrawElement } from "@zsviczian/excalidraw/types/excalidraw/element/types"; import { EmbeddedFilesLoader } from "src/EmbeddedFileLoader"; import { blobToBase64 } from "src/utils/FileUtils"; import { getEA } from "src"; +import { log } from "src/utils/DebugHelper"; const TASKBONE_URL = "https://api.taskbone.com/"; //"https://excalidraw-preview.onrender.com/"; const TASKBONE_OCR_FN = "execute?id=60f394af-85f6-40bc-9613-5d26dc283cbb"; diff --git a/src/settings.ts b/src/settings.ts index 90d148a..db14c65 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -44,6 +44,7 @@ export interface ExcalidrawSettings { templateFilePath: string; scriptFolderPath: string; compress: boolean; + decompressForMDView: boolean; autosave: boolean; autosaveInterval: number; autosaveIntervalDesktop: number; @@ -188,6 +189,7 @@ export interface ExcalidrawSettings { areaZoomLimit: number; longPressDesktop: number; longPressMobile: number; + isDebugMode: boolean; } declare const PLUGIN_VERSION:string; @@ -200,6 +202,7 @@ export const DEFAULT_SETTINGS: ExcalidrawSettings = { templateFilePath: "Excalidraw/Template.excalidraw", scriptFolderPath: "Excalidraw/Scripts", compress: false, + decompressForMDView: true, autosave: true, autosaveInterval: 15000, autosaveIntervalDesktop: 15000, @@ -436,6 +439,7 @@ export const DEFAULT_SETTINGS: ExcalidrawSettings = { areaZoomLimit: 1, longPressDesktop: 500, longPressMobile: 500, + isDebugMode: false, }; export class ExcalidrawSettingTab extends PluginSettingTab { @@ -662,6 +666,18 @@ export class ExcalidrawSettingTab extends PluginSettingTab { }), ); + new Setting(detailsEl) + .setName(t("DECOMPRESS_FOR_MD_NAME")) + .setDesc(fragWithHTML(t("DECOMPRESS_FOR_MD_DESC"))) + .addToggle((toggle) => + toggle + .setValue(this.plugin.settings.decompressForMDView) + .onChange(async (value) => { + this.plugin.settings.decompressForMDView = value; + this.applySettingsUpdate(); + }), + ); + new Setting(detailsEl) .setName(t("AUTOSAVE_INTERVAL_DESKTOP_NAME")) .setDesc(fragWithHTML(t("AUTOSAVE_INTERVAL_DESKTOP_DESC"))) @@ -2461,6 +2477,19 @@ export class ExcalidrawSettingTab extends PluginSettingTab { cls: "excalidraw-setting-h1", }); + new Setting(detailsEl) + .setName(t("DEBUGMODE_NAME")) + .setDesc(fragWithHTML(t("DEBUGMODE_DESC"))) + .addToggle((toggle) => + toggle + .setValue(this.plugin.settings.isDebugMode) + .onChange((value) => { + this.plugin.settings.isDebugMode = value; + this.applySettingsUpdate(); + }), + ); + + new Setting(detailsEl) .setName(t("SLIDING_PANES_NAME")) .setDesc(fragWithHTML(t("SLIDING_PANES_DESC"))) diff --git a/src/svgToExcalidraw/parser.ts b/src/svgToExcalidraw/parser.ts index 4f36168..f313fb7 100644 --- a/src/svgToExcalidraw/parser.ts +++ b/src/svgToExcalidraw/parser.ts @@ -4,37 +4,46 @@ import { createTreeWalker, walk } from "./walker"; export type ConversionResult = { hasErrors: boolean; - errors: NodeListOf | null; + errors: string; content: any; // Serialized Excalidraw JSON }; export const svgToExcalidraw = (svgString: string): ConversionResult => { - const parser = new DOMParser(); - const svgDOM = parser.parseFromString(svgString, "image/svg+xml"); + try { + const parser = new DOMParser(); + const svgDOM = parser.parseFromString(svgString, "image/svg+xml"); - // was there a parsing error? - const errorsElements = svgDOM.querySelectorAll("parsererror"); - const hasErrors = errorsElements.length > 0; - let content = null; + // was there a parsing error? + const errorsElements = svgDOM.querySelectorAll("parsererror"); + const hasErrors = errorsElements.length > 0; + let content = null; - if (hasErrors) { - console.error( - "There were errors while parsing the given SVG: ", - [...errorsElements].map((el) => el.innerHTML), - ); - } else { - const tw = createTreeWalker(svgDOM); - const scene = new ExcalidrawScene(); - const groups: Group[] = []; + if (hasErrors) { + console.error( + "There were errors while parsing the given SVG: ", + [...errorsElements].map((el) => el.innerHTML), + ); + } else { + const tw = createTreeWalker(svgDOM); + const scene = new ExcalidrawScene(); + const groups: Group[] = []; - walk({ tw, scene, groups, root: svgDOM }, tw.nextNode()); + walk({ tw, scene, groups, root: svgDOM }, tw.nextNode()); - content = scene.elements; //scene.toExJSON(); + content = scene.elements; //scene.toExJSON(); + } + + return { + hasErrors, + errors: hasErrors ? `${[...errorsElements].map((el) => el.innerHTML)}` : "", + content, + }; + } catch (error) { + console.log(error); + return { + hasErrors: true, + errors: `${error}`, + content:[], + }; } - - return { - hasErrors, - errors: hasErrors ? errorsElements : null, - content, - }; }; diff --git a/src/utils/CanvasNodeFactory.ts b/src/utils/CanvasNodeFactory.ts index 8e91f3a..7ed8336 100644 --- a/src/utils/CanvasNodeFactory.ts +++ b/src/utils/CanvasNodeFactory.ts @@ -110,7 +110,7 @@ export class CanvasNodeFactory { } } }; - const observer = isDebugMode + const observer = isDebugMode() ? new CustomMutationObserver(nodeObserverFn, "CanvasNodeFactory") : new MutationObserver(nodeObserverFn); diff --git a/src/utils/DebugHelper.ts b/src/utils/DebugHelper.ts index 0746d37..082c78e 100644 --- a/src/utils/DebugHelper.ts +++ b/src/utils/DebugHelper.ts @@ -1,5 +1,15 @@ -export const isDebugMode = false; +import { EXCALIDRAW_PLUGIN } from "src/constants/constants"; + + export const durationTreshold = 0; //0.05; //ms +export const isDebugMode = () => EXCALIDRAW_PLUGIN && EXCALIDRAW_PLUGIN.settings?.isDebugMode; + +export const log = console.log.bind(window.console); +export const debug = (...messages: unknown[]) => { + if(isDebugMode()) { + console.log(...messages); + } +}; export class CustomMutationObserver { private originalCallback: MutationCallback; diff --git a/src/utils/DynamicStyling.ts b/src/utils/DynamicStyling.ts index 4ba6b78..5d45bd4 100644 --- a/src/utils/DynamicStyling.ts +++ b/src/utils/DynamicStyling.ts @@ -114,7 +114,8 @@ export const setDynamicStyle = ( [`--h2-color`]: str(text), [`--h3-color`]: str(text), [`--h4-color`]: str(text), - [`color`]: str(text), + [`color`]: str(text), + ['--excalidraw-caret-color']: str(text), [`--select-highlight-color`]: str(gray1()), [`--color-gray-80`]: str(isDark?text.darkerBy(40):text.lighterBy(40)), //frame }; diff --git a/src/utils/ImageCache.ts b/src/utils/ImageCache.ts index a6af74d..a169795 100644 --- a/src/utils/ImageCache.ts +++ b/src/utils/ImageCache.ts @@ -2,7 +2,6 @@ import { App, Notice, TFile } from "obsidian"; import ExcalidrawPlugin from "src/main"; import { convertSVGStringToElement } from "./Utils"; import { FILENAMEPARTS, PreviewImageType } from "./UtilTypes"; -import { has } from "src/svgToExcalidraw/attributes"; import { hasExcalidrawEmbeddedImagesTreeChanged } from "./FileUtils"; //@ts-ignore diff --git a/src/utils/StylesManager.ts b/src/utils/StylesManager.ts index 09d09eb..4151f01 100644 --- a/src/utils/StylesManager.ts +++ b/src/utils/StylesManager.ts @@ -1,6 +1,7 @@ import { WorkspaceWindow } from "obsidian"; import ExcalidrawPlugin from "src/main"; import { getAllWindowDocuments } from "./ObsidianUtils"; +import { debug } from "./DebugHelper"; const STYLE_VARIABLES = ["--background-modifier-cover","--background-primary-alt","--background-secondary","--background-secondary-alt","--background-modifier-border","--text-normal","--text-muted","--text-accent","--text-accent-hover","--text-faint","--text-highlight-bg","--text-highlight-bg-active","--text-selection","--interactive-normal","--interactive-hover","--interactive-accent","--interactive-accent-hover","--scrollbar-bg","--scrollbar-thumb-bg","--scrollbar-active-thumb-bg"]; const EXCALIDRAW_CONTAINER_CLASS = "excalidraw__embeddable__outer"; @@ -16,6 +17,7 @@ export class StylesManager { constructor(plugin: ExcalidrawPlugin) { this.plugin = plugin; plugin.app.workspace.onLayoutReady(async () => { + debug("StylesManager.constructor app.workspace.onLayoutReady"); await this.harvestStyles(); getAllWindowDocuments(plugin.app).forEach(doc => { this.copyPropertiesToTheme(doc); diff --git a/src/utils/Utils.ts b/src/utils/Utils.ts index 68e51a3..472e85e 100644 --- a/src/utils/Utils.ts +++ b/src/utils/Utils.ts @@ -27,14 +27,11 @@ import { ExcalidrawElement } from "@zsviczian/excalidraw/types/excalidraw/elemen import { ExportSettings } from "../ExcalidrawView"; import { getDataURLFromURL, getIMGFilename, getMimeType, getURLImageExtension } from "./FileUtils"; import { generateEmbeddableLink } from "./CustomEmbeddableUtils"; -import ExcalidrawScene from "src/svgToExcalidraw/elements/ExcalidrawScene"; import { FILENAMEPARTS } from "./UtilTypes"; import { Mutable } from "@zsviczian/excalidraw/types/excalidraw/utility-types"; import { cleanBlockRef, cleanSectionHeading, getFileCSSClasses } from "./ObsidianUtils"; import { updateElementLinksToObsidianLinks } from "src/ExcalidrawAutomate"; import { CropImage } from "./CropImage"; -import { ExcalidrawData } from "src/ExcalidrawData"; -import { ExcalidrawGenericElement } from "lib/svgToExcalidraw/types"; declare const PLUGIN_VERSION:string; @@ -546,7 +543,7 @@ export const getLinkParts = (fname: string, file?: TFile): LinkParts => { }; export const compress = (data: string): string => { - return LZString.compressToBase64(data).replace(/(.{64})/g, "$1\n\n"); + return LZString.compressToBase64(data).replace(/(.{256})/g, "$1\n\n"); }; export const decompress = (data: string): string => { @@ -764,8 +761,6 @@ export const sleep = async (ms: number) => new Promise((resolve) => setTimeout(r export const awaitNextAnimationFrame = async () => new Promise(requestAnimationFrame); */ -export const log = console.log.bind(window.console); -export const debug = console.log.bind(window.console); //export const debug = function(){}; diff --git a/styles.css b/styles.css index a64b4b7..643ab71 100644 --- a/styles.css +++ b/styles.css @@ -579,4 +579,19 @@ img.excalidraw-cropped-pdfpage, .ex-opacity-0 { opacity: 0; +} + +.popover .excalidraw-svg { + width: 100%; + max-width: inherit; + height: 100%; + max-height: inherit; +} + +root { + --excalidraw-caret-color: initial; +} + +textarea.excalidraw-wysiwyg, .excalidraw input { + caret-color: var(--excalidraw-caret-color); } \ No newline at end of file