From d77249088fa61485bfb04adb0b3b5cf950b74577 Mon Sep 17 00:00:00 2001 From: Zsolt Viczian Date: Sat, 10 Jul 2021 23:32:25 +0200 Subject: [PATCH] 1.2.2 text lock/unlock solved --- manifest.json | 2 +- src/ExcalidrawView.ts | 90 +++++++++++++++++++++++++++++++++++++------ src/lang/locale/en.ts | 2 +- src/main.ts | 2 +- 4 files changed, 82 insertions(+), 14 deletions(-) diff --git a/manifest.json b/manifest.json index 1ef64332..47014642 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "id": "obsidian-excalidraw-plugin", "name": "Excalidraw", - "version": "1.2.1", + "version": "1.2.2", "minAppVersion": "0.11.13", "description": "An Obsidian plugin to edit and view Excalidraw drawings", "author": "Zsolt Viczian", diff --git a/src/ExcalidrawView.ts b/src/ExcalidrawView.ts index 61759fc2..27043c3f 100644 --- a/src/ExcalidrawView.ts +++ b/src/ExcalidrawView.ts @@ -6,6 +6,8 @@ import { WorkspaceItem, Notice, Menu, + parseLinktext, + MarkdownSourceView, } from "obsidian"; import * as React from "react"; import * as ReactDOM from "react-dom"; @@ -581,9 +583,64 @@ export default class ExcalidrawView extends TextFileView { if(!excalidrawRef?.current) return; excalidrawRef.current.refresh(); }; - + + /* + const dropAction = (transfer: DataTransfer) => { + // Return a 'copy' or 'link' action according to the content types, or undefined if no recognized type + if (transfer.types.includes('text/uri-list')) return 'link'; + if (['file', 'files', 'link'].includes((this.app as any).dragManager.draggable?.type)) return 'link'; + if (transfer.types.includes('text/html') || transfer.types.includes('text/plain')) return 'copy'; + } + + const linkTo = (f: TFile, subpath?: string) => { + this.addText(this.app.metadataCache.fileToLinktext(f,subpath ? subpath : this.file.path,true)); + }; + + const fixBulletsAndLInks = (text: string) => { + // Internal links from e.g. dataview plugin incorrectly begin with `app://obsidian.md/`, and + // we also want to remove bullet points and task markers from text and markdown + return text.replace(/^\s*[-+*]\s+(\[.]\s+)?/, "").trim().replace(/^\[(.*)\]\(app:\/\/obsidian.md\/(.*)\)$/, "[$1]($2)"); + } + + const getMarkdown = (transfer: DataTransfer ) => { + // crude hack to use Obsidian's html-to-markdown converter (replace when Obsidian exposes it in API): + console.log(transfer); + + } + + let importLines = (transfer: DataTransfer, forcePlaintext: boolean = false) => { + const draggable = (this.app as any).dragManager.draggable; + const html = transfer.getData("text/html"); + const plain = transfer.getData("text/plain"); + const uris = transfer.getData("text/uri-list"); + + switch(draggable?.type) { + case "file": + linkTo(draggable.file); + break; + case "files": + for(const f of draggable.files) { + linkTo(f); + } + break; + case "link": + if(draggable.file) { + linkTo(draggable.file, parseLinktext(draggable.linktext).subpath); + break; + } + console.log(`[[${draggable.linktext}]]`); + break; + default: + const text = forcePlaintext ? (plain||html) : getMarkdown(transfer); + // Split lines and strip leading bullets/task indicators + const lines: string[] = (text || html || uris || plain || "").split(/\r\n?|\n/).map(fixBulletsAndLInks); + console.log( lines.filter(line => line)); + break; + } + }*/ + let timestamp = (new Date()).getTime(); - + return React.createElement( React.Fragment, null, @@ -597,12 +654,9 @@ export default class ExcalidrawView extends TextFileView { if(this.isTextLocked && (e.target instanceof HTMLCanvasElement) && this.getSelectedText(true)) { //text element is selected const now = (new Date()).getTime(); if(now-timestamp < 600) { //double click - let event = new MouseEvent('dblclick', { - 'view': window, - 'bubbles': true, - 'cancelable': true, - }); - e.target.dispatchEvent(event); + e.preventDefault(); + e.stopPropagation(); + this.lock(false); new Notice(t("UNLOCK_TO_EDIT")); timestamp = now; return; @@ -619,15 +673,29 @@ export default class ExcalidrawView extends TextFileView { if(ev.keyCode!=13) return; //not an enter if(!(ev.target instanceof HTMLDivElement)) return; if(!this.getSelectedId()) return; - const event = new MouseEvent('dblclick', { +/* const event = new MouseEvent('dblclick', { 'view': window, 'bubbles': true, 'cancelable': true, }); - ev.target.querySelector("canvas").dispatchEvent(event); + ev.target.querySelector("canvas").dispatchEvent(event);*/ + this.lock(false); new Notice(t("UNLOCK_TO_EDIT")); }, - +/* onDragOver: (e:any) => { + const action = dropAction(e.dataTransfer); + if (action) { + e.dataTransfer.dropEffect = action; + e.preventDefault(); + return false; + } + }, + onDragLeave: () => { }, + onDrop: (e:any) => { + importLines(e.dataTransfer); + e.preventDefault(); + // shift key to force plain text, the same way Obsidian does it + },*/ }, React.createElement(Excalidraw.default, { ref: excalidrawRef, diff --git a/src/lang/locale/en.ts b/src/lang/locale/en.ts index bede15f4..e4dc981c 100644 --- a/src/lang/locale/en.ts +++ b/src/lang/locale/en.ts @@ -31,7 +31,7 @@ export default { SAVE_AS_SVG: "Save as SVG into Vault (CTRL/META+CLICK to export)", OPEN_LINK: "Open selected text as link\n(SHIFT+CLICK to open in a new pane)", EXPORT_EXCALIDRAW: "Export to an .Excalidraw file", - UNLOCK_TO_EDIT: "UNLOCK Text Elements to edit", + UNLOCK_TO_EDIT: "Automatically UNLOCKED Text Elements to allow edit", LINK_BUTTON_CLICK_NO_TEXT: 'Select a Text Element containing an internal or external link.\n'+ 'SHIFT CLICK this button to open the link in a new pane.\n'+ 'CTRL/META CLICK the Text Element on the canvas has the same effect!', diff --git a/src/main.ts b/src/main.ts index 5d4e0114..e0e07bc6 100644 --- a/src/main.ts +++ b/src/main.ts @@ -156,7 +156,7 @@ export default class ExcalidrawPlugin extends Plugin { if(parts.fheight) img.setAttribute("height",parts.fheight); img.addClass(parts.style); - img.setAttribute("src","data:image/svg+xml;base64,"+btoa(unescape(encodeURIComponent(svg.outerHTML)))); + img.setAttribute("src","data:image/svg+xml;base64,"+btoa(unescape(encodeURIComponent(svg.outerHTML.replaceAll(" "," "))))); return img; }