├── fakeDocBreadcrumb ├── manifest.json ├── README.md ├── README_english.md └── main.js ├── hierarchyNavigate ├── manifest.json ├── README.md ├── README_english.md └── main.js ├── README.md ├── README_english.md └── LICENSE /fakeDocBreadcrumb/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "key": "fakeDocBreadcrumb", 3 | "name": "(伪)文档面包屑", 4 | "description": "一个虚拟的文档面包屑", 5 | "author": "OpaqueGlass", 6 | "url": "https://github.com/OpaqueGlass/syplugin-my-plugin-collection", 7 | "version": "0.1.0" 8 | } -------------------------------------------------------------------------------- /hierarchyNavigate/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "key": "hierarchyNavigate", 3 | "name": "文档上下层级导航", 4 | "description": "参考HBuilderX-Light主题的插件实现 | [Navigation to Parent and Child docs] derived from siyuan theme \"HBuilderX-Light\"", 5 | "author": "OpaqueGlass", 6 | "url": "https://github.com/OpaqueGlass/syplugin-my-plugin-collection", 7 | "version": "0.1.1" 8 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [English](README_english.md) 2 | 3 | 这里收录我写的简单插件。 4 | 5 | 由于插件系统变更,文档层级导航项目迁移至[此处](https://github.com/OpaqueGlass/syplugin-hierarchyNavigate),文档面包屑项目迁移至[此处](https://github.com/OpaqueGlass/syplugin-fakeDocBreadcrumb)。~~而本合集项目将被归档。~~ 6 | 7 | 在[思源笔记](https://github.com/siyuan-note/siyuan/)推出官方插件后,此项目的[`new`分支](https://github.com/OpaqueGlass/syplugin-my-plugin-collection/tree/new)将更新适用于官方插件系统的其他简单插件。 -------------------------------------------------------------------------------- /README_english.md: -------------------------------------------------------------------------------- 1 | > Most of this document was translated by Google Translate 2 | 3 | Here is a simple plugin I wrote. 4 | 5 | Due to the modifications in the siyuan plugin system, the repo of Hierarchy Navigation plugin has been migrated [here](https://github.com/OpaqueGlass/syplugin-hierarchyNavigate), and the repo of Fake Doc Breadcrumb plugin has been migrated [here](https://github.com/OpaqueGlass/syplugin-fakeDocBreadcrumb). After migrating to official plugin system, ~~this repo will be archived.~~ 6 | 7 | After the official release of plugins in [Siyuan](https://github.com/siyuan-note/siyuan/), the [`new` branch] of this project will be updated to include other simple plugins compatible with the official plugin system. -------------------------------------------------------------------------------- /fakeDocBreadcrumb/README.md: -------------------------------------------------------------------------------- 1 | ## fakeDocBreadcrumb (伪)文档面包屑 2 | 3 | [English](https://github.com/OpaqueGlass/syplugin-my-plugin-collection/blob/main/fakeDocBreadcrumb/README_english.md) 4 | 5 | > 当前版本:v0.1.0 6 | 7 | ### 快速开始 8 | 9 | - 开启插件即可; 10 | 11 | #### 说明 12 | 13 | 本插件: 14 | 15 | - 不支持鼠标悬停时显示浮窗; 16 | - 手机端无法使用; 17 | - 不支持显示同一层级的其他文档,只能向上层跳转; 18 | 19 | ## 反馈bug 20 | 21 | 请前往[github仓库](https://github.com/OpaqueGlass/syplugin-my-plugin-collection)反馈问题。 22 | 23 | ### 参考&感谢 24 | 25 | | 开发者/项目 | 描述 | 说明 | 26 | | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------ | 27 | | [leolee9086](https://github.com/leolee9086) / [cc-template](https://github.com/leolee9086/cc-template) | 使用挂件渲染模板;[木兰宽松许可证, 第2版](https://github.com/leolee9086/cc-template/blob/main/LICENSE) | 点击打开文档 | 28 | | [zuoez02](https://github.com/zuoez02)/[siyuan-plugin-system](https://github.com/zuoez02/siyuan-plugin-system) | 插件系统 | | 29 | 30 | -------------------------------------------------------------------------------- /fakeDocBreadcrumb/README_english.md: -------------------------------------------------------------------------------- 1 | ## fakeDocBreadcrumb 2 | 3 | > This document was translated by Google Translate without manual checking. The author cannot guarantee the accuracy of the translation results. And this document does not express the author's attitude or position. 4 | 5 | > Current Version: v0.1.0 6 | 7 | ### Quick Start 8 | 9 | - Just turn on the plugin; 10 | 11 | #### Other explanation 12 | 13 | - Does not support displaying the floating window when the mouse hovers over; 14 | - The mobile terminal cannot be used; 15 | - It does not support displaying other documents of the same level, and can only jump to the upper level; 16 | 17 | ## Feedback bugs 18 | 19 | Please go to [github repository](https://github.com/OpaqueGlass/syplugin-my-plugin-collection) to report problems. 20 | 21 | ### Reference & Thanks 22 | 23 | | Developer/Project | Description | Illustration | 24 | | ------------------------------------------------------------ | ------------------------------------------------------------ | ---------------------- | 25 | | [leolee9086](https://github.com/leolee9086) / [cc-template](https://github.com/leolee9086/cc-template) | Render template in widget; [Mulan Permissive Software License,Version 2](https://github.com/leolee9086/cc-template/blob/main/LICENSE) | Click to open the doc. | 26 | | [zuoez02]([zuoez02 (Luto Yvan) (github.com)](https://github.com/zuoez02))/[siyuan-plugin-system](https://github.com/zuoez02/siyuan-plugin-system) | A plugin system for siyuan | | 27 | 28 | -------------------------------------------------------------------------------- /hierarchyNavigate/README.md: -------------------------------------------------------------------------------- 1 | ## hierarchyNavigate 文档标题下添加上下层文档导航 2 | 3 | [English](https://github.com/OpaqueGlass/syplugin-my-plugin-collection/blob/main/hierarchyNavigate/README_english.md) 4 | 5 | > 当前版本:v0.1.1 新增:设置项配置;改进:默认样式;修复:快速切换标签页插入错误的问题;修复:导致选项`转移引用`无法显示;修复:安卓端 6 | 7 | ### 快速开始 8 | 9 | - 开启插件即可; 10 | - 其他请浏览插件设置页面; 11 | 12 | #### 说明 13 | 14 | - 已尽力保证在安卓App上可用,如果仍有问题,麻烦反馈,谢谢; 15 | 16 | 17 | 18 | - 插入导航部分后,标题左侧的文档图标将有一些错位,可通过“设置--外观--代码片段--添加css”解决: 19 | 20 | ```css 21 | .protyle-title__icon { 22 | top: 40px; 23 | } 24 | ``` 25 | 26 | 27 | 28 | ## 反馈bug 29 | 30 | 请前往[github仓库](https://github.com/OpaqueGlass/syplugin-my-plugin-collection)反馈问题。 31 | 32 | ## 参考&感谢 33 | 34 | 代码贡献者(开发者)详见[贡献者列表](https://github.com/OpaqueGlass/syplugin-my-plugin-collection/graphs/contributors)。 35 | 36 | | 开发者/项目 | 描述 | 说明 | 37 | | ------------------------------------------------------------ | ------------------------------------------------------------ | ---------------------------- | 38 | | [UFDXD](https://github.com/UFDXD)/[HBuilderX-Light](https://github.com/UFDXD/HBuilderX-Light) | 一个无边距的护眼主题 | 参考其标题下父子文档信息实现 | 39 | | [leolee9086](https://github.com/leolee9086) / [cc-template](https://github.com/leolee9086/cc-template) | 使用挂件渲染模板;[木兰宽松许可证, 第2版](https://github.com/leolee9086/cc-template/blob/main/LICENSE) | 点击打开文档 | 40 | | [zuoez02](https://github.com/zuoez02)/[siyuan-plugin-system](https://github.com/zuoez02/siyuan-plugin-system) | 插件系统 | | 41 | | [zxhd863943427](https://github.com/zxhd863943427)&[mozhux (赐我一胖) (github.com)](https://github.com/mozhux) | | 样式建议等 | 42 | -------------------------------------------------------------------------------- /hierarchyNavigate/README_english.md: -------------------------------------------------------------------------------- 1 | ## hierarchyNavigate 2 | 3 | > This document was translated by Google Translate without manual checking. The author cannot guarantee the accuracy of the translation results. And this document does not express the author's attitude or position. 4 | 5 | > Current Version:v0.1.1 New: Set item configuration; Improved: Default style;Fixed: wrongly display after quickly switching tab; Fixed: Option 'transfer reference' cannot be displayed. 6 | 7 | Add parent and children documents links under the document title. 8 | 9 | ### Quick Start 10 | 11 | - Just turn on the plugin; 12 | - For more information, please refer to the plugin setting page (named "文档上下层级导航"); 13 | 14 | #### Other explanation 15 | 16 | - Maybe available in siyuan Android App (in testing); 17 | 18 | - After inserting the navigation part, the document icon on the left side of the title will have some misalignment, which can be solved by "Settings - Appearance - Code Snippet - Add css" 19 | 20 | ```css 21 | .protyle-title__icon { 22 | top: 40px; 23 | } 24 | ``` 25 | 26 | 27 | 28 | ## Feedback bugs 29 | 30 | Please go to [github repository](https://github.com/OpaqueGlass/syplugin-my-plugin-collection) to report problems. 31 | 32 | ### Reference & Thanks 33 | 34 | | Developer/Project | Description | Illustration | 35 | | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | 36 | | [UFDXD](https://github.com/UFDXD)/[HBuilderX-Light](https://github.com/UFDXD/HBuilderX-Light) | A borderless eye protection theme | This plug-in is implemented by referring to the parent-child document information under its title | 37 | | [leolee9086](https://github.com/leolee9086) / [cc-template](https://github.com/leolee9086/cc-template) | Render template in widget; [Mulan Permissive Software License,Version 2](https://github.com/leolee9086/cc-template/blob/main/LICENSE) | Click to open the doc. | 38 | | [zuoez02]([zuoez02 (Luto Yvan) (github.com)](https://github.com/zuoez02))/[siyuan-plugin-system](https://github.com/zuoez02/siyuan-plugin-system) | A plugin system for siyuan | | 39 | | [zxhd863943427](https://github.com/zxhd863943427)&[mozhux (赐我一胖) (github.com)](https://github.com/mozhux) | | Style suggestions and contributions. | 40 | 41 | -------------------------------------------------------------------------------- /fakeDocBreadcrumb/main.js: -------------------------------------------------------------------------------- 1 | const siyuan = require('siyuan'); 2 | const { serverApi } = require("siyuan"); 3 | const { Plugin, Menu, MenuItem } = siyuan; 4 | 5 | class FakeDocBreadcrumbPlugin extends Plugin { 6 | el = null; 7 | 8 | tabOpenObserver = null; 9 | 10 | constructor() { 11 | super(); 12 | try { 13 | g_tabbarElement = window.siyuan?.layout?.centerLayout?.element?.querySelectorAll("[data-type='wnd'] ul.layout-tab-bar"); 14 | }catch(err) { 15 | console.warn(err); 16 | g_tabbarElement = undefined; 17 | } 18 | if (g_tabbarElement == undefined) { 19 | g_isMobile = true; 20 | } 21 | console.log('TestRemotePluginCreated'); 22 | } 23 | 24 | async onload() { 25 | setObserver(); 26 | console.log("TEST_LOADED", g_importApi); 27 | console.log("PLUGIN_API", siyuan, serverApi); 28 | setStyle(); 29 | } 30 | 31 | onunload() { 32 | this.el && this.el.remove(); 33 | removeObserver(); 34 | removeStyle(); 35 | } 36 | } 37 | 38 | module.exports = { 39 | default: FakeDocBreadcrumbPlugin, 40 | }; 41 | 42 | /** 43 | * 全局变量 44 | */ 45 | let g_switchTabObserver; // 页签切换与新建监视器 46 | let g_windowObserver; // 窗口监视器 47 | let CONSTANTS = { 48 | RANDOM_DELAY: 300, // 插入挂件的延迟最大值,300(之后会乘以10)对应最大延迟3秒 49 | OBSERVER_RANDOM_DELAY: 500, // 插入链接、引用块和自定义时,在OBSERVER_RANDOM_DELAY_ADD的基础上增加延时,单位毫秒 50 | OBSERVER_RANDOM_DELAY_ADD: 100, // 插入链接、引用块和自定义时,延时最小值,单位毫秒 51 | OBSERVER_RETRY_INTERVAL: 1000, // 找不到页签时,重试间隔 52 | } 53 | let g_observerRetryInterval; 54 | let g_observerStartupRefreshTimeout; 55 | let g_TIMER_LABLE_NAME_COMPARE = "文档栏插件"; 56 | let g_importCommon = null; 57 | let g_importApi = null; 58 | let g_importUtils = null; 59 | let g_tabbarElement = undefined; 60 | let g_fontSize = "13px"; 61 | let g_isMobile = false; 62 | /* API */ 63 | 64 | 65 | /** 66 | * 设置监视器Observer 67 | */ 68 | function setObserver() { 69 | if (g_isMobile) { 70 | g_switchTabObserver = new MutationObserver(async (mutationList) => { 71 | for (let mutation of mutationList) { 72 | // console.log("发现页签切换", mutation); 73 | setTimeout(async () => { 74 | console.time(g_TIMER_LABLE_NAME_COMPARE); 75 | try{ 76 | // TODO: 改为动态获取id 77 | await main([mutation.target]); 78 | }catch(err) { 79 | console.error(err); 80 | } 81 | console.timeEnd(g_TIMER_LABLE_NAME_COMPARE); 82 | }, Math.round(Math.random() * CONSTANTS.OBSERVER_RANDOM_DELAY) + CONSTANTS.OBSERVER_RANDOM_DELAY_ADD); 83 | } 84 | }); 85 | g_switchTabObserver.observe(window.document.querySelector(".protyle-background[data-node-id]"), {"attributes": true, "attributeFilter": ["data-node-id"]}); 86 | console.log("MOBILE_LOADED"); 87 | main(); 88 | return; 89 | } 90 | g_switchTabObserver = new MutationObserver(async (mutationList) => { 91 | for (let mutation of mutationList) { 92 | // console.log("发现页签切换", mutation); 93 | setTimeout(async () => { 94 | console.time(g_TIMER_LABLE_NAME_COMPARE); 95 | try{ 96 | // TODO: 改为动态获取id 97 | await main([mutation.target]); 98 | }catch(err) { 99 | console.error(err); 100 | } 101 | console.timeEnd(g_TIMER_LABLE_NAME_COMPARE); 102 | }, Math.round(Math.random() * CONSTANTS.OBSERVER_RANDOM_DELAY) + CONSTANTS.OBSERVER_RANDOM_DELAY_ADD); 103 | } 104 | }); 105 | g_windowObserver = new MutationObserver((mutationList) => { 106 | for (let mutation of mutationList) { 107 | // console.log("发现窗口变化", mutation); 108 | if (mutation.removedNodes.length > 0 || mutation.addedNodes.length > 0) { 109 | // console.log("断开Observer"); 110 | // tabBarObserver.disconnect(); 111 | g_switchTabObserver.disconnect(); 112 | clearInterval(g_observerRetryInterval); 113 | g_observerRetryInterval = setInterval(observerRetry, CONSTANTS.OBSERVER_RETRY_INTERVAL); 114 | } 115 | 116 | } 117 | 118 | }); 119 | g_observerRetryInterval = setInterval(observerRetry, CONSTANTS.OBSERVER_RETRY_INTERVAL); 120 | g_windowObserver.observe(window.siyuan.layout.centerLayout.element, {childList: true}); 121 | } 122 | /** 123 | * 重试页签监听 124 | */ 125 | function observerRetry() { 126 | g_tabbarElement = window.siyuan.layout.centerLayout.element.querySelectorAll("[data-type='wnd'] ul.layout-tab-bar"); 127 | if (g_tabbarElement.length > 0) { 128 | // console.log("重新监视页签变化"); 129 | g_tabbarElement.forEach((element)=>{ 130 | g_switchTabObserver.observe(element, {"attributes": true, "attributeFilter": ["data-activetime"], "subtree": true}); 131 | 132 | // 重启监听后立刻执行检查 133 | if (element.children.length > 0) { 134 | g_observerStartupRefreshTimeout = setTimeout(async () => { 135 | console.time(g_TIMER_LABLE_NAME_COMPARE); 136 | try{ 137 | // TODO 138 | await main(element.children); 139 | }catch (err) { 140 | console.error(err); 141 | } 142 | console.timeEnd(g_TIMER_LABLE_NAME_COMPARE); 143 | }, Math.round(Math.random() * CONSTANTS.OBSERVER_RANDOM_DELAY) + CONSTANTS.OBSERVER_RANDOM_DELAY_ADD); 144 | } 145 | }); 146 | clearInterval(g_observerRetryInterval); 147 | } 148 | } 149 | 150 | function removeObserver() { 151 | g_switchTabObserver?.disconnect(); 152 | g_windowObserver?.disconnect(); 153 | } 154 | 155 | async function main(targets) { 156 | // 获取当前文档id 157 | const docId = getCurrentDocIdF(); 158 | const docDetail = await getCurrentDocDetail(docId); 159 | console.warn('DETAIL', docDetail); 160 | // 检查是否重复插入 161 | if (window.top.document.querySelector(`.fn__flex-1.protyle:has(.protyle-background[data-node-id="${docId}"]) #fake-doc-breadcrumb`)) return; 162 | // 获取并解析hpath与path 163 | let pathObject = await parseDocPath(docDetail, docId); 164 | console.warn("OBJECT", pathObject); 165 | // 组合显示元素 166 | let element = await generateElement(pathObject, docId); 167 | console.warn("ELEMT", element); 168 | // 插入显示元素和设置监听 169 | setAndApply(element, docId); 170 | } 171 | 172 | async function parseDocPath(docDetail) { 173 | let pathArray = docDetail.path.substring(0, docDetail.path.length - 3).split("/"); 174 | let hpathArray = docDetail.hpath.split("/"); 175 | let resultArray = []; 176 | let notebooks = getNotebooks(); 177 | let box; 178 | for (let notebook of notebooks) { 179 | if (notebook.id == docDetail.box) { 180 | box = notebook; 181 | break; 182 | } 183 | } 184 | let temp = { 185 | "name": box.name, 186 | "id": box.id, 187 | "icon": box.icon, 188 | "box": box.id, 189 | "path": "/", 190 | "type": "NOTEBOOK" 191 | } 192 | resultArray.push(temp); 193 | let temp_path = ""; 194 | for (let i = 1; i < pathArray.length; i++) { 195 | let temp = { 196 | "name": hpathArray[i], 197 | "id": pathArray[i], 198 | "icon": "", 199 | "path": `${temp_path}/${pathArray[i]}.sy`, 200 | "box": box.id, 201 | "type": "FILE", 202 | } 203 | temp_path += "/" + pathArray[i]; 204 | resultArray.push(temp); 205 | } 206 | return resultArray; 207 | } 208 | 209 | async function generateElement(pathObjects, docId) { 210 | const divideArrow = ``; 211 | const oneItem = ` 212 | %2% 213 | `; 214 | let htmlStr = ""; 215 | for (let i = 0; i < pathObjects.length; i++) { 216 | if (pathObjects.length > 5 && i >= 2 && i < pathObjects.length - 3) { 217 | htmlStr += oneItem 218 | .replaceAll("%0%", "") 219 | .replaceAll("%1%", "···") 220 | .replaceAll("%2%", `···`) 221 | .replaceAll("%3%", "..."); 222 | htmlStr += divideArrow; 223 | i = pathObjects.length - 4; 224 | continue; 225 | } 226 | let onePathObject = pathObjects[i]; 227 | htmlStr += oneItem 228 | .replaceAll("%0%", onePathObject.id) 229 | .replaceAll("%1%", onePathObject.name) 230 | .replaceAll("%2%", onePathObject.name.length > 20 ? 231 | onePathObject.name.substring(0, 20) + "..." 232 | :onePathObject.name) 233 | .replaceAll("%3%", onePathObject.type); 234 | htmlStr += divideArrow; 235 | } 236 | let result = document.createElement("div"); 237 | let barElement = document.createElement("div"); 238 | barElement.classList.add("protyle-breadcrumb__bar"); 239 | barElement.classList.add("protyle-breadcrumb__bar--nowrap"); 240 | barElement.innerHTML = htmlStr; 241 | result.appendChild(barElement); 242 | result.setAttribute("id", "fake-doc-breadcrumb"); 243 | result.classList.add("protyle-breadcrumb"); 244 | result.style.top = (window.document.querySelector(`.fn__flex-1.protyle:has(.protyle-background[data-node-id="${docId}"]) .protyle-breadcrumb`).clientHeight) + "px"; 245 | // 修改以使得内容下移30px .protyle-content 246 | return result; 247 | 248 | } 249 | 250 | function setAndApply(element, docId) { 251 | window.top.document.querySelector(`.fn__flex-1.protyle:has(.protyle-background[data-node-id="${docId}"]) .protyle-breadcrumb`).insertAdjacentElement("afterend",element); 252 | [].forEach.call(window.document.querySelectorAll(`.fake-breadcrumb-click[data-type="FILE"]`), (elem)=>{ 253 | elem.addEventListener("click", openRefLink); 254 | }); 255 | } 256 | 257 | function setStyle() { 258 | let contentElem = window.top.document.querySelector(`.fn__flex-1.protyle .protyle-content`); 259 | let contentPaddingTop = parseFloat(window.getComputedStyle(contentElem)?.getPropertyValue("padding-top")?.replace("px")??30); 260 | console.log(contentPaddingTop); 261 | let newPaddingTop = contentPaddingTop + window.document.querySelector(`.fn__flex-1.protyle .protyle-breadcrumb`)?.clientHeight ?? 30; 262 | console.log("new padding top", newPaddingTop); 263 | const head = document.getElementsByTagName('head')[0]; 264 | 265 | // 创建