/*\r
-Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.\r
+Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved.\r
For licensing, see LICENSE.html or http://ckeditor.com/license\r
*/\r
\r
* @fileOverview The floating dialog plugin.\r
*/\r
\r
-CKEDITOR.plugins.add( 'dialog',\r
- {\r
- requires : [ 'dialogui' ]\r
- });\r
-\r
/**\r
* No resize for this dialog.\r
* @constant\r
return null;\r
}\r
\r
- // Stores dialog related data from skin definitions. e.g. margin sizes.\r
- var skinData = {};\r
-\r
/**\r
* This is the base class for runtime dialog objects. An instance of this\r
* class represents a single named dialog for a single editor instance.\r
{\r
// Load the dialog definition.\r
var definition = CKEDITOR.dialog._.dialogDefinitions[ dialogName ];\r
- if ( !definition )\r
- {\r
- console.log( 'Error: The dialog "' + dialogName + '" is not defined.' );\r
- return;\r
- }\r
\r
// Completes the definition with the default values.\r
definition = CKEDITOR.tools.extend( definition( editor ), defaultDialogDefinition );\r
if ( focusList.length < 1 )\r
return;\r
\r
- var currentIndex = ( me._.currentFocusIndex + offset + focusList.length ) % focusList.length;\r
+ var startIndex = ( me._.currentFocusIndex + offset + focusList.length ) % focusList.length,\r
+ currentIndex = startIndex;\r
while ( !focusList[ currentIndex ].isFocusable() )\r
{\r
currentIndex = ( currentIndex + offset + focusList.length ) % focusList.length;\r
- if ( currentIndex == me._.currentFocusIndex )\r
+ if ( currentIndex == startIndex )\r
break;\r
}\r
focusList[ currentIndex ].focus();\r
focusList[ currentIndex ].select();\r
}\r
\r
+ var processed;\r
+\r
function focusKeydownHandler( evt )\r
{\r
// If I'm not the top dialog, ignore.\r
if ( me != CKEDITOR.dialog._.currentTop )\r
return;\r
\r
- var keystroke = evt.data.getKeystroke(),\r
- processed = false;\r
+ var keystroke = evt.data.getKeystroke();\r
+\r
+ processed = 0;\r
if ( keystroke == 9 || keystroke == CKEDITOR.SHIFT + 9 )\r
{\r
var shiftPressed = ( keystroke == CKEDITOR.SHIFT + 9 );\r
changeFocus( !shiftPressed );\r
}\r
\r
- processed = true;\r
+ processed = 1;\r
}\r
else if ( keystroke == CKEDITOR.ALT + 121 && !me._.tabBarMode )\r
{\r
// Alt-F10 puts focus into the current tab item in the tab bar.\r
me._.tabBarMode = true;\r
me._.tabs[ me._.currentTabId ][ 0 ].focus();\r
- processed = true;\r
+ processed = 1;\r
}\r
else if ( ( keystroke == 37 || keystroke == 39 ) && me._.tabBarMode )\r
{\r
nextId = ( keystroke == 37 ? getPreviousVisibleTab.call( me ) : getNextVisibleTab.call( me ) );\r
me.selectPage( nextId );\r
me._.tabs[ nextId ][ 0 ].focus();\r
- processed = true;\r
+ processed = 1;\r
}\r
\r
if ( processed )\r
}\r
}\r
\r
+ function focusKeyPressHandler( evt )\r
+ {\r
+ processed && evt.data.preventDefault();\r
+ }\r
+\r
// Add the dialog keyboard handlers.\r
this.on( 'show', function()\r
{\r
CKEDITOR.document.on( 'keydown', focusKeydownHandler, this, null, 0 );\r
+ // Some browsers instead, don't cancel key events in the keydown, but in the\r
+ // keypress. So we must do a longer trip in those cases. (#4531)\r
+ if ( CKEDITOR.env.opera || ( CKEDITOR.env.gecko && CKEDITOR.env.mac ) )\r
+ CKEDITOR.document.on( 'keypress', focusKeyPressHandler, this );\r
\r
if ( CKEDITOR.env.ie6Compat )\r
{\r
this.on( 'hide', function()\r
{\r
CKEDITOR.document.removeListener( 'keydown', focusKeydownHandler );\r
+ if ( CKEDITOR.env.opera || ( CKEDITOR.env.gecko && CKEDITOR.env.mac ) )\r
+ CKEDITOR.document.removeListener( 'keypress', focusKeyPressHandler );\r
} );\r
this.on( 'iframeAdded', function( evt )\r
{\r
};\r
\r
// Focusable interface. Use it via dialog.addFocusable.\r
- function Focusable( dialog, element, index ) {\r
+ function Focusable( dialog, element, index )\r
+ {\r
this.element = element;\r
this.focusIndex = index;\r
this.isFocusable = function()\r
{\r
- return true;\r
+ return !element.getAttribute( 'disabled' ) && element.isVisible();\r
};\r
this.focus = function()\r
{\r
*/\r
show : function()\r
{\r
- if ( this._.editor.mode == 'wysiwyg' && CKEDITOR.env.ie )\r
- this._.editor.getSelection().lock();\r
+ var editor = this._.editor;\r
+ if ( editor.mode == 'wysiwyg' && CKEDITOR.env.ie )\r
+ {\r
+ var selection = editor.getSelection();\r
+ selection && selection.lock();\r
+ }\r
\r
// Insert the dialog's element to the root document.\r
var element = this._.element;\r
this._.parentDialog = null;\r
addCover( this._.editor );\r
\r
- CKEDITOR.document.on( 'keydown', accessKeyDownHandler );\r
- CKEDITOR.document.on( 'keyup', accessKeyUpHandler );\r
+ element.on( 'keydown', accessKeyDownHandler );\r
+ element.on( CKEDITOR.env.opera ? 'keypress' : 'keyup', accessKeyUpHandler );\r
\r
// Prevent some keys from bubbling up. (#4269)\r
for ( var event in { keyup :1, keydown :1, keypress :1 } )\r
- CKEDITOR.document.on( event, preventKeyBubbling );\r
+ element.on( event, preventKeyBubbling );\r
}\r
else\r
{\r
// Execute onLoad for the first show.\r
this.fireOnce( 'load', {} );\r
this.fire( 'show', {} );\r
+ this._.editor.fire( 'dialogShow', this );\r
\r
// Save the initial values of the dialog.\r
this.foreach( function( contentObj ) { contentObj.setInitValue && contentObj.setInitValue(); } );\r
hide : function()\r
{\r
this.fire( 'hide', {} );\r
+ this._.editor.fire( 'dialogHide', this );\r
\r
// Remove the dialog's element from the root document.\r
var element = this._.element;\r
CKEDITOR.dialog._.currentZIndex = null;\r
\r
// Remove access key handlers.\r
- CKEDITOR.document.removeListener( 'keydown', accessKeyDownHandler );\r
- CKEDITOR.document.removeListener( 'keyup', accessKeyUpHandler );\r
- CKEDITOR.document.removeListener( 'keypress', accessKeyUpHandler );\r
+ element.removeListener( 'keydown', accessKeyDownHandler );\r
+ element.removeListener( CKEDITOR.env.opera ? 'keypress' : 'keyup', accessKeyUpHandler );\r
\r
// Remove bubbling-prevention handler. (#4269)\r
for ( var event in { keyup :1, keydown :1, keypress :1 } )\r
- CKEDITOR.document.removeListener( event, preventKeyBubbling );\r
+ element.removeListener( event, preventKeyBubbling );\r
\r
var editor = this._.editor;\r
editor.focus();\r
\r
if ( editor.mode == 'wysiwyg' && CKEDITOR.env.ie )\r
- editor.getSelection().unlock( true );\r
+ {\r
+ var selection = editor.getSelection();\r
+ selection && selection.unlock( true );\r
+ }\r
}\r
else\r
CKEDITOR.dialog._.currentZIndex -= 10;\r
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
element = dialog.getElement().getFirst(),\r
editor = dialog.getParentEditor(),\r
magnetDistance = editor.config.dialog_magnetDistance,\r
- margins = skinData[ editor.skinName ].margins || [ 0, 0, 0, 0 ];\r
+ margins = editor.skin.margins || [ 0, 0, 0, 0 ];\r
\r
if ( typeof magnetDistance == 'undefined' )\r
magnetDistance = 20;\r
minWidth = definition.minWidth || 0,\r
minHeight = definition.minHeight || 0,\r
resizable = definition.resizable,\r
- margins = skinData[ dialog.getParentEditor().skinName ].margins || [ 0, 0, 0, 0 ];\r
+ margins = dialog.getParentEditor().skin.margins || [ 0, 0, 0, 0 ];\r
\r
function topSizer( coords, dy )\r
{\r
\r
if ( !coverElement )\r
{\r
+ var backgroundColorStyle = editor.config.dialog_backgroundCoverColor || 'white';\r
+\r
var html = [\r
'<div style="position: ', ( CKEDITOR.env.ie6Compat ? 'absolute' : 'fixed' ),\r
'; z-index: ', editor.config.baseFloatZIndex,\r
'; top: 0px; left: 0px; ',\r
- 'background-color: ', editor.config.dialog_backgroundCoverColor || 'white',\r
+ ( !CKEDITOR.env.ie6Compat ? 'background-color: ' + backgroundColorStyle : '' ),\r
'" id="cke_dialog_background_cover">'\r
];\r
\r
if ( CKEDITOR.env.ie6Compat )\r
{\r
// Support for custom document.domain in IE.\r
- var isCustomDomain = CKEDITOR.env.isCustomDomain();\r
+ var isCustomDomain = CKEDITOR.env.isCustomDomain(),\r
+ iframeHtml = '<html><body style=\\\'background-color:' + backgroundColorStyle + ';\\\'></body></html>';\r
\r
html.push(\r
'<iframe' +\r
' id="cke_dialog_background_iframe"' +\r
' src="javascript:' );\r
\r
- html.push(\r
- isCustomDomain ?\r
- 'void((function(){' +\r
+ html.push( 'void((function(){' +\r
'document.open();' +\r
- 'document.domain=\'' + document.domain + '\';' +\r
+ ( isCustomDomain ? 'document.domain=\'' + document.domain + '\';' : '' ) +\r
+ 'document.write( \'' + iframeHtml + '\' );' +\r
'document.close();' +\r
- '})())'\r
- :\r
- '\'\'' );\r
+ '})())' );\r
\r
html.push(\r
'"' +\r
return;\r
\r
keyProcessor = keyProcessor[keyProcessor.length - 1];\r
- keyProcessor.keyup && keyProcessor.keyup.call( keyProcessor.uiElement, keyProcessor.dialog, keyProcessor.key );\r
- evt.data.preventDefault();\r
+ if ( keyProcessor.keyup )\r
+ {\r
+ keyProcessor.keyup.call( keyProcessor.uiElement, keyProcessor.dialog, keyProcessor.key );\r
+ evt.data.preventDefault();\r
+ }\r
};\r
\r
var registerAccessKey = function( uiElement, dialog, key, downFunc, upFunc )\r
*/\r
isVisible : function()\r
{\r
- return !!this.getInputElement().$.offsetHeight;\r
+ return this.getInputElement().isVisible();\r
},\r
\r
/**\r
}\r
};\r
})();\r
-\r
- // Grab the margin data from skin definition and store it away.\r
- CKEDITOR.skins.add = ( function()\r
- {\r
- var original = CKEDITOR.skins.add;\r
- return function( skinName, skinDefinition )\r
- {\r
- skinData[ skinName ] = { margins : skinDefinition.margins };\r
- return original.apply( this, arguments );\r
- };\r
- } )();\r
})();\r
\r
// Extend the CKEDITOR.editor class with dialog specific functions.\r
/**\r
* Loads and opens a registered dialog.\r
* @param {String} dialogName The registered name of the dialog.\r
+ * @param {Function} callback The function to be invoked after dialog instance created.\r
* @see CKEDITOR.dialog.add\r
* @example\r
* CKEDITOR.instances.editor1.openDialog( 'smiley' );\r
* @returns {CKEDITOR.dialog} The dialog object corresponding to the dialog displayed. null if the dialog name is not registered.\r
*/\r
- openDialog : function( dialogName )\r
+ openDialog : function( dialogName, callback )\r
{\r
var dialogDefinitions = CKEDITOR.dialog._.dialogDefinitions[ dialogName ];\r
\r
var dialog = storedDialogs[ dialogName ] ||\r
( storedDialogs[ dialogName ] = new CKEDITOR.dialog( this, dialogName ) );\r
\r
+ callback && callback.call( dialog, dialog );\r
dialog.show();\r
\r
return dialog;\r
// In case of plugin error, mark it as loading failed.\r
if ( typeof CKEDITOR.dialog._.dialogDefinitions[ dialogName ] != 'function' )\r
CKEDITOR.dialog._.dialogDefinitions[ dialogName ] = 'failed';\r
- me.openDialog( dialogName );\r
+ me.openDialog( dialogName, callback );\r
body.setStyle( 'cursor', cursor );\r
} );\r
\r
}\r
});\r
\r
+CKEDITOR.plugins.add( 'dialog',\r
+ {\r
+ requires : [ 'dialogui' ]\r
+ });\r
+\r
// Dialog related configurations.\r
\r
/**\r