javascripttinymceroxy-fileman

Roxy Fileman with TinyMCE 5 using file_picker_callback


I'm trying to upgrade TinyMCE from ver.4 to ver.5, but the function file_browser_callback has been replaced by file_picker_callback that has completely different parameters:

TinyMCE v.4

file_browser_callback: function (fieldId, value, type, win) {
    browseFiles(value, type, function (fileUrl) {
      win.document.getElementById(fieldId).value = fileUrl;
    });
}

TinyMCE v.5

file_picker_callback: function (callback, value, meta) {
   browseFiles(value, meta.filetype, function (fileUrl) {
      callback(fileUrl);
   });
}

I'm able to retrieve only the old parameter type that in v.5 is in meta.filetype, but not the other parameters, field_name and win, necessary to Roxy Fileman.

and here is my full implementation using v.4:

function initEditor(selector) {
            tinymce.init({
                selector: selector,
                plugins: "paste,link,lists,advlist,image,table,contextmenu,media,fullscreen",
                paste_as_text: true,
                menubar: false,
                language: 'en',
                forced_root_block: 'div',
                encoding: 'xml', //used to solve Dangerous Request.Form exception - Seems it's not enough alone.
                block_formats: 'Paragraph=p;Header 1=h1;Header 2=h2;Header 3=h3',
                toolbar: 'undo redo | styleselect | bold italic underline strikethrough | alignleft aligncenter alignright alignjustify | bullist numlist | link unlink | image | media | fullscreen',
                file_browser_callback: RoxyFileBrowser,
                inline: false,
                setup: function (editor) {
                    editor.on('change', function (e) {
                        //saved = false;
                        //$("#btn-save").css('border', '2px solid #D85145');
                        //$("#btn-save").html('SAVE');
                    });
                }
            });
        }

    function RoxyFileBrowser(field_name, url, type, win) {
        var cmsURL = roxyFileman;  // script URL - use an absolute path!
        if (cmsURL.indexOf("?") < 0) {
            cmsURL = cmsURL + "?type=" + type;
        }
        else {
            cmsURL = cmsURL + "&type=" + type;
        }
        cmsURL += '&input=' + field_name + '&value=' + win.document.getElementById(field_name).value;
        tinyMCE.activeEditor.windowManager.open({
            file: cmsURL,
            title: 'MVAM - Media File Repository',
            width: 850, // Your dimensions may differ - toy around with them!
            height: 650,
            resizable: "yes",
            plugins: "media",
            inline: "yes", // This parameter only has an effect if you use the inlinepopups plugin!
            close_previous: "no"
        }, {
                window: win,
                input: field_name
            });
        return false;
    }

Solution

  • There is a new way of creating dialog windows with external content with TinyMCE5: URL dialog and this method differs from old one in v.4.

    You don’t need parameters win and field_name anymore. Earlier Roxy Fileman used them to put there newly retrieved value. But now you must just send this value to callback and TinyMCE will do the rest. So the new code that works is:

    function RoxyFileBrowser(callback, value, type) {
        var roxyFileman = '/fileman/index.html';
        roxyFileman += (roxyFileman.indexOf("?")<0 ? "?" : "&") + "type=" + type.filetype;
        roxyFileman += '&input=' + field_name + '&value=' + win.document.getElementById(field_name).value;
        if(value)
            roxyFileman += '&value=' + value; // a link to already chosen image if it exists
        if(tinyMCE.activeEditor.settings.language)
            roxyFileman += '&langCode=' + tinyMCE.activeEditor.settings.language;
    
        const instanceApi = tinyMCE.activeEditor.windowManager.openUrl({
            title: 'Roxy Fileman',
            url: roxyFileman,
            width: 850, 
            height: 650,
            onMessage: function(dialogApi, details) {
                callback(details.content);
                instanceApi.close();
            }
        });
        return false;
    }
    

    A new tough part was to get back the value from the dialog into RoxyFileBrowser function. And it solves by using messages in function FileSelected in js/custom.js:

    function FileSelected(file){
      window.parent.postMessage({
        mceAction: 'FileSelected',
        content: file.fullPath
      }, '*');
    }
    

    To get this work you need to set "INTEGRATION": "custom" in conf.json