CKEditor

HTML

<script src="http://ckeditor.com/apps/ckeditor/4.0/ckeditor.js"></script>
<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.0/css/bootstrap-combined.min.css">
<script src="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.0/js/bootstrap.min.js"></script>
<h3>CKEditor 4:</h3>

<textarea id="editor1">Test</textarea>

JavaScript

//CKEDITOR.replace('editor1');

/*CKEDITOR.plugins.add('tokens', {
    requires: ['richcombo'], //, 'styles' ],
    init: function (editor) {
        var rebuildList = CKEDITOR.tools.bind(buildList, this);
        rebuildList(editor);
        $(editor).bind('rebuildList', rebuildList);
    
    }
});*/


CKEDITOR.plugins.add('mergefields', {
    requires: ['richcombo'], //, 'styles' ],
    init: function (editor) {   
        console.log(editor);          
        var rebuildList = CKEDITOR.tools.bind(buildList, this);
        rebuildList(editor);
        $(editor).bind('rebuildList', rebuildList);
    }
});
var buildListHasRunOnce = 0;
var buildList = function (editor) {
    alert(buildListHasRunOnce);
        var config = editor.config,
            lang = editor.lang.format;

        // Gets the list of tags from the settings.
        var tags = []; //new Array();
        tags[0] = ["[contact_name]", "Name", "Name"];
        tags[1] = ["[contact_email]", "email", "email"];
        tags[2] = ["[contact_user_name]", "User name", "User name"];
        // Create style objects for all defined styles.
        editor.ui.addRichCombo('tokens', {
            label: "Merge",
            title: "title",
            voiceLabel: "voiceLabel",
            className: 'cke_format',
            multiSelect: false,

            panel: {
                css: [config.contentsCss, CKEDITOR.getUrl(CKEDITOR.skin.getPath('editor') + 'editor.css')],
                voiceLabel: lang.panelVoiceLabel
            },

            init: function () {
                // this.startGroup("mergefields");
                for (var this_tag in tags) {
                    this.add(tags[this_tag], tags[this_tag], tags[this_tag]);
                }
            },

            onClick: function (value) {
                editor.focus();
                editor.fire('saveSnapshot');
                editor.insertText(value);
                editor.fire('saveSnapshot');
            }
       ...