FCKeditor自定义插件

Plug-ins  插件

Creating & Installing a Plugin in FCKeditor  在FCK中创建和安装一个插件。

Writing a plugin  写一个插件

The directory structure for a plugin must always follow the same pattern. The plugin directory must have the same name as the plugin and it must contain a fckplugin.js file. It may also optionally include a language directory with various localized language definitions for your Users Interface (UI). Each file defines a single language, and the filenames (without .js) are what should be passed to FCKConfig.Plugins.Add. If your command has no UI then you don't need to supply any language files. 
一个插件所在的目录结构通常都有一定的模式,比如,插件的目录名必须与插件名一样,并且插件目录中必须包含一个fckplugin.js 文件。在插件目录里可以根据需要包含一个语言目录,在这个语言目录里可以用多种语言脚本文件定义你的UI界面所显示的语言文字(比如你的界面是中文的,就可以定义一个zh.js文件,然后在后面的配置中设置这种语言)。每个文件定义一种语言,文件名(不包含.js后缀)应当在后面的配置中作为参数传递给FCKConfig.Plugins.Add 函数(具体操作后面会提到),如果你的插件所执行的命令不需要UI界面(比如直接对选中的文字设置粗体样式之类的),那么你没必要提供任何语言文件。
For the 'findreplace' plugin the structure would look like this (assuming the default plugin path iseditor/plugins/):例如,对于一个名为"findreplace"(查找与替换)的插件 ,他的目录结构就类似于如下所示(假设默认的插件路径是 editor/plugins ):

/editor/plugins/findreplace/fckplugin.js
/editor/plugins/findreplace/lang/en.js
/editor/plugins/findreplace/lang/it.js

The fckplugin.js file defines your plugin. It should register the command(s) that it implements, and create a toolbar button for each one.  上面的提到的 fckplugin.js 文件 定义了你的插件的具体实现。在该文件里先将插件所执行的命令进行注册,然后为每个命令创建一个对应的工具条按钮:

// Register the related commands.  注册相关的命令。
FCKCommands.RegisterCommand( 'My_Find' , new FCKDialogCommand( FCKLang['DlgMyFindTitle'] , FCKLang['DlgMyFindTitle'] , FCKConfig.PluginsPath + 'findreplace/find.html' , 340, 170 ) ) ;
FCKCommands.RegisterCommand( 'My_Replace' , new FCKDialogCommand( FCKLang['DlgMyReplaceTitle'], FCKLang['DlgMyReplaceTitle'] , FCKConfig.PluginsPath + 'findreplace/replace.html', 340, 200 ) ) ;
// Create the "Find" toolbar button.  创建 "find" 工具条按钮
var oFindItem = new FCKToolbarButton( 'My_Find', FCKLang['DlgMyFindTitle'] ) ;
oFindItem.IconPath = FCKConfig.PluginsPath + 'findreplace/find.gif' ;
FCKToolbarItems.RegisterItem( 'My_Find', oFindItem ) ; // 'My_Find' is the name used in the Toolbar config. 'My_Find' 是配置文件中ToolbarSets 工具集数组设置时要使用到的项目名(每个项目对应一个按钮)。
// Create the "Replace" toolbar button.  创建"Replace" 工具条按钮
var oReplaceItem = new FCKToolbarButton( 'My_Replace', FCKLang['DlgMyReplaceTitle'] ) ;
oReplaceItem.IconPath = FCKConfig.PluginsPath + 'findreplace/replace.gif' ;
FCKToolbarItems.RegisterItem( 'My_Replace', oReplaceItem ) ; // 'My_Replace' is the name used in the Toolbar config. "My_Replace" 和上面的"My_Find" 一样是工具条配置时要使用到的按钮项目名。

译者注:在英文原著的说明文档中,有关插件的编写并不详细,并没有对fckplugin.js 里的像RegisterCommand 之类的函数做什么解释,所以,译者只好自己去查看 fck 编辑器的源码,以弄清插件安装的内幕。下面先介绍下上面文件中的RegisterCommand 等几个函数的定义。
  前面提到过,在创建编辑器时是通过 FCKeditor 的Create 方法来实现的,该方法 又会创建一个iframe 框架,该框架里再导入fckeditor.html 文件(就在编辑器安装目录里的editor目录下),该文件里有两行这样的代码:var sSuffix = ( /*@cc_on!@*/false ) ? 'ie' : 'gecko' ;   LoadScript( 'js/fckeditorcode_' + sSuffix + '.js' ) ;   也就是说他会加载editor/js目录里的 fckeditorcode_ie.js 文件或 fckeditorcode_gecko.js 文件,这里以 fckeditorcode_ie.js 文件为例来进行说明,fckeditor 大部分的内幕代码都在这文件中实现的。 用dreamweaver 打开 fckeditorcode_ie.js 文件 ,使用 ctrl + F 来搜索 RegisterCommand ,可以找到该函数的定义如下:FCKCommands.RegisterCommand=function(A,B){this.LoadedCommands[A]=B;}  再结合fckplugin.js 文件的代码可知,该函数其实就是 给LoadedCommands 数组添加一个成员,第一个参数作为成员名字在这里就是命令的名字,第二个参数就是对应创建的command命令实例,所以 FCKCommands.RegisterCommand( 'My_Find' , new FCKDialogCommand(...)); 其实就是 FCKCommands.LoadedCommands['My_Find']= new FCKDialogCommand(...);  
