mirror of
https://github.com/zsviczian/obsidian-excalidraw-plugin.git
synced 2025-08-06 05:46:28 +00:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9c5b48c037 | |||
| 4406709920 | |||
| b7ba0f8909 | |||
| c28911c739 | |||
| 28088754ad |
+1
-1
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"id": "obsidian-excalidraw-plugin",
|
||||
"name": "Excalidraw",
|
||||
"version": "2.6.8",
|
||||
"version": "2.7.0-beta-1",
|
||||
"minAppVersion": "1.1.6",
|
||||
"description": "An Obsidian plugin to edit and view Excalidraw drawings",
|
||||
"author": "Zsolt Viczian",
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@popperjs/core": "^2.11.8",
|
||||
"@zsviczian/excalidraw": "0.17.6-18",
|
||||
"@zsviczian/excalidraw": "0.17.6-19",
|
||||
"chroma-js": "^2.4.2",
|
||||
"clsx": "^2.0.0",
|
||||
"@zsviczian/colormaster": "^1.2.2",
|
||||
|
||||
@@ -701,7 +701,11 @@ export class EmbeddedFilesLoader {
|
||||
return;
|
||||
}
|
||||
const data = getMermaidText(element);
|
||||
const result = await mermaidToExcalidraw(data, {fontSize: 20}, true);
|
||||
const result = await mermaidToExcalidraw(
|
||||
data,
|
||||
{ themeVariables: { fontSize: "20" } },
|
||||
true
|
||||
);
|
||||
if(!result) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1489,7 +1489,12 @@ export class ExcalidrawAutomate {
|
||||
diagram: string,
|
||||
groupElements: boolean = true,
|
||||
): Promise<string[]|string> {
|
||||
const result = await mermaidToExcalidraw(diagram, {fontSize: this.style.fontSize});
|
||||
const result = await mermaidToExcalidraw(
|
||||
diagram, {
|
||||
themeVariables: {fontSize: `${this.style.fontSize}`},
|
||||
flowchart: {curve: this.style.roundness===null ? "linear" : "basis"},
|
||||
}
|
||||
);
|
||||
const ids:string[] = [];
|
||||
if(!result) return null;
|
||||
if(result?.error) return result.error;
|
||||
|
||||
Vendored
+33
-2
@@ -6,7 +6,38 @@ import { FontMetadata } from "@zsviczian/excalidraw/types/excalidraw/fonts/metad
|
||||
import { AppState, BinaryFiles, DataURL, GenerateDiagramToCode, Zoom } from "@zsviczian/excalidraw/types/excalidraw/types";
|
||||
import { Mutable } from "@zsviczian/excalidraw/types/excalidraw/utility-types";
|
||||
import { GlobalPoint } from "@zsviczian/excalidraw/types/math/types";
|
||||
import ExcalidrawPlugin from "./main";
|
||||
|
||||
interface MermaidConfig {
|
||||
/**
|
||||
* Whether to start the diagram automatically when the page loads.
|
||||
* @default false
|
||||
*/
|
||||
startOnLoad?: boolean;
|
||||
/**
|
||||
* The flowchart curve style.
|
||||
* @default "linear"
|
||||
*/
|
||||
flowchart?: {
|
||||
curve?: "linear" | "basis";
|
||||
};
|
||||
/**
|
||||
* Theme variables
|
||||
* @default { fontSize: "25px" }
|
||||
*/
|
||||
themeVariables?: {
|
||||
fontSize?: string;
|
||||
};
|
||||
/**
|
||||
* Maximum number of edges to be rendered.
|
||||
* @default 1000
|
||||
*/
|
||||
maxEdges?: number;
|
||||
/**
|
||||
* Maximum number of characters to be rendered.
|
||||
* @default 1000
|
||||
*/
|
||||
maxTextSize?: number;
|
||||
}
|
||||
|
||||
type EmbeddedLink =
|
||||
| ({
|
||||
@@ -159,7 +190,7 @@ declare namespace ExcalidrawLib {
|
||||
|
||||
function mermaidToExcalidraw(
|
||||
mermaidDefinition: string,
|
||||
opts: {fontSize: number},
|
||||
opts: MermaidConfig,
|
||||
forceSVG?: boolean,
|
||||
): Promise<{
|
||||
elements?: ExcalidrawElement[];
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { FILE } from "dns";
|
||||
import {
|
||||
DEVICE,
|
||||
FRONTMATTER_KEYS,
|
||||
@@ -10,6 +11,8 @@ declare const PLUGIN_VERSION:string;
|
||||
|
||||
// 简体中文
|
||||
export default {
|
||||
// Sugester
|
||||
SELECT_FILE_TO_INSERT: "选择一个要插入的文件",
|
||||
// main.ts
|
||||
CONVERT_URL_TO_FILE: "从 URL 下载图像到本地",
|
||||
UNZIP_CURRENT_FILE: "解压当前 Excalidraw 文件",
|
||||
|
||||
+211
-214
@@ -19,7 +19,6 @@ import {
|
||||
Workspace,
|
||||
Editor,
|
||||
MarkdownFileInfo,
|
||||
loadMermaid,
|
||||
} from "obsidian";
|
||||
import {
|
||||
BLANK_DRAWING,
|
||||
@@ -386,23 +385,8 @@ export default class ExcalidrawPlugin extends Plugin {
|
||||
this.addRibbonIcon(ICON_NAME, t("CREATE_NEW"), this.actionRibbonClick.bind(this));
|
||||
|
||||
try {
|
||||
this.loadSettings({reEnableAutosave:true}).then(async () => {
|
||||
const updateSettings = !this.settings.onceOffCompressFlagReset || !this.settings.onceOffGPTVersionReset;
|
||||
if(!this.settings.onceOffCompressFlagReset) {
|
||||
this.settings.compress = true;
|
||||
this.settings.onceOffCompressFlagReset = true;
|
||||
}
|
||||
if(!this.settings.onceOffGPTVersionReset) {
|
||||
if(this.settings.openAIDefaultVisionModel === "gpt-4-vision-preview") {
|
||||
this.settings.openAIDefaultVisionModel = "gpt-4o";
|
||||
}
|
||||
}
|
||||
if(updateSettings) {
|
||||
await this.saveSettings();
|
||||
}
|
||||
this.addSettingTab(new ExcalidrawSettingTab(this.app, this));
|
||||
this.settingsReady = true;
|
||||
});
|
||||
this.loadSettings({reEnableAutosave:true})
|
||||
.then(this.onloadCheckForOnceOffSettingsUpdates.bind(this));
|
||||
} catch (e) {
|
||||
new Notice("Error loading plugin settings", 6000);
|
||||
console.error("Error loading plugin settings", e);
|
||||
@@ -427,205 +411,218 @@ export default class ExcalidrawPlugin extends Plugin {
|
||||
}
|
||||
this.logStartupEvent("Markdown post processor added");
|
||||
|
||||
this.app.workspace.onLayoutReady(async () => {
|
||||
this.loadTimestamp = Date.now();
|
||||
this.lastLogTimestamp = this.loadTimestamp;
|
||||
this.logStartupEvent("\n----------------------------------\nWorkspace onLayoutReady event fired (these actions are outside the plugin initialization)");
|
||||
await this.awaitSettings();
|
||||
this.logStartupEvent("Settings awaited");
|
||||
try {
|
||||
unpackExcalidraw();
|
||||
excalidrawLib = window.eval.call(window,`(function() {${EXCALIDRAW_PACKAGE};return ExcalidrawLib;})()`);
|
||||
this.packageMap.set(window,{react, reactDOM, excalidrawLib});
|
||||
updateExcalidrawLib();
|
||||
} catch (e) {
|
||||
new Notice("Error loading the Excalidraw package", 6000);
|
||||
console.error("Error loading the Excalidraw package", e);
|
||||
}
|
||||
this.logStartupEvent("Excalidraw package unpacked");
|
||||
|
||||
try {
|
||||
initCompressionWorker();
|
||||
} catch (e) {
|
||||
new Notice("Error initializing compression worker", 6000);
|
||||
console.error("Error initializing compression worker", e);
|
||||
}
|
||||
this.logStartupEvent("Compression worker initialized");
|
||||
|
||||
try {
|
||||
this.excalidrawConfig = new ExcalidrawConfig(this);
|
||||
} catch (e) {
|
||||
new Notice("Error initializing Excalidraw config", 6000);
|
||||
console.error("Error initializing Excalidraw config", e);
|
||||
}
|
||||
this.logStartupEvent("Excalidraw config initialized");
|
||||
|
||||
try {
|
||||
await loadMermaid();
|
||||
} catch (e) {
|
||||
new Notice("Error loading Mermaid", 6000);
|
||||
console.error("Error loading Mermaid", e);
|
||||
}
|
||||
this.logStartupEvent("Mermaid loaded");
|
||||
|
||||
try {
|
||||
this.addThemeObserver();
|
||||
} catch (e) {
|
||||
new Notice("Error adding theme observer", 6000);
|
||||
console.error("Error adding theme observer", e);
|
||||
}
|
||||
this.logStartupEvent("Theme observer added");
|
||||
|
||||
try {
|
||||
//inspiration taken from kanban:
|
||||
//https://github.com/mgmeyers/obsidian-kanban/blob/44118e25661bff9ebfe54f71ae33805dc88ffa53/src/main.ts#L267
|
||||
this.registerMonkeyPatches();
|
||||
} catch (e) {
|
||||
new Notice("Error registering monkey patches", 6000);
|
||||
console.error("Error registering monkey patches", e);
|
||||
}
|
||||
this.logStartupEvent("Monkey patches registered");
|
||||
|
||||
try {
|
||||
this.stylesManager = new StylesManager(this);
|
||||
} catch (e) {
|
||||
new Notice("Error initializing styles manager", 6000);
|
||||
console.error("Error initializing styles manager", e);
|
||||
}
|
||||
this.logStartupEvent("Styles manager initialized");
|
||||
|
||||
try {
|
||||
this.scriptEngine = new ScriptEngine(this);
|
||||
} catch (e) {
|
||||
new Notice("Error initializing script engine", 6000);
|
||||
console.error("Error initializing script engine", e);
|
||||
}
|
||||
this.logStartupEvent("Script engine initialized");
|
||||
|
||||
try {
|
||||
await this.initializeFonts();
|
||||
} catch (e) {
|
||||
new Notice("Error initializing fonts", 6000);
|
||||
console.error("Error initializing fonts", e);
|
||||
}
|
||||
this.logStartupEvent("Fonts initialized");
|
||||
|
||||
try {
|
||||
imageCache.initializeDB(this);
|
||||
} catch (e) {
|
||||
new Notice("Error initializing image cache", 6000);
|
||||
console.error("Error initializing image cache", e);
|
||||
}
|
||||
this.logStartupEvent("Image cache initialized");
|
||||
|
||||
try {
|
||||
this.isReady = true;
|
||||
switchToExcalidraw(this.app);
|
||||
this.switchToExcalidarwAfterLoad();
|
||||
} catch (e) {
|
||||
new Notice("Error switching views to Excalidraw", 6000);
|
||||
console.error("Error switching views to Excalidraw", e);
|
||||
}
|
||||
this.logStartupEvent("Switched to Excalidraw views");
|
||||
|
||||
try {
|
||||
if (this.settings.showReleaseNotes) {
|
||||
//I am repurposing imageElementNotice, if the value is true, this means the plugin was just newly installed to Obsidian.
|
||||
const obsidianJustInstalled = (this.settings.previousRelease === "0.0.0") || !this.settings.previousRelease;
|
||||
|
||||
if (isVersionNewerThanOther(PLUGIN_VERSION, this.settings.previousRelease ?? "0.0.0")) {
|
||||
new ReleaseNotes(
|
||||
this.app,
|
||||
this,
|
||||
obsidianJustInstalled ? null : PLUGIN_VERSION,
|
||||
).open();
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
new Notice("Error opening release notes", 6000);
|
||||
console.error("Error opening release notes", e);
|
||||
}
|
||||
this.logStartupEvent("Release notes opened");
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
//initialization that can happen after Excalidraw views are initialized
|
||||
//---------------------------------------------------------------------
|
||||
try {
|
||||
this.registerEventListeners();
|
||||
} catch (e) {
|
||||
new Notice("Error registering event listeners", 6000);
|
||||
console.error("Error registering event listeners", e);
|
||||
}
|
||||
this.logStartupEvent("Event listeners registered");
|
||||
|
||||
try {
|
||||
this.runStartupScript();
|
||||
} catch (e) {
|
||||
new Notice("Error running startup script", 6000);
|
||||
console.error("Error running startup script", e);
|
||||
}
|
||||
this.logStartupEvent("Startup script run");
|
||||
|
||||
try {
|
||||
this.editorHandler = new EditorHandler(this);
|
||||
this.editorHandler.setup();
|
||||
} catch (e) {
|
||||
new Notice("Error setting up editor handler", 6000);
|
||||
console.error("Error setting up editor handler", e);
|
||||
}
|
||||
this.logStartupEvent("Editor handler initialized");
|
||||
|
||||
try {
|
||||
this.registerInstallCodeblockProcessor();
|
||||
} catch (e) {
|
||||
new Notice("Error registering script install-codeblock processor", 6000);
|
||||
console.error("Error registering script install-codeblock processor", e);
|
||||
}
|
||||
this.logStartupEvent("Script install-codeblock processor registered");
|
||||
|
||||
try {
|
||||
this.experimentalFileTypeDisplayToggle(this.settings.experimentalFileType);
|
||||
} catch (e) {
|
||||
new Notice("Error setting up experimental file type display", 6000);
|
||||
console.error("Error setting up experimental file type display", e);
|
||||
}
|
||||
this.logStartupEvent("Experimental file type display set");
|
||||
|
||||
try {
|
||||
this.registerCommands();
|
||||
} catch (e) {
|
||||
new Notice("Error registering commands", 6000);
|
||||
console.error("Error registering commands", e);
|
||||
}
|
||||
this.logStartupEvent("Commands registered");
|
||||
|
||||
try {
|
||||
this.registerEditorSuggest(new FieldSuggester(this));
|
||||
} catch (e) {
|
||||
new Notice("Error registering editor suggester", 6000);
|
||||
console.error("Error registering editor suggester", e);
|
||||
}
|
||||
this.logStartupEvent("Editor suggester registered");
|
||||
|
||||
try {
|
||||
this.setPropertyTypes();
|
||||
} catch (e) {
|
||||
new Notice("Error setting up property types", 6000);
|
||||
console.error("Error setting up property types", e);
|
||||
}
|
||||
this.logStartupEvent("Property types set");
|
||||
|
||||
try {
|
||||
this.taskbone = new Taskbone(this);
|
||||
} catch (e) {
|
||||
new Notice("Error setting up taskbone", 6000);
|
||||
console.error("Error setting up taskbone", e);
|
||||
}
|
||||
this.logStartupEvent("Taskbone set up");
|
||||
});
|
||||
this.app.workspace.onLayoutReady(this.onloadOnLayoutReady.bind(this));
|
||||
this.logStartupEvent("Workspace ready event handler added");
|
||||
}
|
||||
|
||||
private async onloadCheckForOnceOffSettingsUpdates() {
|
||||
const updateSettings = !this.settings.onceOffCompressFlagReset || !this.settings.onceOffGPTVersionReset;
|
||||
if(!this.settings.onceOffCompressFlagReset) {
|
||||
this.settings.compress = true;
|
||||
this.settings.onceOffCompressFlagReset = true;
|
||||
}
|
||||
if(!this.settings.onceOffGPTVersionReset) {
|
||||
this.settings.onceOffGPTVersionReset = true;
|
||||
if(this.settings.openAIDefaultVisionModel === "gpt-4-vision-preview") {
|
||||
this.settings.openAIDefaultVisionModel = "gpt-4o";
|
||||
}
|
||||
}
|
||||
if(updateSettings) {
|
||||
await this.saveSettings();
|
||||
}
|
||||
this.addSettingTab(new ExcalidrawSettingTab(this.app, this));
|
||||
this.settingsReady = true;
|
||||
}
|
||||
|
||||
private async onloadOnLayoutReady() {
|
||||
this.loadTimestamp = Date.now();
|
||||
this.lastLogTimestamp = this.loadTimestamp;
|
||||
this.logStartupEvent("\n----------------------------------\nWorkspace onLayoutReady event fired (these actions are outside the plugin initialization)");
|
||||
await this.awaitSettings();
|
||||
this.logStartupEvent("Settings awaited");
|
||||
try {
|
||||
unpackExcalidraw();
|
||||
excalidrawLib = window.eval.call(window,`(function() {${EXCALIDRAW_PACKAGE};return ExcalidrawLib;})()`);
|
||||
this.packageMap.set(window,{react, reactDOM, excalidrawLib});
|
||||
updateExcalidrawLib();
|
||||
} catch (e) {
|
||||
new Notice("Error loading the Excalidraw package", 6000);
|
||||
console.error("Error loading the Excalidraw package", e);
|
||||
}
|
||||
this.logStartupEvent("Excalidraw package unpacked");
|
||||
|
||||
try {
|
||||
initCompressionWorker();
|
||||
} catch (e) {
|
||||
new Notice("Error initializing compression worker", 6000);
|
||||
console.error("Error initializing compression worker", e);
|
||||
}
|
||||
this.logStartupEvent("Compression worker initialized");
|
||||
|
||||
try {
|
||||
this.excalidrawConfig = new ExcalidrawConfig(this);
|
||||
} catch (e) {
|
||||
new Notice("Error initializing Excalidraw config", 6000);
|
||||
console.error("Error initializing Excalidraw config", e);
|
||||
}
|
||||
this.logStartupEvent("Excalidraw config initialized");
|
||||
|
||||
try {
|
||||
this.addThemeObserver();
|
||||
} catch (e) {
|
||||
new Notice("Error adding theme observer", 6000);
|
||||
console.error("Error adding theme observer", e);
|
||||
}
|
||||
this.logStartupEvent("Theme observer added");
|
||||
|
||||
try {
|
||||
//inspiration taken from kanban:
|
||||
//https://github.com/mgmeyers/obsidian-kanban/blob/44118e25661bff9ebfe54f71ae33805dc88ffa53/src/main.ts#L267
|
||||
this.registerMonkeyPatches();
|
||||
} catch (e) {
|
||||
new Notice("Error registering monkey patches", 6000);
|
||||
console.error("Error registering monkey patches", e);
|
||||
}
|
||||
this.logStartupEvent("Monkey patches registered");
|
||||
|
||||
try {
|
||||
this.stylesManager = new StylesManager(this);
|
||||
} catch (e) {
|
||||
new Notice("Error initializing styles manager", 6000);
|
||||
console.error("Error initializing styles manager", e);
|
||||
}
|
||||
this.logStartupEvent("Styles manager initialized");
|
||||
|
||||
try {
|
||||
this.scriptEngine = new ScriptEngine(this);
|
||||
} catch (e) {
|
||||
new Notice("Error initializing script engine", 6000);
|
||||
console.error("Error initializing script engine", e);
|
||||
}
|
||||
this.logStartupEvent("Script engine initialized");
|
||||
|
||||
try {
|
||||
await this.initializeFonts();
|
||||
} catch (e) {
|
||||
new Notice("Error initializing fonts", 6000);
|
||||
console.error("Error initializing fonts", e);
|
||||
}
|
||||
this.logStartupEvent("Fonts initialized");
|
||||
|
||||
try {
|
||||
imageCache.initializeDB(this);
|
||||
} catch (e) {
|
||||
new Notice("Error initializing image cache", 6000);
|
||||
console.error("Error initializing image cache", e);
|
||||
}
|
||||
this.logStartupEvent("Image cache initialized");
|
||||
|
||||
try {
|
||||
this.isReady = true;
|
||||
switchToExcalidraw(this.app);
|
||||
this.switchToExcalidarwAfterLoad();
|
||||
} catch (e) {
|
||||
new Notice("Error switching views to Excalidraw", 6000);
|
||||
console.error("Error switching views to Excalidraw", e);
|
||||
}
|
||||
this.logStartupEvent("Switched to Excalidraw views");
|
||||
|
||||
try {
|
||||
if (this.settings.showReleaseNotes) {
|
||||
//I am repurposing imageElementNotice, if the value is true, this means the plugin was just newly installed to Obsidian.
|
||||
const obsidianJustInstalled = (this.settings.previousRelease === "0.0.0") || !this.settings.previousRelease;
|
||||
|
||||
if (isVersionNewerThanOther(PLUGIN_VERSION, this.settings.previousRelease ?? "0.0.0")) {
|
||||
new ReleaseNotes(
|
||||
this.app,
|
||||
this,
|
||||
obsidianJustInstalled ? null : PLUGIN_VERSION,
|
||||
).open();
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
new Notice("Error opening release notes", 6000);
|
||||
console.error("Error opening release notes", e);
|
||||
}
|
||||
this.logStartupEvent("Release notes opened");
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
//initialization that can happen after Excalidraw views are initialized
|
||||
//---------------------------------------------------------------------
|
||||
try {
|
||||
this.registerEventListeners();
|
||||
} catch (e) {
|
||||
new Notice("Error registering event listeners", 6000);
|
||||
console.error("Error registering event listeners", e);
|
||||
}
|
||||
this.logStartupEvent("Event listeners registered");
|
||||
|
||||
try {
|
||||
this.runStartupScript();
|
||||
} catch (e) {
|
||||
new Notice("Error running startup script", 6000);
|
||||
console.error("Error running startup script", e);
|
||||
}
|
||||
this.logStartupEvent("Startup script run");
|
||||
|
||||
try {
|
||||
this.editorHandler = new EditorHandler(this);
|
||||
this.editorHandler.setup();
|
||||
} catch (e) {
|
||||
new Notice("Error setting up editor handler", 6000);
|
||||
console.error("Error setting up editor handler", e);
|
||||
}
|
||||
this.logStartupEvent("Editor handler initialized");
|
||||
|
||||
try {
|
||||
this.registerInstallCodeblockProcessor();
|
||||
} catch (e) {
|
||||
new Notice("Error registering script install-codeblock processor", 6000);
|
||||
console.error("Error registering script install-codeblock processor", e);
|
||||
}
|
||||
this.logStartupEvent("Script install-codeblock processor registered");
|
||||
|
||||
try {
|
||||
this.experimentalFileTypeDisplayToggle(this.settings.experimentalFileType);
|
||||
} catch (e) {
|
||||
new Notice("Error setting up experimental file type display", 6000);
|
||||
console.error("Error setting up experimental file type display", e);
|
||||
}
|
||||
this.logStartupEvent("Experimental file type display set");
|
||||
|
||||
try {
|
||||
this.registerCommands();
|
||||
} catch (e) {
|
||||
new Notice("Error registering commands", 6000);
|
||||
console.error("Error registering commands", e);
|
||||
}
|
||||
this.logStartupEvent("Commands registered");
|
||||
|
||||
try {
|
||||
this.registerEditorSuggest(new FieldSuggester(this));
|
||||
} catch (e) {
|
||||
new Notice("Error registering editor suggester", 6000);
|
||||
console.error("Error registering editor suggester", e);
|
||||
}
|
||||
this.logStartupEvent("Editor suggester registered");
|
||||
|
||||
try {
|
||||
this.setPropertyTypes();
|
||||
} catch (e) {
|
||||
new Notice("Error setting up property types", 6000);
|
||||
console.error("Error setting up property types", e);
|
||||
}
|
||||
this.logStartupEvent("Property types set");
|
||||
|
||||
try {
|
||||
this.taskbone = new Taskbone(this);
|
||||
} catch (e) {
|
||||
new Notice("Error setting up taskbone", 6000);
|
||||
console.error("Error setting up taskbone", e);
|
||||
}
|
||||
this.logStartupEvent("Taskbone set up");
|
||||
}
|
||||
|
||||
public async awaitSettings() {
|
||||
let counter = 0;
|
||||
while(!this.settingsReady && counter < 150) {
|
||||
|
||||
Reference in New Issue
Block a user