Skip to content

Commit 8240d87

Browse files
committed
2.13.0 code, but not yet released. Manifest version not updated
1 parent a7db044 commit 8240d87

27 files changed

Lines changed: 1069 additions & 415 deletions

manifest-beta.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"id": "obsidian-excalidraw-plugin",
33
"name": "Excalidraw",
44
"version": "2.12.4",
5-
"minAppVersion": "1.1.6",
5+
"minAppVersion": "1.5.7",
66
"description": "An Obsidian plugin to edit and view Excalidraw drawings",
77
"author": "Zsolt Viczian",
88
"authorUrl": "https://excalidraw-obsidian.online",

manifest.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22
"id": "obsidian-excalidraw-plugin",
33
"name": "Excalidraw",
44
"version": "2.12.4",
5-
"minAppVersion": "1.1.6",
5+
"minAppVersion": "1.5.7",
66
"description": "An Obsidian plugin to edit and view Excalidraw drawings",
77
"author": "Zsolt Viczian",
88
"authorUrl": "https://excalidraw-obsidian.online",
99
"fundingUrl": "https://ko-fi.com/zsolt",
1010
"helpUrl": "https://github.com/zsviczian/obsidian-excalidraw-plugin#readme",
1111
"isDesktopOnly": false
12-
}
12+
}

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
"license": "MIT",
2424
"dependencies": {
2525
"@popperjs/core": "^2.11.8",
26-
"@zsviczian/excalidraw": "0.18.0-24",
26+
"@zsviczian/excalidraw": "0.18.0-25",
2727
"chroma-js": "^3.1.2",
2828
"clsx": "^2.0.0",
2929
"@zsviczian/colormaster": "^1.2.2",

src/constants/assets/startupScript.md

Lines changed: 134 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -125,20 +125,148 @@
125125
* @returns {string} - The new filepath for the image including full vault path and extension.
126126
*
127127
* Example usage:
128-
* ```
129128
* onImageFilePathHook: (data) => {
130129
* const { currentImageName, drawingFilePath } = data;
131130
* const ext = currentImageName.split('.').pop();
132131
* // Generate a new filepath based on the drawing file name and other criteria
133132
* return `${drawingFileName} - ${currentImageName || 'image'}.${ext}`;
134133
* }
135-
* ```
136-
* onImageFilePathHook: (data: {
134+
*
135+
* Signiture:
136+
* onImageFilePathHook: (data: {
137137
* currentImageName: string; // Excalidraw generated name of the image, or the name received from the file system.
138138
* drawingFilePath: string; // The full filepath of the Excalidraw file where the image is being used.
139139
* }) => string = null;
140140
*/
141-
//ea.onImageFilePathHook = (data) => {};
141+
// ea.onImageFilePathHook = (data) => { console.log(data); };
142+
143+
/**
144+
* If set, this callback is triggered when the Excalidraw image is being exported to
145+
* .svg, .png, or .excalidraw.
146+
* You can use this callback to customize the naming and path of the images. This allows
147+
* you to place images into an assets folder.
148+
*
149+
* If the function returns null or undefined, the normal Excalidraw operation will continue
150+
* with the currentImageName and in the same folder as the Excalidraw file
151+
* If a filepath is returned, that will be used. Include the full Vault filepath and filename
152+
* with the file extension.
153+
* !!!! If an image already exists on the path, that will be overwritten. When returning
154+
* your own image path, you must take care of unique filenames (if that is a requirement) !!!!
155+
* The current image name is the name generated by Excalidraw:
156+
* - my-drawing.png
157+
* - my-drawing.svg
158+
* - my-drawing.excalidraw
159+
* - my-drawing.dark.svg
160+
* - my-drawing.light.svg
161+
* - my-drawing.dark.png
162+
* - my-drawing.light.png
163+
*
164+
* @param data - An object containing the following properties:
165+
* @property {string} exportFilepath - Default export filepath for the image.
166+
* @property {string} excalidrawFile - TFile: The Excalidraw file being exported.
167+
* @property {string} exportExtension - The file extension of the export (e.g., .dark.svg, .png, .excalidraw).
168+
* @property {string} oldExcalidrawPath - If action === "move" The old path of the Excalidraw file, else undefined
169+
* @property {string} action - The action being performed:
170+
* "export" | "move" | "delete"
171+
* move and delete reference the change to the Excalidraw file.
172+
*
173+
* @returns {string} - The new filepath for the image including full vault path and extension.
174+
*
175+
* action === "move" || action === "delete" is only possible if "keep in sync" is enabled
176+
* in plugin export settings
177+
*
178+
* Example usage:
179+
* onImageFilePathHook: (data) => {
180+
* const { currentImageName, drawingFilePath, frontmatter } = data;
181+
* // Generate a new filepath based on the drawing file name and other criteria
182+
* const ext = currentImageName.split('.').pop();
183+
* if(frontmatter && frontmatter["my-custom-field"]) {
184+
* }
185+
* return `${drawingFileName} - ${currentImageName || 'image'}.${ext}`;
186+
* }
187+
*
188+
*/
189+
/*ea.onImageExportPathHook = (data) => {
190+
//debugger; //remove comment to debug using Developer Console
191+
192+
let {excalidrawFile, exportFilepath, exportExtension, oldExcalidrawPath, action} = data;
193+
const frontmatter = app.metadataCache.getFileCache(excalidrawFile)?.frontmatter;
194+
//console.log(data, frontmatter);
195+
196+
const excalidrawFilename = action === "move"
197+
? ea.splitFolderAndFilename(excalidrawFile.name).filename
198+
: excalidrawFile.name
199+
200+
if(excalidrawFilename.match(/^icon - /i)) {
201+
const {folderpath, filename, basename, extension} = ea.splitFolderAndFilename(exportFilepath);
202+
exportFilepath = "assets/icons/" + filename;
203+
return exportFilepath;
204+
}
205+
206+
if(excalidrawFilename.match(/^stickfigure - /i)) {
207+
const {folderpath, filename, basename, extension} = ea.splitFolderAndFilename(exportFilepath);
208+
exportFilepath = "assets/stickfigures/" + filename;
209+
return exportFilepath;
210+
}
211+
212+
if(excalidrawFilename.match(/^logo - /i)) {
213+
const {folderpath, filename, basename, extension} = ea.splitFolderAndFilename(exportFilepath);
214+
exportFilepath = "assets/logos/" + filename;
215+
return exportFilepath;
216+
}
217+
218+
// !!!! frontmatter will be undefined when action === "delete"
219+
// this means if you base your logic on frontmatter properties, then
220+
// plugin settings keep files in sync will break for those files when
221+
// deleting the Excalidraw file. The images will not be deleted, or worst
222+
// your logic might result in deleting other files. This hook gives you
223+
// powerful control, but the hook function logic requires careful testing
224+
// on your part.
225+
//if(frontmatter && frontmatter["is-asset"]) { //custom frontmatter property
226+
exportFilepath = ea.obsidian.normalizePath("assets/" + exportFilepath);
227+
return exportFilepath;
228+
//}
229+
230+
return exportFilepath;
231+
};*/
232+
233+
/**
234+
* Excalidraw supports auto-export of Excalidraw files to .png, .svg, and .excalidraw formats.
235+
*
236+
* Auto-export of Excalidraw files can be controlled at multiple levels.
237+
* 1) In plugin settings where you can set up default auto-export applicable to all your Excalidraw files.
238+
* 2) However, if you do not want to auto-export every file, you can also control auto-export
239+
* at the file level using the 'excalidraw-autoexport' frontmatter property.
240+
* 3) This hook gives you an additional layer of control over the auto-export process.
241+
*
242+
* This hook is triggered when an Excalidraw file is being saved.
243+
*
244+
* interface AutoexportConfig {
245+
* png: boolean; // Whether to auto-export to PNG
246+
* svg: boolean; // Whether to auto-export to SVG
247+
* excalidraw: boolean; // Whether to auto-export to Excalidraw format
248+
* theme: "light" | "dark" | "both"; // The theme to use for the export
249+
* }
250+
*
251+
* @param {Object} data - The data for the hook.
252+
* @param {AutoexportConfig} data.autoexportConfig - The current autoexport configuration.
253+
* @param {TFile} data.excalidrawFile - The Excalidraw file being auto-exported.
254+
* @returns {AutoexportConfig | null} - Return a modified AutoexportConfig to override the export behavior, or null to use the default.
255+
*/
256+
/*ea.onTriggerAutoexportHook = (data) => {
257+
let {autoexportConfig, excalidrawFile} = data;
258+
const frontmatter = app.metadataCache.getFileCache(excalidrawFile)?.frontmatter;
259+
//console.log(data, frontmatter);
260+
//logic based on filepath and frontmatter
261+
if(excalidrawFile.name.match(/^(?:icon|stickfigure|logo) - /i)) {
262+
autoexportConfig.theme = "light";
263+
autoexportConfig.svg = true;
264+
autoexportConfig.png = false;
265+
autoexportConfig.excalidraw = false;
266+
return autoexportConfig;
267+
}
268+
return autoexportConfig;
269+
};*/
142270
143271
/**
144272
* If set, this callback is triggered whenever the active canvas color changes
@@ -147,5 +275,5 @@
147275
* view: ExcalidrawView, //the excalidraw view
148276
* color: string,
149277
* ) => void = null;
150-
*/
151-
//ea.onCanvasColorChangeHook = (ea, view, color) => {};
278+
*/
279+
//ea.onCanvasColorChangeHook = (ea, view, color) => {};

src/constants/constants.ts

Lines changed: 57 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { customAlphabet } from "nanoid";
22
import { ExcalidrawLib } from "../types/excalidrawLib";
3-
import { moment } from "obsidian";
43
import ExcalidrawPlugin from "src/core/main";
54
import { DeviceType } from "src/types/types";
5+
import { errorHandler } from "../utils/ErrorHandler";
66
//This is only for backward compatibility because an early version of obsidian included an encoding to avoid fantom links from littering Obsidian graph view
77
declare const PLUGIN_VERSION:string;
88
export let EXCALIDRAW_PLUGIN: ExcalidrawPlugin = null;
@@ -106,33 +106,65 @@ export let {
106106
getCSSFontDefinition,
107107
loadSceneFonts,
108108
loadMermaid,
109+
syncInvalidIndices,
109110
} = excalidrawLib;
110111

111112
export function updateExcalidrawLib() {
112-
({
113-
sceneCoordsToViewportCoords,
114-
viewportCoordsToSceneCoords,
115-
determineFocusDistance,
116-
intersectElementWithLine,
117-
getCommonBoundingBox,
118-
getMaximumGroups,
119-
measureText,
120-
getLineHeight,
121-
wrapText,
122-
getFontString,
123-
getBoundTextMaxWidth,
124-
exportToSvg,
125-
exportToBlob,
126-
mutateElement,
127-
restore,
128-
mermaidToExcalidraw,
129-
getFontFamilyString,
130-
getContainerElement,
131-
refreshTextDimensions,
132-
getCSSFontDefinition,
133-
loadSceneFonts,
134-
loadMermaid,
135-
} = excalidrawLib);
113+
try {
114+
// First validate that excalidrawLib exists and has the expected methods
115+
if (!excalidrawLib) {
116+
throw new Error("excalidrawLib is undefined");
117+
}
118+
119+
// Check that critical functions exist before assigning them
120+
const requiredFunctions = [
121+
'sceneCoordsToViewportCoords',
122+
'viewportCoordsToSceneCoords',
123+
'determineFocusDistance',
124+
'intersectElementWithLine',
125+
'getCommonBoundingBox',
126+
'measureText',
127+
'getLineHeight',
128+
'restore'
129+
];
130+
131+
for (const fnName of requiredFunctions) {
132+
if (!(fnName in excalidrawLib) || typeof excalidrawLib[fnName as keyof typeof excalidrawLib] !== 'function') {
133+
throw new Error(`Required function ${fnName} is missing from excalidrawLib`);
134+
}
135+
}
136+
137+
// If validation passes, update the exported functions
138+
({
139+
sceneCoordsToViewportCoords,
140+
viewportCoordsToSceneCoords,
141+
determineFocusDistance,
142+
intersectElementWithLine,
143+
getCommonBoundingBox,
144+
getMaximumGroups,
145+
measureText,
146+
getLineHeight,
147+
wrapText,
148+
getFontString,
149+
getBoundTextMaxWidth,
150+
exportToSvg,
151+
exportToBlob,
152+
mutateElement,
153+
restore,
154+
mermaidToExcalidraw,
155+
getFontFamilyString,
156+
getContainerElement,
157+
refreshTextDimensions,
158+
getCSSFontDefinition,
159+
loadSceneFonts,
160+
loadMermaid,
161+
syncInvalidIndices,
162+
} = excalidrawLib);
163+
} catch (error) {
164+
errorHandler.handleError(error, "updateExcalidrawLib", true);
165+
// Don't throw here - we'll try to continue with potentially stale functions
166+
// but at least we won't crash
167+
}
136168
}
137169

138170
export const FONTS_STYLE_ID = "excalidraw-custom-fonts";

0 commit comments

Comments
 (0)