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

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

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

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

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

    22290 引用 • 89154 回帖 • 1 关注
  • Q&A

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

    8090 引用 • 36934 回帖 • 160 关注

相关帖子

被采纳的回答
  • 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);
      }
    });
    })()
    
    

欢迎来到这里!

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

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

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

  • 引述、超级块、折叠

    image.png

    image.png

    image.png

    1 回复
  • wenbocn

    折叠快捷键,只能折叠一个块。只能折叠引述里面光标所在的单个块

  • 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

    可用,非常感谢!

推荐标签 标签

  • Unity

    Unity 是由 Unity Technologies 开发的一个让开发者可以轻松创建诸如 2D、3D 多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

    25 引用 • 7 回帖 • 174 关注
  • TensorFlow

    TensorFlow 是一个采用数据流图(data flow graphs),用于数值计算的开源软件库。节点(Nodes)在图中表示数学操作,图中的线(edges)则表示在节点间相互联系的多维数据数组,即张量(tensor)。

    20 引用 • 19 回帖
  • 博客

    记录并分享人生的经历。

    273 引用 • 2388 回帖
  • Kotlin

    Kotlin 是一种在 Java 虚拟机上运行的静态类型编程语言,由 JetBrains 设计开发并开源。Kotlin 可以编译成 Java 字节码,也可以编译成 JavaScript,方便在没有 JVM 的设备上运行。在 Google I/O 2017 中,Google 宣布 Kotlin 成为 Android 官方开发语言。

    19 引用 • 33 回帖 • 61 关注
  • ngrok

    ngrok 是一个反向代理,通过在公共的端点和本地运行的 Web 服务器之间建立一个安全的通道。

    7 引用 • 63 回帖 • 625 关注
  • 反馈

    Communication channel for makers and users.

    123 引用 • 911 回帖 • 245 关注
  • Laravel

    Laravel 是一套简洁、优雅的 PHP Web 开发框架。它采用 MVC 设计,是一款崇尚开发效率的全栈框架。

    20 引用 • 23 回帖 • 720 关注
  • Linux

    Linux 是一套免费使用和自由传播的类 Unix 操作系统,是一个基于 POSIX 和 Unix 的多用户、多任务、支持多线程和多 CPU 的操作系统。它能运行主要的 Unix 工具软件、应用程序和网络协议,并支持 32 位和 64 位硬件。Linux 继承了 Unix 以网络为核心的设计思想,是一个性能稳定的多用户网络操作系统。

    943 引用 • 943 回帖
  • 七牛云

    七牛云是国内领先的企业级公有云服务商,致力于打造以数据为核心的场景化 PaaS 服务。围绕富媒体场景,七牛先后推出了对象存储,融合 CDN 加速,数据通用处理,内容反垃圾服务,以及直播云服务等。

    27 引用 • 225 回帖 • 172 关注
  • 服务器

    服务器,也称伺服器,是提供计算服务的设备。由于服务器需要响应服务请求,并进行处理,因此一般来说服务器应具备承担服务并且保障服务的能力。

    125 引用 • 588 回帖 • 1 关注
  • WebComponents

    Web Components 是 W3C 定义的标准,它给了前端开发者扩展浏览器标签的能力,可以方便地定制可复用组件,更好的进行模块化开发,解放了前端开发者的生产力。

    1 引用
  • Windows

    Microsoft Windows 是美国微软公司研发的一套操作系统,它问世于 1985 年,起初仅仅是 Microsoft-DOS 模拟环境,后续的系统版本由于微软不断的更新升级,不但易用,也慢慢的成为家家户户人们最喜爱的操作系统。

    222 引用 • 473 回帖 • 1 关注
  • CongSec

    本标签主要用于分享网络空间安全专业的学习笔记

    1 引用 • 1 回帖 • 6 关注
  • uTools

    uTools 是一个极简、插件化、跨平台的现代桌面软件。通过自由选配丰富的插件,打造你得心应手的工具集合。

    6 引用 • 14 回帖
  • ZeroNet

    ZeroNet 是一个基于比特币加密技术和 BT 网络技术的去中心化的、开放开源的网络和交流系统。

    1 引用 • 21 回帖 • 638 关注
  • WiFiDog

    WiFiDog 是一套开源的无线热点认证管理工具,主要功能包括:位置相关的内容递送;用户认证和授权;集中式网络监控。

    1 引用 • 7 回帖 • 585 关注
  • PHP

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

    179 引用 • 407 回帖 • 487 关注
  • Eclipse

    Eclipse 是一个开放源代码的、基于 Java 的可扩展开发平台。就其本身而言,它只是一个框架和一组服务,用于通过插件组件构建开发环境。

    75 引用 • 258 回帖 • 616 关注
  • GitLab

    GitLab 是利用 Ruby 一个开源的版本管理系统,实现一个自托管的 Git 项目仓库,可通过 Web 界面操作公开或私有项目。

    46 引用 • 72 回帖 • 2 关注
  • HTML

    HTML5 是 HTML 下一个的主要修订版本,现在仍处于发展阶段。广义论及 HTML5 时,实际指的是包括 HTML、CSS 和 JavaScript 在内的一套技术组合。

    107 引用 • 295 回帖
  • 黑曜石

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

    A second brain, for you, forever.

    15 引用 • 122 回帖 • 1 关注
  • WebClipper

    Web Clipper 是一款浏览器剪藏扩展,它可以帮助你把网页内容剪藏到本地。

    3 引用 • 9 回帖
  • MyBatis

    MyBatis 本是 Apache 软件基金会 的一个开源项目 iBatis,2010 年这个项目由 Apache 软件基金会迁移到了 google code,并且改名为 MyBatis ,2013 年 11 月再次迁移到了 GitHub。

    170 引用 • 414 回帖 • 388 关注
  • 电影

    这是一个不能说的秘密。

    120 引用 • 599 回帖
  • 创业

    你比 99% 的人都优秀么?

    84 引用 • 1399 回帖 • 2 关注
  • Electron

    Electron 基于 Chromium 和 Node.js,让你可以使用 HTML、CSS 和 JavaScript 构建应用。它是一个由 GitHub 及众多贡献者组成的活跃社区共同维护的开源项目,兼容 Mac、Windows 和 Linux,它构建的应用可在这三个操作系统上面运行。

    15 引用 • 136 回帖 • 1 关注
  • Maven

    Maven 是基于项目对象模型(POM)、通过一小段描述信息来管理项目的构建、报告和文档的软件项目管理工具。

    186 引用 • 318 回帖 • 304 关注