diff --git a/-1. 捕获/未命名.md b/-1. 捕获/未命名.md new file mode 100644 index 0000000..e69de29 diff --git a/.obsidian/community-plugins.json b/.obsidian/community-plugins.json index 7a1a51f..b026ba9 100644 --- a/.obsidian/community-plugins.json +++ b/.obsidian/community-plugins.json @@ -4,5 +4,6 @@ "obsidian-icon-folder", "obsidian-emoji-toolbar", "execute-code", - "auto-card-link" + "auto-card-link", + "link-preview" ] \ No newline at end of file diff --git a/.obsidian/plugins/execute-code/data.json b/.obsidian/plugins/execute-code/data.json index b03ed30..e05a1ff 100644 --- a/.obsidian/plugins/execute-code/data.json +++ b/.obsidian/plugins/execute-code/data.json @@ -1,4 +1,5 @@ { + "lastOpenLanguageTab": "python", "releaseNote2_0_0wasShowed": true, "persistentOuput": false, "timeout": 10000, diff --git a/.obsidian/plugins/link-preview/main.js b/.obsidian/plugins/link-preview/main.js new file mode 100644 index 0000000..65f2522 --- /dev/null +++ b/.obsidian/plugins/link-preview/main.js @@ -0,0 +1,183 @@ +/* +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 */ \ No newline at end of file diff --git a/.obsidian/plugins/link-preview/manifest.json b/.obsidian/plugins/link-preview/manifest.json new file mode 100644 index 0000000..1451bad --- /dev/null +++ b/.obsidian/plugins/link-preview/manifest.json @@ -0,0 +1,10 @@ +{ + "id": "link-preview", + "name": "Link Preview", + "version": "0.1.3", + "minAppVersion": "1.7.6", + "description": "Show a preview of external links on hover", + "author": "Felipe Tappata", + "authorUrl": "https://github.com/felipetappata", + "isDesktopOnly": false +} diff --git a/.obsidian/plugins/link-preview/styles.css b/.obsidian/plugins/link-preview/styles.css new file mode 100644 index 0000000..26a87ae --- /dev/null +++ b/.obsidian/plugins/link-preview/styles.css @@ -0,0 +1,70 @@ +/* Main preview container */ +.hover-popup { + background-color: var(--background-primary); + border: 1px solid var(--background-modifier-border); + border-radius: var(--radius-m); + box-shadow: var(--shadow-s); + padding: var(--size-4-2); + display: flex; + flex-direction: column; + pointer-events: all; + position: fixed; + z-index: 1000; + min-height: 100px; /* Minimum height to prevent tiny windows */ +} + +/* Preview navigation controls */ +.preview-nav-group { + display: flex; + gap: 4px; +} + +.preview-nav-button-disabled { + opacity: 0.5; + cursor: default; +} + +.preview-nav-button-disabled:hover { + background-color: transparent !important; + color: var(--text-muted) !important; +} + +/* Only keep tooltip for external link button */ +.preview-nav-button:not([data-tooltip]):hover::after { + display: none; +} + +/* Preview content container */ +.preview-iframe-wrapper { + flex: 1; + position: relative; + background-color: var(--background-secondary); + border-radius: var(--radius-s); + box-shadow: var(--shadow-xs); + overflow: hidden; /* Ensure content respects rounded corners */ + height: 100%; /* Make sure wrapper takes full height */ + min-height: 0; /* Allow wrapper to shrink */ + width: 100%; + height: 100%; +} + +/* Preview iframe */ +.preview-iframe-wrapper iframe { + display: none; + width: 100%; + height: 100%; + border: none; + background-color: white; + pointer-events: all; +} + +/* Loading state indicator */ +.preview-loading { + padding: 20px; + text-align: center; + color: var(--text-muted); + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); +} diff --git a/.obsidian/workspace.json b/.obsidian/workspace.json index 40e6d6a..4c38afb 100644 --- a/.obsidian/workspace.json +++ b/.obsidian/workspace.json @@ -4,17 +4,21 @@ "type": "split", "children": [ { - "id": "7f6f1987ec27d37d", + "id": "ddf41b12945d3a76", "type": "tabs", "children": [ { - "id": "a7094b501a1737ff", + "id": "2a04da54a021f0f6", "type": "leaf", "state": { - "type": "empty", - "state": {}, + "type": "markdown", + "state": { + "file": "5. 表达/未命名.md", + "mode": "source", + "source": false + }, "icon": "lucide-file", - "title": "新标签页" + "title": "未命名" } } ] @@ -158,26 +162,28 @@ "left-ribbon": { "hiddenItems": { "switcher:打开快速切换": false, - "graph:查看关系图谱": false, "canvas:新建白板": false, "daily-notes:打开/创建今天的日记": false, "templates:插入模板": false, - "command-palette:打开命令面板": false, - "card-board:CardBoard": false, "obsidian-kanban:创建新看板": false, - "obsidian-git:Open Git source control": false, - "markdown-importer:打开 Markdown 格式转换器": false, - "workspaces:管理工作区布局": false + "obsidian-git:Open Git source control": false } }, - "active": "6497486430fd2d6d", + "active": "2a04da54a021f0f6", "lastOpenFiles": [ - "4. 存档/附件", + "-1. 捕获/未命名.md", + "5. 表达/未命名.md", + "0. 日记/未命名.md", + "1. 项目/未命名.md", + "2. 邻域/未命名.md", + "3. 资源/图表类型.md", + "3. 资源/PARA 组织法.md", "任务.md", - "4. 存档/模板", "主页.canvas", "4. 存档/插件效果 实验测试页.md", - "3. 资源/PARA 组织法.md", + "0. 日记/2024-12-26.md", + "4. 存档/附件", + "4. 存档/模板", "2024-12-26.md", "未命名看板.md", "1. 项目/未命名.canvas", diff --git a/0. 日记/未命名.md b/0. 日记/未命名.md new file mode 100644 index 0000000..e69de29 diff --git a/1. 项目/未命名.md b/1. 项目/未命名.md new file mode 100644 index 0000000..e69de29 diff --git a/2. 邻域/未命名.md b/2. 邻域/未命名.md new file mode 100644 index 0000000..e69de29 diff --git a/3. 资源/PARA 组织法.md b/3. 资源/PARA 组织法.md index 121e423..1116015 100644 --- a/3. 资源/PARA 组织法.md +++ b/3. 资源/PARA 组织法.md @@ -1,5 +1,4 @@ ## PARA 组织法 - [PARA](https://fortelabs.com/blog/para/) 组织法是一种个人知识管理系统,由时间管理教练 Tiago Forte 创立。 PARA 代表四个核心类别: diff --git a/3. 资源/图表类型.md b/3. 资源/图表类型.md new file mode 100644 index 0000000..76cedf3 --- /dev/null +++ b/3. 资源/图表类型.md @@ -0,0 +1,2 @@ +热力图 heatmap +路线图 roadmap diff --git a/4. 存档/插件效果 实验测试页.md b/4. 存档/插件效果 实验测试页.md index 502e262..817d33d 100644 --- a/4. 存档/插件效果 实验测试页.md +++ b/4. 存档/插件效果 实验测试页.md @@ -8,3 +8,7 @@ favicon: https://xjyofc.top/upload/头像.webp image: https://xjyofc.top/upload/头像.webp ``` +```python +print('hello) +``` + diff --git a/5. 表达/未命名.md b/5. 表达/未命名.md new file mode 100644 index 0000000..e69de29