Skip to content

Commit

Permalink
Support Templater scripts in Embeddable Markdown Documents
Browse files Browse the repository at this point in the history
  • Loading branch information
zsviczian committed Aug 2, 2023
1 parent c9c5468 commit 83aa043
Show file tree
Hide file tree
Showing 9 changed files with 87 additions and 10 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "obsidian-excalidraw-plugin",
"version": "1.9.9-2",
"version": "1.9.13",
"description": "This is an Obsidian.md plugin that lets you view and edit Excalidraw drawings",
"main": "lib/index.js",
"types": "lib/index.d.ts",
Expand Down
9 changes: 5 additions & 4 deletions src/ExcalidrawAutomate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
StrokeRoundness,
RoundnessType,
} from "@zsviczian/excalidraw/types/element/types";
import { normalizePath, Notice, TFile, WorkspaceLeaf } from "obsidian";
import { normalizePath, Notice, OpenViewState, TFile, WorkspaceLeaf } from "obsidian";
import * as obsidian_module from "obsidian";
import ExcalidrawView, { ExportSettings, TextMode } from "src/ExcalidrawView";
import { ExcalidrawData, getMarkdownDrawingSection } from "src/ExcalidrawData";
Expand Down Expand Up @@ -2010,18 +2010,19 @@ export class ExcalidrawAutomate {

/**
* Open a file in a new workspaceleaf or reuse an existing adjacent leaf depending on Excalidraw Plugin Settings
* @param file
* @param file
* @param openState - if not provided {active: true} will be used
* @returns
*/
openFileInNewOrAdjacentLeaf(file: TFile): WorkspaceLeaf {
openFileInNewOrAdjacentLeaf(file: TFile, openState?: OpenViewState): WorkspaceLeaf {
if (!file || !(file instanceof TFile)) {
return null;
}
if (!this.targetView) {
return null;
}
const leaf = getNewOrAdjacentLeaf(this.plugin, this.targetView.leaf);
leaf.openFile(file, {active: true});
leaf.openFile(file, openState ?? {active: true});
return leaf;
};

Expand Down
40 changes: 39 additions & 1 deletion src/ExcalidrawView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ import { InsertPDFModal } from "./dialogs/InsertPDFModal";
import { CustomEmbeddable, renderWebView } from "./customEmbeddable";
import { insertEmbeddableToView, insertImageToView } from "./utils/ExcalidrawViewUtils";
import { imageCache } from "./utils/ImageCache";
import { CanvasNodeFactory } from "./utils/CanvasNodeFactory";
import { CanvasNodeFactory, ObsidianCanvasNode } from "./utils/CanvasNodeFactory";
import { EmbeddableMenu } from "./menu/EmbeddableActionsMenu";
import { useDefaultExcalidrawFrame } from "./utils/CustomEmbeddableUtils";
import { UniversalInsertFileModal } from "./dialogs/UniversalInsertFileModal";
Expand Down Expand Up @@ -255,6 +255,7 @@ export default class ExcalidrawView extends TextFileView {
private draginfoDiv: HTMLDivElement;
public canvasNodeFactory: CanvasNodeFactory;
private embeddableRefs = new Map<ExcalidrawElement["id"], HTMLIFrameElement | HTMLWebViewElement>();
private embeddableLeafRefs = new Map<ExcalidrawElement["id"], any>();

public semaphores: {
popoutUnload: boolean; //the unloaded Excalidraw view was the last leaf in the popout window
Expand Down Expand Up @@ -1626,6 +1627,7 @@ export default class ExcalidrawView extends TextFileView {
clear() {
this.canvasNodeFactory.purgeNodes();
this.embeddableRefs.clear();
this.embeddableLeafRefs.clear();

delete this.exportDialog;
const api = this.excalidrawAPI;
Expand Down Expand Up @@ -4467,6 +4469,42 @@ export default class ExcalidrawView extends TextFileView {
public getEmbeddableElementById(id: string): HTMLIFrameElement | HTMLWebViewElement | undefined {
return this.embeddableRefs.get(id);
}

public updateEmbeddableLeafRef(id: string, ref: any) {
if(ref) {
this.embeddableLeafRefs.set(id, ref);
}
}

public getEmbeddableLeafElementById(id: string): {leaf: WorkspaceLeaf; node?: ObsidianCanvasNode} | null {
const ref = this.embeddableLeafRefs.get(id);
if(!ref) {
return null;
}
return ref as {leaf: WorkspaceLeaf; node?: ObsidianCanvasNode};
}

getActiveEmbeddable = ():{leaf: WorkspaceLeaf; node?: ObsidianCanvasNode}|null => {
if(!this.excalidrawAPI) return null;
const api = this.excalidrawAPI as ExcalidrawImperativeAPI;
const st = api.getAppState();
if(!st.activeEmbeddable || st.activeEmbeddable.state !== "active" ) return null;
return this.getEmbeddableLeafElementById(st.activeEmbeddable?.element?.id);
}

get editor(): any {
const embeddable = this.getActiveEmbeddable();
if(embeddable) {
if(embeddable.node && embeddable.node.isEditing) {
return embeddable.node.child.editor;
}
if(embeddable.leaf?.view instanceof MarkdownView) {
return embeddable.leaf.view.editor;
}
}
app.workspace.openLinkText
return null;
}
}

export function getTextMode(data: string): TextMode {
Expand Down
6 changes: 3 additions & 3 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,9 @@ export const SCRIPT_INSTALL_CODEBLOCK = "excalidraw-script-install";
export const SCRIPT_INSTALL_FOLDER = "Downloaded";
export const fileid = customAlphabet("1234567890abcdef", 40);
export const REG_LINKINDEX_INVALIDCHARS = /[<>:"\\|?*#]/g;
export const REG_BLOCK_REF_CLEAN =
/[!"#$%&()*+,.:;<=>?@^`{|}~\/\[\]\\]/g; //https://discord.com/channels/686053708261228577/989603365606531104/1000128926619816048
// /\+|\/|~|=|%|\(|\)|{|}|,|&|\.|\$|!|\?|;|\[|]|\^|#|\*|<|>|&|@|\||\\|"|:|\s/g;
export const REG_BLOCK_REF_CLEAN = /[!"#$%&()*+,.:;<=>?@^`{|}~\/\[\]\\]/g;
// https://discord.com/channels/686053708261228577/989603365606531104/1000128926619816048
// /\+|\/|~|=|%|\(|\)|{|}|,|&|\.|\$|!|\?|;|\[|]|\^|#|\*|<|>|&|@|\||\\|"|:|\s/g;
export const IMAGE_TYPES = ["jpeg", "jpg", "png", "gif", "svg", "webp", "bmp", "ico"];
export const EXPORT_TYPES = ["svg", "dark.svg", "light.svg", "png", "dark.png", "light.png"];
export const MAX_IMAGE_SIZE = 500;
Expand Down
1 change: 1 addition & 0 deletions src/customEmbeddable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ function RenderObsidianView(
containerRef.current.appendChild(rootSplit.containerEl);
}
patchMobileView(view);
view.updateEmbeddableLeafRef(element.id, leafRef.current);
})();
}

Expand Down
26 changes: 25 additions & 1 deletion src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
MetadataCache,
FrontMatterCache,
Command,
Workspace,
} from "obsidian";
import {
BLANK_DRAWING,
Expand Down Expand Up @@ -63,7 +64,7 @@ import {
search,
} from "./ExcalidrawAutomate";
import { Prompt } from "./dialogs/Prompt";
import { around } from "monkey-around";
import { around, dedupe } from "monkey-around";
import { t } from "./lang/helpers";
import {
checkAndCreateFolder,
Expand All @@ -82,6 +83,7 @@ import {
debug,
isVersionNewerThanOther,
getExportTheme,
isCallerFromTemplaterPlugin,
} from "./utils/Utils";
import { getAttachmentsFolderAndFilePath, getNewOrAdjacentLeaf, getParentOfClass, isObsidianThemeDark } from "./utils/ObsidianUtils";
//import { OneOffs } from "./OneOffs";
Expand Down Expand Up @@ -1578,6 +1580,28 @@ export default class ExcalidrawPlugin extends Plugin {
}

private registerMonkeyPatches() {
const key = "https://github.com/zsviczian/obsidian-excalidraw-plugin/issues";
this.register(
around(Workspace.prototype, {
getActiveViewOfType(old) {
return dedupe(key, old, function(...args) {
const result = old && old.apply(this, args);
const maybeEAView = app?.workspace?.activeLeaf?.view;
if(!maybeEAView || !(maybeEAView instanceof ExcalidrawView)) return result;
const error = new Error();
const stackTrace = error.stack;
if(!isCallerFromTemplaterPlugin(stackTrace)) return result;
const leafOrNode = maybeEAView.getActiveEmbeddable();
if(leafOrNode) {
if(leafOrNode.node && leafOrNode.node.isEditing) {
return {file: leafOrNode.node.file, editor: leafOrNode.node.child.editor};
}
}
return result;
});
}
})
);
//@ts-ignore
if(!app.plugins?.plugins?.["obsidian-hover-editor"]) {
this.register( //stolen from hover editor
Expand Down
1 change: 1 addition & 0 deletions src/menu/EmbeddableActionsMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export class EmbeddableMenu {
const view = this.view;
const api = view?.excalidrawAPI as ExcalidrawImperativeAPI;
if(!api) return null;
if(!view.file) return null;
const disableFrameButtons = appState.viewModeEnabled && !view.allowFrameButtonsInViewMode;
if(!appState.activeEmbeddable || appState.activeEmbeddable.state !== "active" || disableFrameButtons) {
this.menuElementId = null;
Expand Down
2 changes: 2 additions & 0 deletions src/utils/CanvasNodeFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ interface ObsidianCanvas {
export interface ObsidianCanvasNode {
startEditing: Function;
child: any;
isEditing: boolean;
file: TFile;
}

export class CanvasNodeFactory {
Expand Down
10 changes: 10 additions & 0 deletions src/utils/Utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -725,4 +725,14 @@ export const getYouTubeThumbnailLink = async (youtubelink: string):Promise<strin


return `https://i.ytimg.com/vi/${videoId}/default.jpg`;
}

export const isCallerFromTemplaterPlugin = (stackTrace:string) => {
const lines = stackTrace.split("\n");
for (const line of lines) {
if (line.trim().startsWith("at Templater.")) {
return true;
}
}
return false;
}

0 comments on commit 83aa043

Please sign in to comment.