Offer to edit images

Any SVG image in assets/ can now be edited with js-draw. It won't reload automatically (yet)
This commit is contained in:
MassiveBox 2025-04-01 23:03:22 +02:00
parent 5c261b35f2
commit 8d1438de33
Signed by: massivebox
GPG key ID: 9B74D3A59181947D
4 changed files with 240 additions and 18 deletions

View file

@ -1,6 +1,9 @@
function copyEditLink(fileID) {
navigator.clipboard.writeText(getEditLink(fileID));
}
function copyImageLink(fileID) {
navigator.clipboard.writeText(`![Drawing](assets/${fileID}.svg)`);
}
function refreshPage() {
window.location.reload();
@ -20,7 +23,7 @@ function addButton(document, fileID) {
popupMenu.innerHTML = `
<button onclick="refreshPage()">Refresh</button>
<button onclick="copyEditLink('${fileID}')">Copy Direct Edit Link</button>
<button onclick="copyImageLink('${fileID}')">Copy Image Link</button>
`;
document.body.appendChild(popupMenu);
@ -31,6 +34,7 @@ function addButton(document, fileID) {
document.body.addEventListener('mouseleave', () => {
floatingButton.style.display = 'none';
popupMenu.style.display = 'none';
});
// Toggle popup menu on button click

View file

@ -55,3 +55,36 @@ export function getPreviewHTML(id: string): string {
<iframe src="${EMBED_PATH + id}&antiCache=0"></iframe>
`
}
// given a tag (such as a div) containing an image as a child at any level, return the src of the image
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;
}
// Recursively check children
if (element.children) {
for (const child of Array.from(element.children)) {
const src = findImgSrc(child as HTMLElement);
if (src) return src;
}
}
return null;
}
export function extractFileID(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);
return match?.[1] || null;
}

View file

@ -1,12 +1,11 @@
import {Plugin, Protyle} from 'siyuan';
import {getPreviewHTML, loadIcons, getMenuHTML, generateSiyuanId} from "@/helper";
import {getPreviewHTML, loadIcons, getMenuHTML, generateSiyuanId, findImgSrc, extractFileID} from "@/helper";
import {createEditor, openEditorTab} from "@/editorTab";
export default class DrawJSPlugin extends Plugin {
onload() {
loadIcons(this);
//const id = Math.random().toString(36).substring(7);
this.addTab({
'type': "whiteboard",
init() {
@ -25,20 +24,21 @@ export default class DrawJSPlugin extends Plugin {
}
}];
this.eventBus.on("open-menu-image", (e: any) => {
const fileID = extractFileID(findImgSrc(e.detail.element));
if(fileID === null) {
return;
}
console.log("got ID" + fileID);
e.detail.menu.addItem({
icon: "iconDraw",
label: "Edit with js-draw",
click: () => {
openEditorTab(this, fileID);
}
})
})
}
onLayoutReady() {
// This function is automatically called when the layout is loaded.
}
onunload() {
// This function is automatically called when the plugin is disabled.
}
uninstall() {
// This function is automatically called when the plugin is uninstalled.
}
}

File diff suppressed because one or more lines are too long