-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Description
Affected Packages
core,react,pm
Version(s)
2.10.3
Bug Description
`import { Extension } from '@tiptap/core';
import { Plugin, PluginKey } from '@tiptap/pm/state';
import { Decoration, DecorationSet } from '@tiptap/pm/view';
function createWordGapElement() {
const span = document.createElement('i');
span.className = 'word-gap';
span.setAttribute('contenteditable', 'false');
span.innerHTML = '\u2006';
return span;
}
function findWordGaps(doc) {
const decorations = [];
const regex = /([\u4e00-\u9fa5])([a-zA-Z])/g; // 中文后跟英文
const regexRev = /([a-zA-Z])([\u4e00-\u9fa5])/g; // 英文后跟中文
let prevText = '';
let prevPos = 0;
doc.descendants((node, pos) => {
if (!node.isText) return;
console.log(node);
// 处理当前节点内部的中英文间隔
let match;
// 中文后接英文
while ((match = regex.exec(node.text)) !== null) {
const deco = Decoration.widget(
pos + match.index + match[1].length, // 插入空格的位置
createWordGapElement(),
{
side: -1,
ignoreSelection: true,
stopEvent: () => true,
},
);
decorations.push(deco);
}
// 英文后接中文
while ((match = regexRev.exec(node.text)) !== null) {
const deco = Decoration.widget(
pos + match.index + match[1].length, // 插入空格的位置
createWordGapElement(),
{
side: -1,
ignoreSelection: true,
stopEvent: () => true,
},
);
decorations.push(deco);
}
// 跨节点的处理中英文间隔
if (prevText) {
const combinedText = prevText.at(-1) + node.text.at(0);
// 中文后接英文
let match = regex.exec(combinedText);
if (match) {
const deco = Decoration.widget(
pos, // 插入空格的位置
createWordGapElement(),
{
side: -1,
ignoreSelection: true,
},
);
decorations.push(deco);
}
// 英文后接中文
match = regexRev.exec(combinedText);
if (match) {
const deco = Decoration.widget(
pos, // 插入空格的位置
createWordGapElement(),
{
side: -1,
ignoreSelection: true,
},
);
decorations.push(deco);
}
}
prevText = node.text;
prevPos = pos;
});
return DecorationSet.create(doc, decorations);
}
export const WordGap = Extension.create({
name: 'wordGap',
addProseMirrorPlugins() {
return [
new Plugin({
key: new PluginKey('wordGap'),
state: {
init(_, { doc }) {
return findWordGaps(doc);
},
apply(transaction, oldState) {
return transaction.docChanged
? findWordGaps(transaction.doc)
: oldState;
},
},
props: {
decorations(state) {
return this.getState(state);
},
},
}),
];
},
});`
432187560-331d86a8-80b1-44ff-9fc6-972f61e59e4d.mp4
This is the widget I implemented to add spaces between Chinese and English, but when I click on the widget and drag the cursor, I cannot select the text.
Browser Used
Chrome
Code Example URL
No response
Expected Behavior
https://github.com/user-attachments/assets/8b22f8c9-fa51-4073-a246-b21de154c348
It should be possible to select text by focusing the mouse on the decoration and clicking on the focus button to select the text to the left or right
Additional Context (Optional)
No response
Dependency Updates
- Yes, I've updated all my dependencies.