撤消不会将文档内容恢复到 editor.insertHtml 之前的状态
Undo does not revert document contents to the state before editor.insertHtml
我在编写 ckeditor 插件时遇到 undo 问题。
我正在使用 editor.insertHtml
将带有特定 class 的 div 添加到文档中。如果我从一个空文档开始,撤消和重做是不亮的。当我执行命令时,撤消将亮起。如果我按撤消,两者都会点亮。 "undoing" 不会还原文档内容。
为什么不呢?
CKEDITOR.plugins.add('plugin_name',
{
init: function(editor)
{
editor.ui.addButton('Button_name',
{
label: 'some text',
command: 'Command_name',
icon: this.path + 'images/icon.png'
});
editor.addCommand('Command_name', { canUndo: true, exec: function()
{
editor.fire('saveSnapshot');
editor.insertHtml("<div contenteditable='false' class='foobar'></div>\r\n");
editor.fire('saveSnapshot');
}});
}
});
我也不明白为什么插入html之前和之后都需要保存快照,但那是另外一回事了。
首先 - editor.insertHtml()
负责拍摄快照,因为它是一种高级方法。如果您停止射击 editor#saveSnapshot
.
可能会有所帮助
第二件事 - 由于您的命令 canUndo
设置为 true
快照将在您执行时自动记录。所以我建议将它设置为 false
以使 editor.insertHtml()
成为唯一保存快照的人。
如果以上方法没有帮助,那么您需要检查拍摄了哪些快照。为此,只需访问 editor.undoManager.snapshots
。在您的情况下,应该有两个 - 一个包含初始内容,一个在执行命令后获取。不幸的是,调试撤消管理器是一种痛苦...
I also do not understand why saving of snapshots is needed both before and after the insertion of html, but that is another story.
这是个好问题。但让我们概括一下 - 为什么我需要在更改内容之前 和更改内容之后 和之后拍摄快照?
IIRC在CKEditor 4.4.3之前有两个原因,现在只剩下第二个:
- 因为初始快照栈是空的,所以记录初始内容,
- 将键入的文本与之后所做的更改分开。
第一个是一个古怪的行为,在几个版本前终于得到修复。现在初始快照拍摄于 editor#instanceReady
.
但第二个仍然是正确的。当您开始键入时,编辑器开始计算键数,每 25 个键就会记录一次快照。但是,如果例如您键入 5 个字符,然后按粗体按钮,您希望这 5 个字符作为单独的操作保存,然后按粗体作为第二个操作。这就是粗体命令在执行之前拍摄快照的原因 - 记录包含这 5 个新字符的快照,然后拍摄另一个快照来记录 <strong></strong>
元素的插入。
事实是,记录击键最有可能以一种无需在操作前拍摄快照的方式实现。这将需要在插入每个字符后拍摄快照,然后将它们分组。可以,但是会更重
可悲的是,最近我们无论如何都需要开始对每个键进行快照,以处理键入和删除文本时的一些棘手情况。没有可靠的方法来判断 keydown
上的字符是否会是 inserted/removed 并且好的撤消管理器应该将输入与删除分开。所以我们需要知道前面的字符插入后的内容是什么,以防按下backspace/delete press,反之亦然。
换句话说 - 在我们对撤消管理器进行了最近的更改之后,也许今天所有这些都可以简化。但可以肯定的是 - 实施一个好的撤消管理器(尤其是在您不控制字符插入的情况下)非常棘手,很少有人能做到这一点。
PS。 "\r\n"
末尾的HTML要插入没有区别。
我在编写 ckeditor 插件时遇到 undo 问题。
我正在使用 editor.insertHtml
将带有特定 class 的 div 添加到文档中。如果我从一个空文档开始,撤消和重做是不亮的。当我执行命令时,撤消将亮起。如果我按撤消,两者都会点亮。 "undoing" 不会还原文档内容。
为什么不呢?
CKEDITOR.plugins.add('plugin_name',
{
init: function(editor)
{
editor.ui.addButton('Button_name',
{
label: 'some text',
command: 'Command_name',
icon: this.path + 'images/icon.png'
});
editor.addCommand('Command_name', { canUndo: true, exec: function()
{
editor.fire('saveSnapshot');
editor.insertHtml("<div contenteditable='false' class='foobar'></div>\r\n");
editor.fire('saveSnapshot');
}});
}
});
我也不明白为什么插入html之前和之后都需要保存快照,但那是另外一回事了。
首先 - editor.insertHtml()
负责拍摄快照,因为它是一种高级方法。如果您停止射击 editor#saveSnapshot
.
第二件事 - 由于您的命令 canUndo
设置为 true
快照将在您执行时自动记录。所以我建议将它设置为 false
以使 editor.insertHtml()
成为唯一保存快照的人。
如果以上方法没有帮助,那么您需要检查拍摄了哪些快照。为此,只需访问 editor.undoManager.snapshots
。在您的情况下,应该有两个 - 一个包含初始内容,一个在执行命令后获取。不幸的是,调试撤消管理器是一种痛苦...
I also do not understand why saving of snapshots is needed both before and after the insertion of html, but that is another story.
这是个好问题。但让我们概括一下 - 为什么我需要在更改内容之前 和更改内容之后 和之后拍摄快照?
IIRC在CKEditor 4.4.3之前有两个原因,现在只剩下第二个:
- 因为初始快照栈是空的,所以记录初始内容,
- 将键入的文本与之后所做的更改分开。
第一个是一个古怪的行为,在几个版本前终于得到修复。现在初始快照拍摄于 editor#instanceReady
.
但第二个仍然是正确的。当您开始键入时,编辑器开始计算键数,每 25 个键就会记录一次快照。但是,如果例如您键入 5 个字符,然后按粗体按钮,您希望这 5 个字符作为单独的操作保存,然后按粗体作为第二个操作。这就是粗体命令在执行之前拍摄快照的原因 - 记录包含这 5 个新字符的快照,然后拍摄另一个快照来记录 <strong></strong>
元素的插入。
事实是,记录击键最有可能以一种无需在操作前拍摄快照的方式实现。这将需要在插入每个字符后拍摄快照,然后将它们分组。可以,但是会更重
可悲的是,最近我们无论如何都需要开始对每个键进行快照,以处理键入和删除文本时的一些棘手情况。没有可靠的方法来判断 keydown
上的字符是否会是 inserted/removed 并且好的撤消管理器应该将输入与删除分开。所以我们需要知道前面的字符插入后的内容是什么,以防按下backspace/delete press,反之亦然。
换句话说 - 在我们对撤消管理器进行了最近的更改之后,也许今天所有这些都可以简化。但可以肯定的是 - 实施一个好的撤消管理器(尤其是在您不控制字符插入的情况下)非常棘手,很少有人能做到这一点。
PS。 "\r\n"
末尾的HTML要插入没有区别。