求助实现多个块的快速合并及折叠

求助一个 quicker 动作、思源按钮或快捷键,手动选中思源笔记的连续多个块时,点击思源按钮或 quicker 动作,实现以下功能:

  1. 将选中的多个块转换成引述或超级块。
  2. 将这个整体的引述或超级块折叠。
  • 思源笔记

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

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

    22338 引用 • 89382 回帖
  • Q&A

    提问之前请先看《提问的智慧》,好的问题比好的答案更有价值。

    8112 引用 • 37002 回帖 • 160 关注

相关帖子

被采纳的回答
  • 选中后 ctrl+q 触发, 触发后会将选中的内容转换成引用, 过程中会有点卡顿, 因为不知道为啥, 延时低了就会报错, 所以只能先让 sleep 时间长一点

    触发前, image.png, 触发后, image.png

    (()=>{
    // 延迟执行
    function sleep(ms) {
      return new Promise(resolve => setTimeout(resolve, ms));
    }
    function press_once(keyInit, selector = null) {
      keyInit["bubbles"] = true;
      if (selector == null) {
        selector = document.querySelector('[data-type="wnd"].layout__wnd--active .protyle:not(.fn__none) .protyle-wysiwyg.protyle-wysiwyg--attr')
      }
      else if (typeof selector === 'function') {
        selector = selector()
      }
      else if (typeof selector === 'string') {
        selector = document.querySelector(selector)
      }
      if (!selector) return
      selector.dispatchEvent(new KeyboardEvent('keydown', keyInit));
      selector.dispatchEvent(new KeyboardEvent('keyup', keyInit));
    }
    async function add_new_line_before() {
      press_once({
        key: 'Enter',
        ctrlKey: true,
        shiftKey: true,
        keyCode: 13, // 不推荐使用,但某些情况下需要
      });
    }
    function click_right(ele) {
      // 创建一个右键点击的 MouseEvent
      const rightClickEvent = new MouseEvent('contextmenu', {
        bubbles: true,
        cancelable: true,
        view: window,
        button: 2 
      });
      ele.dispatchEvent(rightClickEvent);
    }
    
    
    // 获取光标所在的元素
    function getElementAtCursor() {
      const selection = window.getSelection();
    
      if (selection.rangeCount > 0) {
        const range = selection.getRangeAt(0);
        const startContainer = range.startContainer;
        // 如果是文本节点,获取其父元素
        const element = startContainer.nodeType === 3 ? startContainer.parentNode : startContainer;
        return element;
      }
    
      return null; // 如果没有选中内容或光标位置无效
    }
    
    // 获取当前选中的文本
    async function get_selected_data() {
      // 触发 ctrl+c, 复制选中的块
      document.execCommand('copy');
      // 获取剪贴板文本
      return await navigator.clipboard.readText();
    }
    // 设置文本
    async function paste_data(data) {
      // 将处理后的文本复制到剪贴板
      await navigator.clipboard.writeText(data);
      // 触发 ctrl+v, 粘贴处理后的内容
      document.execCommand('paste');
      await sleep(20)
    }
    
    // 清空选中的内容: 先剪切, 再增加空行
    async function clear_selected_data() {
      // 触发 ctrl+x, 剪切选中的块, 目的是删除原有内容
      document.execCommand('cut');
      await add_new_line_before()
    }
    
    // 转换引用 - 使用系统自带的转换功能 
    function convert_quote_from_sys(event) {
      click_right(event.target)
      // 创建 mouseover 事件
      const mouseOverEvent = new MouseEvent('mouseover', {
        view: window,
        bubbles: true,
        cancelable: true,
      });
      let turn_ele = document.querySelector('.b3-menu__items>[data-id="turnInto"]')
      turn_ele?.dispatchEvent(mouseOverEvent);
      turn_ele = turn_ele?.querySelector('.b3-menu__submenu>.b3-menu__items>[data-id="quote"]')
      if (!turn_ele) return false
      turn_ele.click()
      return true
    }
    // 转换引用 - 使用自己实现的的转换功能
    async function convert_quote_from_my(clipboardText) {
      // 删除原有内容, 并增加空行
      await clear_selected_data()
      let clipboardTextRet = clipboardText
        .split('\n')
        .map(line => "> " + line)
        .join('\n')
      // 粘贴处理后的文本
      await paste_data(clipboardTextRet);
    }
    async function fold_block() {
      await sleep(300);
      let ele = getElementAtCursor();
      if (!ele) return
      while (!ele.parentNode.classList.contains("protyle-wysiwyg--attr") && ele.getAttribute('data-type') != 'NodeBlockquote') {
        ele = ele.parentNode
      }
      click_right(ele)
      await sleep(300)
      document.querySelector('.b3-menu__items>[data-id="fold"]')?.click()
    }
    
    // 合并选中的块
    async function handle_merge(event) {
      // 获取当前选中的文本
      let clipboardText = await get_selected_data();
      // 如果不需要处理, 则直接返回
      if (clipboardText == "") {
        console.log("不需要处理")
        return;
      }
      
      if (convert_quote_from_sys(event)) {
        console.log("系统转换成功")
      }
      else {
        await convert_quote_from_my(clipboardText)
        console.log("自定义转换成功")
      }
      await fold_block();
    }
    
    // 事件监听
    document.addEventListener('keydown', async (event) => {
      // 检查是否按下了 Ctrl + q
      if (event.ctrlKey && event.key === 'q') {
        // event.preventDefault(); // 防止快捷键默认行为
        await handle_merge(event);
      }
    });
    })()
    
    

