JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
vanilla ckeditor-3.5
[ckeditor.git] / _source / plugins / dialog / plugin.js
index 26d8a8d..b5aab81 100644 (file)
@@ -105,10 +105,19 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3;
        CKEDITOR.dialog = function( editor, dialogName )\r
        {\r
                // Load the dialog definition.\r
-               var definition = CKEDITOR.dialog._.dialogDefinitions[ dialogName ];\r
+               var definition = CKEDITOR.dialog._.dialogDefinitions[ dialogName ],\r
+                       defaultDefinition = CKEDITOR.tools.clone( defaultDialogDefinition ),\r
+                       buttonsOrder = editor.config.dialog_buttonsOrder || 'OS',\r
+                       dir = editor.lang.dir;\r
+\r
+                       if ( ( buttonsOrder == 'OS' && CKEDITOR.env.mac ) ||    // The buttons in MacOS Apps are in reverse order (#4750)\r
+                               ( buttonsOrder == 'rtl' && dir == 'ltr' ) ||\r
+                               ( buttonsOrder == 'ltr' && dir == 'rtl' ) )\r
+                                       defaultDefinition.buttons.reverse();\r
+\r
 \r
                // Completes the definition with the default values.\r
-               definition = CKEDITOR.tools.extend( definition( editor ), defaultDialogDefinition );\r
+               definition = CKEDITOR.tools.extend( definition( editor ), defaultDefinition );\r
 \r
                // Clone a functionally independent copy for this dialog.\r
                definition = CKEDITOR.tools.clone( definition );\r
@@ -117,7 +126,6 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3;
                // functions.\r
                definition = new definitionObject( this, definition );\r
 \r
-\r
                var doc = CKEDITOR.document;\r
 \r
                var themeBuilt = editor.theme.buildDialog( editor );\r
@@ -130,7 +138,6 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3;
                        name : dialogName,\r
                        contentSize : { width : 0, height : 0 },\r
                        size : { width : 0, height : 0 },\r
-                       updateSize : false,\r
                        contents : {},\r
                        buttons : {},\r
                        accessKeyMap : {},\r
@@ -179,6 +186,34 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3;
                                definition : definition\r
                        }\r
                        , editor ).definition;\r
+\r
+               var tabsToRemove = {};\r
+               // Cache tabs that should be removed.\r
+               if ( !( 'removeDialogTabs' in editor._ ) && editor.config.removeDialogTabs )\r
+               {\r
+                       var removeContents = editor.config.removeDialogTabs.split( ';' );\r
+\r
+                       for ( i = 0; i < removeContents.length; i++ )\r
+                       {\r
+                               var parts = removeContents[ i ].split( ':' );\r
+                               if ( parts.length == 2 )\r
+                               {\r
+                                       var removeDialogName = parts[ 0 ];\r
+                                       if ( !tabsToRemove[ removeDialogName ] )\r
+                                               tabsToRemove[ removeDialogName ] = [];\r
+                                       tabsToRemove[ removeDialogName ].push( parts[ 1 ] );\r
+                               }\r
+                       }\r
+                       editor._.removeDialogTabs = tabsToRemove;\r
+               }\r
+\r
+               // Remove tabs of this dialog.\r
+               if ( editor._.removeDialogTabs && ( tabsToRemove = editor._.removeDialogTabs[ dialogName ] ) )\r
+               {\r
+                       for ( i = 0; i < tabsToRemove.length; i++ )\r
+                               definition.removeContents( tabsToRemove[ i ] );\r
+               }\r
+\r
                // Initialize load, show, hide, ok and cancel events.\r
                if ( definition.onLoad )\r
                        this.on( 'load', definition.onLoad );\r
@@ -601,7 +636,6 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3;
                                        }, this._.editor );\r
 \r
                                this._.contentSize = { width : width, height : height };\r
-                               this._.updateSize = true;\r
                        };\r
                })(),\r
 \r