再来看看 FCKToolbarItems.RegisterItem 函数的定义 :FCKToolbarItems.RegisterItem=function(A,B){this.LoadedItems[A]=B;}  所以 FCKToolbarItems.RegisterItem( 'My_Find', oFindItem ) ; 等效于 FCKToolbarItems.LoadedItems['My_Find']=oFindItem;
那么编辑器又是如何利用 FCKToolbarItems.LoadedItems 和 FCKCommands.LoadedCommands 这两个数组来完成各种操作的呢?(像编辑器如何通过配置文件中的工具集数组(FCKConfig.ToolbarSets)里的项目名找到相关的按钮,以及在点击按钮时找到相关的命令)。
  在 RegisterItem 函数定义的后面紧跟着一个函数 ---> FCKToolbarItems.GetItem 函数,这个函数的定义如下:
function(A){var B=FCKToolbarItems.LoadedItems[A];if (B) return B;switch (A){case 'Source':B=new FCKToolbarButton('Source',FCKLang.Source,null,0,true,true,1);break;case 'Preview': .....(中间的省略)...FCKToolbarItems.LoadedItems[A]=B;return B;}; 。 可以知道,他先从 LoadItem数组里查找项目名,找到按钮的项目名,就将对应的按钮实例返回,否则就利用switch ... case ... 结构根据参数名创建相应的按钮实例,例如 'Source' (源代码显示)项目就会使用new FCKToolbarButton('Source',FCKLang.Source,null,0,true,true,1); 创建一个 Source按钮,FCKToolbarButton函数的定义也可以使用搜索功能搜索到,定义如下:

  var FCKToolbarButton=function(A,B,C,D,E,F,G){this.CommandName=A;this.Label=B;this.Tooltip=C;this.Style=D;this.SourceView=E?true:false;this.ContextSensitive=F?true:false;if (G==null) this.IconPath=FCKConfig.SkinPath+'toolbar/'+A.toLowerCase()+'.gif';else if (typeof(G)=='number') this.IconPath=[FCKConfig.SkinPath+'fck_strip.gif',16,G];else this.IconPath=G;} 可以看出,该创建按钮实例的函数的各参数的含义:第一个A参数表示该按钮对应的执行命令的名称(相关的命令实例可以使用类似于new FCKDialogCommand的形式创建),第二个B参数就是该按钮的标签名(如果第三个参数为null,那么就以这个参数作为气泡提醒的内容),C 参数就是 Tooltip 工具条气泡提醒内容,D从Style名称可知应该是相关的样式,E参数还没弄的很清楚,不过应该就是是否显示源码的意思,F参数表示是否加入右键点击弹出 上下文中,G参数就是该按钮的图标的位置,如果是数字那么就从fck_strip.gif图片中通过定位得到!

回到 FCKToolbarItems.GetItem 函数,该函数中的switch  case 部分是编辑器里所有默认的按钮实例的创建过程,一些CMS 像dedeCMS 在处理图片浏览功能时代码如下:
//这里是按钮描述部份 Dede扩展
case 'Image':B=new FCKToolbarButton('Image',FCKLang.InsertImageLbl,FCKLang.InsertImage,null,false,true,37);break;
dedecms通过修改 switch case 部分的代码,从而创建出属于自己的按钮实例。
   编辑器的工具条的创建过程,其实就是通过配置文件里的ToolbarSets数组里的项目名循环调用FCKToolbarItems.GetItem 函数从而得到每个按钮实例的。可以查看 FCKToolbarSet.prototype.Load 函数,里面的 for (var j=0;j<C.length;j++) ...(省略代码)...FCKToolbarItems.GetItem(E) ....(省略代码)  就是循环处理部分。

posted @ 2010-09-04 07:44  夜壶  阅读(611)  评论(0编辑  收藏  举报