欢迎来到这里!

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

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

    可用,非常感谢!

  • 其他回帖
  • 引述、超级块、折叠

    image.png

    image.png

    image.png

    1 回复
  • EmberSky

    选中后 ctrl+q 触发, 触发后会将选中的内容转换成引用, 过程中会有点卡顿, 因为不知道为啥, 延时低了就会报错, 所以只能先让 sleep 时间长一点

    触发前, image.png, 触发后, image.png

    (()=>{
    // 延迟执行
    function sleep(ms) {
      return new Promise(resolve => setTimeout(resolve, ms));
    }
    function press_once(keyInit, selector = null) {
      keyInit["bubbles"] = true;
      if (selector == null) {
        selector = document.querySelector('[data-type="wnd"].layout__wnd--active .protyle:not(.fn__none) .protyle-wysiwyg.protyle-wysiwyg--attr')
      }
      else if (typeof selector === 'function') {
        selector = selector()
      }
      else if (typeof selector === 'string') {
        selector = document.querySelector(selector)
      }
      if (!selector) return
      selector.dispatchEvent(new KeyboardEvent('keydown', keyInit));
      selector.dispatchEvent(new KeyboardEvent('keyup', keyInit));
    }
    async function add_new_line_before() {
      press_once({
        key: 'Enter',
        ctrlKey: true,
        shiftKey: true,
        keyCode: 13, // 不推荐使用,但某些情况下需要
      });
    }
    function click_right(ele) {
      // 创建一个右键点击的 MouseEvent
      const rightClickEvent = new MouseEvent('contextmenu', {
        bubbles: true,
        cancelable: true,
        view: window,
        button: 2 
      });
      ele.dispatchEvent(rightClickEvent);
    }
    
    
    // 获取光标所在的元素
    function getElementAtCursor() {
      const selection = window.getSelection();
    
      if (selection.rangeCount > 0) {
        const range = selection.getRangeAt(0);
        const startContainer = range.startContainer;
        // 如果是文本节点,获取其父元素
        const element = startContainer.nodeType === 3 ? startContainer.parentNode : startContainer;
        return element;
      }
    
      return null; // 如果没有选中内容或光标位置无效
    }
    
    // 获取当前选中的文本
    async function get_selected_data() {
      // 触发 ctrl+c, 复制选中的块
      document.execCommand('copy');
      // 获取剪贴板文本
      return await navigator.clipboard.readText();
    }
    // 设置文本
    async function paste_data(data) {
      // 将处理后的文本复制到剪贴板
      await navigator.clipboard.writeText(data);
      // 触发 ctrl+v, 粘贴处理后的内容
      document.execCommand('paste');
      await sleep(20)
    }
    
    // 清空选中的内容: 先剪切, 再增加空行
    async function clear_selected_data() {
      // 触发 ctrl+x, 剪切选中的块, 目的是删除原有内容
      document.execCommand('cut');
      await add_new_line_before()
    }
    
    // 转换引用 - 使用系统自带的转换功能 
    function convert_quote_from_sys(event) {
      click_right(event.target)
      // 创建 mouseover 事件
      const mouseOverEvent = new MouseEvent('mouseover', {
        view: window,
        bubbles: true,
        cancelable: true,
      });
      let turn_ele = document.querySelector('.b3-menu__items>[data-id="turnInto"]')
      turn_ele?.dispatchEvent(mouseOverEvent);
      turn_ele = turn_ele?.querySelector('.b3-menu__submenu>.b3-menu__items>[data-id="quote"]')
      if (!turn_ele) return false
      turn_ele.click()
      return true
    }
    // 转换引用 - 使用自己实现的的转换功能
    async function convert_quote_from_my(clipboardText) {
      // 删除原有内容, 并增加空行
      await clear_selected_data()
      let clipboardTextRet = clipboardText
        .split('\n')
        .map(line => "> " + line)
        .join('\n')
      // 粘贴处理后的文本
      await paste_data(clipboardTextRet);
    }
    async function fold_block() {
      await sleep(300);
      let ele = getElementAtCursor();
      if (!ele) return
      while (!ele.parentNode.classList.contains("protyle-wysiwyg--attr") && ele.getAttribute('data-type') != 'NodeBlockquote') {
        ele = ele.parentNode
      }
      click_right(ele)
      await sleep(300)
      document.querySelector('.b3-menu__items>[data-id="fold"]')?.click()
    }
    
    // 合并选中的块
    async function handle_merge(event) {
      // 获取当前选中的文本
      let clipboardText = await get_selected_data();
      // 如果不需要处理, 则直接返回
      if (clipboardText == "") {
        console.log("不需要处理")
        return;
      }
      
      if (convert_quote_from_sys(event)) {
        console.log("系统转换成功")
      }
      else {
        await convert_quote_from_my(clipboardText)
        console.log("自定义转换成功")
      }
      await fold_block();
    }
    
    // 事件监听
    document.addEventListener('keydown', async (event) => {
      // 检查是否按下了 Ctrl + q
      if (event.ctrlKey && event.key === 'q') {
        // event.preventDefault(); // 防止快捷键默认行为
        await handle_merge(event);
      }
    });
    })()
    
    
    1 回复
  • wenbocn

    或选中多个块后,中键任意一个块的块标,能够实现组合这些块并折叠,那就更好了
    [js] 鼠标中键折叠块 - 链滴

  • 查看全部回帖

