prosemirror 学习记录(四)decoration

使用 decorations

使用 props - decorations() 添加 decorations

写一个简单的插件:高亮所有 apple 节点

export const MyHighlightApplesPlugin = new Plugin({props: {// view 每次变化都会执行 decorations 方法decorations(state) {let arrs = [];state.doc.descendants((node, pos) => {if (node.type.name === "apple") {const deco = Decoration.inline(pos, pos + 1, { class: "highlight" });arrs.push(deco);}});return DecorationSet.create(state.doc, arrs);	// 返回 DecorationSet},},
});

css

span[custom-node-type="apple"].highlight::before {background: yellow;color: red;
}

效果:

在这里插入图片描述

用 Plugin - state 存储数据

Plugin 中的 state 字段可以存储数据

  • init: (config, state) => T
  • apply: (tr, value:T, oldState, newState) => T

plugin.getState(state) 可以获取这个数据

将 DecorationSet 存在 state 中,改写上面的插件:

export const MyHighlightApplesPlugin = new Plugin({state: {init(_, state) {return createAppleDecos(state.doc);},apply(tr) {return createAppleDecos(tr.doc);},},props: {decorations(state) {const set = MyHighlightApplesPlugin.getState(state);return set;},},
});function createAppleDecos(doc) {let arrs = [];doc.descendants((node, pos) => {if (node.type.name === "apple") {const deco = Decoration.inline(pos, pos + 1, { class: "highlight" });arrs.push(deco);}});return DecorationSet.create(doc, arrs); // 返回 DecorationSet
}

setMeta

给高亮效果添加开关,点击按钮随时切换是否高亮

plugin 中存储 enable 字段(以前只存储 set,现在是 {enable,set}

export const MyHighlightApplesPlugin = new Plugin({state: {init(_, state) {return {enable: true,set: createAppleDecos(state.doc),};},apply(tr, value) {const { enable } = value;let set;if (enable) {set = createAppleDecos(tr.doc);} else {set = DecorationSet.empty;}return { enable, set };},},props: {decorations(state) {const { set } = MyHighlightApplesPlugin.getState(state);return set;},},
});

enable 字段添加上了,接下来要在点击按钮时修改它的值


function toggleHighlightApples() {// 通过 getState 获取数据const state = MyHighlightApplesPlugin.getState(editorView.value.state);// 直接修改!state.enable = !state.enable;// 然后 dispatch 一个 trconst tr = editorView.value.state.tr;editorView.value.dispatch(tr);
}

上面的代码在插件外部直接修改 state.enable ,能实现效果,但是不好。
正确的做法是发一个信号,让 plugin 内部自己修改。

tr.setMeta 发信号:

function toggleHighlightApples() {const state = MyHighlightApplesPlugin.getState(editorView.value.state);const tr = editorView.value.state.tr;tr.setMeta(MyHighlightApplesPlugin, !state.enable);editorView.value.dispatch(tr);
}

applygetMeta 接收信号

    apply(tr, value) {let { enable } = value;const meta = tr.getMeta(MyHighlightApplesPlugin);if (meta !== undefined) {enable = meta;}let set;if (enable) {set = createAppleDecos(tr.doc);} else {set = DecorationSet.empty;}return { enable, set };},

效果

在这里插入图片描述

set.map(tr.mapping, tr.doc) 的作用

官网示例 image placeholder example 中用到 set.map(tr.mapping, tr.doc) ,作用看不懂,写代码测试一下

写一个简单的插件:给粗体文字自动添加红色背景

export const TestPlugin = new Plugin({state: {init(_, state) {return addRedBg(state.doc);},apply(tr, set) {return set;},},props: {decorations(state) {const set = TestPlugin.getState(state);return set;},},
});function addRedBg(doc) {let arrs = [];doc.descendants((node, pos) => {if (node.marks.find((mark) => mark.type.name === "strong")) {const deco = Decoration.inline(pos, pos + node.nodeSize, { style: "background:red" });arrs.push(deco);}});return DecorationSet.create(doc, arrs);
}

文档初始内容为:

<p>你好,今天天气不错。<strong>中午</strong>吃什么</p>

效果:

在这里插入图片描述

因为只在 init 中设置 deco,在 apply 中什么都没做。所以插件不会响应后续视图变化

新增 bold 文本,不会变红:

在这里插入图片描述

移除 bold,不会消失:

在这里插入图片描述

修改文档内容,致使bold文字位置变动,红色不跟着挪位置:

在这里插入图片描述
这些都是意料之中的效果。现在在 apply 中添加上这一句:

    apply(tr, set) {set = set.map(tr.mapping, tr.doc);	// 新增return set;},

新增 bold 文本、移除 bold 的效果不变,不放图了。

修改文档内容,致使bold文字位置变动,效果和之前不同了:

在这里插入图片描述

transform Guide 中讲到了 Mapping 的用法

let tr = new Transform(myDoc)
tr.split(10)    // split a node, +2 tokens at 10
tr.delete(2, 5) // -3 tokens at 2
console.log(tr.mapping.map(15)) // → 14
console.log(tr.mapping.map(6))  // → 3
console.log(tr.mapping.map(10)) // → 9

结合 DecorationSet.map 的说明:
在这里插入图片描述
set.map(tr.mapping, tr.doc) 的含义就明白了 —— 所有 deco 都应用 tr.mapping 找到新位置。

但是对于新增的 bold 文本(需要新增 deco),或者已经有的 bold 文本去掉 bold 效果(需要移除 deco),set.map(tr.mapping, tr.doc) 就无能为力了(剪切、复制、拖拽等同样处理不了)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/118853.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

QT项目如何打包成可执行文件

QT项目打包成可执行文件 一 建立一个文件夹二. 编译2.1 打开QT MSVC编译工具2.2 进入publish文件夹 一 建立一个文件夹 例如&#xff1a;publish 二. 编译 2.1 打开QT MSVC编译工具 2.2 进入publish文件夹 cd 路径 执行命令 windeployqt 项目名 例&#xff1a;windeployq…

美海军用于情报、监视和侦察的中大型无人系统概述

源自&#xff1a;中国指挥与控制学会 “人工智能技术与咨询” 发布 简 介 1 引 言 2 超大型无人潜航器 图1 波音“回声航行者”无人潜航器 图2 “虎鲸”超大型无人潜航器 3 中型无人水面舰艇 图3 “海鹰”无人水面舰艇 图4 “海上猎人”无人水面舰艇 4 …

SpringMVC 资源状态转移RESTful

文章目录 1、RESTful简介a>资源b>资源的表述c>状态转移 2、RESTful的实现HiddenHttpMethodFilterRESTful案例 1、RESTful简介 REST&#xff1a;Representational State Transfer&#xff0c;表现层资源状态转移。 a>资源 资源是一种看待服务器的方式&#xff0c…

GO语言代码示例

首先&#xff0c;我们需要安装 rod 库&#xff0c;这是一个用于构建网络爬虫的 Go 语言库。 使用 go get 命令安装 rod 库&#xff1a;go get -u github.com/gofiber/rod 创建一个新的 Go 程序文件&#xff0c;例如&#xff1a;main.go 在 main.go 文件中&#xff0c;导入 r…

都2023年了,诸佬们肯定熟知RabbitMQ了吧

前言&#xff1a;大家好&#xff0c;我是小威&#xff0c;24届毕业生&#xff0c;曾经在某央企公司实习&#xff0c;目前入职某税务公司。本篇文章将记录和分享RabbitMQ相关的知识点。 本篇文章记录的基础知识&#xff0c;适合在学Java的小白&#xff0c;也适合复习中&#xff…

binutils 2.40 Linker (ld) 官方文档下载

前言 最近需要熟悉 elf 与 共享库 的链接与加载流程&#xff0c;需要先了解 elf 文件 是怎么链接的&#xff0c;链接脚本如何阅读 最有效的方式是查看 GNU 官方的 Linker (ld) 文档&#xff0c;通过查找&#xff0c;这个 Linker (ld) 属于 GNU binutils&#xff0c;当前的较新…

Godot 官方2D C#重构(3):TileMap使用

文章目录 前言Godot Tilemap使用Tilemap使用TileSet和TilemapTilemap 图片资源添加TileSet&#xff0c;开始切图导入图片切图 简单添加TileMap如何使用 Auto Tilemap使用Auto Tilemap 前言 Godot 官方 教程 Godot 2d 官方案例C#重构 专栏 Godot 2d 重构 github地址 Godot Tilem…

MFC 注册表

文章目录 打开注册表对注册表的键的操作创建子键删除子键遍历子键 对注册表值的操作读取值设置值 打开注册表 void CREGDemoDlg::OnBnClickedBtnOpen() {//打开注册表HKEY hKey;if (ERROR_SUCCESS ! RegOpenKeyEx(HKEY_CURRENT_USER, L"SOFTWARE\\Baidu.com", 0, KEY…

[算法训练营] 回溯算法专题(二)

&#x1f57a;作者&#xff1a; 主页 我的专栏C语言从0到1探秘C数据结构从0到1探秘Linux菜鸟刷题集 &#x1f618;欢迎关注&#xff1a;&#x1f44d;点赞&#x1f64c;收藏✍️留言 &#x1f3c7;码字不易&#xff0c;你的&#x1f44d;点赞&#x1f64c;收藏❤️关注对我真的…

Android笔记(七)Android JetPack Compose组件搭建Scaffold脚手架

在去年2022年曾发布一篇关于脚手架的文章&#xff1a;“Android JetPack Compose组件中Scaffold的应用” 。但是Android的版本从12变更到13及以上版本&#xff0c;导致一些细节的实现存在不同。在本文中&#xff0c;将从头开始介绍整个脚手架的搭建过程。 一、新建项目模块 在…

从0到1配置TensorRT环境

根据博文&#xff1a;TensorFlow2.x模型转onnx、TensorRT给出的环境来配置。 以下是该博文中给出的版本信息 TensorFlow 2.4 CUDA 11.1 CUDNN 8 TensorRT 8.2.1.8 tf2onnx 1.13.0 onnx 1.12.0 下载地址 包下载地址TensorRT 8.2.1.8https://developer.nvidia.com/nvidia-tenso…

【Overload游戏引擎细节分析】standard材质Shader

提示&#xff1a;Shader属于GPU编程&#xff0c;难写难调试&#xff0c;阅读本文需有一定的OpenGL基础&#xff0c;可以写简单的Shader&#xff0c;不适合不会OpenGL的朋友 一、Blinn-Phong光照模型 Blinn-Phong光照模型&#xff0c;又称为Blinn-phong反射模型&#xff08;Bli…

腾讯云抱歉不满足产品首购条件解决方法

购买腾讯云服务器提示“抱歉&#xff0c;检测到相同实名认证主体已购买&#xff0c;不满足产品首购条件&#xff0c;您可了解其他商品。”&#xff0c;购买腾讯云特价云服务器是有新用户首购限制的&#xff0c;说当前腾讯云认证主体的其他账号已经购买过云服务器&#xff0c;一…

【wespeaker】模型ECAPA_TDNN介绍

本次主要介绍开源项目wespeaker模型介绍 1. 模型超参数 model_args: feat_dim: 80 embed_dim: 192 pooling_func: “ASTP” projection_args: project_type: “softmax” # add_margin, arc_margin, sphere, softmax scale: 32.0 easy_margin: False 2. 模型结构 2.1 Layer…

node-red常用包分析

node-red-contrib-opcua Use OpcUa-Item to define variables. Use OpcUa-Client to read / write / subscribe / browse OPC UA server. 需要想通过OpcUa-Item节点来指定一个数据点。 触发器-->opcua_item----->opcua_client opcua_client的Action项解析&#xff1a; …

HugeGraph Hubble 配置 https 协议的操作步骤

背景 HugeGraph 图数据库的 Server 端支持 https 配置&#xff0c;官方文档中有说明相对比较容易&#xff0c;而 Hubble 部署过程都是 http的。 我们有一个应用要嵌入 hubble 页面&#xff0c;而且部署为 https &#xff0c;那么 Hubble 是否支持配置 https 呢&#xff1f;网…

大数据技术学习笔记(三)—— Hadoop 的运行模式

目录 1 本地模式2 伪分布式模式3 完全分布式模式3.1 准备3台客户机3.2 同步分发内容3.2.1 分发命令3.2.2 执行分发操作 3.3 集群配置3.3.1 集群部署规划3.3.2 配置文件说明3.3.3 修改配置文件3.3.4 分发配置信息 3.4 SSH无密登录配置3.4.1 配置ssh3.4.2 无密钥配置 3.5 单点启动…

C++【多态】

文章目录&#xff1a; C 多态1. 多态的概念2. 多态的定义和实现2.1 构成多态的必要条件2.2 虚函数和重写2.3 虚函数重写的两个例外2.4 例题运用2.5 final 和 override2.6 重载、重写、重定义 3. 抽象类4. 多态的原理4.1 虚表指针4.2 多态和非多态调用4.3 回想满足条件4.4 虚函数…

Selenium中WebDriver最新Chrome驱动安装教程

&#x1f60f;作者简介&#xff1a;博主是一位测试管理者&#xff0c;同时也是一名对外企业兼职讲师。 &#x1f4e1;主页地址&#xff1a;【Austin_zhai】 &#x1f646;目的与景愿&#xff1a;旨在于能帮助更多的测试行业人员提升软硬技能&#xff0c;分享行业相关最新信息。…

【广州华锐互动】智能家居设计3D虚拟还原系统

随着科技的飞速发展&#xff0c;人们对家居生活的需求也在不断提高。智能家居作为一种新兴的生活方式&#xff0c;正逐渐成为现代人追求的理想居住环境。而智能家居设计3D虚拟还原系统&#xff0c;正是为了让人们更好地了解和体验智能家居带来的便捷与舒适&#xff0c;让未来生…