generated from obsidianmd/obsidian-sample-plugin
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.ts
86 lines (69 loc) · 2.82 KB
/
main.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
import { Notice, Plugin, TFile } from 'obsidian';
export default class PasteImageIntoProperty extends Plugin {
async onload() {
this.registerDomEvent(document, "paste", (evt: ClipboardEvent) => this.handlePaste(evt), true);
}
handlePaste(evt: ClipboardEvent) {
const activeEl = document.activeElement as HTMLElement;
if (this.isValidFrontmatterField(activeEl))
this.handleImagePaste(evt, activeEl);
}
isValidFrontmatterField(element: HTMLElement | null): boolean {
if (!element)
return false;
return element.matches('.metadata-input-longtext.mod-truncate');//only text property fields
}
async handleImagePaste(evt: ClipboardEvent, target: HTMLElement) {
if (!evt.clipboardData)
return;
if(evt.clipboardData.types[0] != 'Files')
return;
const items: DataTransferItemList = evt.clipboardData.items;
for (let i = 0; i < items.length; i++) {
const item = items[i];
if (item.kind === "file" && item.type.startsWith("image/")) {
const file = item.getAsFile();
if (file) {
await this.saveImageAndWriteLink(file, target);
evt.preventDefault();
break;
}
}
}
}
async saveImageAndWriteLink(file: File, target: HTMLElement) {
const arrayBuffer = await file.arrayBuffer();
const fileExtension = file.type.split("/")[1] || "png";
const fileName = `Pasted image ${Date.now()}.${fileExtension}`;
const activeFile = this.app.workspace.getActiveFile();
if(!activeFile)
{
new Notice(`No active file!`);
return;
}
const savePath = await this.app.fileManager.getAvailablePathForAttachment(fileName, activeFile.path);
//store selected property before safing to ensure compatability with obsidian-paste-image-rename plugin
const activeEl = document.activeElement as HTMLElement;
const propertyName = activeEl.parentNode?.parentNode?.children[0].children[1].getAttribute("aria-label");
const newFile = await this.app.vault.createBinary(savePath, arrayBuffer);
const linkName = savePath.split('/').last();
await this.writeLinkIntoFrontmatter(activeFile, `[[${linkName}]]`, activeEl, propertyName, newFile);
}
async writeLinkIntoFrontmatter(activeFile: TFile, filePath: string, activeEl: HTMLElement, propertyName: string | null | undefined, newFile: TFile) {
if(document.activeElement as HTMLElement == activeEl)
activeEl.blur();
await new Promise(resolve => setTimeout(resolve, 50));
try {
if (!propertyName)
throw new Error("aria-label attribute not found on the expected element.");
await this.app.fileManager.processFrontMatter(activeFile, (frontmatter) => {
frontmatter[propertyName] = filePath;
});
new Notice(`Image added to frontmatter: ${filePath}`);
} catch (error) {
await this.app.vault.delete(newFile);
new Notice(`Failed to update frontmatter!\n${error}`);
console.error("Error updating frontmatter:", error);
}
}
}