mirror of
https://github.com/zsviczian/obsidian-excalidraw-plugin.git
synced 2025-08-06 05:46:28 +00:00
Compare commits
8 Commits
2.2.13
...
2.4.0-beta
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bf148adc68 | ||
|
|
9fc0452b70 | ||
|
|
83eda9b3f5 | ||
|
|
9bfbf47963 | ||
|
|
252bf411b1 | ||
|
|
5622c019dd | ||
|
|
b32fab7865 | ||
|
|
cafdad1f7a |
@@ -63,6 +63,13 @@ The Obsidian-Excalidraw plugin integrates [Excalidraw](https://excalidraw.com/),
|
||||
<a href="https://youtu.be/4N6efq1DtH0" target="_blank"><img src="https://user-images.githubusercontent.com/14358394/158008902-12c6a851-237e-4edd-a631-d48e81c904b2.jpg" width="100" style="vertical-align: middle;"/> Eraser, left-handed mode, improved filename configuration</a><br>
|
||||
</details>
|
||||
|
||||
### Beta testing
|
||||
The plugin follows a monthly release schedule. If you want to receive more frequent updates with new features (e.g. shiny new stuff available on excalidraw.com, but not yet in Obsidian) and minor bug fixes, then join the beta community.
|
||||
|
||||
[](https://youtu.be/2poSS-Z91lY)
|
||||
|
||||
[](https://github.com/user-attachments/assets/120a0790-7239-48ae-bfbd-eb249f8b518d)
|
||||
|
||||
---
|
||||
|
||||
## Features
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"id": "obsidian-excalidraw-plugin",
|
||||
"name": "Excalidraw",
|
||||
"version": "2.2.10-2",
|
||||
"version": "2.4.0-beta-2",
|
||||
"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.13",
|
||||
"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-38",
|
||||
"chroma-js": "^2.4.2",
|
||||
"clsx": "^2.0.0",
|
||||
"colormaster": "^1.2.1",
|
||||
|
||||
@@ -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";
|
||||
@@ -140,7 +140,6 @@ import { Mutable } from "@zsviczian/excalidraw/types/excalidraw/utility-types";
|
||||
import { SelectCard } from "./dialogs/SelectCard";
|
||||
import { Packages } from "./types/types";
|
||||
import React from "react";
|
||||
import { StoreAction } from "@zsviczian/excalidraw";
|
||||
|
||||
const EMBEDDABLE_SEMAPHORE_TIMEOUT = 2000;
|
||||
const PREVENT_RELOAD_TIMEOUT = 2000;
|
||||
@@ -245,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;
|
||||
@@ -1353,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;
|
||||
|
||||
@@ -1614,7 +1628,7 @@ export default class ExcalidrawView extends TextFileView {
|
||||
}
|
||||
const st = api.getAppState();
|
||||
const isEditing = st.editingElement !== null;
|
||||
const isDragging = st.draggingElement !== null;
|
||||
const isDragging = st.newElement !== null;
|
||||
//this will reset positioning of the cursor in case due to the popup keyboard,
|
||||
//or the command palette, or some other unexpected reason the onResize would not fire...
|
||||
this.refreshCanvasOffset();
|
||||
@@ -2156,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);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -2203,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};
|
||||
}
|
||||
|
||||
@@ -3358,7 +3372,7 @@ export default class ExcalidrawView extends TextFileView {
|
||||
//(process.env.NODE_ENV === 'development') && DEBUGGING && debug(this.showHoverPreview, "ExcalidrawView.showHoverPreview", linktext, element);
|
||||
if(!this.lastMouseEvent) return;
|
||||
const st = this.excalidrawAPI?.getAppState();
|
||||
if(st?.editingElement || st?.draggingElement) return; //should not activate hover preview when element is being edited or dragged
|
||||
if(st?.editingElement || st?.newElement) return; //should not activate hover preview when element is being edited or dragged
|
||||
if(this.semaphores.wheelTimeout) return;
|
||||
//if link text is not provided, try to get it from the element
|
||||
if (!linktext) {
|
||||
@@ -3683,7 +3697,7 @@ export default class ExcalidrawView extends TextFileView {
|
||||
//Removed because of
|
||||
//https://github.com/zsviczian/obsidian-excalidraw-plugin/issues/565
|
||||
/*st.resizingElement === null &&
|
||||
st.draggingElement === null &&
|
||||
st.newElement === null &&
|
||||
st.editingGroupId === null &&*/
|
||||
st.editingLinearElement === null
|
||||
) {
|
||||
@@ -5510,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) {
|
||||
|
||||
@@ -17,6 +17,21 @@ 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)
|
||||
|
||||
27
src/main.ts
27
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);
|
||||
})();
|
||||
},
|
||||
});
|
||||
@@ -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());
|
||||
@@ -3598,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;
|
||||
|
||||
@@ -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