I did just that. We do not use built-in dialogs at all. We use iframedialog.
Here is the template template that I use to create plugins using this template.
CKEDITOR.plugins.add( '$PLUGINNAMEALLLOWERCASE$', { init : function( editor ) { var pluginName = '$PLUGINNAMEALLLOWERCASE$'; // Register the dialog. CKEDITOR.dialog.addIframe(pluginName, pluginName, '/path/to/load/the/html.html', 410, 508, function() {}); // Register the command. var command = editor.addCommand(pluginName, {exec: function() { editor.openDialog(pluginName); }}); command.modes = { wysiwyg:1, source:0 }; command.canUndo = false; editor.ui.addButton('$PLUGINNAMEPASCALCASE$', { label: $BUTTONLABEL$, className: 'cke_button_' + pluginName, command: pluginName }); editor.on( 'doubleclick', function( evt ) { var element = evt.data.element; if ( element.is( '$NODENAME$' ) && !element.data( 'cke-realelement' ) ) { evt.data.dialog = '$PLUGINNAMEALLLOWERCASE$'; evt.cancel(); } }); // If the "menu" plugin is loaded, register the menu items. if ( editor.addMenuItems ) { editor.addMenuItems( { $PLUGINNAMEALLLOWERCASE$ : { label : $EDITLABEL$, command : '$PLUGINNAMEALLLOWERCASE$', group : '$PLUGINNAMEALLLOWERCASE$' } }); } // If the "contextmenu" plugin is loaded, register the listeners. if ( editor.contextMenu ) { editor.contextMenu.addListener( function( element, selection ) { if ( !element || !element.is('$NODENAME$') || element.data( 'cke-realelement' ) || element.isReadOnly() ) return null; return { $PLUGINNAMEALLLOWERCASE$ : CKEDITOR.TRISTATE_OFF }; }); } } } );
You can then create any HTML inside the iframe, including custom CSS / JS
source share