Fckeditor 3.6.1 integration in SmartClient 8.2

based on this thread http://forums.smartclient.com/showthread.php?t=20175&goto=nextoldest

I'm using ckeditor 3.6.1

I've included this CkeditorIntegration.js file:

CkeditorIntegration.js
CKEDITOR.config.customConfig = '../com/juve/classes/ckeditor/ckeditorConfig.js';
// HACK 1 - variable to hold setValue() calls made before the editor is ready
var ckInitValue = null;

CKEDITOR.on('instanceReady', function(ev) {
	isc.Log.logInfo("Editor Ready!: " + ev.editor.id);
	if (ckInitValue) {
		ev.editor.setData(ckInitValue);
		ckInitValue = null;
	}
});

isc.defineClass("Ckeditor", "Canvas").addProperties({
	overflow: "visible",
	canDragResize: true,
	redrawOnResize: true,
	zIndex: 0,
	getInnerHTML: function() {
		return "<textarea STYLE='width:100%;height:100%' ID=" + this.getCkId() + "></textarea>";
	},
	redrawOnResize: false,
	draw: function() {
		this.Super("draw", arguments);
		this.loadEditor();
		return this;
	},
	getCkId: function() {
		return this.getID() + ckeditorIntegrationCanvasIdSuffix;
	},
	loadEditor: function() {
		if (this.ckLoaded == null) {
			isc.Log.logInfo("Creating editor:" + this.getCkId());
			CKEDITOR.replace(this.getCkId(), {
//				toolbar: [['Styles', 'Format'], ['Bold', 'Italic', '-', 'NumberedList', 'BulletedList', '-', 'Link']]
			});
			isc.Log.logInfo("Editor Setup initiated...");
			this.ckLoaded = true;
		}
	},
    resetDirty:function() {
        CKEDITOR.instances[this.getCkId()].resetDirty();
    },
    checkDirty:function() {
        return CKEDITOR.instances[this.getCkId()].checkDirty();
    },
    getValue:function() {
        return CKEDITOR.instances[this.getCkId()].getData();
    },
    setValue:function(value) {
        if (CKEDITOR.instances[this.getCkId()]) {
			CKEDITOR.instances[this.getCkId()].setData(value);
		} else {
			ckInitValue = value;
		}
    }
});
isc.defineClass("CkeditorItem", "CanvasItem").addProperties({
	canvasConstructor: "Ckeditor",
	getValue: function() {
		var superValue = this.Super("getValue", arguments);
		var editorValue = null;
		isc.Log.logInfo("Super Value: " + superValue);
		if (CKEDITOR.instances[this.canvas.getCkId()].getData()) {
			editorValue = CKEDITOR.instances[this.canvas.getCkId()].getData();
			isc.Log.logInfo("Editor value:" + editorValue);
			// HACK 2 - we need to work out a better way of keeping the underlying item's value in sync
			// - this could be a SC bug - why not calling getValue() - using direct access instead?
			if (superValue != editorValue)
				this.Super("setValue", editorValue);
			return editorValue;
		} else {
			return superValue;
		}
	},
	setValue: function(value) {
		isc.Log.logInfo("Setting value:" + value);
		// HACK 1 - setValue is called before the editor is ready, so we need to keep hold of the value until it is loaded.
		if (CKEDITOR.instances[this.canvas.getCkId()]) {
			CKEDITOR.instances[this.canvas.getCkId()].setData(value);
		} else {
			ckInitValue = value;
		}
		return this.Super("setValue", arguments);
	}
});

and this is the ckeditorConfig.js file:

/*
Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license
*/

