ready to release

This commit is contained in:
Zsolt Viczian
2022-04-30 16:31:53 +02:00
parent fa2fe5e462
commit 26e12e8cec
13 changed files with 299 additions and 63 deletions

View File

@@ -17,7 +17,7 @@
"author": "",
"license": "MIT",
"dependencies": {
"@zsviczian/excalidraw": "0.11.0-obsidian-11",
"@zsviczian/excalidraw": "0.11.0-obsidian-16",
"monkey-around": "^2.3.0",
"react": "^17.0.2",
"react-dom": "^17.0.2",

View File

@@ -162,7 +162,6 @@ export class EmbeddedFile {
export class EmbeddedFilesLoader {
private plugin: ExcalidrawPlugin;
private processedFiles: Map<string, number> = new Map<string, number>();
private isDark: boolean;
public terminate = false;
public uid: string;
@@ -173,7 +172,7 @@ export class EmbeddedFilesLoader {
this.uid = nanoid();
}
public async getObsidianImage(inFile: TFile | EmbeddedFile): Promise<{
public async getObsidianImage(inFile: TFile | EmbeddedFile, depth: number): Promise<{
mimeType: MimeType;
fileId: FileId;
dataURL: DataURL;
@@ -196,15 +195,7 @@ export class EmbeddedFilesLoader {
width: this.plugin.settings.mdSVGwidth,
height: this.plugin.settings.mdSVGmaxHeight,
};
//to block infinite loop of recursive loading of images
const count = this.processedFiles.has(file.path)
? this.processedFiles.get(file.path)
: 0;
if (file.extension === "md" && count > 2) {
new Notice(t("INFINITE_LOOP_WARNING") + file.path, 6000);
return null;
}
this.processedFiles.set(file.path, count + 1);
let hasSVGwithBitmap = false;
const app = this.plugin.app;
const isExcalidrawFile = this.plugin.isExcalidrawFile(file);
@@ -240,6 +231,7 @@ export class EmbeddedFilesLoader {
null,
[],
this.plugin,
depth+1,
getSVGPadding(this.plugin, file),
);
//https://stackoverflow.com/questions/51154171/remove-css-filter-on-child-elements
@@ -315,7 +307,12 @@ export class EmbeddedFilesLoader {
public async loadSceneFiles(
excalidrawData: ExcalidrawData,
addFiles: Function,
depth:number
) {
if(depth > 4) {
new Notice(t("INFINITE_LOOP_WARNING")+depth.toString(), 6000);
return;
}
const entries = excalidrawData.getFileEntries();
//debug({where:"EmbeddedFileLoader.loadSceneFiles",uid:this.uid,isDark:this.isDark,sceneTheme:excalidrawData.scene.appState.theme});
if (this.isDark === undefined) {
@@ -327,7 +324,7 @@ export class EmbeddedFilesLoader {
const embeddedFile: EmbeddedFile = entry.value[1];
if (!embeddedFile.isLoaded(this.isDark)) {
//debug({where:"EmbeddedFileLoader.loadSceneFiles",uid:this.uid,status:"embedded Files are not loaded"});
const data = await this.getObsidianImage(embeddedFile);
const data = await this.getObsidianImage(embeddedFile, depth);
if (data) {
files.push({
mimeType: data.mimeType,

View File

@@ -6,6 +6,7 @@ import {
ExcalidrawElement,
ExcalidrawBindableElement,
FileId,
NonDeletedExcalidrawElement,
} from "@zsviczian/excalidraw/types/element/types";
import { normalizePath, TFile, WorkspaceLeaf } from "obsidian";
import ExcalidrawView, { ExportSettings, TextMode } from "./ExcalidrawView";
@@ -17,6 +18,7 @@ import {
MAX_IMAGE_SIZE,
PLUGIN_ID,
COLOR_NAMES,
fileid,
} from "./Constants";
import { getDrawingFilename, } from "./utils/FileUtils";
import {
@@ -202,6 +204,7 @@ export class ExcalidrawAutomate implements ExcalidrawAutomateInterface {
templatePath,
false,
new EmbeddedFilesLoader(this.plugin),
0
)
: null;
let elements = template ? template.elements : [];
@@ -253,6 +256,11 @@ export class ExcalidrawAutomate implements ExcalidrawAutomateInterface {
"excalidraw-link-prefix"?: string;
"excalidraw-link-brackets"?: boolean;
"excalidraw-url-prefix"?: string;
"excalidraw-export-transparent"?: boolean;
"excalidraw-export-dark"?: boolean;
"excalidraw-export-svgpadding"?: number;
"excalidraw-export-pngscale"?: number;
"excalidraw-default-mode"?: "view" | "zen";
};
}): Promise<string> {
const template = params?.templatePath
@@ -261,6 +269,7 @@ export class ExcalidrawAutomate implements ExcalidrawAutomateInterface {
params.templatePath,
true,
new EmbeddedFilesLoader(this.plugin),
0
)
: null;
let elements = template ? template.elements : [];
@@ -341,7 +350,7 @@ export class ExcalidrawAutomate implements ExcalidrawAutomateInterface {
return this.plugin.createAndOpenDrawing(
params?.filename
? `${params.filename}.excalidraw.md`
? params.filename + (params.filename.endsWith(".md") ? "": ".excalidraw.md")
: getDrawingFilename(this.plugin.settings),
params?.onNewPane ? params.onNewPane : false,
params?.foldername ? params.foldername : this.plugin.settings.folder,
@@ -400,6 +409,7 @@ export class ExcalidrawAutomate implements ExcalidrawAutomateInterface {
this.canvas.viewBackgroundColor,
this.getElements(),
this.plugin,
0
);
};
@@ -451,6 +461,7 @@ export class ExcalidrawAutomate implements ExcalidrawAutomateInterface {
this.canvas.viewBackgroundColor,
this.getElements(),
this.plugin,
0
);
};
@@ -497,6 +508,7 @@ export class ExcalidrawAutomate implements ExcalidrawAutomateInterface {
groupIds: [] as any,
boundElements: [] as any,
link: null as string,
locked: false,
};
}
@@ -842,13 +854,14 @@ export class ExcalidrawAutomate implements ExcalidrawAutomateInterface {
this.plugin,
this.canvas.theme === "dark",
);
const image = await loader.getObsidianImage(imageFile);
const image = await loader.getObsidianImage(imageFile,0);
if (!image) {
return null;
}
this.imagesDict[image.fileId] = {
const fileId = imageFile.extension === "md" ? fileid() as FileId : image.fileId;
this.imagesDict[fileId] = {
mimeType: image.mimeType,
id: image.fileId,
id: fileId,
dataURL: image.dataURL,
created: image.created,
file: imageFile.path,
@@ -869,7 +882,7 @@ export class ExcalidrawAutomate implements ExcalidrawAutomateInterface {
image.size.width,
image.size.height,
);
this.elementsDict[id].fileId = image.fileId;
this.elementsDict[id].fileId = fileId;
this.elementsDict[id].scale = [1, 1];
return id;
};
@@ -1311,7 +1324,54 @@ export class ExcalidrawAutomate implements ExcalidrawAutomateInterface {
};
/**
* if set Excalidraw will call this function onDrop events
* Register instance of EA to use for hooks with TargetView
* By default ExcalidrawViews will check window.ExcalidrawAutomate for event hooks.
* Using this event you can set a different instance of Excalidraw Automate for hooks
*/
registerThisAsViewEA() {
//@ts-ignore
if (!this.targetView || !this.targetView?._loaded) {
errorMessage("targetView not set", "addElementsToView()");
return false;
}
this.targetView.hookServer = this;
}
/**
* If set, this callback is triggered, when the user changes the view mode.
* You can use this callback in case you want to do something additional when the user switches to view mode and back.
*/
onViewModeChangeHook: (isViewModeEnabled:boolean) => void = null;
/**
* If set, this callback is triggered, when the user hovers a link in the scene.
* You can use this callback in case you want to do something additional when the onLinkHover event occurs.
* This callback must return a boolean value.
* In case you want to prevent the excalidraw onLinkHover action you must return false, it will stop the native excalidraw onLinkHover management flow.
*/
onLinkHoverHook: (
element: NonDeletedExcalidrawElement,
linkText: string,
) => boolean = null;
/**
* If set, this callback is triggered, when the user click a link in the scene.
* You can use this callback in case you want to do something additional when the onLinkClick event occurs.
* This callback must return a boolean value.
* In case you want to prevent the excalidraw onLinkClick action you must return false, it will stop the native excalidraw onLinkClick management flow.
*/
onLinkClickHook:(
element: ExcalidrawElement,
linkText: string,
event: MouseEvent
) => boolean = null;
/**
* If set, this callback is triggered, when Excalidraw receives an onDrop event.
* You can use this callback in case you want to do something additional when the onDrop event occurs.
* This callback must return a boolean value.
* In case you want to prevent the excalidraw onDrop action you must return false, it will stop the native excalidraw onDrop management flow.
*/
onDropHook: (data: {
ea: ExcalidrawAutomate;
@@ -1776,6 +1836,7 @@ async function getTemplate(
fileWithPath: string,
loadFiles: boolean = false,
loader: EmbeddedFilesLoader,
depth: number
): Promise<{
elements: any;
appState: any;
@@ -1839,7 +1900,7 @@ async function getTemplate(
};
}
scene = scaleLoadedImage(excalidrawData.scene, fileArray).scene;
});
}, depth);
}
return {
@@ -1869,12 +1930,13 @@ export async function createPNG(
canvasBackgroundColor: string = undefined,
automateElements: ExcalidrawElement[] = [],
plugin: ExcalidrawPlugin,
depth: number
) {
if (!loader) {
loader = new EmbeddedFilesLoader(plugin);
}
const template = templatePath
? await getTemplate(plugin, templatePath, true, loader)
? await getTemplate(plugin, templatePath, true, loader, depth)
: null;
let elements = template?.elements ?? [];
elements = elements.concat(automateElements);
@@ -1910,13 +1972,14 @@ export async function createSVG(
canvasBackgroundColor: string = undefined,
automateElements: ExcalidrawElement[] = [],
plugin: ExcalidrawPlugin,
depth: number,
padding?: number,
): Promise<SVGSVGElement> {
if (!loader) {
loader = new EmbeddedFilesLoader(plugin);
}
const template = templatePath
? await getTemplate(plugin, templatePath, true, loader)
? await getTemplate(plugin, templatePath, true, loader, depth)
: null;
let elements = template?.elements ?? [];
elements = elements.concat(automateElements);

View File

@@ -14,6 +14,7 @@ import {
FRONTMATTER_KEY_DEFAULT_MODE,
fileid,
REG_BLOCK_REF_CLEAN,
FRONTMATTER_KEY_LINKBUTTON_OPACITY,
} from "./Constants";
import { _measureText } from "./ExcalidrawAutomate";
import ExcalidrawPlugin from "./main";
@@ -1021,6 +1022,35 @@ export class ExcalidrawData {
return false;
}
//assing new fileId to duplicate equation and markdown files
//https://github.com/zsviczian/obsidian-excalidraw-plugin/issues/601
//https://github.com/zsviczian/obsidian-excalidraw-plugin/issues/593
//https://github.com/zsviczian/obsidian-excalidraw-plugin/issues/297
const processedIds = new Set<string>();
fileIds.forEach(fileId=>{
if(processedIds.has(fileId)) {
const file = this.files.get(fileId as FileId);
const equation = this.equations.get(fileId as FileId);
//images should have a single reference, but equations and markdown embeds should have as many as instances of the file in the scene
if(file && file.file.extension !== "md") {
return;
}
const newId = fileid();
//scene.files[newId] = {...scene.files[fileId]};
(scene.elements.filter((el:ExcalidrawImageElement)=>el.fileId === fileId)[0] as any).fileId = newId;
dirty = true;
processedIds.add(newId);
if(file) {
this.files.set(newId as FileId,new EmbeddedFile(this.plugin,this.file.path,file.linkParts.original))
}
if(equation) {
this.equations.set(newId as FileId, equation);
}
}
processedIds.add(fileId);
});
for (const key of Object.keys(scene.files)) {
if (!(this.hasFile(key as FileId) || this.hasEquation(key as FileId))) {
dirty = true;
@@ -1069,7 +1099,7 @@ export class ExcalidrawData {
}
//https://github.com/zsviczian/obsidian-excalidraw-plugin/issues/297
const equations = new Set<string>();
/*const equations = new Set<string>();
const duplicateEqs = new Set<string>();
for (const key of fileIds) {
if (this.hasEquation(key as FileId)) {
@@ -1095,7 +1125,7 @@ export class ExcalidrawData {
dirty = true;
}
}
}
}*/
return dirty;
}
@@ -1225,6 +1255,18 @@ export class ExcalidrawData {
}
}
public getLinkOpacity(): number {
const fileCache = this.app.metadataCache.getFileCache(this.file);
let opacity = this.plugin.settings.linkOpacity;
if (
fileCache?.frontmatter &&
fileCache.frontmatter[FRONTMATTER_KEY_LINKBUTTON_OPACITY] != null
) {
opacity = fileCache.frontmatter[FRONTMATTER_KEY_LINKBUTTON_OPACITY];
}
return opacity;
}
private setLinkPrefix(): boolean {
const linkPrefix = this.linkPrefix;
const fileCache = this.app.metadataCache.getFileCache(this.file);
@@ -1425,11 +1467,17 @@ export const getTransclusion = async (
let startPos: number = null;
let lineNum: number = 0;
let endPos: number = null;
let depth:number = 1;
for (let i = 0; i < headings.length; i++) {
if (startPos && !endPos) {
let j = i;
while (j<headings.length && headings[j].node.depth>depth) {j++};
if(j === headings.length && headings[j-1].node.depth > depth) {
return { contents: "#".repeat(depth)+" "+contents.substring(startPos).trim(), lineNum };
}
endPos = headings[i].node.position.start.offset - 1;
return {
contents: contents.substring(startPos, endPos).trim(),
contents: "#".repeat(depth)+" "+contents.substring(startPos, endPos).trim(),
lineNum,
};
}
@@ -1446,11 +1494,12 @@ export const getTransclusion = async (
: false))
) {
startPos = headings[i].node.children[0]?.position.start.offset; //
depth = headings[i].node.depth;
lineNum = headings[i].node.children[0]?.position.start.line; //
}
}
if (startPos) {
return { contents: contents.substring(startPos).trim(), lineNum };
return { contents: "#".repeat(depth)+" "+contents.substring(startPos).trim(), lineNum };
}
return { contents: linkParts.original.trim(), lineNum: 0 };
};

View File

@@ -41,7 +41,7 @@ import {
LOCAL_PROTOCOL,
} from "./Constants";
import ExcalidrawPlugin from "./main";
import { repositionElementsToCursor } from "./ExcalidrawAutomate";
import { repositionElementsToCursor, ExcalidrawAutomate } from "./ExcalidrawAutomate";
import { t } from "./lang/helpers";
import {
ExcalidrawData,
@@ -180,6 +180,7 @@ export default class ExcalidrawView extends TextFileView {
public toolsPanelRef: React.MutableRefObject<any> = null;
private parentMoveObserver: MutationObserver;
public linksAlwaysOpenInANewPane: boolean = false; //override the need for SHIFT+CTRL+click
public hookServer: ExcalidrawAutomate;
public semaphores: {
//The role of justLoaded is to capture the Excalidraw.onChange event that fires right after the canvas was loaded for the first time to
@@ -242,6 +243,7 @@ export default class ExcalidrawView extends TextFileView {
super(leaf);
this.plugin = plugin;
this.excalidrawData = new ExcalidrawData(plugin);
this.hookServer = plugin.ea;
}
preventAutozoom() {
@@ -640,6 +642,19 @@ export default class ExcalidrawView extends TextFileView {
return;
}
linkText = linkText.replaceAll("\n", ""); //https://github.com/zsviczian/obsidian-excalidraw-plugin/issues/187
if(this.hookServer?.onLinkClickHook) {
const id = selectedText.id??selectedElementWithLink.id;
const el = this.excalidrawAPI.getSceneElements().filter((el:ExcalidrawElement)=>el.id === id)[0];
try {
if(!this.hookServer.onLinkClickHook(el,linkText,ev)) {
return;
}
} catch (e) {
errorlog({where: "ExcalidrawView.handleLinkClick selectedText.id!==null", fn: this.hookServer.onLinkClickHook, error: e});
}
}
if (linkText.match(REG_LINKINDEX_HYPERLINK)) {
window.open(linkText, "_blank");
return;
@@ -753,6 +768,18 @@ export default class ExcalidrawView extends TextFileView {
return;
}
if(this.hookServer?.onLinkClickHook) {
const id = selectedImage.id??selectedText.id??selectedElementWithLink.id;
const el = this.excalidrawAPI.getSceneElements().filter((el:ExcalidrawElement)=>el.id === id)[0];
try {
if(!this.hookServer.onLinkClickHook(el,linkText,ev)) {
return;
}
} catch (e) {
errorlog({where: "ExcalidrawView.handleLinkClick selectedText.id===null", fn: this.hookServer.onLinkClickHook, error: e});
}
}
try {
if (ev.shiftKey && this.isFullscreen()) {
this.exitFullscreen();
@@ -1233,7 +1260,7 @@ export default class ExcalidrawView extends TextFileView {
if (this.nextLoader) {
runLoader(this.nextLoader);
}
},
},0
);
};
if (!this.activeLoader) {
@@ -1277,7 +1304,7 @@ export default class ExcalidrawView extends TextFileView {
...excalidrawData.appState,
zenModeEnabled,
viewModeEnabled,
linkOpacity: this.plugin.settings.linkOpacity,
linkOpacity: this.excalidrawData.getLinkOpacity(),
trayModeEnabled: this.plugin.settings.defaultTrayMode,
penMode: penEnabled,
penDetected: penEnabled,
@@ -1305,7 +1332,7 @@ export default class ExcalidrawView extends TextFileView {
...excalidrawData.appState,
zenModeEnabled: om.zenModeEnabled,
viewModeEnabled: om.viewModeEnabled,
linkOpacity: this.plugin.settings.linkOpacity,
linkOpacity: this.excalidrawData.getLinkOpacity(),
trayModeEnabled: this.plugin.settings.defaultTrayMode,
penMode: penEnabled,
penDetected: penEnabled,
@@ -1764,6 +1791,7 @@ export default class ExcalidrawView extends TextFileView {
this.addText = async (
text: string,
fontFamily?: 1 | 2 | 3 | 4,
save: boolean = true
): Promise<string> => {
const api = this.excalidrawAPI;
if (!excalidrawRef?.current || !api) {
@@ -1778,7 +1806,7 @@ export default class ExcalidrawView extends TextFileView {
ea.style.fontSize = st.currentItemFontSize ?? 20;
ea.style.textAlign = st.currentItemTextAlign ?? "left";
const id = ea.addText(currentPosition.x, currentPosition.y, text);
await this.addElements(ea.getElements(), false, true);
await this.addElements(ea.getElements(), false, save);
return id;
};
@@ -1997,6 +2025,7 @@ export default class ExcalidrawView extends TextFileView {
});
this.handleLinkClick(this, event);
selectedTextElement = null;
return;
}
selectedImageElement = getImageElementAtPointer(currentPosition, this);
if (selectedImageElement && selectedImageElement.id) {
@@ -2008,6 +2037,7 @@ export default class ExcalidrawView extends TextFileView {
});
this.handleLinkClick(this, event);
selectedImageElement = null;
return;
}
selectedElementWithLink = getElementWithLinkAtPointer(currentPosition, this);
@@ -2020,18 +2050,21 @@ export default class ExcalidrawView extends TextFileView {
});
this.handleLinkClick(this, event);
selectedElementWithLink = null;
return;
}
};
let mouseEvent: any = null;
const showHoverPreview = (linktext?: string) => {
const showHoverPreview = (linktext?: string, element?: ExcalidrawElement) => {
if (!linktext) {
if(!currentPosition) return;
linktext = "";
const selectedElement = getTextElementAtPointer(currentPosition, this);
if (!selectedElement || !selectedElement.text) {
const selectedImgElement =
getImageElementAtPointer(currentPosition, this);
element = this.excalidrawAPI.getSceneElements().filter((el:ExcalidrawElement)=>el.id === selectedImgElement.id)[0];
if (!selectedImgElement || !selectedImgElement.fileId) {
return;
}
@@ -2046,6 +2079,7 @@ export default class ExcalidrawView extends TextFileView {
this.excalidrawData.getFile(selectedImgElement.fileId).file.path +
ref;
} else {
element = this.excalidrawAPI.getSceneElements().filter((el:ExcalidrawElement)=>el.id === selectedElement.id)[0];
const text: string =
this.textMode === TextMode.parsed
? this.excalidrawData.getRawText(selectedElement.id)
@@ -2069,12 +2103,22 @@ export default class ExcalidrawView extends TextFileView {
}
}
if(this.hookServer?.onLinkHoverHook) {
try {
if(!this.hookServer.onLinkHoverHook(element,linktext)) {
return;
}
} catch (e) {
errorlog({where: "ExcalidrawView.showHoverPreview", fn: this.hookServer.onLinkHoverHook, error: e});
}
}
if (this.semaphores.hoverSleep) {
return;
}
const f = this.app.metadataCache.getFirstLinkpathDest(
linktext,
linktext.split("#")[0],
this.file.path,
);
if (!f) {
@@ -2221,7 +2265,10 @@ export default class ExcalidrawView extends TextFileView {
if (p.button === "up") {
blockOnMouseButtonDown = false;
}
if (this.plugin.ctrlKeyDown) {
if (this.plugin.ctrlKeyDown ||
(this.excalidrawAPI.getAppState().isViewModeEnabled &&
this.plugin.settings.hoverPreviewWithoutCTRL)) {
showHoverPreview();
}
},
@@ -2305,11 +2352,11 @@ export default class ExcalidrawView extends TextFileView {
files: TFile[],
text: string,
): boolean => {
if (this.plugin.ea.onDropHook) {
if (this.hookServer.onDropHook) {
try {
return this.plugin.ea.onDropHook({
return this.hookServer.onDropHook({
//@ts-ignore
ea: this.plugin.ea, //the Excalidraw Automate object
ea: this.hookServer, //the ExcalidrawAutomate object
event, //React.DragEvent<HTMLDivElement>
draggable, //Obsidian draggable object
type, //"file"|"text"
@@ -2331,6 +2378,8 @@ export default class ExcalidrawView extends TextFileView {
}
};
//https://github.com/zsviczian/obsidian-excalidraw-plugin/issues/468
event[CTRL_OR_CMD] = event.shiftKey || event[CTRL_OR_CMD];
switch (draggable?.type) {
case "file":
if (!onDropHook("file", [draggable.file], null)) {
@@ -2339,10 +2388,8 @@ export default class ExcalidrawView extends TextFileView {
new Notice(t("FILENAME_INVALID_CHARS"), 4000);
return false;
}
//https://github.com/zsviczian/obsidian-excalidraw-plugin/issues/468
event[CTRL_OR_CMD] = event.shiftKey || event[CTRL_OR_CMD];
if (
event[CTRL_OR_CMD] && //.ctrlKey||event.metaKey)
event[CTRL_OR_CMD] &&
(IMAGE_TYPES.contains(draggable.file.extension) ||
draggable.file.extension === "md")
) {
@@ -2371,16 +2418,38 @@ export default class ExcalidrawView extends TextFileView {
return false;
case "files":
if (!onDropHook("file", draggable.files, null)) {
for (const f of draggable.files) {
this.addText(
`[[${this.app.metadataCache.fileToLinktext(
f,
this.file.path,
true,
)}]]`,
);
currentPosition.y += st.currentItemFontSize * 2;
}
(async () => {
if (event[CTRL_OR_CMD]) {
const ea = this.plugin.ea;
ea.reset();
ea.setView(this);
ea.canvas.theme = api.getAppState().theme;
let counter:number = 0;
for (const f of draggable.files) {
if ((IMAGE_TYPES.contains(f.extension) || f.extension === "md")) {
await ea.addImage(
currentPosition.x + counter*50,
currentPosition.y + counter*50,
f,
);
counter++;
await ea.addElementsToView(false, false, true);
}
}
return;
}
for (const f of draggable.files) {
await this.addText(
`[[${this.app.metadataCache.fileToLinktext(
f,
this.file.path,
true,
)}]]`, undefined,false
);
currentPosition.y += st.currentItemFontSize * 2;
}
this.save(false);
})();
}
return false;
}
@@ -2418,6 +2487,22 @@ export default class ExcalidrawView extends TextFileView {
})();
return false;
}
//https://github.com/zsviczian/obsidian-excalidraw-plugin/issues/599
if(text.startsWith("obsidian://open?vault=")) {
const html = event.dataTransfer.getData("text/html");
if(html) {
const path = html.match(/href="app:\/\/obsidian\.md\/(.*?)"/);
if(path.length === 2) {
this.addText(`[[${decodeURIComponent(path[1])}]]`);
return false;
}
}
const path = text.split("file=");
if(path.length === 2) {
this.addText(`[[${decodeURIComponent(path[1])}]]`);
return false;
}
}
this.addText(text.replace(/(!\[\[.*#[^\]]*\]\])/g, "$1{40}"));
}
return false;
@@ -2527,6 +2612,15 @@ export default class ExcalidrawView extends TextFileView {
return;
}
const event = e?.detail?.nativeEvent;
if(this.hookServer?.onLinkClickHook) {
try {
if(!this.hookServer.onLinkClickHook(element,element.link,event)) {
return;
}
} catch (e) {
errorlog({where: "ExcalidrawView.onLinkOpen", fn: this.hookServer.onLinkClickHook, error: e});
}
}
if (link.startsWith(LOCAL_PROTOCOL) || link.startsWith("[[")) {
(async () => {
const linkMatch = link.match(/(md:\/\/)?\[\[(?<link>.*?)\]\]/);
@@ -2617,10 +2711,7 @@ export default class ExcalidrawView extends TextFileView {
return;
}
let linkText = linkMatch.groups.link;
if (linkText.search("#") > -1) {
linkText = linkText.substring(0, linkText.search("#"));
}
showHoverPreview(linkText);
showHoverPreview(linkText, element);
}
}
},
@@ -2628,6 +2719,14 @@ export default class ExcalidrawView extends TextFileView {
this.toolsPanelRef?.current?.setExcalidrawViewMode(
isViewModeEnabled,
);
if(this.hookServer?.onViewModeChangeHook) {
try {
this.hookServer.onViewModeChangeHook(isViewModeEnabled);
} catch(e) {
errorlog({where: "ExcalidrawView.onViewModeChange", fn: this.hookServer.onViewModeChangeHook, error: e});
}
}
},
}),
React.createElement(ToolsPanel, {

View File

@@ -129,6 +129,7 @@ const getIMG = async (
null,
[],
plugin,
0
));
if (!png) {
return null;
@@ -152,6 +153,7 @@ const getIMG = async (
null,
[],
plugin,
0,
getSVGPadding(plugin, file),
)
).outerHTML;

View File

@@ -30,6 +30,7 @@ export const FRONTMATTER_KEY_EXPORT_PNGSCALE = "excalidraw-export-pngscale";
export const FRONTMATTER_KEY_CUSTOM_PREFIX = "excalidraw-link-prefix";
export const FRONTMATTER_KEY_CUSTOM_URL_PREFIX = "excalidraw-url-prefix";
export const FRONTMATTER_KEY_CUSTOM_LINK_BRACKETS = "excalidraw-link-brackets";
export const FRONTMATTER_KEY_LINKBUTTON_OPACITY = "excalidraw-linkbutton-opacity";
export const FRONTMATTER_KEY_DEFAULT_MODE = "excalidraw-default-mode";
export const FRONTMATTER_KEY_FONT = "excalidraw-font";
export const FRONTMATTER_KEY_FONTCOLOR = "excalidraw-font-color";

View File

@@ -17,6 +17,24 @@ I develop this plugin as a hobby, spending most of my free time doing this. If y
<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>
`,
"1.6.26": `
## Fixed
- Dragging multiple files onto the canvas will now correctly [#589](https://github.com/zsviczian/obsidian-excalidraw-plugin/issues/589)
- add multiple links
- or if you hold the CTRL/(SHIFT on Mac) while dropping the files, then adding multiple images
- Dropped images and links were not selectable with the selection tool until the file was saved. This is now fixed.
- Display the linked block/section on link-hover instead of the full page. [#597](https://github.com/zsviczian/obsidian-excalidraw-plugin/issues/597)
- Hover preview without CTRL/CMD works again. Requires configuration in plugin settings. [#595](https://github.com/zsviczian/obsidian-excalidraw-plugin/issues/595)
- If you embed the same markdown document into a drawing multiple times, you can now display different sections of the documents in each embedded object. [#601](https://github.com/zsviczian/obsidian-excalidraw-plugin/issues/601).
- If you make a copy of an equation and edit this copy, the original equation will remain unchanged [#593](https://github.com/zsviczian/obsidian-excalidraw-plugin/issues/593)
## New Features
- When you drag files from dataview results onto the canvas the obsidian urls will be converted into wiki links.[#599](https://github.com/zsviczian/obsidian-excalidraw-plugin/issues/599)
- I added one more frontmatter key: ${String.fromCharCode(96)}excalidraw-linkbutton-opacity: 0.5${String.fromCharCode(96)}. This sets the opacity of the blue link-button in the top right corner of the element, overriding the respective setting in plugin settings. Valid values are numbers between 0 and 1, where 0 means the button is fully transparent.
## New Excalidraw Automate Features
- As part of building the new ExcaliBrain plugin, I've added a number of integration features. See the GitHub [Release Notes](https://github.com/zsviczian/obsidian-excalidraw-plugin/releases/tag/1.6.26) for details.
`,
"1.6.25": `
## Fixed
- Pinch-zoom in view mode was broken ([#5001](https://github.com/excalidraw/excalidraw/pull/5001))

View File

@@ -525,6 +525,13 @@ export const FRONTMATTER_KEYS_INFO: SuggesterInfo[] = [
desc: "Specifies how Excalidraw should open by default. Valid values are: view|zen",
after: ": view",
},
{
field: "linkbutton-opacity",
code: null,
desc: "The opacity of the blue link button in the top right of the element overriding the respective setting in plugin settings. "+
"Valid values are between 0 and 1, where 0 means the button is transparent.",
after: ": 0.5",
},
{
field: "font",
code: null,

View File

@@ -210,7 +210,9 @@ export default {
}${FRONTMATTER_KEY_CUSTOM_URL_PREFIX}: "🌐 "</code> to the file's frontmatter.`,
HOVERPREVIEW_NAME: "Hover preview without CTRL/CMD key",
HOVERPREVIEW_DESC:
"Toggle On: Hover preview for [[wiki links]] is shown immediately, without the need to hold the CTRL/CMD key.<br>Toggle Off: Hover preview is shown only when you hold the CTRL/CMD key while hovering the link.",
"<b>Toggle On</b>: In Exalidraw <u>view mode</u> the hover preview for [[wiki links]] will be shown immediately, without the need to hold the CTRL/CMD key. " +
"In Excalidraw <u>normal mode</u>, the preview will be shown immediately only when hovering the blue link icon in the top right of the element.<br> " +
"<b>Toggle Off</b>: Hover preview is shown only when you hold the CTRL/CMD key while hovering the link.",
LINKOPACITY_NAME: "Opacity of link icon",
LINKOPACITY_DESC:
"Opacity of the link indicator icon in the top right corner of an element. 1 is opaque, 0 is transparent.",

View File

@@ -539,7 +539,7 @@ export class ExcalidrawSettingTab extends PluginSettingTab {
el.style.textAlign = "right";
el.innerText = ` ${this.plugin.settings.zoomToFitMaxLevel.toString()}`;
});
this.containerEl.createEl("h1", { text: t("LINKS_HEAD") });
this.containerEl.createEl(
"span",

View File

@@ -542,9 +542,7 @@ export const errorlog = (data: {}) => {
console.error({ plugin: "Excalidraw", ...data });
};
export const sleep = async (ms: number) => {
return new Promise((resolve) => setTimeout(resolve, ms));
};
export const sleep = async (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
export const log = console.log.bind(window.console);
export const debug = console.log.bind(window.console);

View File

@@ -2215,10 +2215,10 @@
dependencies:
"@zerollup/ts-helpers" "^1.7.18"
"@zsviczian/excalidraw@0.11.0-obsidian-11":
"integrity" "sha512-XlT8F7tQfKDXFUQWddGH+w7GTn5doWq3R0mTemuVqL0q5RhwiiNxHc1SNWmKMj/DVF0M3H5bjX/72gvWlRUDLQ=="
"resolved" "https://registry.npmjs.org/@zsviczian/excalidraw/-/excalidraw-0.11.0-obsidian-11.tgz"
"version" "0.11.0-obsidian-11"
"@zsviczian/excalidraw@0.11.0-obsidian-16":
"integrity" "sha512-KVCWC7T31tXo6xfXY6AnGsDEl1j7BVwh3eSwoyn4MTS5UbhD5X0rwB8F6Yl1bdxKbrmnqQV98IKLsdgtfuHoVQ=="
"resolved" "https://registry.npmjs.org/@zsviczian/excalidraw/-/excalidraw-0.11.0-obsidian-16.tgz"
"version" "0.11.0-obsidian-16"
dependencies:
"dotenv" "10.0.0"