mirror of
https://github.com/zsviczian/obsidian-excalidraw-plugin.git
synced 2025-08-06 05:46:28 +00:00
Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9bfbf47963 | ||
|
|
252bf411b1 | ||
|
|
5622c019dd | ||
|
|
b32fab7865 | ||
|
|
cafdad1f7a | ||
|
|
9da40944ab | ||
|
|
f678203a64 | ||
|
|
a9572e08e9 | ||
|
|
ee9b042cdf | ||
|
|
bc138fa78a |
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"id": "obsidian-excalidraw-plugin",
|
||||
"name": "Excalidraw",
|
||||
"version": "2.2.10-2",
|
||||
"version": "2.3.0",
|
||||
"minAppVersion": "1.1.6",
|
||||
"description": "An Obsidian plugin to edit and view Excalidraw drawings",
|
||||
"author": "Zsolt Viczian",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"id": "obsidian-excalidraw-plugin",
|
||||
"name": "Excalidraw",
|
||||
"version": "2.2.12",
|
||||
"version": "2.3.0",
|
||||
"minAppVersion": "1.1.6",
|
||||
"description": "An Obsidian plugin to edit and view Excalidraw drawings",
|
||||
"author": "Zsolt Viczian",
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@popperjs/core": "^2.11.8",
|
||||
"@zsviczian/excalidraw": "0.17.1-obsidian-34",
|
||||
"@zsviczian/excalidraw": "0.17.1-obsidian-36",
|
||||
"chroma-js": "^2.4.2",
|
||||
"clsx": "^2.0.0",
|
||||
"colormaster": "^1.2.1",
|
||||
|
||||
@@ -1997,7 +1997,7 @@ export class ExcalidrawAutomate {
|
||||
appState: {
|
||||
viewModeEnabled: !isFullscreen,
|
||||
},
|
||||
storeAction: "none",
|
||||
storeAction: "update",
|
||||
});
|
||||
this.targetView.toolsPanelRef?.current?.setExcalidrawViewMode(!isFullscreen);
|
||||
}
|
||||
@@ -2016,7 +2016,7 @@ export class ExcalidrawAutomate {
|
||||
return;
|
||||
}
|
||||
const view = this.targetView as ExcalidrawView;
|
||||
view.updateScene({appState:{viewModeEnabled: enabled}});
|
||||
view.updateScene({appState:{viewModeEnabled: enabled}, storeAction: "update"});
|
||||
view.toolsPanelRef?.current?.setExcalidrawViewMode(enabled);
|
||||
}
|
||||
|
||||
@@ -2042,7 +2042,7 @@ export class ExcalidrawAutomate {
|
||||
return;
|
||||
}
|
||||
if (!Boolean(scene.storeAction)) {
|
||||
scene.storeAction = scene.commitToHistory ? "capture" : "none";
|
||||
scene.storeAction = scene.commitToHistory ? "capture" : "update";
|
||||
}
|
||||
|
||||
this.targetView.updateScene({
|
||||
@@ -2763,10 +2763,10 @@ function getFontFamily(id: number) {
|
||||
|
||||
export async function initFonts() {
|
||||
await excalidrawLib.registerFontsInCSS();
|
||||
/*const fonts = excalidrawLib.getFontFamilies();
|
||||
const fonts = excalidrawLib.getFontFamilies();
|
||||
for(let i=0;i<fonts.length;i++) {
|
||||
await (document as any).fonts.load(`20px ${fonts[i]}`);
|
||||
};*/
|
||||
if(fonts[i] !== "Local Font") await (document as any).fonts.load(`16px ${fonts[i]}`);
|
||||
};
|
||||
}
|
||||
|
||||
export function _measureText(
|
||||
|
||||
@@ -103,7 +103,7 @@ import {
|
||||
_getContainerElement,
|
||||
arrayToMap,
|
||||
} from "./utils/Utils";
|
||||
import { cleanBlockRef, cleanSectionHeading, getAttachmentsFolderAndFilePath, getLeaf, getParentOfClass, obsidianPDFQuoteWithRef, openLeaf } from "./utils/ObsidianUtils";
|
||||
import { cleanBlockRef, cleanSectionHeading, closeLeafView, getAttachmentsFolderAndFilePath, getLeaf, getParentOfClass, obsidianPDFQuoteWithRef, openLeaf, setExcalidrawView } from "./utils/ObsidianUtils";
|
||||
import { splitFolderAndFilename } from "./utils/FileUtils";
|
||||
import { ConfirmationPrompt, GenericInputPrompt, NewFileActions, Prompt, linkPrompt } from "./dialogs/Prompt";
|
||||
import { ClipboardData } from "@zsviczian/excalidraw/types/excalidraw/clipboard";
|
||||
@@ -215,7 +215,7 @@ export const addFiles = async (
|
||||
view.updateScene({
|
||||
elements: s.scene.elements,
|
||||
appState: s.scene.appState,
|
||||
storeAction: "none",
|
||||
storeAction: "update",
|
||||
});
|
||||
}
|
||||
for (const f of files) {
|
||||
@@ -244,6 +244,8 @@ const warningUnknowSeriousError = () => {
|
||||
|
||||
type ActionButtons = "save" | "isParsed" | "isRaw" | "link" | "scriptInstall";
|
||||
|
||||
let windowMigratedDisableZoomOnce = false;
|
||||
|
||||
export default class ExcalidrawView extends TextFileView {
|
||||
public exportDialog: ExportDialog;
|
||||
public excalidrawData: ExcalidrawData;
|
||||
@@ -901,21 +903,21 @@ export default class ExcalidrawView extends TextFileView {
|
||||
toggleDisableBinding() {
|
||||
(process.env.NODE_ENV === 'development') && DEBUGGING && debug(this.toggleDisableBinding, "ExcalidrawView.toggleDisableBinding");
|
||||
const newState = !this.excalidrawAPI.getAppState().invertBindingBehaviour;
|
||||
this.updateScene({appState: {invertBindingBehaviour:newState}});
|
||||
this.updateScene({appState: {invertBindingBehaviour:newState}, storeAction: "update"});
|
||||
new Notice(newState ? t("ARROW_BINDING_INVERSE_MODE") : t("ARROW_BINDING_NORMAL_MODE"));
|
||||
}
|
||||
|
||||
toggleFrameRendering() {
|
||||
(process.env.NODE_ENV === 'development') && DEBUGGING && debug(this.toggleFrameRendering, "ExcalidrawView.toggleFrameRendering");
|
||||
const frameRenderingSt = (this.excalidrawAPI as ExcalidrawImperativeAPI).getAppState().frameRendering;
|
||||
this.updateScene({appState: {frameRendering: {...frameRenderingSt, enabled: !frameRenderingSt.enabled}}});
|
||||
this.updateScene({appState: {frameRendering: {...frameRenderingSt, enabled: !frameRenderingSt.enabled}}, storeAction: "update"});
|
||||
new Notice(frameRenderingSt.enabled ? t("FRAME_CLIPPING_ENABLED") : t("FRAME_CLIPPING_DISABLED"));
|
||||
}
|
||||
|
||||
toggleFrameClipping() {
|
||||
(process.env.NODE_ENV === 'development') && DEBUGGING && debug(this.toggleFrameClipping, "ExcalidrawView.toggleFrameClipping");
|
||||
const frameRenderingSt = (this.excalidrawAPI as ExcalidrawImperativeAPI).getAppState().frameRendering;
|
||||
this.updateScene({appState: {frameRendering: {...frameRenderingSt, clip: !frameRenderingSt.clip}}});
|
||||
this.updateScene({appState: {frameRendering: {...frameRenderingSt, clip: !frameRenderingSt.clip}}, storeAction: "update"});
|
||||
new Notice(frameRenderingSt.clip ? "Frame Clipping: Enabled" : "Frame Clipping: Disabled");
|
||||
}
|
||||
|
||||
@@ -1135,7 +1137,7 @@ export default class ExcalidrawView extends TextFileView {
|
||||
if (this.excalidrawData.hasMermaid(selectedImage.fileId) || getMermaidText(imageElement)) {
|
||||
if(shouldRenderMermaid) {
|
||||
const api = this.excalidrawAPI as ExcalidrawImperativeAPI;
|
||||
api.updateScene({appState: {openDialog: { name: "ttd", tab: "mermaid" }}})
|
||||
api.updateScene({appState: {openDialog: { name: "ttd", tab: "mermaid" }}, storeAction: "update"})
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -1352,12 +1354,25 @@ export default class ExcalidrawView extends TextFileView {
|
||||
const apiMissing = Boolean(typeof this.containerEl.onWindowMigrated === "undefined")
|
||||
this.packages = this.plugin.getPackage(this.ownerWindow);
|
||||
|
||||
/*if(!DEVICE.isMobile && !apiMissing) {
|
||||
if(DEVICE.isDesktop && !apiMissing) {
|
||||
this.destroyers.push(
|
||||
//@ts-ignore
|
||||
this.containerEl.onWindowMigrated(this.leaf.rebuildView.bind(this))
|
||||
//this.containerEl.onWindowMigrated(this.leaf.rebuildView.bind(this))
|
||||
this.containerEl.onWindowMigrated(async() => {
|
||||
(process.env.NODE_ENV === 'development') && DEBUGGING && debug(this.onload, "ExcalidrawView.onWindowMigrated");
|
||||
const f = this.file;
|
||||
const l = this.leaf;
|
||||
await closeLeafView(l);
|
||||
windowMigratedDisableZoomOnce = true;
|
||||
l.setViewState({
|
||||
type: VIEW_TYPE_EXCALIDRAW,
|
||||
state: {
|
||||
file: f.path,
|
||||
}
|
||||
});
|
||||
})
|
||||
);
|
||||
}*/
|
||||
}
|
||||
|
||||
this.semaphores.scriptsReady = true;
|
||||
|
||||
@@ -1554,7 +1569,7 @@ export default class ExcalidrawView extends TextFileView {
|
||||
...st,
|
||||
theme,
|
||||
},
|
||||
storeAction: "none",
|
||||
storeAction: "update",
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1902,21 +1917,8 @@ export default class ExcalidrawView extends TextFileView {
|
||||
}
|
||||
|
||||
if (state.rename === "all") {
|
||||
(async () => {
|
||||
let filename = await ScriptEngine.inputPrompt(
|
||||
this,
|
||||
this.plugin,
|
||||
this.plugin.app,
|
||||
"Note Title",
|
||||
"Filename without extension",
|
||||
this.file.basename,
|
||||
);
|
||||
if (!filename) {
|
||||
return;
|
||||
}
|
||||
const {folderpath} = splitFolderAndFilename(this.file.path);
|
||||
this.app.vault.rename(this.file, normalizePath(`${folderpath}/${filename}.md`));
|
||||
})();
|
||||
//@ts-ignore
|
||||
this.app.fileManager.promptForFileRename(this.file);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2168,7 +2170,7 @@ export default class ExcalidrawView extends TextFileView {
|
||||
await this.app.vault.modify(file, drawingBAK);
|
||||
//@ts-ignore
|
||||
plugin.excalidrawFileModes[leaf.id || file.path] = VIEW_TYPE_EXCALIDRAW;
|
||||
plugin.setExcalidrawView(leaf);
|
||||
setExcalidrawView(leaf);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -2215,8 +2217,8 @@ export default class ExcalidrawView extends TextFileView {
|
||||
(process.env.NODE_ENV === 'development') && DEBUGGING && debug(this.getGridColor, "ExcalidrawView.getGridColor", bgColor, st);
|
||||
const cm = this.plugin.ea.getCM(bgColor);
|
||||
const isDark = cm.isDark();
|
||||
const Regular = (isDark ? cm.lighterBy(7) : cm.darkerBy(7)).stringHEX();
|
||||
const Bold = (isDark ? cm.lighterBy(14) : cm.darkerBy(14)).stringHEX();
|
||||
const Regular = (isDark ? cm.lighterBy(7) : cm.darkerBy(7)).stringHEX({alpha: false});
|
||||
const Bold = (isDark ? cm.lighterBy(14) : cm.darkerBy(14)).stringHEX({alpha: false});
|
||||
return {Bold, Regular, MajorGridFrequency:st.gridColor.MajorGridFrequency};
|
||||
}
|
||||
|
||||
@@ -2397,7 +2399,7 @@ export default class ExcalidrawView extends TextFileView {
|
||||
if(this.getSceneVersion(inData.scene.elements) !== this.previousSceneVersion) {
|
||||
this.setDirty(3);
|
||||
}
|
||||
this.updateScene({elements: sceneElements});
|
||||
this.updateScene({elements: sceneElements, storeAction: "capture"});
|
||||
if(reloadFiles) this.loadSceneFiles();
|
||||
} catch(e) {
|
||||
errorlog({
|
||||
@@ -2440,7 +2442,7 @@ export default class ExcalidrawView extends TextFileView {
|
||||
{
|
||||
elements: excalidrawData.elements.concat(deletedElements??[]), //need to preserve deleted elements during autosave if images, links, etc. are updated
|
||||
files: excalidrawData.files,
|
||||
storeAction: justloaded ? "update" : "none",
|
||||
storeAction: justloaded ? "update" : "update", //was none, but I think based on a false understanding of none
|
||||
},
|
||||
justloaded
|
||||
);
|
||||
@@ -2463,7 +2465,7 @@ export default class ExcalidrawView extends TextFileView {
|
||||
pinnedScripts: this.plugin.settings.pinnedScripts,
|
||||
customPens: this.plugin.settings.customPens.slice(0,this.plugin.settings.numberOfCustomPens),
|
||||
},
|
||||
storeAction: justloaded ? "update" : "none",
|
||||
storeAction: justloaded ? "update" : "update", //was none, but I think based on a false understanding of none
|
||||
},
|
||||
);
|
||||
if (
|
||||
@@ -3625,7 +3627,7 @@ export default class ExcalidrawView extends TextFileView {
|
||||
private canvasColorChangeHook(st: AppState) {
|
||||
(process.env.NODE_ENV === 'development') && DEBUGGING && debug(this.canvasColorChangeHook, "ExcalidrawView.canvasColorChangeHook", st);
|
||||
const canvasColor = st.viewBackgroundColor === "transparent" ? "white" : st.viewBackgroundColor;
|
||||
window.setTimeout(()=>this.updateScene({appState:{gridColor: this.getGridColor(canvasColor, st)}}));
|
||||
window.setTimeout(()=>this.updateScene({appState:{gridColor: this.getGridColor(canvasColor, st)}, storeAction: "update"}));
|
||||
setDynamicStyle(this.plugin.ea,this,canvasColor,this.plugin.settings.dynamicStyling);
|
||||
if(this.plugin.ea.onCanvasColorChangeHook) {
|
||||
try {
|
||||
@@ -4335,7 +4337,7 @@ export default class ExcalidrawView extends TextFileView {
|
||||
clone.rawText = WARNING;
|
||||
elements[elements.indexOf(el[0])] = clone;
|
||||
this.excalidrawData.setTextElement(clone.id,WARNING,()=>{});
|
||||
this.updateScene({elements});
|
||||
this.updateScene({elements, storeAction: "update"});
|
||||
api.history.clear();
|
||||
}
|
||||
});
|
||||
@@ -4359,7 +4361,7 @@ export default class ExcalidrawView extends TextFileView {
|
||||
clone.isDeleted = true;
|
||||
this.excalidrawData.deleteTextElement(clone.id);
|
||||
elements[elements.indexOf(el[0])] = clone;
|
||||
this.updateScene({elements});
|
||||
this.updateScene({elements, storeAction: "update"});
|
||||
const ea:ExcalidrawAutomate = getEA(this);
|
||||
if(IMAGE_TYPES.contains(file.extension)) {
|
||||
ea.selectElementsInView([await insertImageToView (ea, center, file)]);
|
||||
@@ -4412,7 +4414,7 @@ export default class ExcalidrawView extends TextFileView {
|
||||
}
|
||||
|
||||
elements[elements.indexOf(el[0])] = clone;
|
||||
this.updateScene({elements});
|
||||
this.updateScene({elements, storeAction: "update"});
|
||||
if(clone.containerId) this.updateContainerSize(clone.containerId);
|
||||
this.setDirty(8.1);
|
||||
}
|
||||
@@ -5522,6 +5524,10 @@ export default class ExcalidrawView extends TextFileView {
|
||||
if (!api || this.semaphores.isEditingText || this.semaphores.preventAutozoom) {
|
||||
return;
|
||||
}
|
||||
if (windowMigratedDisableZoomOnce) {
|
||||
windowMigratedDisableZoomOnce = false;
|
||||
return;
|
||||
}
|
||||
const maxZoom = this.plugin.settings.zoomToFitMaxLevel;
|
||||
const elements = api.getSceneElements().filter((el:ExcalidrawElement)=>el.width<10000 && el.height<10000);
|
||||
if((DEVICE.isMobile && elements.length>1000) || elements.length>2500) {
|
||||
@@ -5547,6 +5553,7 @@ export default class ExcalidrawView extends TextFileView {
|
||||
}
|
||||
api.updateScene({
|
||||
appState: { pinnedScripts: this.plugin.settings.pinnedScripts },
|
||||
storeAction: "update",
|
||||
});
|
||||
}
|
||||
|
||||
@@ -5558,8 +5565,9 @@ export default class ExcalidrawView extends TextFileView {
|
||||
}
|
||||
api.updateScene({
|
||||
appState: {
|
||||
customPens: this.plugin.settings.customPens.slice(0,this.plugin.settings.numberOfCustomPens)
|
||||
customPens: this.plugin.settings.customPens.slice(0,this.plugin.settings.numberOfCustomPens),
|
||||
},
|
||||
storeAction: "update",
|
||||
});
|
||||
}
|
||||
|
||||
@@ -5571,6 +5579,7 @@ export default class ExcalidrawView extends TextFileView {
|
||||
}
|
||||
api.updateScene({
|
||||
appState: { allowPinchZoom: this.plugin.settings.allowPinchZoom },
|
||||
storeAction: "update",
|
||||
});
|
||||
}
|
||||
|
||||
@@ -5582,6 +5591,7 @@ export default class ExcalidrawView extends TextFileView {
|
||||
}
|
||||
api.updateScene({
|
||||
appState: { allowWheelZoom: this.plugin.settings.allowWheelZoom },
|
||||
storeAction: "update",
|
||||
});
|
||||
}
|
||||
|
||||
@@ -5594,6 +5604,7 @@ export default class ExcalidrawView extends TextFileView {
|
||||
const st = api.getAppState();
|
||||
api.updateScene({
|
||||
appState: { trayModeEnabled: !st.trayModeEnabled },
|
||||
storeAction: "update",
|
||||
});
|
||||
|
||||
//just in case settings were updated via Obsidian sync
|
||||
|
||||
@@ -184,7 +184,7 @@ export class EmbeddableSettings extends Modal {
|
||||
new Notice("File rename failed. A file with this name already exists.\n"+newPath,10000);
|
||||
} else {
|
||||
try {
|
||||
await this.app.vault.rename(this.file,newPath);
|
||||
await this.app.fileManager.renameFile(this.file,newPath);
|
||||
el.link = this.element.link.replace(
|
||||
/(\[\[)([^#\]]*)([^\]]*]])/,`$1${
|
||||
this.plugin.app.metadataCache.fileToLinktext(
|
||||
@@ -226,7 +226,7 @@ export class EmbeddableSettings extends Modal {
|
||||
(async() => {
|
||||
await this.ea.addElementsToView();
|
||||
//@ts-ignore
|
||||
this.ea.viewUpdateScene({appState: {}});
|
||||
this.ea.viewUpdateScene({appState: {}, storeAction: "update"});
|
||||
this.close(); //close should only run once update scene is done
|
||||
})();
|
||||
} else {
|
||||
|
||||
@@ -63,7 +63,8 @@ export const showFrameSettings = (ea: ExcalidrawAutomate) => {
|
||||
// @ts-ignore
|
||||
appState: {
|
||||
frameRendering: settings
|
||||
}
|
||||
},
|
||||
storeAction: "update",
|
||||
});
|
||||
frameSettingsModal.close();
|
||||
})
|
||||
|
||||
@@ -17,6 +17,27 @@ 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://cdn.ko-fi.com/cdn/kofi3.png?v=3" height=45></a></div>
|
||||
`,
|
||||
"2.3.0": `
|
||||
I am moving to a new release approach aiming to publish one update per month to the Obsidian script store. If you want to continue to receive more frequent updates with new features and minor bug fixes, then join the beta testing team. [#1912](https://github.com/zsviczian/obsidian-excalidraw-plugin/issues/1912)
|
||||
|
||||
<div class="excalidraw-videoWrapper"><div>
|
||||
<iframe src="https://www.youtube.com/embed/2poSS-Z91lY" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
|
||||
</div></div>
|
||||
|
||||
## New
|
||||
- Elbow connectors: https://x.com/excalidraw/status/1819084086222393554
|
||||
|
||||
## Fixed
|
||||
- Convert Markdown to Excalidraw did not work correctly when there was ${String.fromCharCode(96)}---${String.fromCharCode(96)} anywhere in the file, but no frontmatter (e.g. a table)
|
||||
- Fixed Obsidian move tab to new window
|
||||
- Fixed duplicating bound arrows without its bound elements throwing error [#8315](https://github.com/excalidraw/excalidraw/issues/8315)
|
||||
`,
|
||||
"2.2.13": `
|
||||
## Fixed
|
||||
- Could not undo element after pasting [#1906](https://github.com/zsviczian/obsidian-excalidraw-plugin/issues/1906)
|
||||
- Links broke after renaming an Excalidraw file using the F2 shortcut [#1907](https://github.com/zsviczian/obsidian-excalidraw-plugin/issues/1907)
|
||||
- Unable to open or convert very large ${String.fromCharCode(96)}.excalidraw${String.fromCharCode(96)} file, e.g. BoaPs you can download from [here](https://ko-fi.com/zsolt/shop)
|
||||
`,
|
||||
"2.2.12": `
|
||||
## Fixed
|
||||
- Rename moved files to root folder [#1905](https://github.com/zsviczian/obsidian-excalidraw-plugin/issues/1905)
|
||||
|
||||
@@ -230,7 +230,7 @@ export default {
|
||||
"默认的 OpenAI API URL。请填写有效的 OpenAI API URL。" +
|
||||
"Excalidraw 会通过该 URL 发送 API 请求给 OpenAI。我没有对此选项做任何错误处理,请谨慎修改。",
|
||||
AI_OPENAI_DEFAULT_IMAGE_API_URL_NAME: "OpenAI 图像生成 API URL",
|
||||
AI_OPENAI_DEFAULT_VISION_MODEL_PLACEHOLDER: "gpt-4o",
|
||||
AI_OPENAI_DEFAULT_VISION_MODEL_PLACEHOLDER: "输入你的默认 AI 模型名称,例如:gpt-4o",
|
||||
SAVING_HEAD: "保存",
|
||||
SAVING_DESC: "包括:压缩,自动保存的时间间隔,文件的命名格式和扩展名等的设置。",
|
||||
COMPRESS_NAME: "压缩 Excalidraw JSON",
|
||||
@@ -646,7 +646,7 @@ FILENAME_HEAD: "文件名",
|
||||
LATEX_DEFAULT_NAME: "插入 LaTeX 时的默认表达式",
|
||||
LATEX_DEFAULT_DESC: "允许留空。允许使用类似 <code>\\color{white}</code> 的格式化表达式。",
|
||||
NONSTANDARD_HEAD: "非 Excalidraw.com 官方支持的特性",
|
||||
NONSTANDARD_DESC: `这些特性不受 Excalidraw.com 官方支持。如果以 Excalidraw.com 格式导出绘图,这些特性将会发生不可预知的变化。
|
||||
NONSTANDARD_DESC: `这些特性不受 Excalidraw.com 官方支持。如果在 Excalidraw.com 导入绘图,这些特性将会发生不可预知的变化。
|
||||
包括:自定义画笔工具的数量,自定义字体等。`,
|
||||
RENDER_TWEAK_HEAD: "渲染优化",
|
||||
MAX_IMAGE_ZOOM_IN_NAME: "最大图像放大倍数",
|
||||
@@ -697,7 +697,7 @@ FILENAME_HEAD: "文件名",
|
||||
"启用此功能简化了 Excalidraw 前置属性的使用,使您能够利用许多强大的设置。如果您不希望自动加载这些属性," +
|
||||
"您可以禁用此功能,但您将需要手动从自动提示中移除任何不需要的属性。" +
|
||||
"请注意,启用此设置需要重启插件,因为属性是在启动时加载的。",
|
||||
CUSTOM_FONT_HEAD: "自定义字体",
|
||||
CUSTOM_FONT_HEAD: "本地字体",
|
||||
ENABLE_FOURTH_FONT_NAME: "为文本元素启用本地字体",
|
||||
ENABLE_FOURTH_FONT_DESC:
|
||||
"开启此项后,文本元素的属性面板里会多出一个本地字体按钮。<br>" +
|
||||
|
||||
35
src/main.ts
35
src/main.ts
@@ -101,7 +101,7 @@ import {
|
||||
versionUpdateCheckTimer,
|
||||
getFontMetrics,
|
||||
} from "./utils/Utils";
|
||||
import { editorInsertText, extractSVGPNGFileName, foldExcalidrawSection, getActivePDFPageNumberFromPDFView, getAttachmentsFolderAndFilePath, getNewOrAdjacentLeaf, getParentOfClass, isObsidianThemeDark, mergeMarkdownFiles, openLeaf } from "./utils/ObsidianUtils";
|
||||
import { editorInsertText, extractSVGPNGFileName, foldExcalidrawSection, getActivePDFPageNumberFromPDFView, getAttachmentsFolderAndFilePath, getNewOrAdjacentLeaf, getParentOfClass, isObsidianThemeDark, mergeMarkdownFiles, openLeaf, setExcalidrawView } from "./utils/ObsidianUtils";
|
||||
import { ExcalidrawElement, ExcalidrawEmbeddableElement, ExcalidrawImageElement, ExcalidrawTextElement, FileId } from "@zsviczian/excalidraw/types/excalidraw/element/types";
|
||||
import { ScriptEngine } from "./Scripts";
|
||||
import {
|
||||
@@ -187,7 +187,7 @@ export default class ExcalidrawPlugin extends Plugin {
|
||||
public editorHandler: EditorHandler;
|
||||
//if set, the next time this file is opened it will be opened as markdown
|
||||
public forceToOpenInMarkdownFilepath: string = null;
|
||||
private slob:string;
|
||||
//private slob:string;
|
||||
private ribbonIcon:HTMLElement;
|
||||
public loadTimestamp:number;
|
||||
|
||||
@@ -201,9 +201,9 @@ export default class ExcalidrawPlugin extends Plugin {
|
||||
this.equationsMaster = new Map<FileId, string>();
|
||||
this.mermaidsMaster = new Map<FileId, string>();
|
||||
setExcalidrawPlugin(this);
|
||||
if((process.env.NODE_ENV === 'development')) {
|
||||
/*if((process.env.NODE_ENV === 'development')) {
|
||||
this.slob = new Array(200 * 1024 * 1024 + 1).join('A'); // Create a 200MB blob
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
get locale() {
|
||||
@@ -488,7 +488,7 @@ export default class ExcalidrawPlugin extends Plugin {
|
||||
if (fileShouldDefaultAsExcalidraw(leaf.view.file?.path, this.app)) {
|
||||
this.excalidrawFileModes[(leaf as any).id || leaf.view.file.path] =
|
||||
VIEW_TYPE_EXCALIDRAW;
|
||||
this.setExcalidrawView(leaf);
|
||||
setExcalidrawView(leaf);
|
||||
} else {
|
||||
foldExcalidrawSection(leaf.view);
|
||||
}
|
||||
@@ -2377,7 +2377,7 @@ export default class ExcalidrawPlugin extends Plugin {
|
||||
const activeLeaf = markdownView.leaf;
|
||||
this.excalidrawFileModes[(activeLeaf as any).id || activeFile.path] =
|
||||
VIEW_TYPE_EXCALIDRAW;
|
||||
this.setExcalidrawView(activeLeaf);
|
||||
setExcalidrawView(activeLeaf);
|
||||
})()
|
||||
return;
|
||||
}
|
||||
@@ -2412,7 +2412,7 @@ export default class ExcalidrawPlugin extends Plugin {
|
||||
activeFile,
|
||||
mergedTarget,
|
||||
);
|
||||
this.setExcalidrawView(activeView.leaf);
|
||||
setExcalidrawView(activeView.leaf);
|
||||
})();
|
||||
},
|
||||
});
|
||||
@@ -2450,7 +2450,7 @@ export default class ExcalidrawPlugin extends Plugin {
|
||||
log(fname);
|
||||
const result = await this.app.vault.create(
|
||||
fname,
|
||||
FRONTMATTER + (await this.exportSceneToMD(data)),
|
||||
FRONTMATTER + (await this.exportSceneToMD(data, false)),
|
||||
);
|
||||
if (this.settings.keepInSync) {
|
||||
EXPORT_TYPES.forEach((ext: string) => {
|
||||
@@ -2538,7 +2538,7 @@ export default class ExcalidrawPlugin extends Plugin {
|
||||
await view.save();
|
||||
//@ts-ignore
|
||||
this.excalidrawFileModes[leaf.id || file.path] = VIEW_TYPE_EXCALIDRAW;
|
||||
this.setExcalidrawView(leaf);
|
||||
setExcalidrawView(leaf);
|
||||
}));
|
||||
},
|
||||
),
|
||||
@@ -2563,7 +2563,7 @@ export default class ExcalidrawPlugin extends Plugin {
|
||||
await view.save();
|
||||
//@ts-ignore
|
||||
this.excalidrawFileModes[leaf.id || file.path] = VIEW_TYPE_EXCALIDRAW;
|
||||
this.setExcalidrawView(leaf);
|
||||
setExcalidrawView(leaf);
|
||||
})});
|
||||
//@ts-ignore
|
||||
menu.items.unshift(menu.items.pop());
|
||||
@@ -3486,7 +3486,7 @@ export default class ExcalidrawPlugin extends Plugin {
|
||||
* @param {string} data - Excalidraw scene JSON string
|
||||
* @returns {string} - Text starting with the "# Text Elements" header and followed by each "## id-value" and text
|
||||
*/
|
||||
public async exportSceneToMD(data: string): Promise<string> {
|
||||
public async exportSceneToMD(data: string, compressOverride?: boolean): Promise<string> {
|
||||
if (!data) {
|
||||
return "";
|
||||
}
|
||||
@@ -3511,7 +3511,9 @@ export default class ExcalidrawPlugin extends Plugin {
|
||||
outString +
|
||||
getMarkdownDrawingSection(
|
||||
JSON.stringify(JSON_parse(data), null, "\t"),
|
||||
this.settings.compress,
|
||||
typeof compressOverride === "undefined"
|
||||
? this.settings.compress
|
||||
: compressOverride,
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -3596,14 +3598,7 @@ export default class ExcalidrawPlugin extends Plugin {
|
||||
|
||||
}
|
||||
|
||||
public async setExcalidrawView(leaf: WorkspaceLeaf) {
|
||||
(process.env.NODE_ENV === 'development') && DEBUGGING && debug(this.setExcalidrawView,`ExcalidrawPlugin.setExcalidrawView`, leaf);
|
||||
await leaf.setViewState({
|
||||
type: VIEW_TYPE_EXCALIDRAW,
|
||||
state: leaf.view.getState(),
|
||||
popstate: true,
|
||||
} as ViewState);
|
||||
}
|
||||
|
||||
|
||||
public isExcalidrawFile(f: TFile) {
|
||||
if(!f) return false;
|
||||
|
||||
@@ -70,7 +70,7 @@ export class EmbeddableMenu {
|
||||
};
|
||||
|
||||
private async actionMarkdownSelection (file: TFile, isExcalidrawFile: boolean, subpath: string, element: ExcalidrawEmbeddableElement) {
|
||||
this.view.updateScene({appState: {activeEmbeddable: null}});
|
||||
this.view.updateScene({appState: {activeEmbeddable: null}, storeAction: "update"});
|
||||
const sections = (await app.metadataCache.blockCache
|
||||
.getForFile({ isCancelled: () => false },file))
|
||||
.blocks.filter((b: any) => b.display && b.node?.type === "heading")
|
||||
@@ -98,7 +98,7 @@ export class EmbeddableMenu {
|
||||
|
||||
private async actionMarkdownBlock (file: TFile, subpath: string, element: ExcalidrawEmbeddableElement) {
|
||||
if(!file) return;
|
||||
this.view.updateScene({appState: {activeEmbeddable: null}});
|
||||
this.view.updateScene({appState: {activeEmbeddable: null}, storeAction: "update"});
|
||||
const paragraphs = (await app.metadataCache.blockCache
|
||||
.getForFile({ isCancelled: () => false },file))
|
||||
.blocks.filter((b: any) => b.display && b.node &&
|
||||
|
||||
@@ -34,7 +34,8 @@ export function setPen (pen: PenStyle, api: any) {
|
||||
currentItemRoughness: st.currentItemRoughness,
|
||||
}}
|
||||
: null,
|
||||
}
|
||||
},
|
||||
storeAction: "update",
|
||||
})
|
||||
}
|
||||
|
||||
@@ -50,7 +51,8 @@ export function resetStrokeOptions (resetCustomPen:any, api: ExcalidrawImperativ
|
||||
}: null,
|
||||
resetCustomPen: null,
|
||||
...clearCurrentStrokeOptions ? {currentStrokeOptions: null} : null,
|
||||
}
|
||||
},
|
||||
storeAction: "update",
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ export const setDynamicStyle = (
|
||||
) => {
|
||||
if(dynamicStyle === "none") {
|
||||
view.excalidrawContainer?.removeAttribute("style");
|
||||
setTimeout(()=>view.updateScene({appState:{dynamicStyle: ""}}));
|
||||
setTimeout(()=>view.updateScene({appState:{dynamicStyle: ""}, storeAction: "update"}));
|
||||
const toolspanel = view.toolsPanelRef?.current?.containerRef?.current;
|
||||
if(toolspanel) {
|
||||
let toolsStyle = toolspanel.getAttribute("style");
|
||||
@@ -167,7 +167,8 @@ export const setDynamicStyle = (
|
||||
appState:{
|
||||
frameColor,
|
||||
dynamicStyle: styleObject
|
||||
}
|
||||
},
|
||||
storeAction: "update",
|
||||
});
|
||||
view = null;
|
||||
ea = null;
|
||||
|
||||
@@ -236,8 +236,8 @@ export async function addBackOfTheNoteCard(
|
||||
const el = ea.getViewElements().find(el=>el.id === id);
|
||||
api.selectElements([el]);
|
||||
if(activate) {
|
||||
setTimeout(()=>{
|
||||
api.updateScene({appState: {activeEmbeddable: {element: el, state: "active"}}});
|
||||
window.setTimeout(()=>{
|
||||
api.updateScene({appState: {activeEmbeddable: {element: el, state: "active"}}, storeAction: "update"});
|
||||
if(found) view.getEmbeddableLeafElementById(el.id)?.editNode?.();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -3,13 +3,14 @@ import {
|
||||
Editor,
|
||||
FrontMatterCache,
|
||||
MarkdownView,
|
||||
normalizePath, OpenViewState, parseFrontMatterEntry, TFile, View, Workspace, WorkspaceLeaf, WorkspaceSplit
|
||||
normalizePath, OpenViewState, parseFrontMatterEntry, TFile, View, ViewState, Workspace, WorkspaceLeaf, WorkspaceSplit
|
||||
} from "obsidian";
|
||||
import ExcalidrawPlugin from "../main";
|
||||
import { checkAndCreateFolder, splitFolderAndFilename } from "./FileUtils";
|
||||
import { linkClickModifierType, ModifierKeys } from "./ModifierkeyHelper";
|
||||
import { REG_BLOCK_REF_CLEAN, REG_SECTION_REF_CLEAN } from "src/constants/constants";
|
||||
import { REG_BLOCK_REF_CLEAN, REG_SECTION_REF_CLEAN, VIEW_TYPE_EXCALIDRAW } from "src/constants/constants";
|
||||
import yaml, { Mark } from "js-yaml";
|
||||
import { debug, DEBUGGING } from "./DebugHelper";
|
||||
|
||||
export const getParentOfClass = (element: Element, cssClass: string):HTMLElement | null => {
|
||||
let parent = element.parentElement;
|
||||
@@ -300,7 +301,7 @@ export const openLeaf = ({
|
||||
return {leaf, promise};
|
||||
}
|
||||
|
||||
export const mergeMarkdownFiles = (template: string, target: string): string => {
|
||||
export function mergeMarkdownFiles (template: string, target: string): string {
|
||||
// Extract frontmatter from the template
|
||||
const templateFrontmatterEnd = template.indexOf('---', 4); // Find end of frontmatter
|
||||
const templateFrontmatter = template.substring(4, templateFrontmatterEnd).trim();
|
||||
@@ -312,8 +313,8 @@ export const mergeMarkdownFiles = (template: string, target: string): string =>
|
||||
// Extract frontmatter from the target if it exists
|
||||
let targetFrontmatterObj: FrontMatterCache = {};
|
||||
let targetContent = '';
|
||||
if (target.includes('---')) {
|
||||
const targetFrontmatterEnd = target.indexOf('---', 4); // Find end of frontmatter
|
||||
if (target.startsWith('---\n') && target.indexOf('---\n', 4) > 0) {
|
||||
const targetFrontmatterEnd = target.indexOf('---\n', 4); // Find end of frontmatter
|
||||
const targetFrontmatter = target.substring(4, targetFrontmatterEnd).trim();
|
||||
targetContent = target.substring(targetFrontmatterEnd + 3); // Skip frontmatter and ---
|
||||
|
||||
@@ -392,3 +393,20 @@ export const foldExcalidrawSection = (view: MarkdownView) => {
|
||||
view.currentMode.applyFoldInfo({ folds: foldPositions, lines: lineCount });
|
||||
}
|
||||
};
|
||||
|
||||
export async function setExcalidrawView(leaf: WorkspaceLeaf) {
|
||||
(process.env.NODE_ENV === 'development') && DEBUGGING && debug(setExcalidrawView,`setExcalidrawView`, leaf);
|
||||
await leaf.setViewState({
|
||||
type: VIEW_TYPE_EXCALIDRAW,
|
||||
state: leaf.view.getState(),
|
||||
popstate: true,
|
||||
} as ViewState);
|
||||
}
|
||||
|
||||
export async function closeLeafView(leaf: WorkspaceLeaf) {
|
||||
(process.env.NODE_ENV === 'development') && DEBUGGING && debug(setExcalidrawView,`setExcalidrawView`, leaf);
|
||||
await leaf.setViewState({
|
||||
type: "empty",
|
||||
state: {},
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user