CKEDITOR.editorConfig = function( config )
{
	// Define changes to default configuration here. For example:
	// config.uiColor = '#AADC6E';
	config.baseFloatZIndex = 1000000;
	config.language = 'it';
	config.toolbar = 'Full';
	config.width = 850;
	config.height = 450;
	config.resize_enabled = false;
	config.removePlugins = 'elementspath';
//    config.saveFunction = function(data) {
//		alert(data)
//	}
    config.entities = false;
    config.toolbar_Full_isc_save_toolbar =
    [
        { name: 'document',    items : [ 'Source','-','Isc_save','NewPage','DocProps','Preview','Print','-','Templates' ] },
        { name: 'clipboard',   items : [ 'Cut','Copy','Paste','PasteText','PasteFromWord','-','Undo','Redo' ] },
        { name: 'editing',     items : [ 'Find','Replace','-','SelectAll','-','SpellChecker', 'Scayt' ] },
        { name: 'forms',       items : [ 'Form', 'Checkbox', 'Radio', 'TextField', 'Textarea', 'Select', 'Button', 'ImageButton', 'HiddenField' ] },
        '/',
        { name: 'basicstyles', items : [ 'Bold','Italic','Underline','Strike','Subscript','Superscript','-','RemoveFormat' ] },
        { name: 'paragraph',   items : [ 'NumberedList','BulletedList','-','Outdent','Indent','-','Blockquote','CreateDiv','-','JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock','-','BidiLtr','BidiRtl' ] },
        { name: 'links',       items : [ 'Link','Unlink','Anchor' ] },
        { name: 'insert',      items : [ 'Image',/*'Flash',*/'Table','HorizontalRule','Smiley','SpecialChar','PageBreak' ] },
        '/',
        { name: 'styles',      items : [ 'Styles','Format','Font','FontSize' ] },
        { name: 'colors',      items : [ 'TextColor','BGColor' ] },
        { name: 'tools',       items : [ 'Maximize', 'ShowBlocks','-','About' ] }
    ];
    config.extraPlugins = 'isc_save';
    config.toolbar = 'Full_isc_save_toolbar';
};

this is the code I use to display it in a modal window:

isc.defineClass("ModalWindow", "Window").addProperties({
    showMinimizeButton:false,
    showHeaderIcon:false,
    autoSize:true,
    autoCenter:true,
    isModal:true,
    showModalMask:true,
    dismissOnOutsideClick:true
});
var showCkeditor = function (value, callback) {
    if (window.editorWindow) {
        editorWindow.show();
        editorWindow.setValue(value);
        editorWindow.delayCall('resetDirty', [], 500);
        editorWindow.callback = callback;
    } else {
        isc.Ckeditor.create({
            showEdges: true,
            ID: "AnFCKeditor",
            align: "left",
            height: 572,
            save:function() {
                this.editorWindow.save();
            },
            width: 857
        });
        isc.ModalWindow.create({
            ID: "editorWindow",
            title:"Editor",
            editor: AnFCKeditor,
            callback: callback,
            save:function() {
                this.callback(this.getValue());
            },
            closeClick:function() {
                if (this.checkDirty()) {
                    isc.confirm("There are unsaved changes.<br>Close anyway?", function(value){
                        if (value) {
                            editorWindow.hide();
                        }
                    });
                } else {
                    this.hide();
                }
            },
            resetDirty:function() {
                this.editor.resetDirty();
            },
            checkDirty:function() {
                return this.editor.checkDirty();
            },
            setValue:function(value) {
                this.editor.setValue(value);
            },
            getValue:function() {
                return this.editor.getValue();
            },
            initWidget:function() {
                this.addItem(this.editor);
                this.Super("initWidget", arguments);
                AnFCKeditor.editorWindow = this;
            }
        });
        editorWindow.setValue(value);
        editorWindow.animateShow(defaultAnimationEffect, function(){
                editorWindow.delayCall('resetDirty', [], 500);
        });
    }
};

I open it this way:

showCkeditor(record[fieldName], function(value){
                record[fieldName] = value;
                myDataSource.updateData(record, "if(dsResponse.status >= 0) editorWindow.resetDirty();");
            });

where the function(value) is a callback which will be used to save the edited html.
Saving is triggered by the Isc_save custom button which requires the ckeditor-3.6.1/ckeditor/plugins/isc_save/plugin.js:

CKEDITOR.plugins.add('isc_save',
    {
        init: function(editor) {
            var pluginName = 'isc_save';
            editor.addCommand(pluginName,
                {
                    exec : function(editor) { // the Ckeditor class defined in CkeditorIntegration.js adds ckeditorIntegrationCanvasIdSuffix (defined in index.jsp) to the Canvas ID to obtain textarea ID
                        var editorName = editor.name.substr(0, editor.name.length - ckeditorIntegrationCanvasIdSuffix.length);
                        isc.logEcho(editorName)
                        eval(editorName).save();
                    },
                    canUndo : true
                });

            /*
             editor.addCommand(pluginName,
             new CKEDITOR.dialogCommand(pluginName)

             );
             */

            editor.ui.addButton('Isc_save',
                {
                    label: 'Save',
                    command: pluginName,
                    className : 'cke_button_save'
                });
        }
    });

finally, in my jsp:

<script type="text/javascript">
var ckeditorIntegrationCanvasIdSuffix = '_ta';
</script>
<script type="text/javascript" charset="UTF-8" src="./shared/ui/ckeditor/ckeditor.js"></script>
<script type="text/javascript" charset="UTF-8" src="./shared/ui/com/juve/classes/ckeditor/CkeditorIntegration.js"></script>