使用 Quill 重叠内联注释
Overlapping Inline Annotations with Quill
在我的应用程序中,用户可以在文档正文的任何位置创建边距注释,并且注释锚范围可以任意重叠,如下所示:
This [abc]is a set of [xyz]overlapping[/xyz] comments[/abc]
我正在这样定义我的评论锚印迹:
let Inline = Quill.import('blots/inline');
class CommentAnchorBlot extends Inline {
static create(commentId) {
let node = super.create();
node.setAttribute("class", "comment-anchor comment-anchor-" + commentId);
return node;
}
static formats(node) {
var classNames = node.getAttribute('class').split(/\s+/);
for (var i = 0, len = classNames.length; i < len; i++) {
var className = classNames[i];
if (className.indexOf("comment-anchor-") === 0) {
return className.replace("comment-anchor-", "");
}
}
return null;
}
}
CommentAnchorBlot.blotName = 'comment';
CommentAnchorBlot.className = 'comment-anchor';
CommentAnchorBlot.tagName = 'span';
Quill.register(CommentAnchorBlot);
但是当我在 运行 Quill 实例中对其进行测试时,它会生成这样的羊皮纸:
{
"ops" : [
{ "insert" : "This " },
{ "insert" : "is a set of ", "attributes" : { "comment" : "abc" } },
{ "insert" : "overlapping ", "attributes" : { "comment" : "xyz" } },
{ "insert" : " comments", "attributes" : { "comment" : "abc" } }
]
}
这是有问题的,因为 "overlapping" 这个词实际上应该有 "abc" 和 "xyz" 作为它的评论锚 ID。
您建议如何更改 CommentAnchorBlot 定义以适应此要求?我还没有在 Quill 文档中看到任何其他与此类似的示例。
首先,我会改用 class 属性符,因为评论似乎没有必要拥有自己的 DOM 节点,而是可以将 class 应用于其他节点.
其次,就你的观点而言,大多数时候格式化是一种覆盖行为(将文本颜色格式化为红色,然后是蓝色,使其变为蓝色,而不是 [red, blue]),但你可以通过类似的方式更改它这个:
class Comment extends Parchment.Attributor.Class {
constructor(attrName = 'comment', keyName = 'comment') {
super(attrName, keyName, { scope: Parchment.Scope.INLINE_ATTRIBUTE });
}
add(node, value) {
if (!this.canAdd(node, value)) return false;
const array = Array.isArray(value) ? value : [value];
array.forEach((id) => {
node.classList.add(`${this.keyName}-${id}`);
});
return true;
}
remove(node, id) {
if (id == null) {
super.remove(node);
} else {
node.classList.remove(`${this.keyName}-${id}`);
if (node.classList.length === 0) {
node.removeAttribute('class');
}
}
}
value(node) {
const prefix = `${this.keyName}-`;
const list = _.filter(node.classList, (c) => {
return c.startsWith(prefix);
}).map((c) => {
return c.slice(prefix.length);
});
return (list.length > 0) ? list : null;
}
}
Quill.register({ 'formats/comment': new Comment() });
在我的应用程序中,用户可以在文档正文的任何位置创建边距注释,并且注释锚范围可以任意重叠,如下所示:
This [abc]is a set of [xyz]overlapping[/xyz] comments[/abc]
我正在这样定义我的评论锚印迹:
let Inline = Quill.import('blots/inline');
class CommentAnchorBlot extends Inline {
static create(commentId) {
let node = super.create();
node.setAttribute("class", "comment-anchor comment-anchor-" + commentId);
return node;
}
static formats(node) {
var classNames = node.getAttribute('class').split(/\s+/);
for (var i = 0, len = classNames.length; i < len; i++) {
var className = classNames[i];
if (className.indexOf("comment-anchor-") === 0) {
return className.replace("comment-anchor-", "");
}
}
return null;
}
}
CommentAnchorBlot.blotName = 'comment';
CommentAnchorBlot.className = 'comment-anchor';
CommentAnchorBlot.tagName = 'span';
Quill.register(CommentAnchorBlot);
但是当我在 运行 Quill 实例中对其进行测试时,它会生成这样的羊皮纸:
{
"ops" : [
{ "insert" : "This " },
{ "insert" : "is a set of ", "attributes" : { "comment" : "abc" } },
{ "insert" : "overlapping ", "attributes" : { "comment" : "xyz" } },
{ "insert" : " comments", "attributes" : { "comment" : "abc" } }
]
}
这是有问题的,因为 "overlapping" 这个词实际上应该有 "abc" 和 "xyz" 作为它的评论锚 ID。
您建议如何更改 CommentAnchorBlot 定义以适应此要求?我还没有在 Quill 文档中看到任何其他与此类似的示例。
首先,我会改用 class 属性符,因为评论似乎没有必要拥有自己的 DOM 节点,而是可以将 class 应用于其他节点.
其次,就你的观点而言,大多数时候格式化是一种覆盖行为(将文本颜色格式化为红色,然后是蓝色,使其变为蓝色,而不是 [red, blue]),但你可以通过类似的方式更改它这个:
class Comment extends Parchment.Attributor.Class {
constructor(attrName = 'comment', keyName = 'comment') {
super(attrName, keyName, { scope: Parchment.Scope.INLINE_ATTRIBUTE });
}
add(node, value) {
if (!this.canAdd(node, value)) return false;
const array = Array.isArray(value) ? value : [value];
array.forEach((id) => {
node.classList.add(`${this.keyName}-${id}`);
});
return true;
}
remove(node, id) {
if (id == null) {
super.remove(node);
} else {
node.classList.remove(`${this.keyName}-${id}`);
if (node.classList.length === 0) {
node.removeAttribute('class');
}
}
}
value(node) {
const prefix = `${this.keyName}-`;
const list = _.filter(node.classList, (c) => {
return c.startsWith(prefix);
}).map((c) => {
return c.slice(prefix.length);
});
return (list.length > 0) ? list : null;
}
}
Quill.register({ 'formats/comment': new Comment() });