Midas(壁虎富文本编辑器)在XUL中通过<编辑>元素无法启用

Midas (Gecko Rich Text Editor) in XUL through the <editor> element cannot be enabled

本文关键字:编辑 启用 元素 文本 壁虎 文本编辑 编辑器 XUL Midas      更新时间:2023-09-26

我按照本文的说明,尝试通过XUL元素使用Midas。到目前为止,我的代码如下:

<window id="main" title="Anunciador Blog Editor" width="300" height="300"
    xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
    xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <script type="application/x-javascript">
    <![CDATA[ 
    var editor = null;
    function onLoad() {
        editor = document.getElementById('editor');
        editor.contentDocument.designMode = 'on';
    }
    function onBoldButtonCommand() {
        editor.contentDocument.execCommand('bold', false, null);
    }
    window.addEventListener("load", onLoad, false);
    ]]>
    </script>
    <button label="Bold" oncommand="onBoldButtonCommand();" />
    <editor id="editor" type="content-primary" editortype="html" src="about:blank" flex="1" />
</window>

然而,当我点击"加粗"按钮时,在<editor>中选择了一些文本,文本没有改变,JS控制台呈现以下错误:

Error: uncaught exception: [Exception... "Component returned failure code: 0x80004005
(NS_ERROR_FAILURE) [nsIDOMNSHTMLDocument.execCommand]"  nsresult: "0x80004005
(NS_ERROR_FAILURE)"  location: "JS frame :: chrome://anunciador/content/main.xul :: 
onBoldButtonCommand :: line 14"  data: no]

这对我来说没有意义,因为我已经启用了编辑模式:

editor.contentDocument.designMode = 'on';

同样,如果我只改变

一行
<editor id="editor" type="content-primary" editortype="html" src="about:blank" flex="1" />

<xhtml:iframe id="editor" src="about:blank"></xhtml:iframe>

我可以编辑和格式化iframe中的文本(但我真的更喜欢使用编辑器)。

我忘了什么吗?

经过长时间的研究,这个问题似乎是Gecko的一个bug——一个经常出现的bug,顺便说一句。显然,终于解决了…

当我们等待公共构建时(或者如果您不能使用XULRunner或Firefox的未来新版本),您可以使用编辑器的commandManager属性作为解决方案。该对象提供了一个名为doCommand()的方法,可用于格式化文本。该方法有三个参数:一个表示命令的字符串(与execCommand()接受的字符串不同),一个参数对象(获取起来很麻烦,但可以暂时忽略)和编辑器的contentWindow

如果你想让选区加粗,只需这样使用这个方法:

function onBoldButtonCommand() {
    editor.commandManager.doCommand("cmd_bold", {}, editor.contentWindow)
}

如果您的命令需要参数,但是,它可能会变得有点复杂。首先,您需要一个nsICommandParams接口的实例(它将是一个由JavaScript对象包装的c++对象)。获取此对象涉及一些非常深奥的代码,显然涉及类似XPCOM之类的东西:

var commandParams = Components.classes['@mozilla.org/embedcomp/command-params;1'].getService(Components.interfaces.nsICommandParams);

在这个对象中,我们将命令的参数设置为键值对。在这里,我们有一个所有命令都接受的参数列表。不要害怕这个页面引用c++代码的事实-你可以直观地将它映射到JavaScript。此外,希望看起来所有命令只接收一个参数"state_attribute"。例如,如果我们想要设置文本的颜色,我们可以在param对象中这样设置参数:

commandParams.setCStringValue("state_attribute", "#FF0000");

然后你"只是"调用doCommand(),这次使用参数:

editor.commandManager.doCommand("cmd_fontColor", commandParams, editor.contentWindow);

下面的代码是使用带参数和不带参数的doCommand()的工作示例:

<window id="main" title="Anunciador Blog Editor" width="300" height="300"
   xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
   xmlns:xhtml="http://www.w3.org/1999/xhtml">
   <script type="application/x-javascript">
   <![CDATA[
   var editor = null;
   function onLoad() {
       editor = document.getElementById('editor');
       editor.contentDocument.designMode = 'on';
   }
   function onBoldButtonCommand() {
       editor.commandManager.doCommand("cmd_bold", {}, editor.contentWindow)
   }
    function onRedTextCommand() {
        var commandParams = Components.classes['@mozilla.org/embedcomp/command-params;1'].getService(Components.interfaces.nsICommandParams);
        commandParams.setCStringValue("state_attribute", "#FF0000");
        editor.commandManager.doCommand("cmd_fontColor", commandParams, editor.contentWindow)
    }
   window.addEventListener("load", onLoad, false);
   ]]>
   </script>
   <toolbar>
       <button label="Bold" oncommand="onBoldButtonCommand();" />
       <button label="Red" oncommand="onRedTextCommand();" />
   </toolbar>
   <editor id="editor" type="content-primary" editortype="html" src="about:blank" flex="1" />
</window>

还有,这一页可能很有帮助,而这一页更有帮助(尽管部分是用法语写的!)