FCKeditor的几点重要改进和使用心得,值得分享
以前公司购买过eWebEditor,功能应该还是不错的,但即便到了现在,也还仅是一个IE only的版本,无法满足现在差异化的需求。故前段时间下了最新的FCKeditor2.3.3版本下来(当然了,连带java的integration),demo来看看,发现有几个地方非常不爽:
1、上载的文件,只能放在URL可及的地方(如默认只能放到嵌入应用路径的/UserFiles/下);
2、没有明确的上载视频的按钮;
3、图片、FLASH、附件上载等,步骤多,复杂度高(想想,用户不都是高手)。
怎么办呢,改!
一、第一个就是增加一个FileLocatorServlet,思路很简单:通过这个服务来定位文件,而不是之间产生链接,既是安全的考虑,也是应用集群的一个重要考虑点。而且原来的几个servlet的配置罗嗦且重叠,难以让人产生美感。所谓代码胜千言,通过下面的web.xml大家应该可以看出修理的要点:
<?
xml version="1.0" encoding="ISO-8859-1"
?>
2
3
<!
DOCTYPE web-app4
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"5
"http://java.sun.com/j2ee/dtds/web-app_2_2.dtd"
>
6
7
<
web-app
>
8
<
display-name
>
FCKeditor Test Application
</
display-name
>
9
<
context-param
>
10
<!--
setting the FCKecitor context based parameters
-->
11
<!--
baseDir means the root of the uploaded file/image/flash stored 12
the prefix of 'file:/' means strore in a file system root that cannot get from webapp url13
-->
14
<
param-name
>
baseDir
</
param-name
>
15
<
param-value
>
file:/C:/Temp/FCKeditorUpload/
</
param-value
>
16
</
context-param
>
17
18
<
context-param
>
19
<!--
20
if the baseDir prefix by 'file:/',please set it.21
-->
22
<
param-name
>
fileLocator
</
param-name
>
23
<
param-value
>
/editor/filemanager/browser/default/service/jsp/filelocator
</
param-value
>
24
</
context-param
>
25
26
<
context-param
>
27
<!--
28
debug setting,true means verbose output to the console.29
-->
30
<
param-name
>
debug
</
param-name
>
31
<
param-value
>
true
</
param-value
>
32
</
context-param
>
33
34
<
context-param
>
35
<!--
36
enabled setting,true means upload enabled.37
-->
38
<
param-name
>
enabled
</
param-name
>
39
<
param-value
>
true
</
param-value
>
40
</
context-param
>
41
42
<
context-param
>
43
<!--
44
encoding,the response encoding of the file/image/flash,default is UTF-845
-->
46
<
param-name
>
encoding
</
param-name
>
47
<
param-value
>
UTF-8
</
param-value
>
48
</
context-param
>
49
50
<
context-param
>
51
<!--
52
contentTypeMapping,a map for the response ContentType53
-->
54
<
param-name
>
contentTypeMapping
</
param-name
>
55
<
param-value
>
doc=application/vnd.ms-word56
|xls=application/vnd.ms-excel57
|jpg=image/jpeg58
|gif=image/gif59
|swf=application/x-shockwave-flash60
|avi=video/x-msvideo61
</
param-value
>
62
</
context-param
>
63
64
<
context-param
>
65
<!--
66
allowedExtensionsFile,the logic is 'Not allowed means deny.'67
-->
68
<
param-name
>
allowedExtensionsFile
</
param-name
>
69
<
param-value
>
doc|xls|pdf|avi
</
param-value
>
70
</
context-param
>
71
72
<
context-param
>
73
<!--
74
allowedExtensionsImage,the logic is 'Not allowed means deny.'75
-->
76
<
param-name
>
allowedExtensionsImage
</
param-name
>
77
<
param-value
>
jpg|gif|png
</
param-value
>
78
</
context-param
>
79
80
<
context-param
>
81
<!--
82
allowedExtensionsFlash,the logic is 'Not allowed means deny.'83
-->
84
<
param-name
>
allowedExtensionsFlash
</
param-name
>
85
<
param-value
>
swf|fla
</
param-value
>
86
</
context-param
>
87
88
<
servlet
>
89
<
servlet-name
>
Connector
</
servlet-name
>
90
<
servlet-class
>
com.fredck.FCKeditor.connector.ConnectorServlet
</
servlet-class
>
91
<
load-on-startup
>
1
</
load-on-startup
>
92
</
servlet
>
93
94
<
servlet
>
95
<
servlet-name
>
FileLocator
</
servlet-name
>
96
<
servlet-class
>
com.fredck.FCKeditor.service.FileLocatorServlet
</
servlet-class
>
97
<
load-on-startup
>
1
</
load-on-startup
>
98
</
servlet
>
99
100
<
servlet
>
101
<
servlet-name
>
SimpleUploader
</
servlet-name
>
102
<
servlet-class
>
com.fredck.FCKeditor.uploader.SimpleUploaderServlet
</
servlet-class
>
103
<
load-on-startup
>
1
</
load-on-startup
>
104
</
servlet
>
105
106
<
servlet-mapping
>
107
<
servlet-name
>
Connector
</
servlet-name
>
108
<
url-pattern
>
/editor/filemanager/browser/default/connectors/jsp/connector
</
url-pattern
>
109
</
servlet-mapping
>
110
111
<
servlet-mapping
>
112
<
servlet-name
>
SimpleUploader
</
servlet-name
>
113
<
url-pattern
>
/editor/filemanager/upload/simpleuploader
</
url-pattern
>
114
</
servlet-mapping
>
115
116
<
servlet-mapping
>
117
<
servlet-name
>
FileLocator
</
servlet-name
>
118
<
url-pattern
>
/editor/filemanager/browser/default/service/jsp/filelocator
</
url-pattern
>
119
</
servlet-mapping
>
120
121
</
web-app
>
连带FCKeditorConfigurations.java一并修理,配置统一且singleton。关键代码为:
2
/** */
/** 3
* Make the configuration sigleton4
* @param sc5
* @return the static configuration map6
*/
7
public
static
Map getContextConfigurationsInstance(ServletContext sc)
{8
if (contextConfigurations == null )
{9
initContextConfigurations(sc);10
} 11
return contextConfigurations;12
}
13
14
/** */
/** 15
* Init all the FCKeditor configuration.16
* add by zhengxq17
* @param sc18
*/
19
private
static
void
initContextConfigurations(ServletContext sc)
{20
if (debug)21
System.out.println( " /r/n---- FCKeditorConfigurations for java initialization started ---- " );22
23
String baseDir = sc.getInitParameter( " baseDir " );24
String fileLocator = sc.getInitParameter( " fileLocator " );25
String debugStr = sc.getInitParameter( " debug " );26
String enabledStr = sc.getInitParameter( " enabled " ); 27
String encoding = sc.getInitParameter( " encoding " );28
String contentTypeMapping = sc.getInitParameter( " contentTypeMapping " );29
String AllowedExtensionsFile = sc.getInitParameter( " allowedExtensionsFile " );30
String AllowedExtensionsImage = sc.getInitParameter( " allowedExtensionsImage " );31
String AllowedExtensionsFlash = sc.getInitParameter( " allowedExtensionsFlash " );32
33
debug = ( new Boolean(debugStr)).booleanValue();34
encoding = (encoding == null || encoding.length() == 0 ) ? " UTF-8 " :encoding;35
36
if (baseDir == null || baseDir.length() == 0 ) baseDir = defaultBaseDir;37
String realBaseDir = defaultBaseDir;38
if (baseDir.startsWith(fileSystemUriPrefix))
{39
realBaseDir = baseDir.substring(fileSystemUriPrefix.length()); 40
} else
{41
realBaseDir = sc.getRealPath(baseDir);42
fileLocator = null ; // no use and should set null 43
} 44
File baseFile = new File(realBaseDir);45
if ( ! baseFile.exists())
{46
baseFile.mkdir();47
} 48
contextConfigurations = new HashMap();49
contextConfigurations.put( " baseDir " ,baseDir);50
contextConfigurations.put( " realBaseDir " ,realBaseDir);51
contextConfigurations.put( " fileLocator " ,fileLocator);52
contextConfigurations.put( " debug " ,debugStr);53
contextConfigurations.put( " enabled " ,enabledStr);54
contextConfigurations.put( " encoding " ,encoding);55
contextConfigurations.put( " contentTypeMapping " ,contentTypeMappingToMap(contentTypeMapping));56
contextConfigurations.put( " allowedExtensionsFile " ,stringToArrayList(AllowedExtensionsFile));57
contextConfigurations.put( " allowedExtensionsImage " ,stringToArrayList(AllowedExtensionsImage));58
contextConfigurations.put( " allowedExtensionsFlash " ,stringToArrayList(AllowedExtensionsFlash));59
60
if (debug)61
System.out.println( " /r/n---- FCKeditorConfigurations for java initialization end ---- " );62
63
}
FileLocatorServlet.java也很简单,无非就是文件的物理定位和文件流的输出:
String type
=
request.getParameter(
"
Type
"
);2
String fileName
=
request.getParameter(
"
FileName
"
);3
4
String realFilePath
=
config.get(
"
realBaseDir
"
)
+
type
+
"
/
"
+
fileName;5
File file
=
new
File(realFilePath);6
if
(file.exists())
{7
response.setHeader( " Content-Transfer-Encoding " , " base64 " );8
response.setHeader( " Cache-Control " , " no-store " );9
response.setHeader( " Pragma " , " no-cache " );10
response.setDateHeader( " Expires " , 0 );11
response.setContentType(getContentTypeByFileExt(fileName.substring(fileName.lastIndexOf( " . " ))));12
13
ServletOutputStream out = response.getOutputStream(); 14
InputStream in = new FileInputStream(file);15
BufferedInputStream bis = new BufferedInputStream(in);16
BufferedOutputStream bos = new BufferedOutputStream(out);17
byte [] buff = new byte [ 2048 ];18
int bytesRead;19
while ( - 1 != (bytesRead = bis.read(buff, 0 , buff.length)))
{20
bos.write(buff, 0 , bytesRead);21
} 22
if (bis != null )
{23
bis.close();24
} 25
if (bos != null )
{26
bos.close();27
} 28
}
else
{29
throw new FileNotFoundException(fileName);30
}
上述改动已经提交给了FCKeditor,如果大家真的有兴趣,可以去找里面我所提交的patch。
二、至于上述的2、3问题,同样,动手即可解决,在此略过。
过程中倒是碰到几个有意思的问题,成了花絮,其实也是使用FCKeditor的一些心得,写写可能还有点意思:
1、如何取得FCKeditor的值?
答案:这是我们常常干的事情:取得这个值并赋值给某个hidden,再合法性检查+submit等。怎么取得呢?这样:
var
oEditor
=
FCKeditorAPI.GetInstance('editor') ;2
//
Get the editor contents in XHTML.
3
//
alert( oEditor.GetXHTML(true) ) ; // "true" means you want it formatted.
4
document.all(
"
tip.c_content
"
).value
=
oEditor.GetXHTML(
true
);
2、如何使得FCKeditor接收tab键?
答案:我们希望界面元素按照外面的安排进行tab切换,但FCKeditor怎么能做到呢?也有办法:
function
focusIframeOnTab(caller, tabTargetId, callEvent)
{2
// If keypress TAB and not SHIFT+TAB 3
if (callEvent.keyCode == 9 && ! callEvent.shiftKey)4
document.getElementById(tabTargetId).contentWindow.focus();5
}
光光有个函数顶个什么用,还要这样:在之前的那个界面元素中加上下面的事件,如使用struts的tag的化,这样就可以了:
<
html:text
property
="tip.c_title"
style
="width:450px"
tabindex
="1"
onkeydown
="focusIframeOnTab(this, 'editor___Frame',event);if(!document.all) return false;"
/>
这点是google了半天最终在FCKeditor的FAQ中找到的,看来以后用开源的软件第一件事情就是看FAQ,错不了!
3、如何希望在FCKeditor加载完毕后做点什么事情?
答案:也很简单,编写自己的FCKeditor_OnComplete函数,如:
function
FCKeditor_OnComplete( editorInstance )
{
window.status = editorInstance.Description ;
}
4、如果在图片、FLASH等界面中上载了东西后,希望能告诉自己的表单,怎么做?
答案:这个花了我不少看代码和调试时间!其实这里的关键就是如何获取嵌入FCKeditor的那个window,这样就可以了,在对应的js文件(如editor/dialog/fck_image/fck_image.js)中的ok方法的最后加入:
//
edit by zhengxq
try
{
var obj = window.dialogArguments.Editor.parent.document;
obj.getElementById( " tip.c_tip_has_pic " ).value = " 1 " ;
}
catch
(e)
{}
关键就是:window.dialogArguments.Editor.parent.document,这个能够找到对应窗口的引用,有了这个,还不会控制吗?!
posted on 2007-03-11 20:20 IT进行时 阅读(2291) 评论(5) 编辑 收藏 所属分类: Java Tips
本文介绍了FCKeditor的几个重要改进方案,包括增加文件定位服务、优化上传流程,并分享了一些实用技巧,例如如何获取编辑器内容、实现tab键导航等。
185

被折叠的 条评论
为什么被折叠?



