mirror of
https://github.com/zsviczian/obsidian-excalidraw-plugin.git
synced 2025-08-06 05:46:28 +00:00
1.4.9
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"id": "obsidian-excalidraw-plugin",
|
||||
"name": "Excalidraw",
|
||||
"version": "1.4.7",
|
||||
"version": "1.4.9",
|
||||
"minAppVersion": "0.12.16",
|
||||
"description": "An Obsidian plugin to edit and view Excalidraw drawings",
|
||||
"author": "Zsolt Viczian",
|
||||
|
||||
@@ -257,7 +257,7 @@ export class ExcalidrawData {
|
||||
//first get scene text elements
|
||||
const texts = this.scene.elements?.filter((el:any)=> el.type=="text")
|
||||
for (const te of texts) {
|
||||
this.updateTextElement(te,await this.getText(te.id),forceupdate);
|
||||
this.updateTextElement(te,(await this.getText(te.id))??te.text,forceupdate); //(await this.getText(te.id))??te.text serves the case when the whole #Text Elements section is deleted by accident
|
||||
}
|
||||
}
|
||||
|
||||
@@ -271,7 +271,7 @@ export class ExcalidrawData {
|
||||
return this.textElements.get(id).parsed;
|
||||
}
|
||||
//console.log("raw",this.textElements.get(id).raw);
|
||||
return this.textElements.get(id).raw;
|
||||
return this.textElements.get(id)?.raw;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -439,8 +439,8 @@ export default class ExcalidrawView extends TextFileView {
|
||||
new Notice(t("COMPATIBILITY_MODE"),4000);
|
||||
}
|
||||
} else {
|
||||
const parsed = data.search("excalidraw-plugin: parsed\n")>-1 || data.search("excalidraw-plugin: locked\n")>-1; //locked for backward compatibility
|
||||
this.changeTextMode(parsed ? TextMode.parsed : TextMode.raw,false);
|
||||
const textMode = getTextMode(data);
|
||||
this.changeTextMode(textMode,false);
|
||||
try {
|
||||
if(!(await this.excalidrawData.loadData(data, this.file,this.textMode))) return;
|
||||
} catch(e) {
|
||||
@@ -1276,3 +1276,8 @@ export default class ExcalidrawView extends TextFileView {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function getTextMode(data:string):TextMode {
|
||||
const parsed = data.search("excalidraw-plugin: parsed\n")>-1 || data.search("excalidraw-plugin: locked\n")>-1; //locked for backward compatibility
|
||||
return parsed ? TextMode.parsed : TextMode.raw;
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
import { App, Modal, Notice, TFile } from "obsidian";
|
||||
import { getJSON } from "./ExcalidrawData";
|
||||
import { FRONTMATTER_KEY } from "./constants";
|
||||
import { ExcalidrawData, getJSON } from "./ExcalidrawData";
|
||||
import { getTextMode, TextMode } from "./ExcalidrawView";
|
||||
import ExcalidrawPlugin from "./main";
|
||||
|
||||
export class OneOffs {
|
||||
@@ -72,6 +74,69 @@ export class OneOffs {
|
||||
prompt.open();
|
||||
});
|
||||
}
|
||||
|
||||
public wysiwygPatch() {
|
||||
|
||||
if(this.plugin.settings.patchCommentBlock) return; //the comment block patch needs to happen first (unlikely that someone has waited this long with the update...)
|
||||
//This is a once off process to patch excalidraw files remediate incorrectly placed comment %% before # Text Elements
|
||||
if(!this.plugin.settings.runWYSIWYGpatch) return;
|
||||
const plugin = this.plugin;
|
||||
|
||||
console.log(window.moment().format("HH:mm:ss") + ": Excalidraw will patch drawings to support WYSIWYG in 5 minutes");
|
||||
setTimeout(async ()=>{
|
||||
await plugin.loadSettings();
|
||||
if (!plugin.settings.runWYSIWYGpatch) {
|
||||
console.log(window.moment().format("HH:mm:ss") + ": Excalidraw patching aborted because synched data.json is already patched");
|
||||
return;
|
||||
}
|
||||
console.log(window.moment().format("HH:mm:ss") + ": Excalidraw is starting the patching process");
|
||||
let i = 0;
|
||||
const excalidrawFiles = plugin.app.vault.getFiles();
|
||||
for (const f of (excalidrawFiles || []).filter((f:TFile) => plugin.isExcalidrawFile(f))) {
|
||||
if ( (f.extension !== "excalidraw") //legacy files do not need to be touched
|
||||
&& (plugin.app.workspace.getActiveFile() !== f)) { //file is currently being edited
|
||||
try{
|
||||
const excalidrawData = new ExcalidrawData(plugin);
|
||||
const data = await plugin.app.vault.read(f);
|
||||
const textMode = getTextMode(data);
|
||||
await excalidrawData.loadData(data,f,textMode);
|
||||
|
||||
let trimLocation = data.search(/(^%%\n)?# Text Elements\n/m);
|
||||
if(trimLocation == -1) trimLocation = data.search(/(%%\n)?# Drawing\n/);
|
||||
if(trimLocation > -1) {
|
||||
|
||||
let header = data.substring(0,trimLocation)
|
||||
.replace(/excalidraw-plugin:\s.*\n/,FRONTMATTER_KEY+": " + ( (textMode == TextMode.raw) ? "raw\n" : "parsed\n"));
|
||||
|
||||
if (header.search(/cssclass:[\s]*excalidraw-hide-preview-text/) === -1) {
|
||||
header = header.replace(/(excalidraw-plugin:\s.*\n)/,"$1cssclass: excalidraw-hide-preview-text\n");
|
||||
}
|
||||
|
||||
const REG_IMG = /(^---[\w\W]*?---\n)(!\[\[.*?]]\n(%%\n)?)/m; //(%%\n)? because of 1.4.8-beta... to be backward compatible with anyone who installed that version
|
||||
if(header.match(REG_IMG)) {
|
||||
header = header.replace(REG_IMG,"$1![["+f.path+"]]\n");
|
||||
} else {
|
||||
header = header.replace(/(^---[\w\W]*?---\n)/m, "$1![["+f.path+"]]\n");
|
||||
}
|
||||
const newData = header + excalidrawData.generateMD();
|
||||
|
||||
if (data !== newData) {
|
||||
i++;
|
||||
console.log("Excalidraw patched: " + f.path);
|
||||
await plugin.app.vault.modify(f,newData);
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.log("Unable to process: "+f.path,{error:e});
|
||||
}
|
||||
}
|
||||
}
|
||||
plugin.settings.runWYSIWYGpatch = false;
|
||||
plugin.saveSettings();
|
||||
console.log(window.moment().format("HH:mm:ss") + ": Excalidraw patched in total " + i + " files");
|
||||
},420000) //7 minutes
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class MigrationPrompt extends Modal {
|
||||
|
||||
54
src/main.ts
54
src/main.ts
@@ -36,7 +36,7 @@ import {
|
||||
DARK_BLANK_DRAWING
|
||||
} from "./constants";
|
||||
import ExcalidrawView, {ExportSettings, TextMode} from "./ExcalidrawView";
|
||||
import {getJSON, getMarkdownDrawingSection} from "./ExcalidrawData";
|
||||
import {ExcalidrawData, getJSON, getMarkdownDrawingSection} from "./ExcalidrawData";
|
||||
import {
|
||||
ExcalidrawSettings,
|
||||
DEFAULT_SETTINGS,
|
||||
@@ -138,6 +138,7 @@ export default class ExcalidrawPlugin extends Plugin {
|
||||
const patches = new OneOffs(this);
|
||||
patches.migrationNotice();
|
||||
patches.patchCommentBlock();
|
||||
patches.wysiwygPatch();
|
||||
patches.imageElementLaunchNotice();
|
||||
|
||||
this.switchToExcalidarwAfterLoad()
|
||||
@@ -343,8 +344,10 @@ export default class ExcalidrawPlugin extends Plugin {
|
||||
if(m.length == 0) return;
|
||||
if(!this.hover.linkText) return;
|
||||
const file = this.app.metadataCache.getFirstLinkpathDest(this.hover.linkText, this.hover.sourcePath?this.hover.sourcePath:"");
|
||||
if(!file || !(file instanceof TFile) || !this.isExcalidrawFile(file)) return;
|
||||
|
||||
if(!file) return;
|
||||
if(!(file instanceof TFile)) return;
|
||||
if(file.extension!=="excalidraw") return;
|
||||
|
||||
const svgFileName = getIMGFilename(file.path,"svg");
|
||||
const svgFile = this.app.vault.getAbstractFileByPath(svgFileName);
|
||||
if(svgFile && svgFile instanceof TFile) return; //If auto export SVG or PNG is enabled it will be inserted at the top of the excalidraw file. No need to manually insert hover preview
|
||||
@@ -353,45 +356,6 @@ export default class ExcalidrawPlugin extends Plugin {
|
||||
const pngFile = this.app.vault.getAbstractFileByPath(pngFileName);
|
||||
if(pngFile && pngFile instanceof TFile) return; //If auto export SVG or PNG is enabled it will be inserted at the top of the excalidraw file. No need to manually insert hover preview
|
||||
|
||||
if(file.extension === "excalidraw") {
|
||||
observerForLegacyFileFormat(m,file);
|
||||
return;
|
||||
}
|
||||
|
||||
let i=0;
|
||||
//@ts-ignore
|
||||
while(i<m.length && m[i].target?.className!="markdown-preview-sizer markdown-preview-section") i++;
|
||||
if(i==m.length) return;
|
||||
if(m[i].addedNodes.length==0) return;
|
||||
//@ts-ignore
|
||||
if(m[i].addedNodes[0].childElementCount!=2) return;
|
||||
//@ts-ignore
|
||||
if(m[i].addedNodes[0].firstElementChild.className.indexOf("frontmatter")==-1) return;
|
||||
//@ts-ignore
|
||||
if(m[i].addedNodes[0].firstElementChild?.firstElementChild?.className=="excalidraw-svg") return;
|
||||
|
||||
//@ts-ignore
|
||||
const hoverPopover = m[i].addedNodes[0].matchParent(".hover-popover");
|
||||
if(!hoverPopover) return;
|
||||
const node = m[i].addedNodes[0];
|
||||
|
||||
//this div will be on top of original DIV. By stopping the propagation of the click
|
||||
//I prevent the default Obsidian feature of openning the link in the native app
|
||||
const div = createDiv("", async (el)=>{
|
||||
const img = await getIMG({file:file,fname:file.path,fwidth:"300",fheight:null,style:"excalidraw-svg"});
|
||||
el.appendChild(img);
|
||||
el.setAttribute("src",file.path);
|
||||
el.onClickEvent((ev)=>{
|
||||
ev.stopImmediatePropagation();
|
||||
let src = el.getAttribute("src");
|
||||
if(src) this.openDrawing(this.app.vault.getAbstractFileByPath(src) as TFile,ev.ctrlKey||ev.metaKey);
|
||||
});
|
||||
});
|
||||
node.insertBefore(div,node.firstChild)
|
||||
});
|
||||
|
||||
//compatibility: .excalidraw file observer
|
||||
let observerForLegacyFileFormat = async (m:MutationRecord[], file:TFile) => {
|
||||
if(!this.hover.linkText) return;
|
||||
if(m.length!=1) return;
|
||||
if(m[0].addedNodes.length != 1) return;
|
||||
@@ -413,11 +377,9 @@ export default class ExcalidrawPlugin extends Plugin {
|
||||
});
|
||||
});
|
||||
node.appendChild(div);
|
||||
}
|
||||
this.observer.observe(document, {childList: true, subtree: true});
|
||||
|
||||
|
||||
});
|
||||
|
||||
this.observer.observe(document, {childList: true, subtree: true});
|
||||
}
|
||||
|
||||
public experimentalFileTypeDisplayToggle(enabled: boolean) {
|
||||
|
||||
@@ -45,6 +45,7 @@ export interface ExcalidrawSettings {
|
||||
library: string,
|
||||
patchCommentBlock: boolean, //1.3.12
|
||||
imageElementNotice: boolean, //1.4.0
|
||||
runWYSIWYGpatch: boolean, //1.4.9
|
||||
}
|
||||
|
||||
export const DEFAULT_SETTINGS: ExcalidrawSettings = {
|
||||
@@ -83,6 +84,7 @@ export const DEFAULT_SETTINGS: ExcalidrawSettings = {
|
||||
library: `{"type":"excalidrawlib","version":1,"library":[]}`,
|
||||
patchCommentBlock: true,
|
||||
imageElementNotice: true,
|
||||
runWYSIWYGpatch: true,
|
||||
}
|
||||
|
||||
export class ExcalidrawSettingTab extends PluginSettingTab {
|
||||
|
||||
14
styles.css
14
styles.css
@@ -103,6 +103,12 @@ li[data-testid] {
|
||||
|
||||
.markdown-preview-view mark,
|
||||
.markdown-preview-view.excalidraw-hide-preview-text span:not(.image-embed),
|
||||
.markdown-preview-view.excalidraw-hide-preview-text ol,
|
||||
.markdown-preview-view.excalidraw-hide-preview-text li,
|
||||
.markdown-preview-view.excalidraw-hide-preview-text table,
|
||||
.markdown-preview-view.excalidraw-hide-preview-text pre,
|
||||
.markdown-preview-view.excalidraw-hide-preview-text hr,
|
||||
.markdown-preview-view.excalidraw-hide-preview-text a,
|
||||
.markdown-preview-view.excalidraw-hide-preview-text h1,
|
||||
.markdown-preview-view.excalidraw-hide-preview-text h2,
|
||||
.markdown-preview-view.excalidraw-hide-preview-text h3,
|
||||
@@ -111,3 +117,11 @@ li[data-testid] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.markdown-preview-view.excalidraw-hide-preview-text p:first-child {
|
||||
margin-top:0px !important;
|
||||
}
|
||||
|
||||
.markdown-preview-view.excalidraw-hide-preview-text div.markdown-preview-sizer.markdown-preview-section {
|
||||
padding-bottom:0px !important;
|
||||
min-height: 0px !important;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{
|
||||
"1.4.7": "0.12.16",
|
||||
"1.4.9": "0.12.16",
|
||||
"1.4.2": "0.11.13"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user