创建自己的插件如果 Dojo 工具箱提供的插件无法满足您的需要,那么可以自己构建一个插件。Dojo 富文本编辑器使您能够扩展编辑器的功能。您可以创建一个新的插件类(继承自 dijit._editor._Plugin)并将其添加到编辑器的插件列表。
编辑器插件的生命周期dijit._editor._Plugin 是编辑器插件的基类,通常为工具栏上的一个按钮和一些相关代码。它定义了插件的生命周期。
当通过 addPlugin 函数将插件添加到编辑器时,插件的生命周期随即开始,通过该函数将发布一个 Dojo 主题,从而使插件能够创建自身。随后将分别调用插件的 setEditor 和 setToolbar 函数,用来将插件安装到编辑器。默认情况下,setEditor 函数将完成以下操作:
- 创建对编辑器的本地引用。
- 创建命令按钮。
- 将编辑器的 execCommand 方法连接到按钮。
- 将插件的 updateState 方法连接到编辑器。
一切都很简单。setToolbar 的默认行为甚至更简单:它将先前创建的命令按钮添加到工具栏。
此时,初始化过程已经完成。插件生命周期将进入 “无尽的” 事件驱动阶段,直到某些人破坏了整个编辑器,此时生命周期结束,将调用插件的 destroy 方法。
总结起来,生命周期的功能包括:
- Editor.addPlugin
- 插件的构造函数
- plugin.setEditor
- plugin.setToolbar
- 事件驱动阶段。持续调用 plugin.updateState。
- Editor.destroy
要更好地了解细节,在接下来的部分将编写一个名为 FindReplace 的查找/替换插件。FindReplace 将在编辑器中查找包含给定关键字的文本,在找到后突出显示结果。它还支持使用其他新的内容替换关键字。要实现这种插件,您将设计一个特殊的工具栏,该工具栏将在单击命令按钮后显示。
继承 dijit._editor._Plugin第一步是通过继承 dijit._editor._Plugin 基类建立一个空的代码框架,如清单 6 所示。
清单 6. 新插件的基本代码框架1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
| dojo.provide("dojox.editor.plugins.FindReplace");
dojo.require("dijit._editor._Plugin");
dojo.declare("dojox.editor.plugins.FindReplace", dijit._editor._Plugin, {
// When you click the command button, you show a toolbar,
// instead of executing some editor commands.
useDefaultCommand: false,
// You can just use the original method.
// setEditor: function(editor){},
setToolbar: function(editorToolbar){
this.inherited(arguments);
//TODO: Create your additional find/replace toolbar here,
// and append it after the editor toolbar.
},
updateState: function(){
// You don't need to handle anything when editor state is updated.
// So just leave this empty.
},
destroy: function(){
this.inherited(arguments);
//TODO: Remember to destroy the toolbar you created.
}
});
// Register this plug-in so it can construct itself when the editor publishes a topic.
dojo.subscribe(dijit._scopeName + ".Editor.getPlugin", null, function(o){
if(!o.plugin && o.args.name.toLowerCase() === "findreplace"){
o.plugin = new dojox.editor.plugins.FindReplace({});
}
});
|
扩展工具栏第二个任务是在编辑器的工具栏上生成一个按钮。setEditor 方法将自动完成这一过程;您所需做的就是使用不同的标签和不同的图标。清单 7 显示了最简单的方法。
清单 7. 在编辑器工具栏中创建一个 ToggleButton1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| ...
dojo.declare("dojox.editor.plugins.FindReplace", dijit._editor._Plugin, {
...
// You'd like to use a toggle button to show/hide your own find/replace toolbar.
buttonClass: dijit.form.ToggleButton,
// As long as you provide a command, the CSS class of the button icon will be
// generated automatically. For this one, it will be "dijitEditorFindReplace".
command: "findReplace",
// You can also use localization here.
getLabel: function(){
return "Find and Replace";
},
...
});
...
|
在为 CSS 类 dijitEditorFindReplace 使用一个背景图片后,您可以看到示例按钮,如图 3 所示。
图 3. 示例插件的新按钮 下一步是创建查找/替换工具栏,并将它绑定到命令按钮。您需要一个用于搜索字符串的字段,一个用于替换字符串的字段,一个查找按钮,以及一个替换按钮。如果希望增加更多的功能,还可以添加其他一些内容,使其看上去更加专业,比如一个 Replace All 按钮或 Case Sensitive Search 和 Backwards Search 复选框。可以编写一个简单的、单独的小部件来实现这些内容,如清单 8 所示。
清单 8. 创建一个查找/替换工具栏1
2
3
4
5
6
7
| dojo.declare("dojox.editor.plugins.FindReplacePane", [dijit._Widget, dijit._Templated], {
// With templates, you don't need to create all the stuff manually.
templateString: dojo.cache("dojox.editor.plugins", "FindReplacePane.html"),
// There are widgets in template. Tell the parser to parse them.
widgetsInTemplate: true
});
|
在 FindReplacePane.html 中,可以直接使用 dijit.Toolbar 和其他表格小部件。清单 9 中的例子使用一个标签和一个文本字段(或复选框)构成了一个新的部件,从而简化了代码。
清单 9. 查找/替换工具栏的内容1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| <div><div dojotype="dijit.Toolbar" dojoattachpoint="frToolbar">
<div dojoattachpoint="findField" dojotype="dojox.editor.plugins._FindReplaceTextBox"
label="Find:"></div>
<div dojoattachpoint="replaceField" dojotype="dojox.editor.plugins._FindReplaceTextBox"
label="Replace with:"></div>
<div dojotype="dojox.editor.plugins._ToolbarLineBreak"></div>
<div dojoattachpoint="findButton" dojotype="dijit.form.Button"
label="Find" showLable="true"></div>
<div dojoattachpoint="replaceButton" dojotype="dijit.form.Button"
label="Replace" showLable="true"></div>
<div dojoattachpoint="replaceAllButton" dojotype="dijit.form.Button"
label="Replace All" showLable="true"></div>
<div dojoattachpoint="matchCase" dojotype="dojox.editor.plugins._FindReplaceCheckBox"
label="Match case"></div>
<div dojoattachpoint="backwards" dojotype="dojox.editor.plugins._FindReplaceCheckBox"
label="Backwards"></div>
</div></div>
|
使用 dojoattachpoint,您可以以 FindReplacePane 属性的方式轻松访问小部件。dojox.editor.plugins._ToolbarLineBreak 对于多行工具栏非常有用。
现在,您已经创建了按钮和工具栏,下一步是将它们连接起来。您只需要将工具栏放到合适的位置并定义在单击开关按钮后应该执行哪些操作。清单 10 给出一个示例。
清单 10. 连接按钮和工具栏1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
| // This initialization work should be done in setToolbar,
// because you want to be sure that the editor toolbar is ready.
setToolbar: function(editorToolbar){
// Super class will add the command button to the editor toolbar for you.
this.inherited(arguments);
// Create your find/replace toolbar, place it after the editor toolbar,
// hide it, and start it up.
var frtb = this.frToolbar = new dojox.editor.plugins.FindReplacePane();
frtb.placeAt(toolbar.domNode, "after");
dojo.style(frtb.domNode, "display", "none");
frtb.startup();
// Toggle it when your toggle button is clicked...
this.connect(this.button, "onChange", "_toggleFindReplace");
...
},
_toggleFindReplace: function(toShow){
// Remember the original height.
var height = dojo.marginBox(this.editor.domNode).h
dojo.style(this.frToolbar.domNode, "display", toShow ? "block" : "none");
// Resize the editor to maintain the height.
this.editor.resize({h: height});
}
|
图 4 显示了目前示例的外观。
图 4. 查找/替换工具栏  |