茫茫網海中的冷日 - 對這文章發表回應
茫茫網海中的冷日
         
茫茫網海中的冷日
發生過的事,不可能遺忘,只是想不起來而已!
 恭喜您是本站第 1729249 位訪客!  登入  | 註冊
主選單

Google 自訂搜尋

Goole 廣告

隨機相片
PIMG_00063.jpg

授權條款

使用者登入
使用者名稱:

密碼:


忘了密碼?

現在就註冊!

對這文章發表回應

發表限制: 非會員 可以發表

發表者: 冷日 發表時間: 2009/3/27 1:15:14
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" ?>
<! DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"
"http://java.sun.com/j2ee/dtds/web-app_2_2.dtd" >

< web-app >
< display-name > FCKeditor Test Application </ display-name >
< context-param >
<!-- setting the FCKecitor context based parameters -->
<!-- baseDir means the root of the uploaded file/image/flash stored
the prefix of 'file:/' means strore in a file system root that cannot get from webapp url
-->
< param-name > baseDir </ param-name >
< param-value > file:/C:/Temp/FCKeditorUpload/ </ param-value >
</ context-param >

< context-param >
<!--
if the baseDir prefix by 'file:/',please set it.
-->
< param-name > fileLocator </ param-name >
< param-value > /editor/filemanager/browser/default/service/jsp/filelocator </ param-value >
</ context-param >

< context-param >
<!--
debug setting,true means verbose output to the console.
-->
< param-name > debug </ param-name >
< param-value > true </ param-value >
</ context-param >

< context-param >
<!--
enabled setting,true means upload enabled.
-->
< param-name > enabled </ param-name >
< param-value > true </ param-value >
</ context-param >

< context-param >
<!--
encoding,the response encoding of the file/image/flash,default is UTF-8
-->
< param-name > encoding </ param-name >
< param-value > UTF-8 </ param-value >
</ context-param >

< context-param >
<!--
contentTypeMapping,a map for the response ContentType
-->
< param-name > contentTypeMapping </ param-name >
< param-value > doc=application/vnd.ms-word
|xls=application/vnd.ms-excel
|jpg=image/jpeg
|gif=image/gif
|swf=application/x-shockwave-flash
|avi=video/x-msvideo
</ param-value >
</ context-param >

< context-param >
<!--
allowedExtensionsFile,the logic is 'Not allowed means deny.'
-->
< param-name > allowedExtensionsFile </ param-name >
< param-value > doc|xls|pdf|avi </ param-value >
</ context-param >

< context-param >
<!--
allowedExtensionsImage,the logic is 'Not allowed means deny.'
-->
< param-name > allowedExtensionsImage </ param-name >
< param-value > jpg|gif|png </ param-value >
</ context-param >

< context-param >
<!--
allowedExtensionsFlash,the logic is 'Not allowed means deny.'
-->
< param-name > allowedExtensionsFlash </ param-name >
< param-value > swf|fla </ param-value >
</ context-param >

< servlet >
< servlet-name > Connector </ servlet-name >
< servlet-class > com.fredck.FCKeditor.connector.ConnectorServlet </ servlet-class >
< load-on-startup > 1 </ load-on-startup >
</ servlet >

< servlet >
< servlet-name > FileLocator </ servlet-name >
< servlet-class > com.fredck.FCKeditor.service.FileLocatorServlet </ servlet-class >
< load-on-startup > 1 </ load-on-startup >
</ servlet >

< servlet >
< servlet-name > SimpleUploader </ servlet-name >
< servlet-class > com.fredck.FCKeditor.uploader.SimpleUploaderServlet </ servlet-class >
< load-on-startup > 1 </ load-on-startup >
</ servlet >

< servlet-mapping >
< servlet-name > Connector </ servlet-name >
< url-pattern > /editor/filemanager/browser/default/connectors/jsp/connector </ url-pattern >
</ servlet-mapping >

< servlet-mapping >
< servlet-name > SimpleUploader </ servlet-name >
< url-pattern > /editor/filemanager/upload/simpleuploader </ url-pattern >
</ servlet-mapping >

< servlet-mapping >
< servlet-name > FileLocator </ servlet-name >
< url-pattern > /editor/filemanager/browser/default/service/jsp/filelocator </ url-pattern >
</ servlet-mapping >

</ web-app >


連帶FCKeditorConfigurations.java一併修理,配置統一且singleton。關鍵代碼為:

程序代碼:
/** */ /**
* Make the configuration sigleton
* @param sc
* @return the static configuration map
*/
public static Map getContextConfigurationsInstance(ServletContext sc) {
if (contextConfigurations == null ) {
initContextConfigurations(sc);
}
return contextConfigurations;
}