@@ -613,15 +647,8 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3;
                 */\r
                getSize : function()\r
                {\r
-                       if ( !this._.updateSize )\r
-                               return this._.size;\r
                        var element = this._.element.getFirst();\r
-                       var size = this._.size = { width : element.$.offsetWidth || 0, height : element.$.offsetHeight || 0};\r
-\r
-                       // If either the offsetWidth or offsetHeight is 0, the element isn't visible.\r
-                       this._.updateSize = !size.width || !size.height;\r
-\r
-                       return size;\r
+                       return { width : element.$.offsetWidth || 0, height : element.$.offsetHeight || 0};\r
                },\r
 \r
                /**\r
@@ -629,13 +656,14 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3;
                 * @function\r
                 * @param {Number} x The target x-coordinate.\r
                 * @param {Number} y The target y-coordinate.\r
+                * @param {Boolean} save Flag indicate whether the dialog position should be remembered on next open up.\r
                 * @example\r
                 * dialogObj.move( 10, 40 );\r
                 */\r
                move : (function()\r
                {\r
                        var isFixed;\r
-                       return function( x, y )\r
+                       return function( x, y, save )\r
                        {\r
                                // The dialog may be fixed positioned or absolute positioned. Ask the\r
                                // browser what is the current situation first.\r
@@ -662,6 +690,8 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3;
                                                        'left'  : ( x > 0 ? x : 0 ) + 'px',\r
                                                        'top'   : ( y > 0 ? y : 0 ) + 'px'\r
                                                });\r
+\r
+                               save && ( this._.moved = 1 );\r
                        };\r
                })(),\r
 \r
@@ -708,7 +738,8 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3;
 \r
 \r
                        // First, set the dialog to an appropriate size.\r
-                       this.resize( definition.minWidth, definition.minHeight );\r
+                       this.resize( this._.contentSize && this._.contentSize.width || definition.minWidth,\r
+                                       this._.contentSize && this._.contentSize.height || definition.minHeight );\r
 \r
                        // Reset all inputs back to their default value.\r
                        this.reset();\r
@@ -753,20 +784,15 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3;
                        // Reset the hasFocus state.\r
                        this._.hasFocus = false;\r
 \r
