output.push(\r
'<div class="', editor.skinClass ,'"' +\r
' lang="', editor.langCode, '"' +\r
+ ' role="presentation"' +\r
// iframe loading need sometime, keep the panel hidden(#4186).\r
' style="display:none;z-index:' + ( editor.config.baseFloatZIndex + 1 ) + '">' +\r
'<div' +\r
' id=', id,\r
' dir=', editor.lang.dir,\r
+ ' role="presentation"' +\r
' class="cke_panel cke_', editor.lang.dir );\r
\r
if ( this.className )\r
output.push(\r
'<iframe id="', id, '_frame"' +\r
' frameborder="0"' +\r
- ' src="javascript:void(' );\r
+ ' role="application" src="javascript:void(' );\r
\r
output.push(\r
// Support for custom document.domain in IE.\r
'<style>.' + className + '_container{visibility:hidden}</style>' +\r
'</head>' +\r
'<body class="cke_' + dir + ' cke_panel_frame ' + CKEDITOR.env.cssClass + '" style="margin:0;padding:0"' +\r
- ' onload="( window.CKEDITOR || window.parent.CKEDITOR ).tools.callFunction(' + onLoad + ');">' +\r
- '</body>' +\r
+ ' onload="( window.CKEDITOR || window.parent.CKEDITOR ).tools.callFunction(' + onLoad + ');"></body>' +\r
// It looks strange, but for FF2, the styles must go\r
// after <body>, so it (body) becames immediatelly\r
// available. (#3031)\r
\r
doc.on( 'keydown', function( evt )\r
{\r
- var keystroke = evt.data.getKeystroke();\r
+ var keystroke = evt.data.getKeystroke(),\r
+ dir = this.document.getById( 'cke_' + this.id ).getAttribute( 'dir' );\r
\r
// Delegate key processing to block.\r
if ( this._.onKeyDown && this._.onKeyDown( keystroke ) === false )\r
return;\r
}\r
\r
- if ( keystroke == 27 ) // ESC\r
- this.onEscape && this.onEscape();\r
+ // ESC/ARROW-LEFT(ltr) OR ARROW-RIGHT(rtl)\r
+ if ( keystroke == 27 || keystroke == ( dir == 'rtl' ? 39 : 37 ) )\r
+ {\r
+ if ( this.onEscape && this.onEscape( keystroke ) === false )\r
+ evt.data.preventDefault( );\r
+ }\r
},\r
this );\r
\r
\r
addBlock : function( name, block )\r
{\r
- block = this._.blocks[ name ] = block || new CKEDITOR.ui.panel.block( this.getHolderElement() );\r
+ block = this._.blocks[ name ] = block instanceof CKEDITOR.ui.panel.block ? block\r
+ : new CKEDITOR.ui.panel.block( this.getHolderElement(), block );\r
\r
if ( !this._.currentBlock )\r
this.showBlock( name );\r
{\r
var blocks = this._.blocks,\r
block = blocks[ name ],\r
- current = this._.currentBlock;\r
+ current = this._.currentBlock,\r
+ holder = this.forceIFrame ?\r
+ this.document.getById( 'cke_' + this.id + '_frame' )\r
+ : this._.holder;\r
\r
if ( current )\r
+ {\r
+ // Clean up the current block's effects on holder.\r
+ holder.removeAttributes( current.attributes );\r
current.hide();\r
+ }\r
\r
this._.currentBlock = block;\r
\r
+ holder.setAttributes( block.attributes );\r
+ CKEDITOR.fire( 'ariaWidget', holder );\r
+\r
// Reset the focus index, so it will always go into the first one.\r
block._.focusIndex = -1;\r
\r
\r
CKEDITOR.ui.panel.block = CKEDITOR.tools.createClass(\r
{\r
- $ : function( blockHolder )\r
+ $ : function( blockHolder, blockDefinition )\r
{\r
this.element = blockHolder.append(\r
blockHolder.getDocument().createElement( 'div',\r
{\r
attributes :\r
{\r
- 'class' : 'cke_panel_block'\r
+ 'tabIndex' : -1,\r
+ 'class' : 'cke_panel_block',\r
+ 'role' : 'presentation'\r
},\r
styles :\r
{\r
}\r
}) );\r
\r
+ // Copy all definition properties to this object.\r
+ if ( blockDefinition )\r
+ CKEDITOR.tools.extend( this, blockDefinition );\r
+\r
this.keys = {};\r
\r
this._.focusIndex = -1;\r
this.element.disableContextMenu();\r
},\r
\r
- _ : {},\r
+ _ : {\r
+\r
+ /**\r
+ * Mark the item specified by the index as current activated.\r
+ */\r
+ markItem: function( index )\r
+ {\r
+ if ( index == -1 )\r
+ return;\r
+ var links = this.element.getElementsByTag( 'a' );\r
+ var item = links.getItem( this._.focusIndex = index );\r
+\r
+ // Safari need focus on the iframe window first(#3389), but we need\r
+ // lock the blur to avoid hiding the panel.\r
+ if ( CKEDITOR.env.webkit )\r
+ item.getDocument().getWindow().focus();\r
+ item.focus();\r
+ }\r
+ },\r
\r
proto :\r
{\r