CKEditor扩展插件:自动排版功能
CKEditor是新一代的FCKeditor,是一个重新开发的版本。CKEditor是全球最优秀的网页在线文字编辑器之一,因其惊人的性能与可扩展性而广泛的被运用于各大网站。
如果还没接触过的可以看看,在线演示地址:http://ckeditor.com/demo
当然了,今天我们的主要目的还不是介绍。
还未下载CKEditor的同学可以点击下载:http://ckeditor.com/download
下载完后的结构是这样的:
好了,开始制作了,我们照着执行顺序来吧。
1.注册插件
首先找到根目录下的config.js文件,打开文件如下:
CKEDITOR.editorConfig = function (config) { // Define changes to default configuration here. For example: // config.language = 'fr'; // config.uiColor = '#AADC6E'; };
我们需要将我们的插件注册进CKEDITOR中。
在方法内部加入如下代码:
config.extraPlugins = "autoformart";
2.创建Plugin.js文件
在Plugins文件下新建一个与插件名相同的文件夹:aotuformart 的文件夹,意为自动排版。
再在文件夹内创建一个plugin.js文件,因为在注册插件后,首先加载和执行的就是plugin.js这个文件。
首先我们构建一个自执行函数,在自执行函数中添加一个插件:
1 (function() 2 { 3 CKEDITOR.plugins.add('autoformat',{ 4 init:function(editor){ 5 //初始化操作 6 } 7 }); 8 })();
添加一个命令和按钮在初始化函数中,如下:
1 (function() 2 { 3 CKEDITOR.plugins.add('autoformat',{ 4 init:function(editor){ 5 editor.addCommand( 'autoformat', new CKEDITOR.autoformatCommand()); 6 editor.ui.addButton('Autoformat',{label:'自动排版',command:'autoformat',icon:CKEDITOR.getUrl( this.path + 'images/autoformat.gif' )}); 7 } 8 }); 9 })();
addCommand方法有两个参数:插件命令名称,第二个是命令执行的方法。
addButton方法的第一个参数是:插件的按钮名称
label:鼠标悬浮时插件提示
command:执行插件命令的名称
icon:插件图标
好了,直接放出所有代码吧
1 //一键排版 2 (function () { 3 CKEDITOR.plugins.add('autoformat', { 4 requires: ['styles', 'button'], 5 init: function (a) { 6 a.addCommand('autoformat', CKEDITOR.plugins.autoformat.commands.autoformat); 7 a.ui.addButton('autoformat', { 8 label: "一键排版", 9 command: 'autoformat', 10 icon: this.path + "images/autoformat.gif" 11 }); 12 } 13 }); 14 CKEDITOR.plugins.autoformat = { 15 commands: { 16 autoformat: { 17 exec: function (editor) { 18 formatText(editor); 19 } 20 } 21 } 22 }; 23 24 //格式化 25 function formatText(editor) { 26 var myeditor = editor; 27 if (myeditor.mode == "wysiwyg") { 28 var tempimg = new Array(); 29 var temptable = new Array(); 30 var tempobject = new Array(); 31 32 var isPart = false; //暂时无法实现局部格式化 33 if (!isPart) { 34 var tmpDiv = document.createElement("DIV"); 35 var editorhtml = myeditor.getData(); 36 editorhtml = editorhtml.replace(/<div style="page-break-after: always;?">\s*<span style="display: none;?"> <\/span>\s*<\/div>/gi, '<p>[page]</p>'); //将div span标签替换为p 标签 37 tmpDiv.innerHTML = editorhtml.replace(/ /gi, '').replace(/<div/gi, '<p').replace(/<\/div/gi, '</p'); //移除空格标签,div替换为p标签。 38 if (window.navigator.userAgent.toLowerCase().indexOf("msie") > 0) { 39 tmpDiv.innerHTML = tmpDiv.innerHTML.replace(/<\/p>/gi, '<br /><\/p>'); //每个段落相隔一行 40 } 41 var tables = tmpDiv.getElementsByTagName("TABLE"); 42 if (tables != null && tables.length > 0) { 43 for (var j = 0; j < tables.length; j++) { 44 temptable[temptable.length] = tables[j].outerHTML; 45 } 46 var formattableCount = 0; 47 for (var j = 0; j < tables.length;) { 48 tables[j].outerHTML = "#FormatTableID_" + formattableCount + "#"; 49 formattableCount++; 50 } 51 } 52 53 var objects = tmpDiv.getElementsByTagName("OBJECT"); 54 if (objects != null && objects.length > 0) { 55 for (var j = 0; j < objects.length; j++) { 56 tempobject[tempobject.length] = objects[j].outerHTML; 57 } 58 var formatobjectCount = 0; 59 for (var j = 0; j < objects.length;) { 60 objects[j].outerHTML = "#FormatObjectID_" + formatobjectCount + "#"; 61 formatobjectCount++; 62 } 63 } 64 65 var imgs = tmpDiv.getElementsByTagName("IMG"); 66 if (imgs != null && imgs.length > 0) { 67 for (var j = 0; j < imgs.length; j++) { 68 var t = document.createElement("IMG"); 69 t.alt = imgs[j].alt; 70 t.src = imgs[j].src; 71 t.width = imgs[j].width; 72 t.height = imgs[j].height; 73 t.align = imgs[j].align; 74 tempimg[tempimg.length] = t; 75 } 76 var formatImgCount = 0; 77 for (var j = 0; j < imgs.length;) { 78 imgs[j].outerHTML = "#FormatImgID_" + formatImgCount + "#"; 79 formatImgCount++; 80 } 81 } 82 83 var strongarray = new Array(); 84 var strongcount = 0; 85 for (var i = 0; i < tmpDiv.getElementsByTagName('b').length; i++) { 86 strongarray[strongcount] = tmpDiv.getElementsByTagName('b')[i].innerText.trim(); 87 tmpDiv.getElementsByTagName('b')[i].innerHTML = "#FormatStrongID_" + strongcount + "#"; 88 strongcount++; 89 } 90 91 for (var i = 0; i < tmpDiv.getElementsByTagName('strong').length; i++) { 92 strongarray[strongcount] = tmpDiv.getElementsByTagName('strong')[i].innerText.trim(); 93 tmpDiv.getElementsByTagName('strong')[i].innerHTML = "#FormatStrongID_" + strongcount + "#"; 94 strongcount++; 95 } 96 var html = processFormatText(tmpDiv.innerText); 97 html = html.replace(/<p>\[page\]<\/p>/gi, '<div style="page-break-after: always;"><span style="display: none;"> </span></div>'); //p标签替换回原来的div和span标签。 98 if (temptable != null && temptable.length > 0) { 99 for (var j = 0; j < temptable.length; j++) { 100 var tablehtml = temptable[j]; 101 html = html.replace("#FormatTableID_" + j + "#", tablehtml); 102 } 103 } 104 105 if (tempobject != null && tempobject.length > 0) { 106 for (var j = 0; j < tempobject.length; j++) { 107 var objecthtml = "<p align=\"center\">" + tempobject[j] + "</p>"; 108 html = html.replace("#FormatObjectID_" + j + "#", objecthtml); 109 } 110 } 111 112 if (tempimg != null && tempimg.length > 0) { 113 for (var j = 0; j < tempimg.length; j++) { 114 var imgheight = ""; 115 var imgwidth = ""; 116 if (tempimg[j].height != 0) 117 imgheight = " height=\"" + tempimg[j].height + "\""; 118 if (tempimg[j].width != 0) 119 imgwidth = " width=\"" + tempimg[j].width + "\""; 120 var imgalign = ""; 121 if (tempimg[j].align != "") 122 imgalign = " align=\"" + tempimg[j].align + "\""; 123 var imghtml = "<p align=\"center\"><img src=\"" + tempimg[j].src + "\" alt=\"" + tempimg[j].alt + "\"" + imgwidth + " " + imgheight + " align=\"" + tempimg[j].align + "\" border=\"0\"></p>"; 124 html = html.replace("#FormatImgID_" + j + "#", imghtml); 125 } 126 } 127 128 for (var i = 0; i < strongcount; i++) { 129 html = html.replace("#FormatStrongID_" + i + "#", "<p><strong>" + strongarray[i] + "</strong></p>"); 130 } 131 132 while (html.indexOf("</p></p>") != -1) html = html.replace("</p></p>", "</p>"); 133 while (html.indexOf('<p><p align="center">') != -1) html = html.replace('<p><p align="center">', '<p align="center">'); 134 editor.setData(html); 135 136 } else { 137 138 } 139 } else { 140 alert('必须在设计模式下操作!'); 141 } 142 } 143 144 function processFormatText(textContext) { 145 var text = dbc2Sbc(textContext); 146 var prefix = ""; 147 var tmps = text.split("\n"); 148 var html = ""; 149 for (var i = 0; i < tmps.length; i++) { 150 var tmp = tmps[i].trim(); 151 if (tmp.length > 0) { 152 var reg = /#Format[A-Za-z]+_\d+#/gi; 153 var f = reg.exec(tmp); 154 if (f != null) { 155 tmp = tmp.replace(/#Format[A-Za-z]+_\d+#/gi, ''); 156 html += f; 157 if (tmp != "") 158 html += "<p align=\"center\">" + tmp + "</p>\n"; 159 } else { 160 html += "<p style='text-indent:2em;'>" + tmp + "</p>\n"; 161 } 162 } 163 } 164 return html; 165 } 166 167 function dbc2Sbc(str) { 168 var result = ''; 169 for (var i = 0; i < str.length; i++) { 170 var code = str.charCodeAt(i); 171 // “65281”是“!”,“65373”是“}”,“65292”是“,”。不转换"," 172 173 if (code >= 65281 && code < 65373 && code != 65292 && code != 65306) { 174 // “65248”是转换码距 175 result += String.fromCharCode(str.charCodeAt(i) - 65248); 176 } else { 177 result += str.charAt(i); 178 } 179 } 180 return result; 181 } 182 183 String.prototype.trim = function () { 184 return this.replace(/(^[\s ]*)|([\s ]*$)/g, ""); 185 }; 186 187 String.prototype.leftTrim = function () { 188 return this.replace(/(^\s*)/g, ""); 189 }; 190 191 String.prototype.rightTrim = function () { 192 return this.replace(/(\s*$)/g, ""); 193 }; 194 })();