[js] 标签文档自动加入数据库(转载)

本文只是转载,大佬在评论区分享的 js 代码,我觉得非常好用,于是搬运过来

代码作者:wilsons - 链滴

创意作者及其 quicker 动作:qiancang - 链滴[Quicker] 思源笔记 SuperTag - 链滴

// 思源通过标签插入当前块到数据库(SuperTag) // 功能:给块设置标签,将块添加到标签同名的数据库。 // 说明; // 1、数据库名称需要与标签同名,名称需含前后#,如 #笔记软件# // 2、如果有多个同名数据库,只会将块添加到其中一个,所以不要建立同名数据库 // 3、需要提前建立数据库才能添加成功 // version:0.0.4 // 更新记录 // 0.0.2 增加数据库同名文档标签即可把文档添加到标签同名数据库中(文档标签这里指文档头部的添加标签)。 // 0.0.3 增加可删除数据库引用文本中的标签名选项isShowTagNameInAvCell // 0.0.4 改进当标签在列表中时数据库插入列表项 // 根据qiancang大佬的帖子实现 https://ld246.com/article/1731945645865 (()=>{ // 添加tag后多少毫秒添加当前块到数据库 // 不宜设置过小,过小可能导致标签被插入一半 const delay = 500; // 是否开启文档标签插入同名数据库(文档标签这里指文档头部的添加标签),true开启,false不开启 const enableDocTagToAv = true; // 是否在数据库列表中显示标签名(数据库名),true显示,false不显示(注意,文档块引用不会添加标签名,实现较麻烦暂不支持) const isShowTagNameInAvCell = true; // 发布服务立即返回 if(siyuan.config.readonly) return; // 监听tag输入 observeTagSpans(async (tagEl, tagType) => { // 如果未开启文档标签插入同名数据库,当为文档标签时返回 if(!enableDocTagToAv && tagType === 'doc-tag') return; // 去掉零宽度字符&ZeroWithSpace; const tag = tagEl?.textContent?.replace(/[\u200B-\u200D\uFEFF]/g, '')?.trim(); if(!tag) return; // 获取数据库信息 const av = await getAvByName(tag); if(!av) return; const avId = av.avID; if(!avId) return; const avBlockID = av.blockID; if(!avBlockID) return; // 获取文档块信息 let block; if(tagType === 'doc-tag') { // 如果头部标签,返回文档id const blockParent = tagEl.closest('div.protyle-top'); if(!blockParent) return; block = blockParent.querySelector('.protyle-title'); } else { // 如果块标签,返回块id(监听元素的临时块) block = tagEl.closest('div[data-node-id][data-type]'); if(!block) return; // 获取文档中的block结点 block = document.querySelector('div[data-node-id="'+(block?.dataset?.nodeId||'')+'"]'); if(!block) return; // 判断是否在列表元素内,数据库插入列表项 const listItemNode = block.closest('div[data-node-id][data-type="NodeListItem"]'); if(listItemNode) block = listItemNode; } const blockId = block?.dataset?.nodeId; if(!blockId) return; // 添加块到数据库 await sleep(delay || 500); addBlocksToAv(blockId, avId, avBlockID); }); // 如果不在数据库中显示标签名则删除标签名(注意,文档块引用不会添加标签名,实现较麻烦暂不支持) if(!isShowTagNameInAvCell) { observeElementCreation( document.body, '.av__row:not(.av__row--header) [data-dtype="block"] [data-type="block-ref"]', async ref => { if(!/\s?#.*?#/i.test(ref.textContent)) return; ref.textContent = ref.textContent.replace(/\s?#.*?#/ig, ''); } ); } // 插入块到数据库 async function addBlocksToAv(blockIds, avId, avBlockID) { blockIds = typeof blockIds === 'string' ? [blockIds] : blockIds; const srcs = blockIds.map(blockId => ({ "id": blockId, "isDetached": false, })); const input = { "avID": avId, "blockID": avBlockID, 'srcs': srcs } const result = await fetchSyncPost('/api/av/addAttributeViewBlocks', input); if(!result || result.code !== 0) console.error(result); } // 通过该tag查询数据库 async function getAvByName(name) { const result = await fetchSyncPost('/api/av/searchAttributeView', { "keyword": name }); if(!result || result.code !== 0 || !result?.data?.results || result?.data?.results?.length === 0) return null; for (const av of result.data.results) { if (av.avName === name || av.avName === `#${name}#`) { return av; } } return null; } // 请求api // returnType json返回json格式,text返回文本格式 async function fetchSyncPost(url, data, returnType = 'json') { const init = { method: "POST", }; if (data) { if (data instanceof FormData) { init.body = data; } else { init.body = JSON.stringify(data); } } try { const res = await fetch(url, init); const res2 = returnType === 'json' ? await res.json() : await res.text(); return res2; } catch(e) { console.log(e); return returnType === 'json' ? {code:e.code||1, msg: e.message||"", data: null} : ""; } } // 延迟执行 function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } // 监听tag被添加 function observeTagSpans(callback) { // 创建一个观察者实例并传入回调函数 const observer = new MutationObserver((mutationsList, observer) => { for (const mutation of mutationsList) { if (mutation.type === 'childList') { // 检查新增的节点 for (const node of mutation.addedNodes) { if (node.nodeType === Node.ELEMENT_NODE && node.tagName.toLowerCase() === 'span' && node.getAttribute('data-type') === 'tag') { // 块标签调用回调函数 callback(node, 'block-tag'); } else if(node.nodeType === Node.ELEMENT_NODE && node.tagName.toLowerCase() === 'div' && node.classList?.contains('b3-chip') && node.getAttribute('data-type') === 'open-search') { // 文档头部标签调用回调函数 callback(node, 'doc-tag'); } } } } }); // 配置观察选项: const config = { childList: true, // 观察子节点的变化(添加/删除) subtree: true // 观察所有后代节点 }; // 选择需要观察变动的节点 const targetNode = document.body; // 或者选择更具体的父节点以减少性能消耗 // 开始观察目标节点 observer.observe(targetNode, config); // 返回一个取消观察的方法 return () => observer.disconnect(); } // 监听元素被创建 function observeElementCreation(parentNode, selector, onElementCreated) { // 配置观察器选项 const config = { childList: true, // 观察直接子节点的添加和移除 subtree: true // 观察所有后代节点 }; // 当检测到变动时执行的回调函数 const callback = function(mutationsList, observer) { for (let mutation of mutationsList) { if (mutation.type === 'childList') { mutation.addedNodes.forEach(node => { if (node.nodeType === Node.ELEMENT_NODE) { // 使用 querySelectorAll 查找所有符合条件的新元素 const elements = node.querySelectorAll(selector); elements.forEach(element => { onElementCreated(element); // 调用外部提供的回调函数 }); } }); } } }; // 创建一个观察器实例并传入回调函数 const observer = new MutationObserver(callback); // 开始观察目标节点 observer.observe(parentNode, config); // 返回一个函数来停止观察 return () => observer.disconnect(); } })();
  • 代码片段

    代码片段分为 CSS 与 JS 两种代码,添加在 [设置 - 外观 - 代码片段] 中,这些代码会在思源笔记加载时自动执行,用于改善笔记的样式或功能。

    用户在该标签下分享代码片段时需在帖子标题前添加 [css] [js] 用于区分代码片段类型。

    135 引用 • 904 回帖
  • 思源笔记

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

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

    24939 引用 • 102734 回帖
