寫到這裡,我想說一句公道話,那就是,我之前寫的三篇都可以直接扔進垃圾桶,是一般垃圾不用回收了(翻桌)。編輯器最重要的一個部分,就是自訂的對話框(Dialog),編輯器預設的對話框,跟 FCKeditor 有些許的差異,像是上傳檔案的對話框,在 CKeditor 裡面就沒有在預設工具列內(主要是要提倡跟自家的 CKFinder 合併使用)。
首先呢,在 CKeditor 裡面,所有的對話框都是使用 JavaScript 來產生,所以在設定上並不像以前 FCKeditor 那樣改改他的原始的 html 檔案就能更動對話框,所以關於這一點,對於 JavaScript 不是很熟悉的人恐怕會遇到很多地雷。但是,我看了看還是覺得,這次在 CKeditor 裡面,還是必須要稍微看過原始碼,才能真的有效控制整個 Dialog 的狀況啊(攤手)。
我們繼續來看 Dialog 與 UI,這兩個部分其實是互相綁定的,所以如果把 UI 的部分拿掉,Dialog 可能會半殘。從原始碼看來,UI 有絕大部分是給 Dialog 使用的(CKEDITOR.ui.dialog
),所以如果把 UI 的 Core 拿掉的話,那可想而知會發生什麼事情,而 CKEDITOR.dialog 系列的類別,其實是用來做設定(dialogDefinition
)的,跟產生對話框並沒有直接的關係。
接著,我們先來看看設定的部分在做些甚麼事情。
CKEDITOR.dialog
用來產生與修改對話框,前提是必須要有已經設定(註冊)好的對話框按鈕元件。CKEDITOR.dialog.add
加入(註冊)一個對話框,對話框的對象必須是已定義好的元件(Object)。CKEDITOR.dialog.addIframe
,CKEDITOR.dialog.addUIElement
歐雷~歐雷~歐雷,目前還無法使用 Iframe,而 UIElement 在 builder 有莫名奇妙的雷。CKEDITOR.dialog.exists
檢查對話框是否已存在(已註冊)。
只有一個?那其他的呢?其他的 Class(buttonDefinition
, contentDefinition
, contentDefinitionObject
, dialogDefinition
, dialogDefinitionObject
, uiElementDefinition
, dialogCommand
)並不是能夠直接呼叫的 API,而是要在設定中取得元件之後所能夠使用的方法,具體的使用方法依照官方範例如下:
CKEDITOR.on( 'dialogDefinition', function( evt )
{
var definition = evt.data.definition;
var content = definition.getContents( 'page1' );
...
} );
至於大家很關心的 Uploader 與 FileBrowser 的部分,官方的 簡單說明是這樣的(真的非常簡單)。雖然他也提供了 另外一種說明,但是他依舊非常的 CKEDITOR,令人完全看不懂啊!所以說,檔案上傳到底怎麼辦呢?這裡暫時先不提,等到我說完如何加入新的按鈕之後再補上。首先,我們來看看如何在 Toolbar 裡面加入按鈕,底下是一個典型的 CKEDITOR 編輯器的 Toolbar 設定:
var editor = CKEDITOR.replace( 'editor1', {
toolbar: [
['Source','-','Save','NewPage','Preview','-','Templates'],
['Cut','Copy','Paste','PasteText','PasteFromWord','-','Print', 'SpellChecker', 'Scayt'],
['Undo','Redo','-','Find','Replace','-','SelectAll','RemoveFormat'],
['Form', 'Checkbox', 'Radio', 'TextField', 'Textarea', 'Select', 'Button', 'ImageButton', 'HiddenField'],
'/',
['Bold','Italic','Underline','Strike','-','Subscript','Superscript'],
['NumberedList','BulletedList','-','Outdent','Indent','Blockquote'],
['JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock'],
['Link','Unlink','Anchor'],
['Image','Flash','Table','HorizontalRule','Smiley','SpecialChar','PageBreak'],
'/',
['Styles','Format','Font','FontSize'],
['TextColor','BGColor'],
['Maximize', 'ShowBlocks','-','About','MyButton']
]
});
// 必須要等待編輯器將 pluginsLoaded 做完才可以繼續做 Dialog 設置與綁定動作。
editor.on( 'pluginsLoaded', function( ev )
{
// 檢查 Dialog 是否已經存在,不存在才要建立
if ( !CKEDITOR.dialog.exists( 'myDialog' ) )
{
// 註冊一個新的 Dialog,名稱就叫做 'myDialog'
CKEDITOR.dialog.add( 'myDialog', function( editor )
{
// 這裡所返回的,就是 dialogDefinition 的設定。
return {
title : 'My Dialog',
minWidth : 400,
minHeight : 200,
contents : [
{
// 這裡是定義 Dialog 的內容,所使用到的都是那些 UI 與 Dialog 的 Definition。
// 裡面的東西有複雜到,待會我會直接寫出檔案上傳的範例。
}
]
};
} );
}
// 建立一個新的編輯器命令,並將這個編輯器命令綁定在剛剛建立好的 myDialog 上面。
editor.addCommand( 'myDialogCmd', new CKEDITOR.dialogCommand( 'myDialog' ) );
// 綁定剛剛 Toolbar 所設定的 'MyButton' 並且將命令執行綁定在剛剛的編輯器命令上。
editor.ui.addButton( 'MyButton',
{
label : 'My Dialog',
command : 'myDialogCmd'
} );
});
id : 'Upload',
hidden : true,
filebrowser : 'uploadButton',
label : editor.lang.image.upload,
// 在 Dialog 中註冊元件
elements :
[
{
type : 'file',
id : 'upload',
label : editor.lang.image.btnUpload,
style: 'height:40px',
size : 38
},
{
type : 'fileButton',
id : 'uploadButton',
filebrowser : 'info:txtUrl',
label : editor.lang.image.btnUpload,
'for' : [ 'Upload', 'upload' ]
}
]
那檔案會上傳到哪裡呢?好問題!檔案上傳的資料要在 Toolbar 設定完之後另外設定,官方有說明,其實也就是這樣而已:
var editor = CKEDITOR.replace( 'editor1', {
toolbar: [
[...略...],'MyButton']
],
filebrowserUploadUrl : '/uploader/upload.php'
});
/uploader/upload.php?CKEditor=editor1&CKEditorFuncNum=1&langCode=en
而這個上傳所要用到的監聽很特殊,需要用 CKEDITOR.tools.callFunction
呼叫並取得返回值,而這個 API 的說明是"零"!根據我明查暗訪的結果,這個 callFunction
還必須要先 addFunction
,而 addFunction
需要有一個依照 CKEDITOR 所建立的元素(instance),然後這一整串流程在 API 中的說明是"零"!
所以,CKEDITOR 的 Dialog 到底是改得更順手,還是更麻煩了呢?各位看倌你覺得呢(茶),其他的 Dialog 跟 UI 我會繼續在找時間補上,畢竟這兩個區塊才是我們真正關心的部分啊!