Compare commits

..

4 Commits

Author SHA1 Message Date
zsviczian
bb83523c0f fix script loading error 2024-11-04 12:29:20 +00:00
zsviczian
f83c0a8458 Merge pull request #2097 from dmscode/master
Update zh-cn.ts to 55ce645
2024-11-04 07:58:33 +01:00
dmscode
7411d51477 Update zh-cn.ts to 55ce645 2024-11-04 07:39:41 +08:00
zsviczian
55ce6456d8 2.6.4 2024-11-03 17:56:39 +01:00
8 changed files with 166 additions and 70 deletions

View File

@@ -1,7 +1,7 @@
{ {
"id": "obsidian-excalidraw-plugin", "id": "obsidian-excalidraw-plugin",
"name": "Excalidraw", "name": "Excalidraw",
"version": "2.6.3", "version": "2.6.4",
"minAppVersion": "1.1.6", "minAppVersion": "1.1.6",
"description": "An Obsidian plugin to edit and view Excalidraw drawings", "description": "An Obsidian plugin to edit and view Excalidraw drawings",
"author": "Zsolt Viczian", "author": "Zsolt Viczian",

View File

@@ -1,7 +1,7 @@
{ {
"id": "obsidian-excalidraw-plugin", "id": "obsidian-excalidraw-plugin",
"name": "Excalidraw", "name": "Excalidraw",
"version": "2.6.3", "version": "2.6.4",
"minAppVersion": "1.1.6", "minAppVersion": "1.1.6",
"description": "An Obsidian plugin to edit and view Excalidraw drawings", "description": "An Obsidian plugin to edit and view Excalidraw drawings",
"author": "Zsolt Viczian", "author": "Zsolt Viczian",

View File

@@ -2854,10 +2854,9 @@ export class ExcalidrawAutomate {
} }
}; };
export async function initExcalidrawAutomate( export function initExcalidrawAutomate(
plugin: ExcalidrawPlugin, plugin: ExcalidrawPlugin,
): Promise<ExcalidrawAutomate> { ): ExcalidrawAutomate {
await initFonts();
const ea = new ExcalidrawAutomate(plugin); const ea = new ExcalidrawAutomate(plugin);
//@ts-ignore //@ts-ignore
window.ExcalidrawAutomate = ea; window.ExcalidrawAutomate = ea;
@@ -2892,14 +2891,6 @@ function getFontFamily(id: number):string {
return getFontFamilyString({fontFamily:id}) return getFontFamilyString({fontFamily:id})
} }
export async function initFonts():Promise<void> {
/*await excalidrawLib.registerFontsInCSS();
const fonts = excalidrawLib.getFontFamilies();
for(let i=0;i<fonts.length;i++) {
if(fonts[i] !== "Local Font") await (document as any).fonts.load(`16px ${fonts[i]}`);
};*/
}
export function _measureText( export function _measureText(
newText: string, newText: string,
fontSize: number, fontSize: number,

View File

@@ -1588,6 +1588,7 @@ export class ExcalidrawData {
.filter(el=>el.type === "image" && el.crop && !el.isDeleted) .filter(el=>el.type === "image" && el.crop && !el.isDeleted)
.forEach((el: Mutable<ExcalidrawImageElement>)=>{ .forEach((el: Mutable<ExcalidrawImageElement>)=>{
const ef = this.getFile(el.fileId); const ef = this.getFile(el.fileId);
if(!ef.file) return;
if(ef.file.extension !== "pdf") return; if(ef.file.extension !== "pdf") return;
const pageRef = ef.linkParts.original.split("#")?.[1]; const pageRef = ef.linkParts.original.split("#")?.[1];
if(!pageRef || !pageRef.startsWith("page=") || pageRef.includes("rect")) return; if(!pageRef || !pageRef.startsWith("page=") || pageRef.includes("rect")) return;

View File

@@ -1,6 +1,7 @@
import { import {
App, App,
Instruction, Instruction,
normalizePath,
TAbstractFile, TAbstractFile,
TFile, TFile,
WorkspaceLeaf, WorkspaceLeaf,
@@ -22,6 +23,7 @@ export type ScriptIconMap = {
export class ScriptEngine { export class ScriptEngine {
private plugin: ExcalidrawPlugin; private plugin: ExcalidrawPlugin;
private app: App;
private scriptPath: string; private scriptPath: string;
//https://stackoverflow.com/questions/60218638/how-to-force-re-render-if-map-value-changes //https://stackoverflow.com/questions/60218638/how-to-force-re-render-if-map-value-changes
public scriptIconMap: ScriptIconMap; public scriptIconMap: ScriptIconMap;
@@ -29,6 +31,7 @@ export class ScriptEngine {
constructor(plugin: ExcalidrawPlugin) { constructor(plugin: ExcalidrawPlugin) {
this.plugin = plugin; this.plugin = plugin;
this.app = plugin.app;
this.scriptIconMap = {}; this.scriptIconMap = {};
this.loadScripts(); this.loadScripts();
this.registerEventHandlers(); this.registerEventHandlers();
@@ -58,7 +61,7 @@ export class ScriptEngine {
if (!path.endsWith(".svg")) { if (!path.endsWith(".svg")) {
return; return;
} }
const scriptFile = app.vault.getAbstractFileByPath( const scriptFile = this.app.vault.getAbstractFileByPath(
getIMGFilename(path, "md"), getIMGFilename(path, "md"),
); );
if (scriptFile && scriptFile instanceof TFile) { if (scriptFile && scriptFile instanceof TFile) {
@@ -107,19 +110,19 @@ export class ScriptEngine {
registerEventHandlers() { registerEventHandlers() {
this.plugin.registerEvent( this.plugin.registerEvent(
this.plugin.app.vault.on( this.app.vault.on(
"delete", "delete",
(file: TFile)=>this.deleteEventHandler(file) (file: TFile)=>this.deleteEventHandler(file)
), ),
); );
this.plugin.registerEvent( this.plugin.registerEvent(
this.plugin.app.vault.on( this.app.vault.on(
"create", "create",
(file: TFile)=>this.createEventHandler(file) (file: TFile)=>this.createEventHandler(file)
), ),
); );
this.plugin.registerEvent( this.plugin.registerEvent(
this.plugin.app.vault.on( this.app.vault.on(
"rename", "rename",
(file: TAbstractFile, oldPath: string)=>this.renameEventHandler(file, oldPath) (file: TAbstractFile, oldPath: string)=>this.renameEventHandler(file, oldPath)
), ),
@@ -138,15 +141,16 @@ export class ScriptEngine {
public getListofScripts(): TFile[] { public getListofScripts(): TFile[] {
this.scriptPath = this.plugin.settings.scriptFolderPath; this.scriptPath = this.plugin.settings.scriptFolderPath;
if (!app.vault.getAbstractFileByPath(this.scriptPath)) { if(!this.scriptPath) return;
//this.scriptPath = null; this.scriptPath = normalizePath(this.scriptPath);
if (!this.app.vault.getAbstractFileByPath(this.scriptPath)) {
return; return;
} }
return app.vault return this.app.vault
.getFiles() .getFiles()
.filter( .filter(
(f: TFile) => (f: TFile) =>
f.path.startsWith(this.scriptPath) && f.extension === "md", f.path.startsWith(this.scriptPath+"/") && f.extension === "md",
); );
} }
@@ -166,7 +170,10 @@ export class ScriptEngine {
} }
const subpath = path.split(`${this.scriptPath}/`)[1]; const subpath = path.split(`${this.scriptPath}/`)[1];
const lastSlash = subpath.lastIndexOf("/"); if(!subpath) {
console.warn(`ScriptEngine.getScriptName unexpected basename: ${basename}; path: ${path}`)
}
const lastSlash = subpath?.lastIndexOf("/");
if (lastSlash > -1) { if (lastSlash > -1) {
return subpath.substring(0, lastSlash + 1) + basename; return subpath.substring(0, lastSlash + 1) + basename;
} }
@@ -175,10 +182,10 @@ export class ScriptEngine {
async addScriptIconToMap(scriptPath: string, name: string) { async addScriptIconToMap(scriptPath: string, name: string) {
const svgFilePath = getIMGFilename(scriptPath, "svg"); const svgFilePath = getIMGFilename(scriptPath, "svg");
const file = app.vault.getAbstractFileByPath(svgFilePath); const file = this.app.vault.getAbstractFileByPath(svgFilePath);
const svgString: string = const svgString: string =
file && file instanceof TFile file && file instanceof TFile
? await app.vault.read(file) ? await this.app.vault.read(file)
: null; : null;
this.scriptIconMap = { this.scriptIconMap = {
...this.scriptIconMap, ...this.scriptIconMap,
@@ -199,12 +206,12 @@ export class ScriptEngine {
name: `(Script) ${scriptName}`, name: `(Script) ${scriptName}`,
checkCallback: (checking: boolean) => { checkCallback: (checking: boolean) => {
if (checking) { if (checking) {
return Boolean(app.workspace.getActiveViewOfType(ExcalidrawView)); return Boolean(this.app.workspace.getActiveViewOfType(ExcalidrawView));
} }
const view = app.workspace.getActiveViewOfType(ExcalidrawView); const view = this.app.workspace.getActiveViewOfType(ExcalidrawView);
if (view) { if (view) {
(async()=>{ (async()=>{
const script = await app.vault.read(f); const script = await this.app.vault.read(f);
if(script) { if(script) {
//remove YAML frontmatter if present //remove YAML frontmatter if present
this.executeScript(view, script, scriptName,f); this.executeScript(view, script, scriptName,f);
@@ -218,7 +225,7 @@ export class ScriptEngine {
} }
unloadScripts() { unloadScripts() {
const scripts = app.vault const scripts = this.app.vault
.getFiles() .getFiles()
.filter((f: TFile) => f.path.startsWith(this.scriptPath)); .filter((f: TFile) => f.path.startsWith(this.scriptPath));
scripts.forEach((f) => { scripts.forEach((f) => {
@@ -236,11 +243,11 @@ export class ScriptEngine {
const commandId = `${PLUGIN_ID}:${basename}`; const commandId = `${PLUGIN_ID}:${basename}`;
// @ts-ignore // @ts-ignore
if (!this.plugin.app.commands.commands[commandId]) { if (!this.app.commands.commands[commandId]) {
return; return;
} }
// @ts-ignore // @ts-ignore
delete this.plugin.app.commands.commands[commandId]; delete this.app.commands.commands[commandId];
} }
async executeScript(view: ExcalidrawView, script: string, title: string, file: TFile) { async executeScript(view: ExcalidrawView, script: string, title: string, file: TFile) {
@@ -271,7 +278,7 @@ export class ScriptEngine {
ScriptEngine.inputPrompt( ScriptEngine.inputPrompt(
view, view,
this.plugin, this.plugin,
this.plugin.app, this.app,
header, header,
placeholder, placeholder,
value, value,
@@ -288,7 +295,7 @@ export class ScriptEngine {
instructions?: Instruction[], instructions?: Instruction[],
) => ) =>
ScriptEngine.suggester( ScriptEngine.suggester(
this.plugin.app, this.app,
displayItems, displayItems,
items, items,
hint, hint,
@@ -304,7 +311,7 @@ export class ScriptEngine {
} }
private updateToolPannels() { private updateToolPannels() {
const excalidrawViews = getExcalidrawViews(this.plugin.app); const excalidrawViews = getExcalidrawViews(this.app);
excalidrawViews.forEach(excalidrawView => { excalidrawViews.forEach(excalidrawView => {
excalidrawView.toolsPanelRef?.current?.updateScriptIconMap( excalidrawView.toolsPanelRef?.current?.updateScriptIconMap(
this.scriptIconMap, this.scriptIconMap,

View File

@@ -17,6 +17,10 @@ I develop this plugin as a hobby, spending my free time doing this. If you find
<div class="ex-coffee-div"><a href="https://ko-fi.com/zsolt"><img src="https://storage.ko-fi.com/cdn/kofi6.png?v=6" border="0" alt="Buy Me a Coffee at ko-fi.com" height=45></a></div> <div class="ex-coffee-div"><a href="https://ko-fi.com/zsolt"><img src="https://storage.ko-fi.com/cdn/kofi6.png?v=6" border="0" alt="Buy Me a Coffee at ko-fi.com" height=45></a></div>
`, `,
"2.6.4":`
## Fixed
- Error saving when cropping images embedded from a URL (not from a file in the Vault) [#2096](https://github.com/zsviczian/obsidian-excalidraw-plugin/issues/2096)
`,
"2.6.3":` "2.6.3":`
<div class="excalidraw-videoWrapper"><div> <div class="excalidraw-videoWrapper"><div>
<iframe src="https://www.youtube.com/embed/OfUWAvCgbXk" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe> <iframe src="https://www.youtube.com/embed/OfUWAvCgbXk" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

View File

@@ -6,6 +6,8 @@ import { TAG_AUTOEXPORT, TAG_MDREADINGMODE, TAG_PDFEXPORT } from "src/constants/
import { labelALT, labelCTRL, labelMETA, labelSHIFT } from "src/utils/ModifierkeyHelper"; import { labelALT, labelCTRL, labelMETA, labelSHIFT } from "src/utils/ModifierkeyHelper";
const CJK_FONTS = "CJK Fonts"; const CJK_FONTS = "CJK Fonts";
declare const PLUGIN_VERSION:string;
// 简体中文 // 简体中文
export default { export default {
// main.ts // main.ts
@@ -870,6 +872,7 @@ FILENAME_HEAD: "文件名",
对此带来的不便,我深表歉意。 对此带来的不便,我深表歉意。
</p> </p>
`, `,
//ObsidianMenu.tsx //ObsidianMenu.tsx
GOTO_FULLSCREEN: "进入全屏模式", GOTO_FULLSCREEN: "进入全屏模式",
EXIT_FULLSCREEN: "退出全屏模式", EXIT_FULLSCREEN: "退出全屏模式",
@@ -958,4 +961,7 @@ FILENAME_HEAD: "文件名",
IPM_GROUP_PAGES_DESC: "这将把所有页面建立为一个单独的组。如果您在导入后锁定页面,建议使用此方法,因为这样可以更方便地解锁整个组,而不是逐个解锁。", IPM_GROUP_PAGES_DESC: "这将把所有页面建立为一个单独的组。如果您在导入后锁定页面,建议使用此方法,因为这样可以更方便地解锁整个组,而不是逐个解锁。",
IPM_SELECT_PDF: "请选择一个 PDF 文件", IPM_SELECT_PDF: "请选择一个 PDF 文件",
}; //Utils.ts
UPDATE_AVAILABLE: `Excalidraw 的新版本已在社区插件中可用。\n\n您正在使用 ${PLUGIN_VERSION}\n最新版本是`,
ERROR_PNG_TOO_LARGE: "导出 PNG 时出错 - PNG 文件过大,请尝试较小的分辨率",
};

View File

@@ -365,53 +365,132 @@ export default class ExcalidrawPlugin extends Plugin {
//Compatibility mode with .excalidraw files //Compatibility mode with .excalidraw files
this.registerExtensions(["excalidraw"], VIEW_TYPE_EXCALIDRAW); this.registerExtensions(["excalidraw"], VIEW_TYPE_EXCALIDRAW);
await this.loadSettings({reEnableAutosave:true}); try {
const updateSettings = !this.settings.onceOffCompressFlagReset || !this.settings.onceOffGPTVersionReset; await this.loadSettings({reEnableAutosave:true});
if(!this.settings.onceOffCompressFlagReset) { const updateSettings = !this.settings.onceOffCompressFlagReset || !this.settings.onceOffGPTVersionReset;
this.settings.compress = true; if(!this.settings.onceOffCompressFlagReset) {
this.settings.onceOffCompressFlagReset = true; 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(!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));
} catch (e) {
new Notice("Error loading plugin settings", 6000);
console.error("Error loading plugin settings", e);
}
try {
// need it her for ExcaliBrain
this.ea = initExcalidrawAutomate(this);
} catch (e) {
new Notice("Error initializing Excalidraw Automate", 6000);
console.error("Error initializing Excalidraw Automate", e);
}
try {
//Licat: Are you registering your post processors in onLayoutReady? You should register them in onload instead
this.addMarkdownPostProcessor();
} catch (e) {
new Notice("Error adding markdown post processor", 6000);
console.error("Error adding markdown post processor", e);
} }
if(updateSettings) {
await this.saveSettings();
}
this.addSettingTab(new ExcalidrawSettingTab(this.app, this));
this.ea = await initExcalidrawAutomate(this);
//Licat: Are you registering your post processors in onLayoutReady? You should register them in onload instead
this.addMarkdownPostProcessor();
this.app.workspace.onLayoutReady(async () => { this.app.workspace.onLayoutReady(async () => {
unpackExcalidraw(); try {
excalidrawLib = window.eval.call(window,`(function() {${EXCALIDRAW_PACKAGE};return ExcalidrawLib;})()`); unpackExcalidraw();
this.packageMap.set(window,{react, reactDOM, excalidrawLib}); excalidrawLib = window.eval.call(window,`(function() {${EXCALIDRAW_PACKAGE};return ExcalidrawLib;})()`);
updateExcalidrawLib(); this.packageMap.set(window,{react, reactDOM, excalidrawLib});
initCompressionWorker(); updateExcalidrawLib();
} catch (e) {
new Notice("Error loading the Excalidraw package", 6000);
console.error("Error loading the Excalidraw package", e);
}
try {
initCompressionWorker();
} catch (e) {
new Notice("Error initializing compression worker", 6000);
console.error("Error initializing compression worker", e);
}
this.loadTimestamp = Date.now(); this.loadTimestamp = Date.now();
addIcon(ICON_NAME, EXCALIDRAW_ICON); addIcon(ICON_NAME, EXCALIDRAW_ICON);
addIcon(SCRIPTENGINE_ICON_NAME, SCRIPTENGINE_ICON); addIcon(SCRIPTENGINE_ICON_NAME, SCRIPTENGINE_ICON);
addIcon(EXPORT_IMG_ICON_NAME, EXPORT_IMG_ICON); addIcon(EXPORT_IMG_ICON_NAME, EXPORT_IMG_ICON);
this.excalidrawConfig = new ExcalidrawConfig(this); try {
await loadMermaid(); this.excalidrawConfig = new ExcalidrawConfig(this);
this.addThemeObserver(); } catch (e) {
new Notice("Error initializing Excalidraw config", 6000);
console.error("Error initializing Excalidraw config", e);
}
//inspiration taken from kanban: try {
//https://github.com/mgmeyers/obsidian-kanban/blob/44118e25661bff9ebfe54f71ae33805dc88ffa53/src/main.ts#L267 await loadMermaid();
this.registerMonkeyPatches(); } catch (e) {
new Notice("Error loading Mermaid", 6000);
console.error("Error loading Mermaid", e);
}
this.stylesManager = new StylesManager(this); try {
this.scriptEngine = new ScriptEngine(this); this.addThemeObserver();
await this.initializeFonts(); } catch (e) {
imageCache.initializeDB(this); new Notice("Error adding theme observer", 6000);
console.error("Error adding theme observer", e);
}
this.isReady = true; try {
switchToExcalidraw(this.app); //inspiration taken from kanban:
this.switchToExcalidarwAfterLoad(); //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);
}
try {
this.stylesManager = new StylesManager(this);
} catch (e) {
new Notice("Error initializing styles manager", 6000);
console.error("Error initializing styles manager", e);
}
try {
this.scriptEngine = new ScriptEngine(this);
} catch (e) {
new Notice("Error initializing script engine", 6000);
console.error("Error initializing script engine", e);
}
try {
await this.initializeFonts();
} catch (e) {
new Notice("Error initializing fonts", 6000);
console.error("Error initializing fonts", e);
}
try {
imageCache.initializeDB(this);
} catch (e) {
new Notice("Error initializing image cache", 6000);
console.error("Error initializing image cache", e);
}
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);
}
try { try {
if (this.settings.showReleaseNotes) { if (this.settings.showReleaseNotes) {
@@ -431,20 +510,23 @@ export default class ExcalidrawPlugin extends Plugin {
console.error("Error opening release notes", e); console.error("Error opening release notes", e);
} }
//---------------------------------------------------------------------
//initialization that can happen after Excalidraw views are initialized //initialization that can happen after Excalidraw views are initialized
//---------------------------------------------------------------------
try { try {
this.registerEventListeners(); this.registerEventListeners();
} catch (e) { } catch (e) {
new Notice("Error registering event listeners", 6000); new Notice("Error registering event listeners", 6000);
console.error("Error registering event listeners", e); console.error("Error registering event listeners", e);
} }
try { try {
this.runStartupScript(); this.runStartupScript();
} catch (e) { } catch (e) {
new Notice("Error running startup script", 6000); new Notice("Error running startup script", 6000);
console.error("Error running startup script", e); console.error("Error running startup script", e);
} }
try { try {
this.editorHandler = new EditorHandler(this); this.editorHandler = new EditorHandler(this);
this.editorHandler.setup(); this.editorHandler.setup();
@@ -452,6 +534,7 @@ export default class ExcalidrawPlugin extends Plugin {
new Notice("Error setting up editor handler", 6000); new Notice("Error setting up editor handler", 6000);
console.error("Error setting up editor handler", e); console.error("Error setting up editor handler", e);
} }
try { try {
this.registerInstallCodeblockProcessor(); this.registerInstallCodeblockProcessor();
} catch (e) { } catch (e) {
@@ -465,24 +548,28 @@ export default class ExcalidrawPlugin extends Plugin {
new Notice("Error setting up experimental file type display", 6000); new Notice("Error setting up experimental file type display", 6000);
console.error("Error setting up experimental file type display", e); console.error("Error setting up experimental file type display", e);
} }
try { try {
this.registerCommands(); this.registerCommands();
} catch (e) { } catch (e) {
new Notice("Error registering commands", 6000); new Notice("Error registering commands", 6000);
console.error("Error registering commands", e); console.error("Error registering commands", e);
} }
try { try {
this.registerEditorSuggest(new FieldSuggester(this)); this.registerEditorSuggest(new FieldSuggester(this));
} catch (e) { } catch (e) {
new Notice("Error registering editor suggester", 6000); new Notice("Error registering editor suggester", 6000);
console.error("Error registering editor suggester", e); console.error("Error registering editor suggester", e);
} }
try { try {
this.setPropertyTypes(); this.setPropertyTypes();
} catch (e) { } catch (e) {
new Notice("Error setting up property types", 6000); new Notice("Error setting up property types", 6000);
console.error("Error setting up property types", e); console.error("Error setting up property types", e);
} }
try { try {
this.taskbone = new Taskbone(this); this.taskbone = new Taskbone(this);
} catch (e) { } catch (e) {