/** */ /**
* Init all the FCKeditor configuration.
* add by zhengxq
* @param sc
*/
private static void initContextConfigurations(ServletContext sc) {
if (debug)
System.out.println( " \r\n---- FCKeditorConfigurations for java initialization started ---- " );

String baseDir = sc.getInitParameter( " baseDir " );
String fileLocator = sc.getInitParameter( " fileLocator " );
String debugStr = sc.getInitParameter( " debug " );
String enabledStr = sc.getInitParameter( " enabled " );
String encoding = sc.getInitParameter( " encoding " );
String contentTypeMapping = sc.getInitParameter( " contentTypeMapping " );
String AllowedExtensionsFile = sc.getInitParameter( " allowedExtensionsFile " );
String AllowedExtensionsImage = sc.getInitParameter( " allowedExtensionsImage " );
String AllowedExtensionsFlash = sc.getInitParameter( " allowedExtensionsFlash " );

debug = ( new Boolean(debugStr)).booleanValue();
encoding = (encoding == null || encoding.length() == 0 ) ? " UTF-8 " :encoding;

if (baseDir == null || baseDir.length() == 0 ) baseDir = defaultBaseDir;
String realBaseDir = defaultBaseDir;
if (baseDir.startsWith(fileSystemUriPrefix)) {
realBaseDir = baseDir.substring(fileSystemUriPrefix.length());
} else {
realBaseDir = sc.getRealPath(baseDir);
fileLocator = null ; // no use and should set null
}
File baseFile = new File(realBaseDir);
if ( ! baseFile.exists()) {
baseFile.mkdir();
}
contextConfigurations = new HashMap();
contextConfigurations.put( " baseDir " ,baseDir);
contextConfigurations.put( " realBaseDir " ,realBaseDir);
contextConfigurations.put( " fileLocator " ,fileLocator);
contextConfigurations.put( " debug " ,debugStr);
contextConfigurations.put( " enabled " ,enabledStr);
contextConfigurations.put( " encoding " ,encoding);
contextConfigurations.put( " contentTypeMapping " ,contentTypeMappingToMap(contentTypeMapping));
contextConfigurations.put( " allowedExtensionsFile " ,stringToArrayList(AllowedExtensionsFile));
contextConfigurations.put( " allowedExtensionsImage " ,stringToArrayList(AllowedExtensionsImage));
contextConfigurations.put( " allowedExtensionsFlash " ,stringToArrayList(AllowedExtensionsFlash));

if (debug)
System.out.println( " \r\n---- FCKeditorConfigurations for java initialization end ---- " );

}


FileLocatorServlet.java也很簡單,無非就是文件的物理定位和文件流的輸出:

程序代碼:
String type = request.getParameter( " Type " );
String fileName = request.getParameter( " FileName " );

String realFilePath = config.get( " realBaseDir " ) + type + " / " + fileName;
File file = new File(realFilePath);
if (file.exists()) {
response.setHeader( " Content-Transfer-Encoding " , " base64 " );
response.setHeader( " Cache-Control " , " no-store " );
response.setHeader( " Pragma " , " no-cache " );
response.setDateHeader( " Expires " , 0 );
response.setContentType(getContentTypeByFileExt(fileName.substring(fileName.lastIndexOf( " . " ))));

ServletOutputStream out = response.getOutputStream();
InputStream in = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(in);
BufferedOutputStream bos = new BufferedOutputStream(out);
byte [] buff = new byte [ 2048 ];
int bytesRead;
while ( - 1 != (bytesRead = bis.read(buff, 0 , buff.length))) {
bos.write(buff, 0 , bytesRead);
}
if (bis != null ) {
bis.close();
}
if (bos != null ) {
bos.close();
}
} else {
throw new FileNotFoundException(fileName);
}

上述改動已經提交給了FCKeditor,如果大家真的有興趣,可以去找裡面我所提交的patch。

二、至於上述的2、3問題,同樣,動手即可解決,在此略過。

過程中倒是碰到幾個有意思的問題,成了花絮,其實也是使用FCKeditor的一些心得,寫寫可能還有點意思:

1、如何取得FCKeditor的值?
答案:這是我們常常幹的事情:取得這個值並賦值給某個hidden,再合法性檢查+submit等。怎麼取得呢?這樣:

程序代碼:
var oEditor = FCKeditorAPI.GetInstance('editor') ;
// Get the editor contents in XHTML.
// alert( oEditor.GetXHTML(true) ) ; // "true" means you want it formatted.
document.all( " tip.c_content " ).value = oEditor.GetXHTML( true );


2、如何使得FCKeditor接收tab鍵?

答案:我們希望界面元素按照外面的安排進行tab切換,但FCKeditor怎麼能做到呢?也有辦法:

程序代碼:
function focusIframeOnTab(caller, tabTargetId, callEvent) {
// If keypress TAB and not SHIFT+TAB
if (callEvent.keyCode == 9 && ! callEvent.shiftKey)
document.getElementById(tabTargetId).contentWindow.focus();
}


光光有個函數頂個什麼用,還要這樣:在之前的那個界面元素中加上下面的事件,如使用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,這個能夠找到對應窗口的引用,有了這個,還不會控制嗎?!

有時需要用js來獲取FckEditor中的值

直接用document.getElementById('fckeditor').value是得不到的
正確的獲取方法:
var oEditor = FCKeditorAPI.GetInstance('editor') ;
alert(oEditor.GetXHTML(true));


js修改FckEdior的值:
var oEditor = FCKeditorAPI.GetInstance('editor') ;
oEditor.SetHTML('新內容');
alert(oEditor.GetXHTML(true));


原文出處:作者:Admin 日期:2007-09-09
內容圖示
url email imgsrc image code quote
樣本
bold italic underline linethrough   












 [詳情...]
validation picture

注意事項:
預覽不需輸入認證碼,僅真正發送文章時才會檢查驗證碼。
認證碼有效期10分鐘,若輸入資料超過10分鐘,請您備份內容後,重新整理本頁並貼回您的內容,再輸入驗證碼送出。

選項

Powered by XOOPS 2.0 © 2001-2008 The XOOPS Project|