1 操作
TangQi 在 2024-11-26 17:38:35 更新了该帖

相关帖子

欢迎来到这里!

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

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

推荐标签 标签

  • Follow
    4 引用 • 12 回帖 • 11 关注
  • 反馈

    Communication channel for makers and users.

    126 引用 • 930 回帖 • 270 关注
  • PHP

    PHP(Hypertext Preprocessor)是一种开源脚本语言。语法吸收了 C 语言、 Java 和 Perl 的特点,主要适用于 Web 开发领域,据说是世界上最好的编程语言。

    179 引用 • 408 回帖 • 486 关注
  • 微服务

    微服务架构是一种架构模式,它提倡将单一应用划分成一组小的服务。服务之间互相协调,互相配合,为用户提供最终价值。每个服务运行在独立的进程中。服务于服务之间才用轻量级的通信机制互相沟通。每个服务都围绕着具体业务构建,能够被独立的部署。

    96 引用 • 155 回帖
  • 友情链接

    确认过眼神后的灵魂连接,站在链在!

    24 引用 • 373 回帖
  • Bootstrap

    Bootstrap 是 Twitter 推出的一个用于前端开发的开源工具包。它由 Twitter 的设计师 Mark Otto 和 Jacob Thornton 合作开发,是一个 CSS / HTML 框架。

    18 引用 • 33 回帖 • 650 关注
  • Outlook
    1 引用 • 5 回帖 • 1 关注
  • OAuth

    OAuth 协议为用户资源的授权提供了一个安全的、开放而又简易的标准。与以往的授权方式不同之处是 oAuth 的授权不会使第三方触及到用户的帐号信息(如用户名与密码),即第三方无需使用用户的用户名与密码就可以申请获得该用户资源的授权,因此 oAuth 是安全的。oAuth 是 Open Authorization 的简写。

    36 引用 • 103 回帖 • 30 关注
  • OkHttp

    OkHttp 是一款 HTTP & HTTP/2 客户端库,专为 Android 和 Java 应用打造。

    16 引用 • 6 回帖 • 83 关注
  • SMTP

    SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式。SMTP 协议属于 TCP/IP 协议簇,它帮助每台计算机在发送或中转信件时找到下一个目的地。

    4 引用 • 18 回帖 • 637 关注
  • Chrome

    Chrome 又称 Google 浏览器,是一个由谷歌公司开发的网页浏览器。该浏览器是基于其他开源软件所编写,包括 WebKit,目标是提升稳定性、速度和安全性,并创造出简单且有效率的使用者界面。

    62 引用 • 289 回帖
  • 微软

    微软是一家美国跨国科技公司,也是世界 PC 软件开发的先导,由比尔·盖茨与保罗·艾伦创办于 1975 年,公司总部设立在华盛顿州的雷德蒙德(Redmond,邻近西雅图)。以研发、制造、授权和提供广泛的电脑软件服务业务为主。

    8 引用 • 44 回帖
  • Git

    Git 是 Linux Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。

    211 引用 • 358 回帖
  • 深度学习

    深度学习(Deep Learning)是机器学习的分支,是一种试图使用包含复杂结构或由多重非线性变换构成的多个处理层对数据进行高层抽象的算法。

    53 引用 • 40 回帖
  • 倾城之链
    23 引用 • 66 回帖 • 162 关注
  • Ngui

    Ngui 是一个 GUI 的排版显示引擎和跨平台的 GUI 应用程序开发框架,基于
    Node.js / OpenGL。目标是在此基础上开发 GUI 应用程序可拥有开发 WEB 应用般简单与速度同时兼顾 Native 应用程序的性能与体验。

    7 引用 • 9 回帖 • 400 关注
  • Firefox

    Mozilla Firefox 中文俗称“火狐”(正式缩写为 Fx 或 fx,非正式缩写为 FF),是一个开源的网页浏览器,使用 Gecko 排版引擎,支持多种操作系统,如 Windows、OSX 及 Linux 等。

    7 引用 • 30 回帖 • 391 关注
  • abitmean

    有点意思就行了

    32 关注
  • 知乎

    知乎是网络问答社区,连接各行各业的用户。用户分享着彼此的知识、经验和见解,为中文互联网源源不断地提供多种多样的信息。

    10 引用 • 66 回帖 • 1 关注
  • 又拍云

    又拍云是国内领先的 CDN 服务提供商,国家工信部认证通过的“可信云”,乌云众测平台认证的“安全云”,为移动时代的创业者提供新一代的 CDN 加速服务。

    20 引用 • 37 回帖 • 573 关注
  • BND

    BND(Baidu Netdisk Downloader)是一款图形界面的百度网盘不限速下载器,支持 Windows、Linux 和 Mac,详细介绍请看这里

    107 引用 • 1281 回帖 • 35 关注
  • 导航

    各种网址链接、内容导航。

    43 引用 • 177 回帖
  • Mac

    Mac 是苹果公司自 1984 年起以“Macintosh”开始开发的个人消费型计算机,如:iMac、Mac mini、Macbook Air、Macbook Pro、Macbook、Mac Pro 等计算机。

    169 引用 • 595 回帖
  • 自由行
    2 关注
  • 百度

    百度(Nasdaq:BIDU)是全球最大的中文搜索引擎、最大的中文网站。2000 年 1 月由李彦宏创立于北京中关村,致力于向人们提供“简单,可依赖”的信息获取方式。“百度”二字源于中国宋朝词人辛弃疾的《青玉案·元夕》词句“众里寻他千百度”,象征着百度对中文信息检索技术的执著追求。

    63 引用 • 785 回帖 • 108 关注
  • FFmpeg

    FFmpeg 是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。

    23 引用 • 32 回帖 • 1 关注
  • TextBundle

    TextBundle 文件格式旨在应用程序之间交换 Markdown 或 Fountain 之类的纯文本文件时,提供更无缝的用户体验。

    1 引用 • 2 回帖 • 79 关注