`

CKeditor的插件开发

阅读更多

From: http://www.voofie.com/content/2/ckeditor-plugin-development/ 根据comment有修改
CKeditor API: http://docs.cksource.com/ckeditor_api/index.html
CKEditor 是目前市场上比较灵活的在线WYSIWYG编辑器之一. 它灵活的设计, 开放的API和详细的文档使得用户扩展功能非常容易. 本文尝试勾勒出 CKEditor插件开发的基础,包含了增加按钮,对话框和执行命令.

源代码的结构

在开始之前,感性的认知一下CKEditor源码的组织形式是很有用的. CKEditor固有的一些文件被组织到ckeditor\_source目录里. 核心的功能,诸如DOM元素操作,事件处理,初始化脚本和一些环境设置被包含在ckeditor\_source\core文件夹内. 而其它的一些功能, 比如格式化,拷贝和粘贴, 图片和链接, 都被实现为插件形式放在ckeditor\_source\plugins文件夹内. 每个文件夹表示一个插件. 并且在每个文件夹内, 有一个plugin.js的文件包含了该插件需要用到的代码.
你可以看到源代码被组织成不同的文件. 为了减少HTTP请求, CKEditor把不同的文件压缩并打包到ckeditor.js和ckeditor_basic.js里, 这种方式是运行编辑器的默认方式. 在开发的过程中, 你会希望通过ckedtior_source.js来代替ckeditor.js的执行.
现在, 创建ckeditor\_source\plugins\footnote目录,并在目录里创建plugin.js文件.

配置插件

为了开始开发你的插件, 你需要首先注册你的插件,这样CKEditor才能载入它. 在ckeditor/config.js里,增加:
config.extraPlugins = 'footnote';

此配置将会告诉编辑器在footnote目录下载入plugin.js. 基本的plugin.js结构如下:
1
2
3
4
5
6
7
CKEDITOR.plugins.add('footnote',
{
    init: function(editor)
    {
        //plugin code goes here
    }
});

按钮

CKEditor中主要的功能的实现基本都是通过命令的形式. 命令由事件,函数调用或者点击某个工具栏的按钮触发. 下列代码增加了一个’Footnote’的按钮和‘footnote’的命令.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
CKEDITOR.plugins.add('footnote',
{
    init: function(editor)
    {
        var pluginName = 'footnote';
        CKEDITOR.dialog.add(pluginName, this.path + 'dialogs/footnote.js');
        editor.addCommand(pluginName, new CKEDITOR.dialogCommand(pluginName));
        editor.ui.addButton('Footnote',
            {
                label: 'Footnote or Citation',
                command: pluginName
            });
    }
});
editor.ui.addButton函数声明包含了两个参数, 按钮名字和按钮定义. 在按钮定义中可能的属性还包含:
  • label: 当鼠标位于按钮之上时所出现的文字提示
  • className: 按钮的css类名. 默认为: ‘cke_button_’ + 命令名称
  • click: 当点击按钮后所调用的函数. 默认为: 执行由 命令键值 指定的命令.
  • command: 将在按钮点击之后执行的命令
    上述代码利用了CKEDTIOR.dialogCommand,该函数将在下面的对话章节中介绍. 在添加了一个按钮后,你需要把‘Footnote’增加到config.js的工具栏的定义中, 把该按钮放到工具栏的合适的位置. 之后,你就能看到一个空的按钮出现在工具栏里.

按钮图片

最简单的增加按钮图片的办法是利用属性icon. 代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
CKEDITOR.plugins.add('myplugin',
{
    init: function(editor)
    {
        //plugin code goes here
        editor.ui.addButton('myplugin',
            {
                label: 'myplugin',
                command: FCKCommand_myplugin,
                icon: CKEDITOR.plugins.getPath('myplugin') + 'myplugin.png'
            });
    }
});

命令

CKEditor以命令的方式提供了大部分的功能. 命令和函数之间的不同是 命令是有“ON”, “OFF“和未启用状态的.

定义一个命令

editor.addCommand函数声明了两个参数, 命令名字和命令的对象定义. 可能的命令定义的属性包含:
  • exec: 最小形式, 定义的对象拥有一个exec方法, 该方法会在命令执行时执行.
  • modes: 命令能被执行的模式. 默认为: {wysiwyg:1} 有效的模式是: wysiwyg, source
  • editorFocus: 在执行命令时,是否给予编辑器焦点. 默认: true
  • state: 命令的状态. 默认: CKEDITOR.TRISTATE_OFF
  • canUndo: 该命令是否会和redo/undo系统挂钩
  • async: 在异步功能,例如ajax中被用到. 在执行完命令后, afterCommandExec事件将不会被自动触发. 它将期望程序员能够手工触发该事件.

执行命令

触发命令是很简单的, 通过
editor.execCommand(commandName);

命令状态

命令有三个状态: ON, OFF和DISABLED. 状态能够通过setState进行设置,例如:
editor.getCommand(commandName).setState(state);

状态值将会是: CKEDITOR.TRISTATE_ON, CKEDITOR.TRISTATE_OFF, CKEDITOR.TRISTATE_DISABLED 中的一个.
当设置为未启用的时候, 按钮将会表现为灰色, 并且通过execCommand执行的命令将无效. 当设置为on的时候, 按钮就会被高亮. 当命令的状态改变的时候, 命令将会触发一个’state’事件.

对话框

对话框是一些插件的核心. 为了使用该对话框, 他们必须首先在plugin.js中注册, 包括定义, 通过调用CKEDITOR.dialog.add如下:
CKEDITOR.dialog.add(pluginName, this.path + 'dialogs/pluginName.js');

之后,如果你想通过点击一个按钮触发这个对话框, 你可以通过使用CKEDITOR.dialogCommand来简单的完成这项工作.
editor.addCommand(pluginName, new CKEDITOR.dialogCommand(pluginName));

对话框定义

按约定,有关对话框的代码将会被放到dialogs/.js中. 和按钮和命令类似, 对话框也是通过定义一些属性和方法来定义的. 下面的代码展示了一个标准的.js的模板:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
( function(){
  
  var exampleDialog = function(editor){
    return {
      title : /* title in string*/,
      minWidth : /*number of pixels*/,
      minHeight : /*number of pixels*/,
      buttons: /*array of button definitions*/,
      onOk: /*function*/ ,
      onLoad: /*function*/,
      onShow: /*function*/,
      onHide: /*function*/,
      onCancel: /*function*/,
      resizable: /* none,width,height or both  */,
      contents: /*content definition, basically the UI of the dialog*/
    }
  }
  
  CKEDITOR.dialog.add('insertHTML', function(editor) {
    return exampleDialog(editor);
  });
  
})();
定义里有以下一些属性/方法:
Buttons
该属性定义了对话框底部可用的按钮. 它是一个 CKEDITOR.dialog.buttonDefinition对象的数组. 默认的值是 [ CKEDITOR.dialog.okButton, CKEDITOR.dialog.cancelButton ]. 为了增加你自己的按钮, 你须要写下按钮的定义,并把它加到该数组里. 例如:
1
2
3
4
5
6
7
8
buttons:[{
    type:'button',
    id:'someButtonID', /* note: this is not the CSS ID attribute! */
    label: 'Button',
    onClick: function(){
       //action on clicking the button
    }
},CKEDITOR.dialog.okButton, CKEDITOR.dialog.cancelButton],

效果如下:
对话框事件
onOK, onLoad, onShow, onHide, onCancel 事件在不同的情况下会被触发. onLoad在对话框第一次打开的时候被触发, 可以用来针对该对话框做一些初始化. onShow在对话框显示的时候被触发. onLoad和onShow的不同之处在于onLoad将只触发一次,而不管对话框被打开或关掉多少次, 而同时onShow将在对话框每次显示的时候被触发. 这是因为在按下ok或cancel的时候,对话框将被隐藏(触发onHide),而不是完全的卸载. onOk和onCancel将在ok或cancel按钮被按下的时候触发.
Resizable
该属性用来描述对话框是否可以被调整大小. 可能的值包含: CKEDITOR.DIALOG_RESIZE_NONE, CKEDITOR.DIALOG_RESIZE_WIDTH, CKEDITOR.DIALOG_RESIZE_HEIGHT and CKEDITOR.DIALOG_RESIZE_BOTH. Default is CKEDITOR.DIALOG_RESIZE_NONE

对话框的UI

对话框的用户接口是对话框属性定义的内容. 对话框的UI部分会首先被组织为几个页面, 每个页面表示了对话框的一个tab页. 在每个页面中, 输入元素(按钮,文本输入,文本区域, 单选, 下拉, 多选和文件)都将被辅助性的结构元素(vbox,hbox和label)组织起来. 通过写这些UI元素的定义, 你将不须要写任何html代码而完成对这些UI的行为和外表的定义. 当然,替代使用这些所提供的对象来构建用户界面的方法是依然选择用原始的HTML代码去实现html的UI元素。
对话框的页面
内容域是一个contentDefinition的数组, 每个定义代表了一个对话框的tab页. 下面是一个模板:
1
2
3
4
5
6
7
8
9
10
11
contents: [{
        id: 'page1'/* not CSS ID attribute! */
        label: 'Page1',
        accessKey: 'P',
        elements:[ /*elements */]
    }, {
        id:'page2',
        label:'Page2',
        accessKey: 'Q',
        elements:[/*elements*/]
    }]


结果如下:
UI 元素
在定义了tab页面之后, 你可以通过传递一个uiElements的数组作为contentDefinition的元素来定义每个tab页的UI. 那里右两种类型的uiElements, 结构型的和输入型的. 结构型元素(vbox和hbox)使用表格来放置元素的位置. 结构型的元素可以镶嵌从而形成复杂的结构. 当输入的uiElements拥有一些比较重要的特征的时候这会使得他们比DOM输入元素更有用.
结构型元素

1
2
3
4
5
6
7
8
9
10
elements:[{
                    type : 'hbox',
                    widths : [ '100px', '100px', '100px' ],
                    children :
                    [{
                        type:'html',
                        html:'<div>Cell1',
                    },{
                        type:'html',
                        html:'
Cell2
', },{ type: 'vbox', children:[{ type:'html', html:'
Cell3
', },{ type:'html', html:'
Cell4
' }] }]
输入型元素
输入型元素有很多的属性和方法可用. 更多的细节请参考uiElement文档, 同时这里也有一些比较重要的:
  • id:(必须的) 注意这不是css的id属性, 但是是被CKEditor所使用的标识符. CKEditor将会自动设置css id属性但和这个id无关. 为了得到此对象所表示的元素, 你可以使用getContentElement. 例如, 如果你想得到uiElement内部的某个uiElement, 你可以使用:
this.getDialog().getContentElement(pageIdName,elementIdName)  //pageIdName is the ID for page containing the element
  • type:(必须的) 是以下的其中一个: text, password, textarea, checkbox, button, select, file, fileButton, html
  • label: 和输入元素同时显示的文本标签
  • labelLayout: ‘horizontal’横向 或 ‘vertical’ 纵向. 当设置为纵向的时候,标签会在元素的顶部.
  • on* events: 函数或事件. 第一个字符必须大写. 事件可以是DOM事件,例如onChange, onClick等,就像onShow, onHide 和onLoad, 这些在对话框被激活的时候调用的事件一样.
  • validate: 函数用来验证输入元素的值. 例如为了验证值不为空, 你可以使用:
validate : CKEDITOR.dialog.validate.notEmpty(ErrorMessage)

如果域是空的,那么错误消息将在你点击ok按钮的时候弹出.
内置的验证器包含:
  • regex(regex, msg)
  • notEmpty(msg)
  • integer(msg) //regex: /^\d*$/
  • number(msg) //regex: /^\d*(? :\.\d+)?$/
  • equals(value, msg)
  • notEqual(value, msg)
  • setup: 函数会在父对话框的setupContent方法被调用时执行. 能够被用来初始化一些域的值. 例如当编辑一个文档中已存图片域的时候, 你可能希望初始化该图片的宽度. 这里有个例子:
onShow : function(){ //onShow function for the dialog definition
    //... other code ...
    var elem= this.getParentEditor().getSelection().getSelectedElement(); //get the current selected element
    this.setupContent(elem);  //this function will call all the setup function for all uiElements
    //... other code...
},
contents: [{
    id: 'InfoTab',
    label: 'Info Tab',
    elements:[
    {  //input element for the width
        type: 'text',
        id: 'widthInput',
        label: 'Width',
        labelLayout: 'horizontal',
        setup: function(element){
            this.setValue(element.getAttribute('width'));
        }
    }]
}]
  • commit: 函数在父对话框的commitContent方法被调用的时候执行. 例如, 它能在ok按钮被按下时变更图片的大小.

上下文菜单

上下文菜单是你在CKEditor中右键所弹出的菜单. 就像CKEditor的其它特征一样,它也很容易被定制. 下面的代码展示了如何增加一个“Code“菜单项的过程:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
if(editor.addMenuItems)
{
    editor.addMenuItems(  //have to add menu item first
        {
            insertCode:  //name of the menu item
            {
                label: 'Code'
                command: 'insertCode',
                group: 'insertCode'  //have to be added in config
            }
        });
}
if(editor.contextMenu)
{
    editor.contextMenu.addListener(function(element, selection)  //function to be run when context menu is displayed
        {
            if(! element || !element.is('pre'))
                    return null;
            return { insertCode: CKEDITOR.TRISTATE_OFF };
        });
    }
前述代码在上下文菜单中增加了额外的insertCode元素. 当右击在非‘pre’元素上时, insertCode菜单将不会显示. 当右击在‘pre’元素上时insertCode菜单将会显示OFF状态.
除了上面的代码, 你依然需要把insertCode组放到config中,这样才能排列菜单显示的顺序. 以下是需要在config.js中增加的代码:
config.menu_groups = 'clipboard,form,tablecell,tablecellproperties,tablerow,tablecolumn,table,anchor,link,image,flash,checkbox,radio,textfield,hiddenfield,imagebutton,button,select,textarea,insertCode';

你会看到insertCode插入在了menu_groups配置的最后面. 最终的结果是:

源码打包

写完所有的代码之后, 就须要把你的代码产品化. 就像前面提到的那样, 原始的代码包含了很多文件,都会被压缩成一些个文件从而降低HTTP请求. 有必要把你的代码和这些文件合并。
打包这些文件实际上是由ckeditor.pack控制的. 把你的源代码文件放到‘ckeditor.js’的列表中, 将会把你的文件添加进去.
而事实上的打包,你须要额外的两个文件ckpackager.exe或ckpackager.jar. 在你下载完这两个文件后,在你的ckeditor根下运行下面的命令:
ckpackager.exe ckeditor.pack
现在你的源码文件将会自动被打包并拷贝到ckeditor的根目录下. 可以开始享用你的插件了!
分享到:
评论

相关推荐

    非常全面的CKEditor插件开发文档

    以下是对"非常全面的CKEditor插件开发文档"中关键知识点的详细解释: 1. **CKEditor插件体系**:CKEditor的插件系统是其核心特性之一,允许开发者通过编写插件来扩展编辑器的功能。插件可以是简单的按钮,也可以是...

    Ckeditor自定义插件

    首先,我们需要理解CKEditor插件的基本结构。每个CKEditor插件通常由几个关键部分组成: 1. **plugin.js**:这是插件的核心文件,包含了插件的定义和逻辑。在这里,我们需要定义插件的初始化代码,以及处理用户交互...

    ckeditor插件开发简单实例

    它提供了一个类似Word的界面供用户进行文本编辑,...以上就是CKEditor插件开发的一个简单实例,通过这个示例,可以学会如何为CKEditor创建一个自定义插件,实现用户在编辑文本时通过点击按钮向文本添加特定内容的功能。

    ckeditor行间距插件

    1. **CKEditor插件开发**:CKEditor支持自定义插件,开发者可以利用其提供的API来扩展编辑器的功能。在这个插件中,开发者可能定义了一个新的命令,用于改变选中文本的行间距。 2. **用户界面**:在编辑器的工具栏...

    ckeditor插件richcombo

    "ckeditor插件richcombo"是针对CKEditor这款著名的开源在线文本编辑器的一个增强组件。CKEditor是一款功能强大的富文本编辑器,广泛应用于网站、内容管理系统(CMS)和其他需要用户输入格式化文本的应用场景。 首先...

    CKEditor5开发环境

    CKEditor5的开发环境还支持插件开发。如果你需要添加自定义功能,可以创建一个新的插件。CKEditor5的文档提供了详细的教程,指导你如何编写、注册和使用插件。例如,你可以通过以下步骤创建一个新插件: 1. 在`src`...

    ckeditor插件

    **ckeditor插件详解** 在网页编程中,交互性和用户体验是至关重要的元素,而富文本编辑器则扮演着提升用户交互性的关键角色。CKEditor是一款功能强大的开源JavaScript富文本编辑器,广泛应用于各种网页应用,如内容...

    ckeditor4 行高插件

    这就需要对CKEditor的插件开发机制有深入的了解,包括插件的生命周期、命令处理、数据模型和视图的同步等。 总结来说,CKEditor4的行高插件是一个增强编辑体验的重要工具,它通过提供灵活的行高设置,提升了文本的...

    ckeditor自定义插件

    6. **测试与调试**:在完成插件开发后,需要在实际环境中进行测试,确保插件在各种情况下都能正常工作。CKEditor提供了丰富的API文档,这对于理解和解决可能出现的问题非常有帮助。 在阅读提供的博文链接()时,你...

    ckeditor 行间距插件

    总之,"ckeditor 行间距插件"是CKEditor功能扩展的一个实例,它展示了如何通过插件机制来增强编辑器的功能,同时也涉及到前端开发中的CSS样式控制、事件处理、兼容性测试等多个重要知识点。理解和掌握这些知识,对于...

    为CKEditor开发插入代码的插件

    总之,开发CKEditor插件是一项具有挑战性和创造性的工作,通过这样的插件,我们可以根据实际需求定制编辑器,提升开发效率和用户体验。插入代码的插件是其中的一个实例,它展示了CKEditor强大的可扩展性。理解并掌握...

    CKEditor二次开发手册 超详细哦!

    总的来说,CKEditor的二次开发涉及对编辑器核心功能的理解,插件机制的运用,以及通过API和UI组件来扩展编辑器的能力。这个过程需要开发者具备JavaScript基础,熟悉DOM操作,并能利用CKEditor提供的工具和文档进行...

    ckeditor 自己写的一个简单的image上传js 运用iframe的ajax上传

    4. **CKEditor插件开发**:`ckeditor.js`是CKEditor的核心库,`config.js`用于配置编辑器的行为。开发者创建的`myAddImage.js`或`mydialog.js`可能是自定义插件的实现,它扩展了CKEditor的功能,添加了一个图片上传...

    ckeditor图片自动上传

    1. **CKEditor插件开发**:了解CKEditor的API和插件开发指南,定制符合需求的上传功能。 2. **asp.net文件上传**:掌握asp.net中处理文件上传的方法,如`Request.Files`集合,以及如何处理上传文件的安全性。 3. *...

    ckeditor4音频视频上传自定义插件

    CKEditor 4音频视频上传插件的开发主要涉及以下几个核心知识点: 1. **CKEditor 4 API**:首先,我们需要熟悉CKEditor 4的API,这是创建自定义插件的基础。API提供了各种方法和事件,如`CKEDITOR.instances`用于...

    CKEditor 4 开发人员指南(中文)

    CKEditor支持使用插件来扩展其功能,开发者可以到CKEditor官方网站下载各种插件来满足特定需求。此外,CKEditor提供了一套完整的API,允许开发者编写自定义脚本进一步定制编辑器,比如创建自定义工具栏按钮,定制...

    CKeditor富文本编辑器插件资源

    CKeditor是一款广泛应用于网站开发中的开源富文本编辑器,它为用户提供了一个类似Word的界面,使得用户在网页上编辑内容时能享受到便捷的操作体验。这款编辑器提供了丰富的功能,包括文字格式化、图片上传、链接插入...

    CKEditor FLV视频播放插件

    FLV视频格式具有本身占有率低、视频质量良好、体积小等特点,非常适合在网络上传播。国内的视频站几乎都是采用FLV格式作为解决方案...于是我自己动手开发CKEditor的FLV视频播放插件现在上传。PS:这个版本是.net版的。

Global site tag (gtag.js) - Google Analytics