本文内容
- FineUI ckeditor
- fckeditor/ckeditor
- 演示 ckeditor 4.2.1 上传&插入图片
最近看了一下 FineUI_v3.3.1 控件,对里边的 ckeditor(html 编辑)控件很感兴趣,因为之前用 Ext.Net 的 htmleditor 控件时,需要一个上传并插入图片的功能,可是 htmleditor 本身没有,就写 ext js 代码在其工具条额外增加一个按钮完成次功能。但无论如何 htmleditor 自身实在过于简单,没什么意思。但 FineUI 的 ckeditor 存在 bug。于是就看研究了一下原始的 fckeditor/ckeditor 控件,这是比较严谨、跨浏览器的实现方式。
FineUI ckeditor
FineUI 解决方案目录结构如下图所示,包括文档,FineUI 源代码和示例,以及工具。
图 1 上:FineUI目录;中:FineUI/tools目录,封装ckeditor控件的项目;下:FineUI示例目录下ckeditor支持目录
期间发现 FineUI 因为实现方式过于草率,存在 bug,这跟它开发的方式有很大关系。如果你去看其官网演示,会发现特别像 ext js/Ext.Net,毕竟它是建立在 ext js 基础上的,而且演示组织方式是按各个小功能点来划分,显然有别于一般的演示。另外,针对 FineUI 封装的 ckeditor,部分直接采用通过控件或 html 里 script 标记向客户端输出 iframe 加载 html 页面,以及标记。这样,实现虽然简单了,但总让人感觉不放心。调试果然发现,不是所有主流浏览器都能正常使用,不同的 firefox 版本也存在问题,时不时会出现变量为 null 或 undefined 的情况……说明,FineUI ckeditor 没有控制好自己的资源。
fckeditor/ckeditor
FCKEditor 最初是以其开发者 Frederico Calderia Knabben 命名,在 2009 年更新到 3.0 时改名为 CKEditor,CK 意思“Content and Knowledge”。据官方解释,CK 是对 FCK 的完全重写。CKEditor 4 于2012年11月28日正式版发布,该版本全新外观、提升代码、即时编辑和其他诸多改进。同时,还发布了一个包含扩展中心和 CKBuilder 服务的网站,用于创建你自己的 CKEditor 版本。
看到 fck 的第一反应和联想是,有个控件叫 ck,另一个觉得不爽的人起了一个 fck 的控件,跟 ck 功能完全一样,意指“fuck ck”,跟人家对着干;或是刚开始的 fck 容易让人想到 fuck,之后的版本就改掉了,呵呵~
你可以利用 CKBuilder下载自己的 ckeditor,定制想要 ckeditor的功能,包含有三方面:
- 预设置。工具条内容不同,包括基本、标准、全部。
- 插件和皮肤。ckeditor 工具栏按钮/功能,都是以插件形式存在,页面左边是默认插件,右边是其他人为 ckeditor 开发的其他插件,比如插入 googlemap 或特殊符号等等;主题有三种,自己选择。
- 语言。各个国家的语言。
图 2
演示 ckeditor 4.2.1 上传&插入图片
软件环境
- VS 2010
解决方案结构
图 3 本演示解决方案的结构
说明:
- 项目最好在 ckeditor 目录下,最好不要改变。
图 4 本演示创建的页面和涉及的 ckeditor js 文件
其中,
- Samples\myImage.html 是本演示主页面。
- Samples\myImageUpload.html 是本演示上传图片的处理程序。
- Samples\upload 目录是上传图片的目录。
- Plugins\filebrowser 目录是 ckeditor 工具栏上文件浏览器插件。只要进行适当设置,就可以使用所有文件浏览的功能。包括“浏览服务器资源”(2) 和“向服务器上传资源”(1),资源可以是图片,Flash。
图 5
- Plugins\Image 目录是 ckeditor 工具栏上图片按钮的插件。完成向 html 插入图片,并对图片进行设置。默认情况下,Image插件里边的“浏览服务器”(2) 和“上传到服务器”(1) 这两个按钮是隐藏的,你可以从其源代码看出来 hidden=true。可是只要你在创建 ckeditor 时,指定了 filebrowserBrowseUrl 或 filebrowser***UploadUrl(如,filebrowserImageUploadUrl、filebrowserFlashUploadUrl 等)属性,就可以看到这两个按钮,如下代码所示:
CKEDITOR.replace('editor1', {language: 'zh',filebrowserBrowseUrl:’your handler’,filebrowserImageUploadUrl: ’your handler’});参考:cksource 文档
Samples\myImage.html
<!DOCTYPE html><!--Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.For licensing, see LICENSE.md or http://ckeditor.com/license--><html><head> <title>image upload — CKEditor Sample</title> <meta charset="utf-8"> <script src="../ckeditor.js"></script> <link rel="stylesheet" href="sample.css"></head><body> <h1 class="samples"> <a href="index.html">CKEditor Samples</a> » image upload </h1> <form method="post"> <p> <textarea cols="80" id="editor1" name="editor1" rows="10"><p>This is some <strong>sample text</strong>. You are using <a href="http://ckeditor.com/">CKEditor</a>.</p></textarea> <script> // Replace the <textarea id="editor"> with an CKEditor // instance, using default configurations. CKEDITOR.replace('editor1', { language: 'zh-cn', filebrowserImageUploadUrl: 'myImageUpload.ashx', toolbar: [ ['Bold', 'Italic', '-', 'NumberedList', 'BulletedList', '-', 'Link', 'Unlink'], ['FontSize', 'TextColor', 'BGColor'], ['Image'] ] }); </script> </p> <p> <input type="submit" value="Submit"> </p> </form></body></html>说明:
Samples\myImageUpload.html
<%@ WebHandler Language="C#" Class="myImageUpload" %> using System;using System.Web;using System.Drawing;using System.Drawing.Imaging;using Newtonsoft.Json;using Newtonsoft.Json.Converters; public class myImageUpload : IHttpHandler{ HttpRequest httpRequest; HttpResponse httpResponse; string uploadDir = "upload"; public void ProcessRequest(HttpContext context) { httpRequest = context.Request; httpResponse = context.Response; string funcNum = httpRequest.QueryString["CKEditorFuncNum"]; string fileName = null; string errorMsg = null; string extName = string.Empty; string fileURL = string.Empty; string script = @" <script type='text/javascript'>window.parent.CKEDITOR.tools.callFunction({0}, '{1}', '{2}');</script> "; HttpPostedFile myfile = httpRequest.Files[0]; GetFileName(myfile.FileName, ref extName); fileName = Guid.NewGuid().ToString() + "." + extName; try { fileURL = uploadDir + "/" + fileName; myfile.SaveAs(System.Web.HttpContext.Current.Server.MapPath(uploadDir) + "\\" + fileName); errorMsg = null; } catch (Exception ex) { fileURL = null; errorMsg = ex.Message; } httpResponse.Write(string.Format(script, funcNum, fileURL, errorMsg)); } public bool IsReusable { get { return false; } } private void GetFileName(string fullName, ref string extName) { if (fullName.IsEmpty()) { extName = null; } else { int last; last = fullName.LastIndexOf(@"."); extName = fullName.Substring(last + 1, fullName.Length - last - 1); } }}说明:
- ckeditor会给你指定的处理程序传递三个变量,本演示中,即 myImageUpload.ashx?CKEditor=editor1&CKEditorFuncNum=1&langCode=zh,其中,CKEditorFuncNum 表示最后需要调用的客户端脚本。
运行结果:
图 6