TinyMCE setup hook


tldr; Does anyone know if its possible to modify / augment the setup function for the TinyMCE wrapper plugin?

Not being able to do this (either by modifying the setup function or via some other means) makes this add on non-functional and a deal breaker in a real world scenario.

OK, some more detail. We are using vaadin 7.4.2 with the addon vaadin-wrapper-for-tinymce 3.0 and we are having problems with 2 areas that I suspect being able to define a setup function would help with.

[b]

  1. Adding custom buttons to the button bar
    [/b]
    If you google for how to add custom buttons to TinyMCE, all the results tell you to add your button in the setup function.
    For example, the offical TinyMCE API docs: https://www.tinymce.com/docs/demo/custom-toolbar-button/
    gives this example:

tinymce.init({ selector: 'textarea', height: 500, toolbar: 'mybutton', menubar: false, setup: function (editor) { editor.addButton('mybutton', { text: 'My button', icon: false, onclick: function () { editor.insertContent(' <b>It\'s my button!</b> '); } }); }, content_css: [ '//fast.fonts.net/cssapi/e6dc9b99-64fe-4292-ad98-6974f93cd2a2.css', '//www.tinymce.com/css/codepen.min.css' ] }); Taking this idea, if you take the config object above and pass it into the setConfig method of TinyMCETextField, you get the custom button … but serverside getValue() method calls no longer return the current content. getValue() returns the initial value of the field, rather than the current value of the TinyMCE content.

We have managed to get round this problem by using TinyMCE’s init_instance_callback function as follows, but its not ideal:

    private static final String CLIENTSIDE_OPEN_INSERT_SNIPPET_DIALOG_JS_FN_NAME = "openInsertSnippetDialog";

    private static final String INSERT_SNIPPET_BUTTON_NAME = "insertSnippet";

    private static final String TINY_MCE_EDITOR_JS_CONFIG =
            "{" +
                    "    statusbar: false," +
                    "    menubar: false," +
                    "    toolbar: 'bold underline italic | code' ," +
                    "    init_instance_callback: function (editor) {" +
                    "        var BUTTON_NAME = '" + INSERT_SNIPPET_BUTTON_NAME + "';" +
                    "        var openInsertSnippetDialogFn = window.parent." + CLIENTSIDE_OPEN_INSERT_SNIPPET_DIALOG_JS_FN_NAME + ";" +
                    "        editor.addButton(BUTTON_NAME, {" +
                    "            text: 'Insert Snippet'," +
                    "            icon: false," +
                    "            onclick: function() {" +
                    "                openInsertSnippetDialogFn();" +
                    "            }" +
                    "        });" +
                    "        var insertSnippetButton = editor.buttons[BUTTON_NAME]
;" +
                    "        var buttonGroup = editor.theme.panel.find('toolbar buttongroup')[1]
;" +
                    "        buttonGroup._lastRepaintRect = buttonGroup._layoutRect;" +
                    "        buttonGroup.append(insertSnippetButton);" +
                    "    }" +
                    "}";


2) Initializing editor content with non-html

We plan to use this editor to edit html and non-html. In the case of non-html, when the content is saved, it will be saved as html by virtue of the fact that TinyMCE will have added formating etc and added the appropriate html tags.
We initialize the TinyMCE editor, then call it’s setValue() method. If the content that we pass to setValue() is html, all is well. If the content we pass to setValue() is plain text with line break control characters (carriage return line feed), then TinyMCE ignores the crlf characters and presents the content all on one line.
The core problem of line breaks not being converted appears to be a problem with core TinyMCE (rather than this wrapper), but solutions all revolve around adding a BeforeContentSet handler … in the setup function. For example http://stackoverflow.com/questions/11862938/tinymce-setcontent-removes-new-lines#14313101 suggests the following:

tinyMCE.init({ setup : function(ed) { ed.onBeforeSetContent.add(function(ed, o) { if (o.initial) { o.content = o.content.replace(/\r?\n/g, '<br />'); } }); } }); (the comments to the Stack Overflow answer say that for TinyMCE 4 you should use editor.on(‘BeforeSetContent’, function (contentEvent) … but either way it involves the setup function)


Identified problem area

For both scenarios above (which let’s be honest, are not at all uncommon or unreasonable to want to do), we need to hook into the setup function. And whenever I do that as described, I break the functionality of the TinyMCE wrapper in that it does not send its current content to the server, so server side calls to getValue() do not work.

Looking at the codebase I think I’ve found the problem area. In TinyMCEService, we have the following method:

[code]
public static native void loadEditor(String id, OnChangeListener listener, String cc)
/*-{

     var conf = {
    
        selector : '#' + id ,
        height: 500,
        plugins: [
            'advlist autolink lists link image charmap print preview anchor',
            'searchreplace visualblocks code fullscreen',
            'insertdatetime media table contextmenu paste code'
        ],
        toolbar: 'insertfile undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image',
        setup : function(ed) {
        
            ed.on('setContent', function(e) {
                 listener.@org.vaadin.tinymceeditor.widgetset.client.ui.TinyMCEService.OnChangeListener::onChange()();
            });
            ed.on('change', function(e) {
                  console.log('Editor was changed');
                 listener.@org.vaadin.tinymceeditor.widgetset.client.ui.TinyMCEService.OnChangeListener::onChange()();
            });
          }
    };
    try {
         if(cc) {
             var customConfig = eval('('+cc+')');
             for(var j in customConfig) {
                 conf[j]

= customConfig[j]
;
}
}
} catch (e) {}

    $wnd.tinymce.init(conf);

}-*/
;

[/code]And within there we can see the setup function, and its calls to the server side listeners for the change and setContent methods. That makes complete sense and I can see how this keeps the client content updated on the server. However, it also completely prevents being able to further modify the TinyMCE editor via any other setup function functionality.

Are there any other methods or techniques we can use to enable an editor with the standard core functionility, and also custom functionality via the setup function?

Thanks

Had a similar issue, I wanted to change the toolbar with a wider set of buttons upon making it fullscreen, and back when it gets “minimized”, but most probably for similar reasons I couldn’t. The init worked only once for me, and never again.
Although today I have learned how to destroy the whole component, and maybe I could reinit it depending on the state, I think I will rather check out CkEditor, you’ve suggested.