-                       // Rearrange the dialog to the middle of the window.\r
                        CKEDITOR.tools.setTimeout( function()\r
                                {\r
-                                       var viewSize = CKEDITOR.document.getWindow().getViewPaneSize();\r
-                                       var dialogSize = this.getSize();\r
-\r
-                                       // We're using definition size for initial position because of\r
-                                       // offten corrupted data in offsetWidth at this point. (#4084)\r
-                                       this.move( ( viewSize.width - definition.minWidth ) / 2, ( viewSize.height - dialogSize.height ) / 2 );\r
-\r
+                                       this.layout();\r
                                        this.parts.dialog.setStyle( 'visibility', '' );\r
 \r
                                        // Execute onLoad for the first show.\r
                                        this.fireOnce( 'load', {} );\r
+                                       CKEDITOR.ui.fire( 'ready', this );\r
+\r
                                        this.fire( 'show', {} );\r
                                        this._.editor.fire( 'dialogShow', this );\r
 \r
@@ -778,6 +804,19 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3;
                },\r
 \r
                /**\r
+                * Rearrange the dialog to its previous position or the middle of the window.\r
+                * @since 3.5\r
+                */\r
+               layout : function()\r
+               {\r
+                       var viewSize = CKEDITOR.document.getWindow().getViewPaneSize(),\r
+                                       dialogSize = this.getSize();\r
+\r
+                       this.move( this._.moved ? this._.position.x : ( viewSize.width - dialogSize.width ) / 2,\r
+                                       this._.moved ? this._.position.y : ( viewSize.height - dialogSize.height ) / 2 );\r
+               },\r
+\r
+               /**\r
                 * Executes a function for each UI element.\r
                 * @param {Function} fn Function to execute for each UI element.\r
                 * @returns {CKEDITOR.dialog} The current dialog object.\r
@@ -903,7 +942,7 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3;
                                                        children : contents.elements,\r
                                                        expand : !!contents.expand,\r
                                                        padding : contents.padding,\r
-                                                       style : contents.style || 'width: 100%; height: 100%;'\r
+                                                       style : contents.style || 'width: 100%;'\r
                                                }, pageHtml );\r
 \r
                        // Create the HTML for the tab and the content block.\r
@@ -1342,9 +1381,6 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3;
                buttons : [ CKEDITOR.dialog.okButton, CKEDITOR.dialog.cancelButton ]\r
        };\r
 \r
-       // The buttons in MacOS Apps are in reverse order #4750\r
-       CKEDITOR.env.mac && defaultDialogDefinition.buttons.reverse();\r
-\r
        // Tool function used to return an item from an array based on its id\r
        // property.\r
        var getById = function( array, id, recurse )\r
@@ -1613,7 +1649,7 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3;
                        if ( abstractDialogCoords.x + margins[3] < magnetDistance )\r
                                realX = - margins[3];\r
                        else if ( abstractDialogCoords.x - margins[1] > viewPaneSize.width - dialogSize.width - magnetDistance )\r
-                               realX = viewPaneSize.width - dialogSize.width + margins[1];\r
+                               realX = viewPaneSize.width - dialogSize.width + ( editor.lang.dir == 'rtl' ? 0 : margins[1] );\r
                        else\r
                                realX = abstractDialogCoords.x;\r
 \r
@@ -1624,7 +1660,7 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3;
                        else\r
                                realY = abstractDialogCoords.y;\r
 \r
-                       dialog.move( realX, realY );\r
+                       dialog.move( realX, realY, 1 );\r
 \r
                        evt.data.preventDefault();\r
                }\r
@@ -1644,8 +1680,6 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3;
 \r
                dialog.parts.title.on( 'mousedown', function( evt )\r
                        {\r
-                               dialog._.updateSize = true;\r
-\r
                                lastCoords = { x : evt.data.$.screenX, y : evt.data.$.screenY };\r
 \r
                                CKEDITOR.document.on( 'mousemove', mouseMoveHandler );\r
@@ -1665,118 +1699,106 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3;
 \r
        function initResizeHandles( dialog )\r
        {\r
-               var definition = dialog.definition,\r
-                       minWidth = definition.minWidth || 0,\r
-                       minHeight = definition.minHeight || 0,\r
-                       resizable = definition.resizable,\r
-                       margins = dialog.getParentEditor().skin.margins || [ 0, 0, 0, 0 ];\r
+               var def = dialog.definition,\r
+                       resizable = def.resizable;\r
 \r
-               function topSizer( coords, dy )\r
-               {\r
-                       coords.y += dy;\r
-               }\r
+               if ( resizable == CKEDITOR.DIALOG_RESIZE_NONE )\r
+                       return;\r
 \r
-               function rightSizer( coords, dx )\r
-               {\r
-                       coords.x2 += dx;\r
-               }\r
+               var editor = dialog.getParentEditor();\r
+               var wrapperWidth, wrapperHeight, viewSize, origin, startSize;\r
 \r
-               function bottomSizer( coords, dy )\r
+               function positionDialog( right )\r
                {\r
-                       coords.y2 += dy;\r
+                       // Maintain righthand sizing in RTL.\r
+                       if ( dialog._.moved && editor.lang.dir == 'rtl' )\r
+                       {\r
+                               var element = dialog._.element.getFirst();\r
+                               element.setStyle( 'right', right + "px" );\r
+                               element.removeStyle( 'left' );\r
+                       }\r
+                       else if ( !dialog._.moved )\r
+                               dialog.layout();\r
                }\r
 \r
-               function leftSizer( coords, dx )\r
+               var mouseDownFn = CKEDITOR.tools.addFunction( function( $event )\r
                {\r
-                       coords.x += dx;\r
-               }\r
+                       startSize = dialog.getSize();\r
 \r
-               var lastCoords = null,\r
-                       abstractDialogCoords = null,\r
-                       magnetDistance = dialog._.editor.config.magnetDistance,\r
-                       parts = [ 'tl', 't', 'tr', 'l', 'r', 'bl', 'b', 'br' ];\r
+                       // Calculate the offset between content and chrome size.\r
+                       wrapperHeight = startSize.height - dialog.parts.contents.getSize( 'height',  ! ( CKEDITOR.env.gecko || CKEDITOR.env.opera || CKEDITOR.env.ie && CKEDITOR.env.quirks ) );\r
+                       wrapperWidth = startSize.width - dialog.parts.contents.getSize( 'width', 1 );\r
 \r
-               function mouseDownHandler( evt )\r
-               {\r
-                       var partName = evt.listenerData.part, size = dialog.getSize();\r
-                       abstractDialogCoords = dialog.getPosition();\r
-                       CKEDITOR.tools.extend( abstractDialogCoords,\r
-                               {\r
-                                       x2 : abstractDialogCoords.x + size.width,\r
-                                       y2 : abstractDialogCoords.y + size.height\r
-                               } );\r
-                       lastCoords = { x : evt.data.$.screenX, y : evt.data.$.screenY };\r
+                       origin = { x : $event.screenX, y : $event.screenY };\r
 \r
-                       CKEDITOR.document.on( 'mousemove', mouseMoveHandler, dialog, { part : partName } );\r
-                       CKEDITOR.document.on( 'mouseup', mouseUpHandler, dialog, { part : partName } );\r
+                       viewSize = CKEDITOR.document.getWindow().getViewPaneSize();\r
+\r
+                       CKEDITOR.document.on( 'mousemove', mouseMoveHandler );\r
+                       CKEDITOR.document.on( 'mouseup', mouseUpHandler );\r
 \r
                        if ( CKEDITOR.env.ie6Compat )\r
                        {\r
                                var coverDoc = currentCover.getChild( 0 ).getFrameDocument();\r
-                               coverDoc.on( 'mousemove', mouseMoveHandler, dialog, { part : partName } );\r
-                               coverDoc.on( 'mouseup', mouseUpHandler, dialog, { part : partName } );\r
+                               coverDoc.on( 'mousemove', mouseMoveHandler );\r
+                               coverDoc.on( 'mouseup', mouseUpHandler );\r
                        }\r
 \r
-                       evt.data.preventDefault();\r
-               }\r
+                       $event.preventDefault && $event.preventDefault();\r
+               });\r
+\r
+               // Prepend the grip to the dialog.\r
+               dialog.on( 'load', function()\r
+               {\r
+                       var direction = '';\r
+                       if ( resizable == CKEDITOR.DIALOG_RESIZE_WIDTH )\r
+                               direction = ' cke_resizer_horizontal';\r
+                       else if ( resizable == CKEDITOR.DIALOG_RESIZE_HEIGHT )\r
+                               direction = ' cke_resizer_vertical';\r
+                       var resizer = CKEDITOR.dom.element.createFromHtml( '<div class="cke_resizer' + direction + '"' +\r
+                                       ' title="' + CKEDITOR.tools.htmlEncode( editor.lang.resize ) + '"' +\r
+                                       ' onmousedown="CKEDITOR.tools.callFunction(' + mouseDownFn + ', event )"></div>' );\r
+                       dialog.parts.footer.append( resizer, 1 );\r
+               });\r
+               editor.on( 'destroy', function() { CKEDITOR.tools.removeFunction( mouseDownFn ); } );\r
 \r
                function mouseMoveHandler( evt )\r
                {\r
-                       var x = evt.data.$.screenX,\r
-                               y = evt.data.$.screenY,\r
-                               dx = x - lastCoords.x,\r
-                               dy = y - lastCoords.y,\r
-                               viewPaneSize = CKEDITOR.document.getWindow().getViewPaneSize(),\r
-                               partName = evt.listenerData.part;\r
+                       var rtl = editor.lang.dir == 'rtl',\r
+                               dx = ( evt.data.$.screenX - origin.x ) * ( rtl ? -1 : 1 ),\r
+                               dy = evt.data.$.screenY - origin.y,\r
+                               width = startSize.width,\r
+                               height = startSize.height,\r
+                               internalWidth = width + dx * ( dialog._.moved ? 1 : 2 ),\r
+                               internalHeight = height + dy * ( dialog._.moved ? 1 : 2 ),\r
+                               element = dialog._.element.getFirst(),\r
+                               right = rtl && element.getComputedStyle( 'right' ),\r
+                               position = dialog.getPosition();\r
 \r
-                       if ( partName.search( 't' ) != -1 )\r
-                               topSizer( abstractDialogCoords, dy );\r
-                       if ( partName.search( 'l' ) != -1 )\r
-                               leftSizer( abstractDialogCoords, dx );\r
-                       if ( partName.search( 'b' ) != -1 )\r
-                               bottomSizer( abstractDialogCoords, dy );\r
-                       if ( partName.search( 'r' ) != -1 )\r
-                               rightSizer( abstractDialogCoords, dx );\r
+                       // IE might return "auto", we need exact position.\r
+                       if ( right )\r
+                               right = right == 'auto' ? viewSize.width - ( position.x || 0 ) - element.getSize( 'width' ) : parseInt( right, 10 );\r
 \r
-                       lastCoords = { x : x, y : y };\r
+                       if ( position.y + internalHeight > viewSize.height )\r
+                               internalHeight = viewSize.height - position.y;\r
 \r
-                       var realX, realY, realX2, realY2;\r
+                       if ( ( rtl ? right : position.x ) + internalWidth > viewSize.width )\r
+                               internalWidth = viewSize.width - ( rtl ? right : position.x );\r
 \r
-                       if ( abstractDialogCoords.x + margins[3] < magnetDistance )\r
-                               realX = - margins[3];\r
-                       else if ( partName.search( 'l' ) != -1 && abstractDialogCoords.x2 - abstractDialogCoords.x < minWidth + magnetDistance )\r
-                               realX = abstractDialogCoords.x2 - minWidth;\r
-                       else\r
-                               realX = abstractDialogCoords.x;\r
+                       // Make sure the dialog will not be resized to the wrong side when it's in the leftmost position for RTL.\r
+                       if ( ( resizable == CKEDITOR.DIALOG_RESIZE_WIDTH || resizable == CKEDITOR.DIALOG_RESIZE_BOTH ) && !( rtl && dx > 0 && !position.x ) )\r
+                               width = Math.max( def.minWidth || 0, internalWidth - wrapperWidth );\r
 \r
-                       if ( abstractDialogCoords.y + margins[0] < magnetDistance )\r
-                               realY = - margins[0];\r
-                       else if ( partName.search( 't' ) != -1 && abstractDialogCoords.y2 - abstractDialogCoords.y < minHeight + magnetDistance )\r
-                               realY = abstractDialogCoords.y2 - minHeight;\r
-                       else\r
-                               realY = abstractDialogCoords.y;\r
+                       if ( resizable == CKEDITOR.DIALOG_RESIZE_HEIGHT || resizable == CKEDITOR.DIALOG_RESIZE_BOTH )\r
+                               height = Math.max( def.minHeight || 0, internalHeight - wrapperHeight );\r
 \r
-                       if ( abstractDialogCoords.x2 - margins[1] > viewPaneSize.width - magnetDistance )\r
-                               realX2 = viewPaneSize.width + margins[1] ;\r
-                       else if ( partName.search( 'r' ) != -1 && abstractDialogCoords.x2 - abstractDialogCoords.x < minWidth + magnetDistance )\r
-                               realX2 = abstractDialogCoords.x + minWidth;\r
-                       else\r
-                               realX2 = abstractDialogCoords.x2;\r
-\r
-                       if ( abstractDialogCoords.y2 - margins[2] > viewPaneSize.height - magnetDistance )\r
-                               realY2= viewPaneSize.height + margins[2] ;\r
-                       else if ( partName.search( 'b' ) != -1 && abstractDialogCoords.y2 - abstractDialogCoords.y < minHeight + magnetDistance )\r
-                               realY2 = abstractDialogCoords.y + minHeight;\r
-                       else\r
-                               realY2 = abstractDialogCoords.y2 ;\r
-\r
-                       dialog.move( realX, realY );\r
-                       dialog.resize( realX2 - realX, realY2 - realY );\r
+                       dialog.resize( width, height );\r
+                       // The right property might get broken during resizing, so computing it before the resizing.\r
+                       positionDialog( right );\r
 \r
                        evt.data.preventDefault();\r
                }\r
 \r
-               function mouseUpHandler( evt )\r
+               function mouseUpHandler()\r
                {\r
                        CKEDITOR.document.removeListener( 'mouseup', mouseUpHandler );\r
                        CKEDITOR.document.removeListener( 'mousemove', mouseMoveHandler );\r
@@ -1787,23 +1809,25 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3;
                                coverDoc.removeListener( 'mouseup', mouseUpHandler );\r
                                coverDoc.removeListener( 'mousemove', mouseMoveHandler );\r
                        }\r
-               }\r
 \r
-// TODO : Simplify the resize logic, having just a single resize grip <div>.\r
-//             var widthTest = /[lr]/,\r
-//                     heightTest = /[tb]/;\r
-//             for ( var i = 0 ; i < parts.length ; i++ )\r
-//             {\r
-//                     var element = dialog.parts[ parts[i] + '_resize' ];\r
-//                     if ( resizable == CKEDITOR.DIALOG_RESIZE_NONE ||\r
-//                                     resizable == CKEDITOR.DIALOG_RESIZE_HEIGHT && widthTest.test( parts[i] ) ||\r
-//                                     resizable == CKEDITOR.DIALOG_RESIZE_WIDTH && heightTest.test( parts[i] ) )\r
-//                     {\r
-//                             element.hide();\r
-//                             continue;\r
-//                     }\r
-//                     element.on( 'mousedown', mouseDownHandler, dialog, { part : parts[i] } );\r
-//             }\r
+                       // Switch back to use the left property, if RTL is used.\r
+                       if ( editor.lang.dir == 'rtl' )\r
+                       {\r
+                               var element = dialog._.element.getFirst(),\r
+                                       left = element.getComputedStyle( 'left' );\r
+\r
+                               // IE might return "auto", we need exact position.\r
+                               if ( left == 'auto' )\r
+                                       left = viewSize.width - parseInt( element.getStyle( 'right' ), 10 ) - dialog.getSize().width;\r
+                               else\r
+                                       left = parseInt( left, 10 );\r
+\r
+                               element.removeStyle( 'right' );\r
+                               // Make sure the left property gets applied, even if it is the same as previously.\r
+                               dialog._.position.x += 1;\r
+                               dialog.move( left, dialog._.position.y );\r
+                       }\r
+               }\r
        }\r
 \r
        var resizeCover;\r
@@ -2992,6 +3016,34 @@ CKEDITOR.plugins.add( 'dialog',
  */\r
 \r
 /**\r
+ * The guildeline to follow when generating the dialog buttons. There are 3 possible options:\r
+ * <ul>\r
+ *     <li>'OS' - the buttons will be displayed in the default order of the user's OS;</li>\r
+ *     <li>'ltr' - for Left-To-Right order;</li>\r
+ *     <li>'rtl' - for Right-To-Left order.</li>\r
+ * </ul>\r
+ * @name CKEDITOR.config.dialog_buttonsOrder\r
+ * @type String\r
+ * @default 'OS'\r
+ * @since 3.5\r
+ * @example\r
+ * config.dialog_buttonsOrder = 'rtl';\r
+ */\r
+\r
+/**\r
+ * The dialog contents to removed. It's a string composed by dialog name and tab name with a colon between them.\r
+ * Separate each pair with semicolon (see example).\r
+ * <b>Note: All names are case-sensitive.</b>\r
+ * <b>Note: Be cautious when specifying dialog tabs that are mandatory, like "info", dialog functionality might be broken because of this!<b>\r
+ * @name CKEDITOR.config.removeDialogTabs\r
+ * @type String\r
+ * @since 3.5\r
+ * @default ''\r
+ * @example\r
+ * config.removeDialogTabs = 'flash:advanced;image:Link';\r
+ */\r
+\r
+/**\r
  * Fired when a dialog definition is about to be used to create a dialog into\r
  * an editor instance. This event makes it possible to customize the definition\r
  * before creating it.\r