X-Git-Url: https://jasonwoof.com/gitweb/?a=blobdiff_plain;f=_source%2Fplugins%2Fdialog%2Fplugin.js;h=9927ebee360fb8d32cd6420a59c29808daa677d0;hb=e371ddf8abcb89013e20e6d0dd746adec344d0e5;hp=fa4cc99a206958defbd46f8a7393d6a721d2f984;hpb=c6e377a02b54abc07129d72b632763c727476a15;p=ckeditor.git
diff --git a/_source/plugins/dialog/plugin.js b/_source/plugins/dialog/plugin.js
index fa4cc99..9927ebe 100644
--- a/_source/plugins/dialog/plugin.js
+++ b/_source/plugins/dialog/plugin.js
@@ -127,6 +127,12 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3;
this.parts = themeBuilt.parts;
+ CKEDITOR.tools.setTimeout( function()
+ {
+ editor.fire( 'ariaWidget', this.parts.contents );
+ },
+ 0, this );
+
// Set the startup styles for the dialog, avoiding it enlarging the
// page size on the dialog creation.
this.parts.dialog.setStyles(
@@ -162,6 +168,9 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3;
{
this.on( 'ok', function( evt )
{
+ // Dialog confirm might probably introduce content changes (#5415).
+ editor.fire( 'saveSnapshot' );
+ setTimeout( function () { editor.fire( 'saveSnapshot' ); }, 0 );
if ( definition.onOk.call( this, evt ) === false )
evt.data.hide = false;
});
@@ -242,8 +251,29 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3;
{
if ( this.fire( 'cancel', { hide : true } ).hide !== false )
this.hide();
+ evt.data.preventDefault();
}, this );
+ // Sort focus list according to tab order definitions.
+ function setupFocus()
+ {
+ var focusList = me._.focusList;
+ focusList.sort( function( a, b )
+ {
+ // Mimics browser tab order logics;
+ if ( a.tabIndex != b.tabIndex )
+ return b.tabIndex - a.tabIndex;
+ // Sort is not stable in some browsers,
+ // fall-back the comparator to 'focusIndex';
+ else
+ return a.focusIndex - b.focusIndex;
+ });
+
+ var size = focusList.length;
+ for ( var i = 0; i < size; i++ )
+ focusList[ i ].focusIndex = i;
+ }
+
function changeFocus( forward )
{
var focusList = me._.focusList,
@@ -251,7 +281,17 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3;
if ( focusList.length < 1 )
return;
- var startIndex = ( me._.currentFocusIndex + offset + focusList.length ) % focusList.length,
+ var current = me._.currentFocusIndex;
+
+ // Trigger the 'blur' event of any input element before anything,
+ // since certain UI updates may depend on it.
+ try
+ {
+ focusList[ current ].getInputElement().$.blur();
+ }
+ catch( e ){}
+
+ var startIndex = ( current + offset + focusList.length ) % focusList.length,
currentIndex = startIndex;
while ( !focusList[ currentIndex ].isFocusable() )
{
@@ -266,6 +306,8 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3;
focusList[ currentIndex ].select();
}
+ this.changeFocus = changeFocus;
+
var processed;
function focusKeydownHandler( evt )
@@ -274,7 +316,8 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3;
if ( me != CKEDITOR.dialog._.currentTop )
return;
- var keystroke = evt.data.getKeystroke();
+ var keystroke = evt.data.getKeystroke(),
+ rtl = editor.lang.dir == 'rtl';
processed = 0;
if ( keystroke == 9 || keystroke == CKEDITOR.SHIFT + 9 )
@@ -297,7 +340,7 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3;
processed = 1;
}
- else if ( keystroke == CKEDITOR.ALT + 121 && !me._.tabBarMode )
+ else if ( keystroke == CKEDITOR.ALT + 121 && !me._.tabBarMode && me.getPageCount() > 1 )
{
// Alt-F10 puts focus into the current tab item in the tab bar.
me._.tabBarMode = true;
@@ -307,11 +350,19 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3;
else if ( ( keystroke == 37 || keystroke == 39 ) && me._.tabBarMode )
{
// Arrow keys - used for changing tabs.
- nextId = ( keystroke == 37 ? getPreviousVisibleTab.call( me ) : getNextVisibleTab.call( me ) );
+ nextId = ( keystroke == ( rtl ? 39 : 37 ) ? getPreviousVisibleTab.call( me ) : getNextVisibleTab.call( me ) );
me.selectPage( nextId );
me._.tabs[ nextId ][ 0 ].focus();
processed = 1;
}
+ else if ( ( keystroke == 13 || keystroke == 32 ) && me._.tabBarMode )
+ {
+ this.selectPage( this._.currentTabId );
+ this._.tabBarMode = false;
+ this._.currentFocusIndex = -1;
+ changeFocus( true );
+ processed = 1;
+ }
if ( processed )
{
@@ -325,26 +376,22 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3;
processed && evt.data.preventDefault();
}
+ var dialogElement = this._.element;
// Add the dialog keyboard handlers.
this.on( 'show', function()
{
- CKEDITOR.document.on( 'keydown', focusKeydownHandler, this, null, 0 );
+ dialogElement.on( 'keydown', focusKeydownHandler, this, null, 0 );
// Some browsers instead, don't cancel key events in the keydown, but in the
// keypress. So we must do a longer trip in those cases. (#4531)
if ( CKEDITOR.env.opera || ( CKEDITOR.env.gecko && CKEDITOR.env.mac ) )
- CKEDITOR.document.on( 'keypress', focusKeyPressHandler, this );
+ dialogElement.on( 'keypress', focusKeyPressHandler, this );
- if ( CKEDITOR.env.ie6Compat )
- {
- var coverDoc = coverElement.getChild( 0 ).getFrameDocument();
- coverDoc.on( 'keydown', focusKeydownHandler, this, null, 0 );
- }
} );
this.on( 'hide', function()
{
- CKEDITOR.document.removeListener( 'keydown', focusKeydownHandler );
+ dialogElement.removeListener( 'keydown', focusKeydownHandler );
if ( CKEDITOR.env.opera || ( CKEDITOR.env.gecko && CKEDITOR.env.mac ) )
- CKEDITOR.document.removeListener( 'keypress', focusKeyPressHandler );
+ dialogElement.removeListener( 'keypress', focusKeyPressHandler );
} );
this.on( 'iframeAdded', function( evt )
{
@@ -355,10 +402,30 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3;
// Auto-focus logic in dialog.
this.on( 'show', function()
{
- if ( !this._.hasFocus )
+ // Setup tabIndex on showing the dialog instead of on loading
+ // to allow dynamic tab order happen in dialog definition.
+ setupFocus();
+
+ if ( editor.config.dialog_startupFocusTab
+ && me._.pageCount > 1 )
+ {
+ me._.tabBarMode = true;
+ me._.tabs[ me._.currentTabId ][ 0 ].focus();
+ }
+ else if ( !this._.hasFocus )
{
this._.currentFocusIndex = -1;
- changeFocus( true );
+
+ // Decide where to put the initial focus.
+ if ( definition.onFocus )
+ {
+ var initialFocus = definition.onFocus.call( this );
+ // Focus the field that the user specified.
+ initialFocus && initialFocus.focus();
+ }
+ // Focus the first field in layout order.
+ else
+ changeFocus( true );
/*
* IE BUG: If the initial focus went into a non-text element (e.g. button),
@@ -405,30 +472,29 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3;
// Insert the tabs and contents.
for ( var i = 0 ; i < definition.contents.length ; i++ )
- this.addPage( definition.contents[i] );
+ {
+ var page = definition.contents[i];
+ page && this.addPage( page );
+ }
- var tabRegex = /cke_dialog_tab(\s|$|_)/,
- tabOuterRegex = /cke_dialog_tab(\s|$)/;
this.parts['tabs'].on( 'click', function( evt )
{
- var target = evt.data.getTarget(), firstNode = target, id, page;
-
+ var target = evt.data.getTarget();
// If we aren't inside a tab, bail out.
- if ( !( tabRegex.test( target.$.className ) || target.getName() == 'a' ) )
- return;
-
- // Find the outer
container of the tab.
- id = target.$.id.substr( 0, target.$.id.lastIndexOf( '_' ) );
- this.selectPage( id );
-
- if ( this._.tabBarMode )
+ if ( target.hasClass( 'cke_dialog_tab' ) )
{
- this._.tabBarMode = false;
- this._.currentFocusIndex = -1;
- changeFocus( true );
- }
+ // Get the ID of the tab, without the 'cke_' prefix and the unique number suffix.
+ var id = target.$.id;
+ this.selectPage( id.substring( 4, id.lastIndexOf( '_' ) ) );
- evt.data.preventDefault();
+ if ( this._.tabBarMode )
+ {
+ this._.tabBarMode = false;
+ this._.currentFocusIndex = -1;
+ changeFocus( true );
+ }
+ evt.data.preventDefault();
+ }
}, this );
// Insert buttons.
@@ -444,8 +510,6 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3;
for ( i = 0 ; i < buttons.length ; i++ )
this._.buttons[ buttons[i].id ] = buttons[i];
-
- CKEDITOR.skins.load( editor, 'dialog' );
};
// Focusable interface. Use it via dialog.addFocusable.
@@ -453,6 +517,8 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3;
{
this.element = element;
this.focusIndex = index;
+ // TODO: support tabIndex for focusables.
+ this.tabIndex = 0;
this.isFocusable = function()
{
return !element.getAttribute( 'disabled' ) && element.isVisible();
@@ -480,6 +546,12 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3;
CKEDITOR.dialog.prototype =
{
+ destroy : function()
+ {
+ this.hide();
+ this._.element.remove();
+ },
+
/**
* Resizes the dialog.
* @param {Number} width The width of the dialog in pixels.
@@ -596,7 +668,7 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3;
if ( !( element.getParent() && element.getParent().equals( CKEDITOR.document.getBody() ) ) )
element.appendTo( CKEDITOR.document.getBody() );
else
- return;
+ element.setStyle( 'display', 'block' );
// FIREFOX BUG: Fix vanishing caret for Firefox 2 or Gecko 1.8.
if ( CKEDITOR.env.gecko && CKEDITOR.env.version < 10900 )
@@ -630,7 +702,7 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3;
{
CKEDITOR.dialog._.currentTop = this;
this._.parentDialog = null;
- addCover( this._.editor );
+ showCover( this._.editor );
element.on( 'keydown', accessKeyDownHandler );
element.on( CKEDITOR.env.opera ? 'keypress' : 'keyup', accessKeyUpHandler );
@@ -734,23 +806,24 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3;
*/
hide : function()
{
+ if ( !this.parts.dialog.isVisible() )
+ return;
+
this.fire( 'hide', {} );
this._.editor.fire( 'dialogHide', this );
-
- // Remove the dialog's element from the root document.
var element = this._.element;
- if ( !element.getParent() )
- return;
-
- element.remove();
+ element.setStyle( 'display', 'none' );
this.parts.dialog.setStyle( 'visibility', 'hidden' );
-
// Unregister all access keys associated with this dialog.
unregisterAccessKey( this );
+ // Close any child(top) dialogs first.
+ while( CKEDITOR.dialog._.currentTop != this )
+ CKEDITOR.dialog._.currentTop.hide();
+
// Maintain dialog ordering and remove cover if needed.
if ( !this._.parentDialog )
- removeCover();
+ hideCover();
else
{
var parentElement = this._.parentDialog.getElement().getFirst();
@@ -783,7 +856,7 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3;
else
CKEDITOR.dialog._.currentZIndex -= 10;
-
+ delete this._.parentDialog;
// Reset the initial values of the dialog.
this.foreach( function( contentObj ) { contentObj.resetInitValue && contentObj.resetInitValue(); } );
},
@@ -805,34 +878,37 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3;
children : contents.elements,
expand : !!contents.expand,
padding : contents.padding,
- style : contents.style || 'width: 100%;' + ( CKEDITOR.env.ie6Compat ? '' : 'height: 100%;' )
+ style : contents.style || 'width: 100%; height: 100%;'
}, pageHtml );
// Create the HTML for the tab and the content block.
var page = CKEDITOR.dom.element.createFromHtml( pageHtml.join( '' ) );
- var tab = CKEDITOR.dom.element.createFromHtml( [
+ page.setAttribute( 'role', 'tabpanel' );
+
+ var env = CKEDITOR.env;
+ var tabId = 'cke_' + contents.id + '_' + CKEDITOR.tools.getNextNumber(),
+ tab = CKEDITOR.dom.element.createFromHtml( [
' 0 ? ' cke_last' : 'cke_first' ),
titleHtml,
( !!contents.hidden ? ' style="display:none"' : '' ),
- ' id="', contents.id + '_', CKEDITOR.tools.getNextNumber(), '"' +
- ' href="javascript:void(0)"',
- ' hidefocus="true">',
+ ' id="', tabId, '"',
+ env.gecko && env.version >= 10900 && !env.hc ? '' : ' href="javascript:void(0)"',
+ ' tabIndex="-1"',
+ ' hidefocus="true"',
+ ' role="tab">',
contents.label,
''
].join( '' ) );
- // If only a single page exist, a different style is used in the central pane.
- if ( this._.pageCount === 0 )
- this.parts.dialog.addClass( 'cke_single_page' );
- else
- this.parts.dialog.removeClass( 'cke_single_page' );
+ page.setAttribute( 'aria-labelledby', tabId );
// Take records for the tabs and elements created.
this._.tabs[ contents.id ] = [ tab, page ];
this._.tabIdList.push( contents.id );
- this._.pageCount++;
+ !contents.hidden && this._.pageCount++;
this._.lastTab = tab;
+ this.updateStyle();
var contentMap = this._.contents[ contents.id ] = {},
cursor,
@@ -870,6 +946,13 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3;
*/
selectPage : function( id )
{
+ if ( this._.currentTabId == id )
+ return;
+
+ // Returning true means that the event has been canceled
+ if ( this.fire( 'selectPage', { page : id, currentPage : this._.currentTabId } ) === true )
+ return;
+
// Hide the non-selected tabs and pages.
for ( var i in this._.tabs )
{
@@ -880,6 +963,7 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3;
tab.removeClass( 'cke_dialog_tab_selected' );
page.hide();
}
+ page.setAttribute( 'aria-hidden', i != id );
}
var selected = this._.tabs[id];
@@ -889,6 +973,13 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3;
this._.currentTabIndex = CKEDITOR.tools.indexOf( this._.tabIdList, id );
},
+ // Dialog state-specific style updates.
+ updateStyle : function()
+ {
+ // If only a single page shown, a different style is used in the central pane.
+ this.parts.dialog[ ( this._.pageCount === 1 ? 'add' : 'remove' ) + 'Class' ]( 'cke_single_page' );
+ },
+
/**
* Hides a page's tab away from the dialog.
* @param {String} id The page's Id.
@@ -898,9 +989,15 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3;
hidePage : function( id )
{
var tab = this._.tabs[id] && this._.tabs[id][0];
- if ( !tab )
+ if ( !tab || this._.pageCount == 1 )
return;
+ // Switch to other tab first when we're hiding the active tab.
+ else if ( id == this._.currentTabId )
+ this.selectPage( getPreviousVisibleTab.call( this ) );
+
tab.hide();
+ this._.pageCount--;
+ this.updateStyle();
},
/**
@@ -915,6 +1012,8 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3;
if ( !tab )
return;
tab.show();
+ this._.pageCount++;
+ this.updateStyle();
},
/**
@@ -1197,12 +1296,15 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3;
var defaultDialogDefinition =
{
- resizable : CKEDITOR.DIALOG_RESIZE_NONE,
+ resizable : CKEDITOR.DIALOG_RESIZE_BOTH,
minWidth : 600,
minHeight : 400,
buttons : [ CKEDITOR.dialog.okButton, CKEDITOR.dialog.cancelButton ]
};
+ // The buttons in MacOS Apps are in reverse order #4750
+ CKEDITOR.env.mac && defaultDialogDefinition.buttons.reverse();
+
// Tool function used to return an item from an array based on its id
// property.
var getById = function( array, id, recurse )
@@ -1289,7 +1391,7 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3;
// Transform the contents entries in contentObjects.
var contents = dialogDefinition.contents;
for ( var i = 0, content ; ( content = contents[i] ) ; i++ )
- contents[ i ] = new contentObject( dialog, content );
+ contents[ i ] = content && new contentObject( dialog, content );
CKEDITOR.tools.extend( this, dialogDefinition );
};
@@ -1494,7 +1596,7 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3;
if ( CKEDITOR.env.ie6Compat )
{
- var coverDoc = coverElement.getChild( 0 ).getFrameDocument();
+ var coverDoc = currentCover.getChild( 0 ).getFrameDocument();
coverDoc.removeListener( 'mousemove', mouseMoveHandler );
coverDoc.removeListener( 'mouseup', mouseUpHandler );
}
@@ -1512,7 +1614,7 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3;
if ( CKEDITOR.env.ie6Compat )
{
- var coverDoc = coverElement.getChild( 0 ).getFrameDocument();
+ var coverDoc = currentCover.getChild( 0 ).getFrameDocument();
coverDoc.on( 'mousemove', mouseMoveHandler );
coverDoc.on( 'mouseup', mouseUpHandler );
}
@@ -1570,7 +1672,7 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3;
if ( CKEDITOR.env.ie6Compat )
{
- var coverDoc = coverElement.getChild( 0 ).getFrameDocument();
+ var coverDoc = currentCover.getChild( 0 ).getFrameDocument();
coverDoc.on( 'mousemove', mouseMoveHandler, dialog, { part : partName } );
coverDoc.on( 'mouseup', mouseUpHandler, dialog, { part : partName } );
}
@@ -1641,7 +1743,7 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3;
if ( CKEDITOR.env.ie6Compat )
{
- var coverDoc = coverElement.getChild( 0 ).getFrameDocument();
+ var coverDoc = currentCover.getChild( 0 ).getFrameDocument();
coverDoc.removeListener( 'mouseup', mouseUpHandler );
coverDoc.removeListener( 'mousemove', mouseMoveHandler );
}
@@ -1665,25 +1767,33 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3;
}
var resizeCover;
- var coverElement;
+ // Caching resuable covers and allowing only one cover
+ // on screen.
+ var covers = {},
+ currentCover;
- var addCover = function( editor )
+ function showCover( editor )
{
var win = CKEDITOR.document.getWindow();
+ var backgroundColorStyle = editor.config.dialog_backgroundCoverColor || 'white',
+ backgroundCoverOpacity = editor.config.dialog_backgroundCoverOpacity,
+ baseFloatZIndex = editor.config.baseFloatZIndex,
+ coverKey = CKEDITOR.tools.genKey(
+ backgroundColorStyle,
+ backgroundCoverOpacity,
+ baseFloatZIndex ),
+ coverElement = covers[ coverKey ];
if ( !coverElement )
{
- var backgroundColorStyle = editor.config.dialog_backgroundCoverColor || 'white';
-
var html = [
' '
+ '" class="cke_dialog_background_cover">'
];
-
if ( CKEDITOR.env.ie6Compat )
{
// Support for custom document.domain in IE.
@@ -1719,14 +1829,19 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3;
html.push( ' ' );
coverElement = CKEDITOR.dom.element.createFromHtml( html.join( '' ) );
- }
+ coverElement.setOpacity( backgroundCoverOpacity != undefined ? backgroundCoverOpacity : 0.5 );
- var element = coverElement;
+ coverElement.appendTo( CKEDITOR.document.getBody() );
+ covers[ coverKey ] = coverElement;
+ }
+ else
+ coverElement. show();
+ currentCover = coverElement;
var resizeFunc = function()
{
var size = win.getViewPaneSize();
- element.setStyles(
+ coverElement.setStyles(
{
width : size.width + 'px',
height : size.height + 'px'
@@ -1737,7 +1852,7 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3;
{
var pos = win.getScrollPosition(),
cursor = CKEDITOR.dialog._.currentTop;
- element.setStyles(
+ coverElement.setStyles(
{
left : pos.x + 'px',
top : pos.y + 'px'
@@ -1769,20 +1884,15 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3;
}, 0 );
scrollFunc();
}
+ }
- var opacity = editor.config.dialog_backgroundCoverOpacity;
- element.setOpacity( typeof opacity != 'undefined' ? opacity : 0.5 );
-
- element.appendTo( CKEDITOR.document.getBody() );
- };
-
- var removeCover = function()
+ function hideCover()
{
- if ( !coverElement )
+ if ( !currentCover )
return;
var win = CKEDITOR.document.getWindow();
- coverElement.remove();
+ currentCover.hide();
win.removeListener( 'resize', resizeCover );
if ( CKEDITOR.env.ie6Compat )
@@ -1794,7 +1904,14 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3;
}, 0 );
}
resizeCover = null;
- };
+ }
+
+ function removeCovers()
+ {
+ for ( var coverId in covers )
+ covers[ coverId ].remove();
+ covers = {};
+ }
var accessKeyProcessors = {};
@@ -1938,8 +2055,8 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3;
html = [ '<', nodeName, ' ' ],
styles = ( stylesArg && stylesArg.call ? stylesArg( elementDefinition ) : stylesArg ) || {},
attributes = ( attributesArg && attributesArg.call ? attributesArg( elementDefinition ) : attributesArg ) || {},
- innerHTML = ( contentsArg && contentsArg.call ? contentsArg( dialog, elementDefinition ) : contentsArg ) || '',
- domId = this.domId = attributes.id || CKEDITOR.tools.getNextNumber() + '_uiElement',
+ innerHTML = ( contentsArg && contentsArg.call ? contentsArg.call( this, dialog, elementDefinition ) : contentsArg ) || '',
+ domId = this.domId = attributes.id || CKEDITOR.tools.getNextId() + '_uiElement',
id = this.id = elementDefinition.id,
i;
@@ -2023,6 +2140,8 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3;
// Register the object as a tab focus if it can be included.
if ( this.keyboardFocusable )
{
+ this.tabIndex = elementDefinition.tabIndex || 0;
+
this.focusIndex = dialog._.focusList.push( this ) - 1;
this.on( 'focus', function()
{
@@ -2085,7 +2204,7 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3;
className = 'cke_dialog_ui_hbox_first';
if ( i == childHtmlList.length - 1 )
className = 'cke_dialog_ui_hbox_last';
- html.push( ' | | | ' );
return html.join( '' );
};
- CKEDITOR.ui.dialog.uiElement.call( this, dialog, elementDefinition || { type : 'vbox' }, htmlList, 'div', null, null, innerHTML );
+ CKEDITOR.ui.dialog.uiElement.call( this, dialog, elementDefinition || { type : 'vbox' }, htmlList, 'div', null, { role : 'presentation' }, innerHTML );
}
};
})();
@@ -2564,9 +2686,12 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3;
{
editor.openDialog( this.dialogName );
},
+
// Dialog commands just open a dialog ui, thus require no undo logic,
// undo support should dedicate to specific dialog implementation.
- canUndo: false
+ canUndo: false,
+
+ editorFocus : CKEDITOR.env.ie || CKEDITOR.env.webkit
};
(function()
@@ -2686,6 +2811,24 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3;
return this.functions( function( val ){ return val != value; }, msg );
}
};
+
+ CKEDITOR.on( 'instanceDestroyed', function( evt )
+ {
+ // Remove dialog cover on last instance destroy.
+ if ( CKEDITOR.tools.isEmpty( CKEDITOR.instances ) )
+ {
+ var currentTopDialog;
+ while ( ( currentTopDialog = CKEDITOR.dialog._.currentTop ) )
+ currentTopDialog.hide();
+ removeCovers();
+ }
+
+ var dialogs = evt.editor._.storedDialogs;
+ for ( var name in dialogs )
+ dialogs[ name ].destroy();
+
+ });
+
})();
})();
@@ -2704,10 +2847,11 @@ CKEDITOR.tools.extend( CKEDITOR.editor.prototype,
*/
openDialog : function( dialogName, callback )
{
- var dialogDefinitions = CKEDITOR.dialog._.dialogDefinitions[ dialogName ];
+ var dialogDefinitions = CKEDITOR.dialog._.dialogDefinitions[ dialogName ],
+ dialogSkin = this.skin.dialog;
// If the dialogDefinition is already loaded, open it immediately.
- if ( typeof dialogDefinitions == 'function' )
+ if ( typeof dialogDefinitions == 'function' && dialogSkin._isLoaded )
{
var storedDialogs = this._.storedDialogs ||
( this._.storedDialogs = {} );
@@ -2729,14 +2873,31 @@ CKEDITOR.tools.extend( CKEDITOR.editor.prototype,
me = this;
body.setStyle( 'cursor', 'wait' );
- CKEDITOR.scriptLoader.load( CKEDITOR.getUrl( dialogDefinitions ), function()
- {
- // In case of plugin error, mark it as loading failed.
- if ( typeof CKEDITOR.dialog._.dialogDefinitions[ dialogName ] != 'function' )
- CKEDITOR.dialog._.dialogDefinitions[ dialogName ] = 'failed';
- me.openDialog( dialogName, callback );
- body.setStyle( 'cursor', cursor );
- } );
+
+ function onDialogFileLoaded( success )
+ {
+ var dialogDefinition = CKEDITOR.dialog._.dialogDefinitions[ dialogName ],
+ skin = me.skin.dialog;
+
+ // Check if both skin part and definition is loaded.
+ if ( !skin._isLoaded || loadDefinition && typeof success == 'undefined' )
+ return;
+
+ // In case of plugin error, mark it as loading failed.
+ if ( typeof dialogDefinition != 'function' )
+ CKEDITOR.dialog._.dialogDefinitions[ dialogName ] = 'failed';
+
+ me.openDialog( dialogName, callback );
+ body.setStyle( 'cursor', cursor );
+ }
+
+ if ( typeof dialogDefinitions == 'string' )
+ {
+ var loadDefinition = 1;
+ CKEDITOR.scriptLoader.load( CKEDITOR.getUrl( dialogDefinitions ), onDialogFileLoaded );
+ }
+
+ CKEDITOR.skins.load( this, 'dialog', onDialogFileLoaded );
return null;
}
@@ -2770,6 +2931,15 @@ CKEDITOR.plugins.add( 'dialog',
*/
/**
+ * If the dialog has more than one tab, put focus into the first tab as soon as dialog is opened.
+ * @name CKEDITOR.config.dialog_startupFocusTab
+ * @type Boolean
+ * @default false
+ * @example
+ * config.dialog_startupFocusTab = true;
+ */
+
+/**
* The distance of magnetic borders used in moving and resizing dialogs,
* measured in pixels.
* @name CKEDITOR.config.dialog_magnetDistance
@@ -2793,3 +2963,11 @@ CKEDITOR.plugins.add( 'dialog',
* @param {CKEDITOR.editor} editor The editor instance that will use the
* dialog.
*/
+
+/**
+ * Fired when a tab is going to be selected in a dialog
+ * @name dialog#selectPage
+ * @event
+ * @param String page The id of the page that it's gonna be selected.
+ * @param String currentPage The id of the current page.
+ */
|