思源笔记折腾记录 -urlScheme 动作

本贴最后更新于 822 天前,其中的信息可能已经天翻地覆

一、前情提要:

思源的 URL scheme 能够通过块超链接做到唤起思源并打开指定的块,然后还能。。。。。。。。。。

额,好像然后就不能做什么了。

所以这次我们就来尝试一下扩展一下思源的 URL Scheme

二、实现原理

1、ipcRenderer

可以先在代码片段里面测试一下这段代码:

const {ipcRenderer} = require('electron') ipcRenderer.on('siyuan-openurl',(event,msg)=>{ console.log(event,msg) })

随便在什么地方打开一个思源的块超链接,就可以看到在控制台的输出了:

image

啊,可以看到后面的 msg 参数就是块超链接的内容~~~。

这是为什么呢?

之前我们说过,思源的 main.js 里面是可以直接看到内容的,这里可以看一下第 771 到 799 行:

app.on('open-url', (event, url) => { // for macOS if (url.startsWith('siyuan://')) { siyuanOpenURL = url if (mainWindow && !mainWindow.isDestroyed()) { if (mainWindow.isMinimized()) { mainWindow.restore() } if (!mainWindow.isVisible()) { mainWindow.show() } mainWindow.focus() mainWindow.webContents.send('siyuan-openurl', url) } } }) app.on('second-instance', (event, commandLine) => { if (mainWindow && !mainWindow.isDestroyed()) { if (mainWindow.isMinimized()) { mainWindow.restore() } if (!mainWindow.isVisible()) { mainWindow.show() } mainWindow.focus() mainWindow.webContents.send('siyuan-openurl', commandLine.find((arg) => arg.startsWith('siyuan://'))) } })

这两个地方就是通过进程间通信,把块超链接的内容发送给了思源的主界面。

所以我们可以通过监听这个 siyuan-openurl 信道来获取 url 的内容。

有关 ipcRenderer 之类的参考 electorn 的文档:

ipcRenderer | Electron (electronjs.org)

其实就是用来通信的嘛

2、URL 对象

这个其实就是冷饭了,之前在实现白板的时候不是用了一个解析 URL 参数的对象嘛,这次要使用的就是那个:

思源笔记折腾记录 - 做一个白板 - 保存数据和显示模式 - 链滴 (ld246.com)

之前是这样写的:

export function 获取地址参数(){ let 中间变量 = {} new URL(window.location.href).searchParams.forEach( (value,key)=>{中间变量[key]=value} ) return 中间变量 }

那么很容易就想到,只要把这个函数跟上面的那个结合一下,就可以了:

const {ipcRenderer} = require('electron') ipcRenderer.on('siyuan-openurl',(event,msg)=>{ 执行URL(msg) }) function 执行URL(url){ let url 对象 = new URL(url) console.log(url对象) }

可以看到 url 对象上有这么些属性:

image

这样我们就可以它进行进一步的操作了。

3、注册动作

首先我们假设,一个类似:

siyuan://<路径>/<下级路径>?<参数>

的 url。

它最开始的路径名就是要执行的动作,下级路径和 url 的 searchParams 都直接传递给对应的回调函数。

这样我们就能开始注册回调了:

const url动作注册表 = [] const { ipcRenderer } = require('electron') ipcRenderer.on('siyuan-openurl', (event, msg) => { 执行URL(msg) }) function 执行URL(url) { let url对象 = new URL(url) let 路径名 = url对象.pathname.replace('//', '').split('/')[0] let 搜索参数 = {} url对象.searchParams.forEach( (value, key) => { 搜索参数[key] = value } ) console.log(路径名, 搜索参数) url动作注册表.forEach( 注册表项 => { console.log(注册表项.动作 === 路径名) if (注册表项.动作 === 路径名) { try { (async () => { 注册表项.回调函数(url对象.pathname.replace('//', ''), JSON.parse(JSON.stringify(搜索参数))) })() } catch (e) { console.warn(e) } } } ) } function 注册url动作(动作, 回调函数) { url动作注册表.push({ 动作: 动作, 回调函数: 回调函数 }) } 注册url动作('blocks', (路径名, 参数) => { console.log('你点击的是',路径名, 参数) })

啊,我就随便注册一个函数试试。。。。。

现在点击一个块超链接,啊不对,现在应该叫超级块超链接,因为它的战斗力已经超过 114514 了,看一下输出就可以看到:

image

OK,收工。

把它挂载到 noobApi 上方便以后调用:

const url动作注册表 = [] if (window.require) { const { ipcRenderer } = require('electron') ipcRenderer.on('siyuan-openurl', (event, msg) => { 执行URL(msg) }) function 执行URL(url) { let url对象 = new URL(url) let 路径名 = url对象.pathname.replace('//', '').split('/')[0] let 搜索参数 = {} url对象.searchParams.forEach( (value, key) => { 搜索参数[key] = value } ) console.log(路径名, 搜索参数) url动作注册表.forEach( 注册表项 => { console.log(注册表项.动作 === 路径名) if (注册表项.动作 === 路径名) { try { (async () => { 注册表项.回调函数(url对象.pathname.replace('//', ''), JSON.parse(JSON.stringify(搜索参数))) })() } catch (e) { console.warn(e) } } } ) } } export default function 注册url动作(动作, 回调函数) { url动作注册表.push({ 动作: 动作, 回调函数: 回调函数 }) }

4、试一试

注册一个打开当天日记的函数试试:

noobApi.url动作.注册url动作('DailyNote', () => { noobApi.核心api.创建日记({ notebook : "20210808180117-czj9bvb" }) })

效果就像这样

url 创建日记

这样这个 issue 就能够自己动手撸啦:

丰富 siyuan:// 协议动作,如创建文档 · Issue #6875 · siyuan-note/siyuan (github.com)

所谓折腾就是有 bug 要上,没有 bug,创造 bug 也要上嘛~~~

思考题:issue 里面提到的创建文档咋整?(其实就是换个接口而已。。。。。。)


代码片段的仓库在这里

leolee9086/snippets (github.com)

viteWdigets 的仓库在这里

leolee9086/viteWidgets (github.com)

  • 思源笔记

    思源笔记是一款隐私优先的个人知识管理系统,支持完全离线使用,同时也支持端到端加密同步。

    融合块、大纲和双向链接,重构你的思维。

    24577 引用 • 100677 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...