推荐标签 标签

  • 黑曜石

    黑曜石是一款强大的知识库工具,支持本地 Markdown 文件编辑,支持双向链接和关系图。

    A second brain, for you, forever.

    15 引用 • 122 回帖
  • Hadoop

    Hadoop 是由 Apache 基金会所开发的一个分布式系统基础架构。用户可以在不了解分布式底层细节的情况下,开发分布式程序。充分利用集群的威力进行高速运算和存储。

    86 引用 • 122 回帖 • 625 关注
  • OpenStack

    OpenStack 是一个云操作系统,通过数据中心可控制大型的计算、存储、网络等资源池。所有的管理通过前端界面管理员就可以完成,同样也可以通过 Web 接口让最终用户部署资源。

    10 引用 • 4 关注
  • DevOps

    DevOps(Development 和 Operations 的组合词)是一组过程、方法与系统的统称,用于促进开发(应用程序/软件工程)、技术运营和质量保障(QA)部门之间的沟通、协作与整合。

    47 引用 • 25 回帖
  • RYMCU

    RYMCU 致力于打造一个即严谨又活泼、专业又不失有趣,为数百万人服务的开源嵌入式知识学习交流平台。

    4 引用 • 6 回帖 • 51 关注
  • CSS

    CSS(Cascading Style Sheet)“层叠样式表”是用于控制网页样式并允许将样式信息与网页内容分离的一种标记性语言。

    198 引用 • 550 回帖
  • PWA

    PWA(Progressive Web App)是 Google 在 2015 年提出、2016 年 6 月开始推广的项目。它结合了一系列现代 Web 技术,在网页应用中实现和原生应用相近的用户体验。

    14 引用 • 69 回帖 • 154 关注
  • Oracle

    Oracle(甲骨文)公司,全称甲骨文股份有限公司(甲骨文软件系统有限公司),是全球最大的企业级软件公司,总部位于美国加利福尼亚州的红木滩。1989 年正式进入中国市场。2013 年,甲骨文已超越 IBM,成为继 Microsoft 后全球第二大软件公司。

    105 引用 • 127 回帖 • 382 关注
  • CSDN

    CSDN (Chinese Software Developer Network) 创立于 1999 年,是中国的 IT 社区和服务平台,为中国的软件开发者和 IT 从业者提供知识传播、职业发展、软件开发等全生命周期服务,满足他们在职业发展中学习及共享知识和信息、建立职业发展社交圈、通过软件开发实现技术商业化等刚性需求。

    14 引用 • 155 回帖
  • 运维

    互联网运维工作,以服务为中心,以稳定、安全、高效为三个基本点,确保公司的互联网业务能够 7×24 小时为用户提供高质量的服务。

    149 引用 • 257 回帖
  • Swift

    Swift 是苹果于 2014 年 WWDC(苹果开发者大会)发布的开发语言,可与 Objective-C 共同运行于 Mac OS 和 iOS 平台,用于搭建基于苹果平台的应用程序。

    36 引用 • 37 回帖 • 529 关注
  • 以太坊

    以太坊(Ethereum)并不是一个机构,而是一款能够在区块链上实现智能合约、开源的底层系统。以太坊是一个平台和一种编程语言 Solidity,使开发人员能够建立和发布下一代去中心化应用。 以太坊可以用来编程、分散、担保和交易任何事物:投票、域名、金融交易所、众筹、公司管理、合同和知识产权等等。

    34 引用 • 367 回帖
  • Ant-Design

    Ant Design 是服务于企业级产品的设计体系,基于确定和自然的设计价值观上的模块化解决方案,让设计者和开发者专注于更好的用户体验。

    17 引用 • 23 回帖
  • Google

    Google(Google Inc.,NASDAQ:GOOG)是一家美国上市公司(公有股份公司),于 1998 年 9 月 7 日以私有股份公司的形式创立,设计并管理一个互联网搜索引擎。Google 公司的总部称作“Googleplex”,它位于加利福尼亚山景城。Google 目前被公认为是全球规模最大的搜索引擎,它提供了简单易用的免费服务。不作恶(Don't be evil)是谷歌公司的一项非正式的公司口号。

    49 引用 • 192 回帖 • 1 关注
  • BND

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

    107 引用 • 1281 回帖 • 27 关注
  • 招聘

    哪里都缺人,哪里都不缺人。

    190 引用 • 1057 回帖
  • Gitea

    Gitea 是一个开源社区驱动的轻量级代码托管解决方案,后端采用 Go 编写,采用 MIT 许可证。

    4 引用 • 16 回帖 • 5 关注
  • iOS

    iOS 是由苹果公司开发的移动操作系统,最早于 2007 年 1 月 9 日的 Macworld 大会上公布这个系统,最初是设计给 iPhone 使用的,后来陆续套用到 iPod touch、iPad 以及 Apple TV 等产品上。iOS 与苹果的 Mac OS X 操作系统一样,属于类 Unix 的商业操作系统。

    85 引用 • 139 回帖 • 1 关注
  • 安全

    安全永远都不是一个小问题。

    199 引用 • 816 回帖 • 1 关注
  • Flume

    Flume 是一套分布式的、可靠的,可用于有效地收集、聚合和搬运大量日志数据的服务架构。

    9 引用 • 6 回帖 • 629 关注
  • Typecho

    Typecho 是一款博客程序,它在 GPLv2 许可证下发行,基于 PHP 构建,可以运行在各种平台上,支持多种数据库(MySQL、PostgreSQL、SQLite)。

    12 引用 • 65 回帖 • 437 关注
  • 代码片段

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

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

    69 引用 • 372 回帖
  • IDEA

    IDEA 全称 IntelliJ IDEA,是一款 Java 语言开发的集成环境,在业界被公认为最好的 Java 开发工具之一。IDEA 是 JetBrains 公司的产品,这家公司总部位于捷克共和国的首都布拉格,开发人员以严谨著称的东欧程序员为主。

    180 引用 • 400 回帖
  • Sym

    Sym 是一款用 Java 实现的现代化社区(论坛/BBS/社交网络/博客)系统平台。

    下一代的社区系统,为未来而构建

    524 引用 • 4601 回帖 • 700 关注
  • Node.js

    Node.js 是一个基于 Chrome JavaScript 运行时建立的平台, 用于方便地搭建响应速度快、易于扩展的网络应用。Node.js 使用事件驱动, 非阻塞 I/O 模型而得以轻量和高效。

    139 引用 • 269 回帖 • 43 关注
  • Latke

    Latke 是一款以 JSON 为主的 Java Web 框架。

    71 引用 • 535 回帖 • 787 关注
  • Android

    Android 是一种以 Linux 为基础的开放源码操作系统,主要使用于便携设备。2005 年由 Google 收购注资,并拉拢多家制造商组成开放手机联盟开发改良,逐渐扩展到到平板电脑及其他领域上。

    334 引用 • 323 回帖