CKEditor扩展插件:自动排版功能

CKEditor是新一代的FCKeditor,是一个重新开发的版本。CKEditor是全球最优秀的网页在线文字编辑器之一,因其惊人的性能与可扩展性而广泛的被运用于各大网站。

如果还没接触过的可以看看,在线演示地址:http://ckeditor.com/demo

当然了,今天我们的主要目的还不是介绍。

还未下载CKEditor的同学可以点击下载:http://ckeditor.com/download

下载完后的结构是这样的:


image


 

好了,开始制作了,我们照着执行顺序来吧。

1.注册插件

首先找到根目录下的config.js文件,打开文件如下:

CKEDITOR.editorConfig = function (config) {    // Define changes to default configuration here. For example:
    // config.language = 'fr';
    // config.uiColor = '#AADC6E';};

 

我们需要将我们的插件注册进CKEDITOR中。

在方法内部加入如下代码:

 config.extraPlugins = "autoformat";
 

2.创建Plugin.js文件

在Plugins文件下新建一个与插件名相同的文件夹:autoformat 的文件夹,意为自动排版。

再在文件夹内创建一个plugin.js文件,因为在注册插件后,首先加载和执行的就是plugin.js这个文件。

plugin.js文件内容

//一键排版
(function () {
    CKEDITOR.plugins.add('autoformat', {
        requires: ['styles', 'button'],
        init: function (a) {
            a.addCommand('autoformat', CKEDITOR.plugins.autoformat.commands.autoformat);
            a.ui.addButton('autoformat', {
                label: "一键排版",
                command: 'autoformat',
                icon: this.path + "images/autoformat.gif"
            });
        }
    });
    CKEDITOR.plugins.autoformat = {
        commands: {
            autoformat: {
                exec: function (editor) {
                    formatText(editor);
                }
            }
        }
    };

    //格式化
    function formatText(editor) {
        var myeditor = editor;
        if (myeditor.mode == "wysiwyg") {
            var tempimg = new Array();
            var temptable = new Array();
            var tempobject = new Array();

            var isPart = false; //暂时无法实现局部格式化
            if (!isPart) {
                var tmpDiv = document.createElement("DIV");
                var editorhtml = myeditor.getData();
                editorhtml = editorhtml.replace(/<div style="page-break-after: always;?">\s*<span style="display: none;?">&nbsp;<\/span>\s*<\/div>/gi, '<p>[page]</p>');  //将div span标签替换为p 标签
                tmpDiv.innerHTML = editorhtml.replace(/&nbsp;/gi, '').replace(/<div/gi, '<p').replace(/<\/div/gi, '</p');     //移除空格标签,div替换为p标签。
                if (window.navigator.userAgent.toLowerCase().indexOf("msie") > 0) {
                    tmpDiv.innerHTML = tmpDiv.innerHTML.replace(/<\/p>/gi, '<br /><\/p>');      //每个段落相隔一行
                }
                var tables = tmpDiv.getElementsByTagName("TABLE");
                if (tables != null && tables.length > 0) {
                    for (var j = 0; j < tables.length; j++) {
                        temptable[temptable.length] = tables[j].outerHTML;
                    }
                    var formattableCount = 0;
                    for (var j = 0; j < tables.length;) {
                        tables[j].outerHTML = "#FormatTableID_" + formattableCount + "#";
                        formattableCount++;
                    }
                }

                var objects = tmpDiv.getElementsByTagName("OBJECT");
                if (objects != null && objects.length > 0) {
                    for (var j = 0; j < objects.length; j++) {
                        tempobject[tempobject.length] = objects[j].outerHTML;
                    }
                    var formatobjectCount = 0;
                    for (var j = 0; j < objects.length;) {
                        objects[j].outerHTML = "#FormatObjectID_" + formatobjectCount + "#";
                        formatobjectCount++;
                    }
                }

                var imgs = tmpDiv.getElementsByTagName("IMG");
                if (imgs != null && imgs.length > 0) {
                    for (var j = 0; j < imgs.length; j++) {
                        var t = document.createElement("IMG");
                        t.alt = imgs[j].alt;
                        t.src = imgs[j].src;
                        t.width = imgs[j].width;
                        t.height = imgs[j].height;
                        t.align = imgs[j].align;
                        tempimg[tempimg.length] = t;
                    }
                    var formatImgCount = 0;
                    for (var j = 0; j < imgs.length;) {
                        imgs[j].outerHTML = "#FormatImgID_" + formatImgCount + "#";
                        formatImgCount++;
                    }
                }

                var strongarray = new Array();
                var strongcount = 0;
                for (var i = 0; i < tmpDiv.getElementsByTagName('b').length; i++) {
                    strongarray[strongcount] = tmpDiv.getElementsByTagName('b')[i].innerText.trim();
                    tmpDiv.getElementsByTagName('b')[i].innerHTML = "#FormatStrongID_" + strongcount + "#";
                    strongcount++;
                }

                for (var i = 0; i < tmpDiv.getElementsByTagName('strong').length; i++) {
                    strongarray[strongcount] = tmpDiv.getElementsByTagName('strong')[i].innerText.trim();
                    tmpDiv.getElementsByTagName('strong')[i].innerHTML = "#FormatStrongID_" + strongcount + "#";
                    strongcount++;
                }
                var html = processFormatText(tmpDiv.innerText);
                html = html.replace(/<p>\[page\]<\/p>/gi, '<div style="page-break-after: always;"><span style="display: none;">&nbsp;</span></div>');   //p标签替换回原来的div和span标签。
                if (temptable != null && temptable.length > 0) {
                    for (var j = 0; j < temptable.length; j++) {
                        var tablehtml = temptable[j];
                        html = html.replace("#FormatTableID_" + j + "#", tablehtml);
                    }
                }

                if (tempobject != null && tempobject.length > 0) {
                    for (var j = 0; j < tempobject.length; j++) {
                        var objecthtml = "<p align=\"center\">" + tempobject[j] + "</p>";
                        html = html.replace("#FormatObjectID_" + j + "#", objecthtml);
                    }
                }

                if (tempimg != null && tempimg.length > 0) {
                    for (var j = 0; j < tempimg.length; j++) {
                        var imgheight = "";
                        var imgwidth = "";
                        if (tempimg[j].height != 0)
                            imgheight = " height=\"" + tempimg[j].height + "\"";
                        if (tempimg[j].width != 0)
                            imgwidth = " width=\"" + tempimg[j].width + "\"";
                        var imgalign = "";
                        if (tempimg[j].align != "")
                            imgalign = " align=\"" + tempimg[j].align + "\"";
                        var imghtml = "<p align=\"center\"><img src=\"" + tempimg[j].src + "\" alt=\"" + tempimg[j].alt + "\"" + imgwidth + " " + imgheight + " align=\"" + tempimg[j].align + "\" border=\"0\"></p>";
                        html = html.replace("#FormatImgID_" + j + "#", imghtml);
                    }
                }

                for (var i = 0; i < strongcount; i++) {
                    html = html.replace("#FormatStrongID_" + i + "#", "<p><strong>" + strongarray[i] + "</strong></p>");
                }

                while (html.indexOf("</p></p>") != -1) html = html.replace("</p></p>", "</p>");
                while (html.indexOf('<p><p align="center">') != -1) html = html.replace('<p><p align="center">', '<p align="center">');
                editor.setData(html);

            } else {

            }
        } else {
            alert('必须在设计模式下操作!');
        }
    }

    function processFormatText(textContext) {
        var text = dbc2Sbc(textContext);
        var prefix = "";
        var tmps = text.split("\n");
        var html = "";
        for (var i = 0; i < tmps.length; i++) {
            var tmp = tmps[i].trim();
            if (tmp.length > 0) {
                var reg = /#Format[A-Za-z]+_\d+#/gi;
                var f = reg.exec(tmp);
                if (f != null) {
                    tmp = tmp.replace(/#Format[A-Za-z]+_\d+#/gi, '');
                    html += f;
                    if (tmp != "")
                        html += "<p align=\"center\">" + tmp + "</p>\n";
                } else {
                    html += "<p style='text-indent:2em;'>" + tmp + "</p>\n";
                }
            }
        }
        return html;
    }

    function dbc2Sbc(str) {
        var result = '';
        for (var i = 0; i < str.length; i++) {
            var code = str.charCodeAt(i);
            // “65281”是“!”,“65373”是“}”,“65292”是“,”。不转换","

            if (code >= 65281 && code < 65373 && code != 65292 && code != 65306) {
                //  “65248”是转换码距
                result += String.fromCharCode(str.charCodeAt(i) - 65248);
            } else {
                result += str.charAt(i);
            }
        }
        return result;
    }

    String.prototype.trim = function () {
        return this.replace(/(^[\s ]*)|([\s ]*$)/g, "");
    };

    String.prototype.leftTrim = function () {
        return this.replace(/(^\s*)/g, "");
    };

    String.prototype.rightTrim = function () {
        return this.replace(/(\s*$)/g, "");
    };
})();

Plugin.js

上面文件内容中,前几行:

addCommand方法有两个参数:插件命令名称,第二个是命令执行的方法。

addButton方法的第一个参数是:插件的按钮名称

    label:鼠标悬浮时插件提示

    command:执行插件命令的名称

    icon:插件图标


接下来配置你的editor图标,将 autoformat 填进相应位置,一键自动排版功能就会出现在按钮栏了:

	CKEDITOR.config.toolbar_MyFull =
[
    { name: 'document',    items : [ 'Source','-','autoformat','-','Maximize','-','Preview','-','SelectAll','Undo','Redo','ShowBlocks','-'] },
    { name: 'links',       items : [ 'Link','Unlink','-'] },
    { name: 'insert',      items : [ 'Image','Flash','Table','HorizontalRule','SpecialChar','About'] },
    '/',
    { name: 'basicstyles', items : [ 'Bold','Italic','Underline','Strike','-','RemoveFormat' ] },
    { name: 'paragraph',   items : [ 'NumberedList','BulletedList','-','JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock','-' ] },
    { name: 'styles',      items : [ 'Styles','Format','Font','FontSize' ] },
    { name: 'colors',      items : [ 'TextColor','BGColor' ] },
];

效果如下图:

一键排版.png

此插件可以一键清除超链,清除字体,CSS样式,自动转换段落,并自动排版对齐,图片居中等功能。

方法引用自:https://www.cnblogs.com/yangda/archive/2013/11/12/3410441.html