183 lines
6.3 KiB
JavaScript

/*
THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
if you want to view the source, please visit the github repository of this plugin
*/
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// main.ts
var main_exports = {};
__export(main_exports, {
default: () => LinkPreviewPlugin
});
module.exports = __toCommonJS(main_exports);
var import_obsidian = require("obsidian");
var DEFAULT_SETTINGS = {
previewDelay: 300,
maxPreviewHeight: 400,
maxPreviewWidth: 600
};
var LinkPreviewPlugin = class extends import_obsidian.Plugin {
constructor() {
super(...arguments);
// Track active preview elements by link URL
this.activeLinks = /* @__PURE__ */ new Map();
}
async onload() {
await this.loadSettings();
this.registerHoverHandler(document);
this.registerEvent(
this.app.workspace.on("window-open", ({ win }) => {
this.registerHoverHandler(win.document);
})
);
this.addSettingTab(new LinkPreviewSettingTab(this.app, this));
}
registerHoverHandler(doc) {
this.registerDomEvent(doc, "mouseover", (evt) => {
const target = evt.target;
const linkEl = target.closest("a");
if (!linkEl)
return;
if (linkEl.hasClass("external-link")) {
const rect = linkEl.getBoundingClientRect();
this.showPreview(linkEl, rect, doc);
}
});
}
/**
* Clean up any remaining previews when plugin is disabled
*/
onunload() {
this.activeLinks.forEach((previewEl, linkId) => {
previewEl.remove();
});
this.activeLinks.clear();
}
/**
* Creates and shows a preview window for a link element
* @param linkEl - The link element for which to create a preview
* @param rect - The bounding rectangle of the link element
*/
showPreview(linkEl, rect, doc) {
const url = linkEl.getAttribute("href");
if (!url)
return;
const linkId = `preview-${url}`;
if (this.activeLinks.has(linkId))
return;
let hideTimeout;
const win = doc.defaultView;
if (!win)
return;
const handleLinkLeave = () => {
hideTimeout = win.setTimeout(cleanupPreview, 300);
};
const handlePreviewEnter = () => {
if (hideTimeout) {
win.clearTimeout(hideTimeout);
}
};
const handlePreviewLeave = () => {
cleanupPreview();
};
const cleanupPreview = () => {
const previewEl = this.activeLinks.get(linkId);
if (previewEl) {
previewEl.remove();
this.activeLinks.delete(linkId);
}
linkEl.removeEventListener("mouseleave", handleLinkLeave);
};
setTimeout(() => {
if (this.activeLinks.has(linkId))
return;
const hoverEl = this.createPreviewElement(rect);
this.activeLinks.set(linkId, hoverEl);
const loadingEl = hoverEl.createDiv({ cls: "preview-loading" });
loadingEl.setText("Loading preview...");
const iframeWrapper = hoverEl.createDiv({ cls: "preview-iframe-wrapper" });
const iframe = iframeWrapper.createEl("iframe", {
attr: {
src: url
}
});
iframe.addEventListener("load", () => {
loadingEl.remove();
iframe.style.display = "block";
});
iframe.addEventListener("error", () => {
loadingEl.setText("Failed to load preview");
});
linkEl.addEventListener("mouseleave", handleLinkLeave);
hoverEl.addEventListener("mouseenter", handlePreviewEnter);
hoverEl.addEventListener("mouseleave", handlePreviewLeave);
doc.body.appendChild(hoverEl);
}, this.settings.previewDelay);
}
/**
* Creates the preview container element with proper positioning
* @param rect - The bounding rectangle used for positioning
* @returns HTMLElement configured as preview container
*/
createPreviewElement(rect) {
const el = createEl("div", {
cls: "hover-popup"
});
el.style.cssText = `
position: fixed;
left: ${rect.left}px;
top: ${rect.bottom + 5}px;
width: ${this.settings.maxPreviewWidth}px;
height: ${this.settings.maxPreviewHeight}px;
`;
return el;
}
async loadSettings() {
this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData());
}
async saveSettings() {
await this.saveData(this.settings);
}
};
var LinkPreviewSettingTab = class extends import_obsidian.PluginSettingTab {
constructor(app, plugin) {
super(app, plugin);
this.plugin = plugin;
}
display() {
const { containerEl } = this;
containerEl.empty();
new import_obsidian.Setting(containerEl).setName("Preview delay").setDesc("How long to wait before showing the preview (in milliseconds)").addText((text) => text.setPlaceholder("300").setValue(String(this.plugin.settings.previewDelay)).onChange(async (value) => {
this.plugin.settings.previewDelay = Number(value);
await this.plugin.saveSettings();
}));
new import_obsidian.Setting(containerEl).setName("Maximum preview height").setDesc("Maximum height of the preview window (in pixels)").addText((text) => text.setPlaceholder("300").setValue(String(this.plugin.settings.maxPreviewHeight)).onChange(async (value) => {
this.plugin.settings.maxPreviewHeight = Number(value);
await this.plugin.saveSettings();
}));
new import_obsidian.Setting(containerEl).setName("Maximum preview width").setDesc("Maximum width of the preview window (in pixels)").addText((text) => text.setPlaceholder("400").setValue(String(this.plugin.settings.maxPreviewWidth)).onChange(async (value) => {
this.plugin.settings.maxPreviewWidth = Number(value);
await this.plugin.saveSettings();
}));
}
};
/* nosourcemap */