網頁

2010年12月3日 星期五

YUI 2: Rich Text Editor 修改支援Code編輯


之前有試過利用YUI來做出一個網頁內嵌的編輯器:
花栗鼠柑仔店: YUI 2: Rich Text Editor

最近有一個需求就是需要讓這編輯器可以顯示原始碼直接編輯,
查了一下YUI的範例: YUI Library Examples: Rich Text Editor: Code Editor


主要要修改的是:
1. 用範例選好的 JavaScript與CSS 需要匯入的檔案
YUI 2: Dependency Configurator

2. 加入編輯器新增的圖示到CSS的定義
.yui-skin-sam .yui-toolbar-container .yui-toolbar-editcode span.yui-toolbar-icon {
    background-image: url( html_editor.gif );
    background-position: 0 1px;
    left: 5px;
}
.yui-skin-sam .yui-toolbar-container .yui-button-editcode-selected span.yui-toolbar-icon {
    background-image: url( html_editor.gif );
    background-position: 0 1px;
    left: 5px;
}
.editor-hidden {
    visibility: hidden;
    top: -9999px;
    left: -9999px;
    position: absolute;
}
textarea {
    border: 0;
    margin: 0;
    padding: 0;
}

其中有一個圖檔可以在yahoo抓:
html_editor.gif (GIF Image, 16x16 pixels)

3. 修改editor產生的部份, 需要將code編輯的按鈕加入
myEditor.on('toolbarLoaded', function() {
    var codeConfig = {
        type: 'push', label: 'Edit HTML Code', value: 'editcode'
    };
    YAHOO.log('Create the (editcode) Button', 'info', 'example');
    this.toolbar.addButtonToGroup(codeConfig, 'insertitem');

    this.on('afterRender', function() {
        //snipped
    }, this, true);
}, myEditor, true);

4. 處理按下按鈕時的事件: on時要將其他按鈕disable, 且按掉時要回傳HTML到編輯器視窗
//Somewhere above the Editor code
var state = 'off';
YAHOO.log('Set state to off..', 'info', 'example');

//Inside the toolbarLoaded event
this.toolbar.on('editcodeClick', function() {
    var ta = this.get('element'),
        iframe = this.get('iframe').get('element');

    if (state == 'on') {
        state = 'off';
        this.toolbar.set('disabled', false);
        YAHOO.log('Show the Editor', 'info', 'example');
        YAHOO.log('Inject the HTML from the textarea into the editor', 'info', 'example');
        this.setEditorHTML(ta.value);
        if (!this.browser.ie) {
            this._setDesignMode('on');
        }

        Dom.removeClass(iframe, 'editor-hidden');
        Dom.addClass(ta, 'editor-hidden');
        this.show();
        this._focusWindow();
    } else {
        state = 'on';
        YAHOO.log('Show the Code Editor', 'info', 'example');
        this.cleanHTML();
        YAHOO.log('Save the Editors HTML', 'info', 'example');
        Dom.addClass(iframe, 'editor-hidden');
        Dom.removeClass(ta, 'editor-hidden');
        this.toolbar.set('disabled', true);
        this.toolbar.getButtonByValue('editcode').set('disabled', false);
        this.toolbar.selectButton('editcode');
        this.dompath.innerHTML = 'Editing HTML Code';
        this.hide();
    }
    return false;
}, this, true);

this.toolbar.on('editcodeClick', function() {
    this.on('cleanHTML', function(ev) {
        YAHOO.log('cleanHTML callback fired..', 'info', 'example');
        this.get('element').value = ev.html;
    }, this, true);
}, myEditor, true);

5. 注意事項
(1) 假如嫌上面囉嗦麻煩, 可以直接參考: YUI Library Examples: Rich Text Editor: Code Editor Full Example Javascript Source整合好的直接匯入就好

(2) 用範例整合好的程式碼要注意, 一般我們都會在編輯器編好後, 做一個回存的動作,
但這整合好的範例是透過一個匿名function, 假如在底下接收要回存的事件會產生myEditor變數找不到的問題:
程式碼類似如下:
(function() {
    var myEditor1 = new YAHOO.widget.Editor( ...

}

YAHOO.util.Event.on('update', 'click', function() {
    //Put the HTML back into the text area
    myEditor1.saveHTML();
}

翻一下JavaScript的log就會發現錯誤,
解決的方法很簡單, 相信大家都知道,
就是把變數提升到匿名函式的上一層可以讓底下的事件看到就好.

var myEditor1 = new YAHOO.widget.Editor( ...

(function() {
    ...
}

YAHOO.util.Event.on('update', 'click', function() {
    //Put the HTML back into the text area
    myEditor1.saveHTML();
}


完畢! 收工!

沒有留言:

張貼留言