绿皮科技编辑器式反链,慎用

本贴最后更新于 1031 天前,其中的信息可能已经时过境迁

通过 hack 的方式实现卡片式超链接 - 链滴 (ld246.com)类似的方式往嵌入块和反链挂 shadowDOM 可以实现绿皮版的编辑器式反链,不过这种就更蛋疼了,对机器性能不是很有信心的话就别尝试了,而且效果也不大好,类似这样

image.png

反正就是嵌入块和反向链接面板能够直接编辑笔记内容了。

代码大概这样,原理跟上面那个差不多,不过因为都是 iframe 插入的移动端界面比较吃性能, 加了个可见性判断,不可见的时候就不加载它了,一样的,试思路的产品, 要实际用的话最好改改哈:

import { DOM监听器 } from "/script/public/DOMwatcher.js"; const hideElements = (panels, protyle) => { if (!protyle) { if (panels.includes("dialog")) { for (let i = 0; i < window.siyuan.dialogs.length; i++) { if (window.siyuan.dialogs[i].destroy()) { i--; } } } return; } if (panels.includes("hint")) { clearTimeout(protyle.hint.timeId); protyle.hint.element.classList.add("fn__none"); } if (protyle.gutter && panels.includes("gutter")) { protyle.gutter.element.classList.add("fn__none"); protyle.gutter.element.innerHTML = ""; // https://ld246.com/article/1651935412480 protyle.wysiwyg.element .querySelectorAll(".protyle-wysiwyg--hl") .forEach((item) => { item.classList.remove("protyle-wysiwyg--hl"); }); } if (protyle.toolbar && panels.includes("toolbar")) { protyle.toolbar.element.classList.add("fn__none"); } if (protyle.toolbar && panels.includes("util")) { const pinElement = protyle.toolbar.subElement.querySelector('[data-type="pin"]'); if ( !pinElement || (pinElement && !pinElement.classList.contains("ft__primary")) ) { protyle.toolbar.subElement.classList.add("fn__none"); } } if (panels.includes("select")) { protyle.wysiwyg.element .querySelectorAll(".protyle-wysiwyg--select") .forEach((item) => { item.classList.remove("protyle-wysiwyg--select"); }); } }; const disabledProtyle = (protyle) => { hideElements(["gutter", "toolbar", "select", "hint", "util"], protyle); protyle.disabled = true; protyle.wysiwyg.element.setAttribute("contenteditable", "false"); protyle.wysiwyg.element .querySelectorAll('[contenteditable="true"][spellcheck="false"]') .forEach((item) => { item.setAttribute("contenteditable", "false"); }); }; export class protyleEditor extends naive.plugin { constructor() { super({ name: "protyleEditor" }); window.siyuan.ws.ws.addEventListener("message", () => { this.hackBacklink(); }); document.addEventListener("mouseover", () => { this.hackBacklink(); }); let 监听选项1 = { 监听目标: `[data-node-id]`, 监听器回调: () => this.hackBacklink(), }; this.DOM监听器1 = new DOM监听器(监听选项1); this.hackBacklink(); /*shadowDocument.body.appendChild(editorElement) let styles= document.head.querySelectorAll('style') styles.forEach( style=>{ let shadowStyle=style.cloneNode(true) shadowDocument.head.appendChild(shadowStyle) } ) let links =document.head.querySelectorAll('link') links.forEach( style=>{ let shadowStyle=style.cloneNode(true) shadowDocument.head.appendChild(shadowStyle) if (shadowStyle.getAttribute('href').startsWith('base')){ let href= shadowStyle.getAttribute('href') href ='/stage/build/app/'+href shadowStyle.setAttribute('href',href) } } ) let Protyle =window.siyuan.layout.centerLayout.children[0].children[0].model.editor.__proto__.constructor console.log('protyleEditor',Protyle) new Protyle(editorElement, { blockId: "20201117101902-2ewjjum", hasContext: false, action: ["cb-get-all"], render: { gutter: true, breadcrumbDocName: false, breadcrumbContext: false }, typewriterMode: false, after: (editor) => { if (window.siyuan.config.readonly) { disabledProtyle(editor.protyle); } editorElement.addEventListener("mouseleave", () => { hideElements(["gutter"], editor.protyle); }); } });*/ } async hackBacklink() { let 目标元素组 = document.querySelectorAll( `.backlinkList.fn__flex-1 ul [data-treetype="backlink"] .b3-list-item__text,.backlinkMList.fn__flex-1 ul [data-treetype="backlink"] .b3-list-item__text` ); let 目标元素组1 = document.querySelectorAll( ".protyle-wysiwyg__embed:not(.protyle-wysiwyg__embed .protyle-wysiwyg__embed)" ); this.createEditor(目标元素组); this.createEditor(目标元素组1); //window.requestAnimationFrame(async() => this.hackBacklink()) } createEditor(目标元素组) { this.渲染计数器=0 目标元素组.forEach(async (块元素,i) => setTimeout(() => { if (块元素.parentElement.dataset.type == "NodeDocument") { this.渲染计数器-=1 return; } if (!this.isInViewPort(块元素)) { this.渲染计数器-=1 if(块元素.shadowRoot){ let element = 块元素.shadowRoot.querySelector("iframe"); element.setAttribute('src','') } return; } if(this.渲染计数器>10){ return } this.渲染计数器+=1 if (!块元素.shadowRoot) { 块元素.attachShadow({ mode: "open" }); let editorElement = document.createElement("div"); let element = document.createElement("iframe"); element.classList.add( "block__popover", "block__popover--move", "block__popover--top" ); element.setAttribute("loading", 'lazy'); element.setAttribute("border", 0); element.setAttribute("width", "100%"); element.setAttribute("frameBorder", "none"); element.setAttribute( "src", `/stage/build/mobile/?hideToolBar=true&&id=${ (块元素.dataset && 块元素.dataset.id) || 块元素.previousElementSibling.dataset.id }` ); editorElement.className = "block__edit fn__flex-1 protyle"; 块元素.shadowRoot.appendChild(element); } else { let element = 块元素.shadowRoot.querySelector("iframe"); if ( element && element.getAttribute("src") !== `/stage/build/mobile/?hideToolBar=true&&id=${ (块元素.dataset && 块元素.dataset.id) || 块元素.previousElementSibling.dataset.id }` ) { element.setAttribute( "src", `/stage/build/mobile/?hideToolBar=true&&id=${ (块元素.dataset && 块元素.dataset.id) || 块元素.previousElementSibling.dataset.id }` ); } } }, 10) ); } isInViewPort(element) { const viewWidth = window.innerWidth || document.documentElement.clientWidth; const viewHeight = window.innerHeight || document.documentElement.clientHeight; const { top, right, bottom, left } = element.getBoundingClientRect(); return top >= -100 && left >= -100 && right <= viewWidth+200 && bottom <= viewHeight+200; } } export const environments = ["APP"];
  • 思源笔记

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

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

    26047 引用 • 108127 回帖

相关帖子

欢迎来到这里!

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

注册 关于
请输入回帖内容 ...
  • 对了 源代码还是依赖我自用的 naive 主题的,所以要在别的地方用的话可能需要稍微改改,不过改动应该也不算大

推荐标签 标签

  • RESTful

    一种软件架构设计风格而不是标准,提供了一组设计原则和约束条件,主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。

    30 引用 • 114 回帖
  • GAE

    Google App Engine(GAE)是 Google 管理的数据中心中用于 WEB 应用程序的开发和托管的平台。2008 年 4 月 发布第一个测试版本。目前支持 Python、Java 和 Go 开发部署。全球已有数十万的开发者在其上开发了众多的应用。

    14 引用 • 42 回帖 • 820 关注
  • Ant-Design

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

    17 引用 • 23 回帖 • 4 关注
  • Scala

    Scala 是一门多范式的编程语言,集成面向对象编程和函数式编程的各种特性。

    13 引用 • 11 回帖 • 157 关注
  • 七牛云

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

    29 引用 • 230 回帖 • 123 关注
  • 房星科技

    房星网,我们不和没有钱的程序员谈理想,我们要让程序员又有理想又有钱。我们有雄厚的房地产行业线下资源,遍布昆明全城的 100 家门店、四千地产经纪人是我们坚实的后盾。

    6 引用 • 141 回帖 • 607 关注
  • 数据库

    据说 99% 的性能瓶颈都在数据库。

    345 引用 • 754 回帖
  • 代码片段

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

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

    189 引用 • 1342 回帖 • 1 关注
  • 书籍

    宋真宗赵恒曾经说过:“书中自有黄金屋,书中自有颜如玉。”

    82 引用 • 411 回帖
  • sts
    2 引用 • 2 回帖 • 243 关注
  • Ubuntu

    Ubuntu(友帮拓、优般图、乌班图)是一个以桌面应用为主的 Linux 操作系统,其名称来自非洲南部祖鲁语或豪萨语的“ubuntu”一词,意思是“人性”、“我的存在是因为大家的存在”,是非洲传统的一种价值观,类似华人社会的“仁爱”思想。Ubuntu 的目标在于为一般用户提供一个最新的、同时又相当稳定的主要由自由软件构建而成的操作系统。

    127 引用 • 169 回帖
  • OpenStack

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

    10 引用 • 3 关注
  • JVM

    JVM(Java Virtual Machine)Java 虚拟机是一个微型操作系统,有自己的硬件构架体系,还有相应的指令系统。能够识别 Java 独特的 .class 文件(字节码),能够将这些文件中的信息读取出来,使得 Java 程序只需要生成 Java 虚拟机上的字节码后就能在不同操作系统平台上进行运行。

    180 引用 • 120 回帖 • 3 关注
  • V2EX

    V2EX 是创意工作者们的社区。这里目前汇聚了超过 400,000 名主要来自互联网行业、游戏行业和媒体行业的创意工作者。V2EX 希望能够成为创意工作者们的生活和事业的一部分。

    16 引用 • 236 回帖 • 251 关注
  • Caddy

    Caddy 是一款默认自动启用 HTTPS 的 HTTP/2 Web 服务器。

    10 引用 • 54 回帖 • 180 关注
  • 资讯

    资讯是用户因为及时地获得它并利用它而能够在相对短的时间内给自己带来价值的信息,资讯有时效性和地域性。

    56 引用 • 85 回帖
  • 小说

    小说是以刻画人物形象为中心,通过完整的故事情节和环境描写来反映社会生活的文学体裁。

    32 引用 • 108 回帖
  • ActiveMQ

    ActiveMQ 是 Apache 旗下的一款开源消息总线系统,它完整实现了 JMS 规范,是一个企业级的消息中间件。

    19 引用 • 13 回帖 • 677 关注
  • Gzip

    gzip (GNU zip)是 GNU 自由软件的文件压缩程序。我们在 Linux 中经常会用到后缀为 .gz 的文件,它们就是 Gzip 格式的。现今已经成为互联网上使用非常普遍的一种数据压缩格式,或者说一种文件格式。

    9 引用 • 12 回帖 • 175 关注
  • AWS
    11 引用 • 28 回帖 • 8 关注
  • Eclipse

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

    76 引用 • 258 回帖 • 628 关注
  • Vditor

    Vditor 是一款浏览器端的 Markdown 编辑器,支持所见即所得、即时渲染(类似 Typora)和分屏预览模式。它使用 TypeScript 实现,支持原生 JavaScript、Vue、React 和 Angular。

    371 引用 • 1857 回帖 • 2 关注
  • Sym

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

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

    524 引用 • 4601 回帖 • 710 关注
  • Thymeleaf

    Thymeleaf 是一款用于渲染 XML/XHTML/HTML5 内容的模板引擎。类似 Velocity、 FreeMarker 等,它也可以轻易的与 Spring 等 Web 框架进行集成作为 Web 应用的模板引擎。与其它模板引擎相比,Thymeleaf 最大的特点是能够直接在浏览器中打开并正确显示模板页面,而不需要启动整个 Web 应用。

    11 引用 • 19 回帖 • 395 关注
  • DevOps

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

    59 引用 • 25 回帖
  • uTools

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

    7 引用 • 28 回帖
  • MongoDB

    MongoDB(来自于英文单词“Humongous”,中文含义为“庞大”)是一个基于分布式文件存储的数据库,由 C++ 语言编写。旨在为应用提供可扩展的高性能数据存储解决方案。MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。它支持的数据结构非常松散,是类似 JSON 的 BSON 格式,因此可以存储比较复杂的数据类型。

    91 引用 • 59 回帖 • 4 关注