diff --git a/public/webapp/button.js b/public/webapp/button.js index 7e6a160..5aa902d 100644 --- a/public/webapp/button.js +++ b/public/webapp/button.js @@ -1,15 +1,15 @@ -function copyEditLink(fileID) { - navigator.clipboard.writeText(getEditLink(fileID)); +function copyEditLink(path) { + navigator.clipboard.writeText(getEditLink(path)); } -function copyImageLink(fileID) { - navigator.clipboard.writeText(`![Drawing](assets/${fileID}.svg)`); +function copyImageLink(path) { + navigator.clipboard.writeText(`![Drawing](${path.replace("/data/", "")})`); } function refreshPage() { window.location.reload(); } -function addButton(document, fileID) { +function addButton(document, path) { // Add floating button const floatingButton = document.createElement('button'); @@ -22,8 +22,8 @@ function addButton(document, fileID) { popupMenu.id = 'popupMenu'; popupMenu.innerHTML = ` - - + + `; document.body.appendChild(popupMenu); diff --git a/public/webapp/draw.js b/public/webapp/draw.js index 9d9adfc..baaf005 100644 --- a/public/webapp/draw.js +++ b/public/webapp/draw.js @@ -27,9 +27,9 @@ async function getFile(path) { } -async function getSVG(fileID) { +async function getSVG(path) { - const resp = await getFile("/data/assets/" + fileID + '.svg'); + const resp = await getFile(path); if(resp == null) { return FALLBACK; } @@ -37,10 +37,10 @@ async function getSVG(fileID) { } -function getEditLink(fileID) { +function getEditLink(path) { const data = encodeURIComponent( JSON.stringify({ - id: fileID + path: path, }) ) return `siyuan://plugins/siyuan-jsdraw-pluginwhiteboard/?icon=iconDraw&title=Drawing&data=${data}`; diff --git a/public/webapp/index.html b/public/webapp/index.html index a1fd2f6..c40fb79 100644 --- a/public/webapp/index.html +++ b/public/webapp/index.html @@ -5,18 +5,22 @@ diff --git a/src/const.ts b/src/const.ts index 1acaa80..9e5c04e 100644 --- a/src/const.ts +++ b/src/const.ts @@ -1,7 +1,7 @@ export const SVG_MIME = "image/svg+xml"; export const JSON_MIME = "application/json"; -export const DATA_PATH = "/data/assets"; +export const DATA_PATH = "/data/assets/"; export const STORAGE_PATH = "/data/storage/petal/siyuan-jsdraw-plugin"; export const TOOLBAR_PATH = STORAGE_PATH + "/toolbar.json"; export const CONFIG_PATH = STORAGE_PATH + "/conf.json"; -export const EMBED_PATH = "/plugins/siyuan-jsdraw-plugin/webapp/?id="; \ No newline at end of file +export const EMBED_PATH = "/plugins/siyuan-jsdraw-plugin/webapp/?path="; \ No newline at end of file diff --git a/src/editorTab.ts b/src/editorTab.ts index bef75c7..0399dad 100644 --- a/src/editorTab.ts +++ b/src/editorTab.ts @@ -6,22 +6,22 @@ import {getFile, saveFile} from "@/file"; import {JSON_MIME, SVG_MIME, TOOLBAR_PATH} from "@/const"; import {idToPath} from "@/helper"; -export function openEditorTab(p: Plugin, fileID: string) { +export function openEditorTab(p: Plugin, path: string) { openTab({ app: p.app, custom: { title: 'Drawing', icon: 'iconDraw', id: "siyuan-jsdraw-pluginwhiteboard", - data: { id: fileID } + data: { path: path } } }); } -async function saveCallback(editor: Editor, fileID: string, saveButton: BaseWidget) { +async function saveCallback(editor: Editor, path: string, saveButton: BaseWidget) { const svgElem = editor.toSVG(); try { - saveFile(idToPath(fileID), SVG_MIME, svgElem.outerHTML); + saveFile(path, SVG_MIME, svgElem.outerHTML); saveButton.setDisabled(true); setTimeout(() => { // @todo improve save button feedback saveButton.setDisabled(false); @@ -36,10 +36,14 @@ async function saveCallback(editor: Editor, fileID: string, saveButton: BaseWidg export function createEditor(i: ITabModel) { - const fileID = i.data.id; - if(fileID == null) { - alert("File ID missing - couldn't open file.") - return; + let path = i.data.path; + if(path == null) { + const fileID = i.data.id; // legacy compatibility + if (fileID == null) { + alert("File ID and path missing - couldn't open file.") + return; + } + path = idToPath(fileID); } const editor = new Editor(i.element, { @@ -55,14 +59,14 @@ export function createEditor(i: ITabModel) { } }); // restore drawing - getFile(idToPath(fileID)).then(svg => { + getFile(path).then(svg => { if(svg != null) { editor.loadFromSVG(svg); } }); // save logic - const saveButton = toolbar.addSaveButton(() => saveCallback(editor, fileID, saveButton)); + const saveButton = toolbar.addSaveButton(() => saveCallback(editor, path, saveButton)); // save toolbar config on tool change (toolbar state is not saved in SVGs!) editor.notifier.on(EditorEventType.ToolUpdated, () => { diff --git a/src/helper.ts b/src/helper.ts index 0492b07..7e132ac 100644 --- a/src/helper.ts +++ b/src/helper.ts @@ -45,14 +45,14 @@ export function generateSiyuanId() { } export function idToPath(id: string) { - return DATA_PATH + '/' + id + '.svg'; + return DATA_PATH + id + '.svg'; } // [Edit](siyuan://plugins/siyuan-jsdraw-pluginwhiteboard/?icon=iconDraw&title=Drawing&data={"id":"${id}"}) // ![Drawing](assets/${id}.svg) -export function getPreviewHTML(id: string): string { +export function getPreviewHTML(path: string): string { return ` - + ` } @@ -60,12 +60,7 @@ export function getPreviewHTML(id: string): string { export function findImgSrc(element: HTMLElement): string | null { // Base case: if current element is an image if (element.tagName === 'IMG') { - const fullSrc = (element as HTMLImageElement).src; - // Extract the path after host:port using URL API - const url = new URL(fullSrc); - return url.pathname.startsWith('/assets/') - ? url.pathname.substring(1) // Remove leading slash - : null; + return (element as HTMLImageElement).src; } // Recursively check children @@ -79,12 +74,15 @@ export function findImgSrc(element: HTMLElement): string | null { return null; } -export function extractFileID(imgSrc: string | null): string | null { +export function imgSrcToAbsolutePath(imgSrc: string | null): string | null { if (!imgSrc) return null; - const [pathPart] = imgSrc.split('?'); - // Match pattern: assets/{fileID}.svg - const match = pathPart.match(/^assets\/([^\/]+)\.svg$/i); + const url = new URL(imgSrc); + imgSrc = decodeURIComponent(url.pathname); + + if(imgSrc.startsWith('/assets/')) { + return "/data" + imgSrc; + } + return null - return match?.[1] || null; } diff --git a/src/index.ts b/src/index.ts index 1ea3b47..851d6e5 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,14 @@ import {Plugin, Protyle} from 'siyuan'; -import {getPreviewHTML, loadIcons, getMenuHTML, generateSiyuanId, findImgSrc, extractFileID} from "@/helper"; +import { + getPreviewHTML, + loadIcons, + getMenuHTML, + generateSiyuanId, + findImgSrc, + imgSrcToAbsolutePath +} from "@/helper"; import {createEditor, openEditorTab} from "@/editorTab"; +import {DATA_PATH} from "@/const"; export default class DrawJSPlugin extends Plugin { onload() { @@ -18,23 +26,22 @@ export default class DrawJSPlugin extends Plugin { filter: ["Insert Drawing", "Add drawing", "whiteboard", "freehand", "graphics", "jsdraw"], html: getMenuHTML("iconDraw", this.i18n.insertDrawing), callback: (protyle: Protyle) => { - const uid = generateSiyuanId(); - protyle.insert(getPreviewHTML(uid), true, false); - openEditorTab(this, uid); + const path = DATA_PATH + generateSiyuanId() + ".svg"; + protyle.insert(getPreviewHTML(path), true, false); + openEditorTab(this, path); } }]; this.eventBus.on("open-menu-image", (e: any) => { - const fileID = extractFileID(findImgSrc(e.detail.element)); - if(fileID === null) { + const path = imgSrcToAbsolutePath(findImgSrc(e.detail.element)); + if(path === null) { return; } - console.log("got ID" + fileID); e.detail.menu.addItem({ icon: "iconDraw", label: "Edit with js-draw", click: () => { - openEditorTab(this, fileID); + openEditorTab(this, path); } }) })