2009/12/11

Adjusting the context menu of CKEditor

The easyUpload plugin aims to replace the default image & link plugins as they can be seen as too complex, so we can expect that the config won't include their buttons in the toolbar, but the context menu entries will still be shown even if the command isn't available in the toolbar.

So you might think that it's just a matter of removing the "image" plugin, but you'll find that the context menu is still there. After a little digging you might be able that this is due because the "forms" plugin has stated that "image" is a requirement (for the input type="image). Then the next step would be to remove the forms plugin, but maybe that's a little too much.

Or what about the link plugin? It does include the unlink command as well as the anchor, so if we remove that plugin we need to copy all that code to another file.

The solution would be to remove just the context menu entries for those items that we don't want. In order to do this you need to study a little how the context menu plugin works and you'll find that it stores the available items in an object: editor._.menuItems and when the context menu is fired, every listener returns the object that should be shown at that time, but if that entry doesn't in the editor._.menuItems then it just skips that order.

So we can do this in our plugin to remove the context menu for the image plugin:

    afterInit: function(editor)
    {
        delete editor._.menuItems.image;
    },

On the other side, this plugin creates its own entries for images and links, but maybe you want to use only the new image dialog, so we need to apply some cleanup to the context menu.

Then instead of just hardcoding the elements to remove from the context menu the approach is to review the elements that are defined for the toolbar comparing them with a list of items that can be removed if they aren't used and then finally remove from the context menu all such items.

    afterInit: function(editor)
    {
        // Remove the default context menu for elements that aren't being used in the toolbar.
        // This object is composed of the button name and the name of the context menu entry
        var removableEntries = {Image:'image',Link:'link',Unlink:'unlink',EasyImage:'easyimage',EasyLink:'easylink',EasyUnlink:'easyunlink'},
            // Get the data that is being used for the toolbar, we end with an array of arrays.
            toolbar =
                    ( editor.config.toolbar instanceof Array ) ?
                        editor.config.toolbar
                    :
                        editor.config[ 'toolbar_' + editor.config.toolbar ];

        // Loop the main array (composed of groups of commands)
        for (var i=0; i<toolbar.length; i++)
        {
            var items = toolbar[i];
            if (!items)
                continue;
           
            for (var j=0; j<items.length; j++)
            {
                var buttonName = items[j];
                // If it was marked at our check object remove it because it's in use
                if (removableEntries[buttonName])
                    delete removableEntries[buttonName] ;
            }
        }
       
        // Remove all the entries that aren't used in the toolbar
        for (var command in removableEntries)
            delete editor._.menuItems[ removableEntries[command] ];
    },

With this code our plugin will take care of leaving only the correct entries in the context menu without any extra configuration

No comments: