Index: /CKEditor/branches/features/aria/_source/lang/en.js
===================================================================
--- /CKEditor/branches/features/aria/_source/lang/en.js	(revision 4962)
+++ /CKEditor/branches/features/aria/_source/lang/en.js	(revision 4963)
@@ -530,4 +530,5 @@
 		insertOption: 'Replace actual contents',
 		selectPromptMsg: 'Please select the template to open in the editor',
+		optionsArea	 : 'Templates Options',
 		emptyListMsg : '(No templates defined)'
 	},
Index: /CKEditor/branches/features/aria/_source/plugins/templates/dialogs/templates.js
===================================================================
--- /CKEditor/branches/features/aria/_source/plugins/templates/dialogs/templates.js	(revision 4962)
+++ /CKEditor/branches/features/aria/_source/plugins/templates/dialogs/templates.js	(revision 4963)
@@ -8,107 +8,132 @@
 	var doc = CKEDITOR.document;
 
-	var listId = 'cke' + CKEDITOR.tools.getNextNumber();
-
-	// Constructs the HTML view of the specified templates data.
-	function renderTemplatesList( editor, templatesDefinitions )
-	{
-		var listDiv = doc.getById( listId );
-
-		// clear loading wait text.
-		listDiv.setHtml( '' );
-
-		for ( var i = 0 ; i < templatesDefinitions.length ; i++ )
-		{
-			var definition = CKEDITOR.getTemplates( templatesDefinitions[ i ] ),
-				imagesPath = definition.imagesPath,
-				templates = definition.templates;
-
-			for ( var j = 0 ; j < templates.length ; j++ )
-			{
-				var template = templates[ j ];
-				listDiv.append( createTemplateItem( editor, template, imagesPath ) );
-			}
-		}
-	}
-
-	function createTemplateItem( editor, template, imagesPath )
-	{
-		var div = doc.createElement( 'div' );
-		div.setAttribute( 'class', 'cke_tpl_item' );
-
-		// Build the inner HTML of our new item DIV.
-		var html = '<table style="width:350px;" class="cke_tpl_preview"><tr>';
-
-		if( template.image && imagesPath )
-			html += '<td class="cke_tpl_preview_img"><img src="' + CKEDITOR.getUrl( imagesPath + template.image ) + '"></td>';
-
-		html += '<td style="white-space:normal;"><span class="cke_tpl_title">' + template.title + '</span><br/>';
-
-		if( template.description )
-			html += '<span>' + template.description + '</span>';
-
-		html += '</td></tr></table>';
-
-		div.setHtml( html );
-
-		div.on( 'mouseover', function()
-			{
-				div.addClass( 'cke_tpl_hover' );
-			});
-
-		div.on( 'mouseout', function()
-			{
-				div.removeClass( 'cke_tpl_hover' );
-			});
-
-		div.on( 'click', function()
-			{
-				insertTemplate( editor, template.html );
-			});
-
-		return div;
-	}
-
-	/**
-	 * Insert the specified template content
-	 * to document.
-	 * @param {Number} index
-	 */
-	function insertTemplate( editor, html )
-	{
-		var dialog = CKEDITOR.dialog.getCurrent(),
-			isInsert = dialog.getValueOf( 'selectTpl', 'chkInsertOpt' );
-
-		if( isInsert )
-		{
-			// Everything should happen after the document is loaded (#4073).
-			editor.on( 'contentDom', function( evt )
-			{
-				evt.removeListener();
-				dialog.hide();
-
-				// Place the cursor at the first editable place.
-				var range = new CKEDITOR.dom.range( editor.document );
-				range.moveToElementEditStart( editor.document.getBody() );
-				range.select( true );
-			} );
-			editor.setData( html );
-		}
-		else
-		{
-			editor.insertHtml( html );
-			dialog.hide();
-		}
-	}
-
 	CKEDITOR.dialog.add( 'templates', function( editor )
 		{
+			// Constructs the HTML view of the specified templates data.
+			function renderTemplatesList( container, templatesDefinitions )
+			{
+				// clear loading wait text.
+				container.setHtml( '' );
+
+				for ( var i = 0 ; i < templatesDefinitions.length ; i++ )
+				{
+					var definition = CKEDITOR.getTemplates( templatesDefinitions[ i ] ),
+						imagesPath = definition.imagesPath,
+						templates = definition.templates,
+						count = templates.length;
+
+					for ( var j = 0 ; j < count ; j++ )
+					{
+						var template = templates[ j ],
+							item =  createTemplateItem( template, imagesPath );
+						item.setAttribute( 'aria-posinset', j + 1 );
+						item.setAttribute( 'aria-setsize', count );
+						container.append( item );
+					}
+				}
+			}
+
+			function createTemplateItem( template, imagesPath )
+			{
+				var item = CKEDITOR.dom.element.createFromHtml(
+						'<a href="javascript:void(0)" tabIndex="-1" role="option" >' +
+							'<div class="cke_tpl_item"></div>' +
+						'</a>' );
+
+				// Build the inner HTML of our new item DIV.
+				var html = '<table style="width:350px;" class="cke_tpl_preview"><tr>';
+
+				if( template.image && imagesPath )
+					html += '<td class="cke_tpl_preview_img"><img src="' + CKEDITOR.getUrl( imagesPath + template.image ) + '"></td>';
+
+				html += '<td style="white-space:normal;"><span class="cke_tpl_title">' + template.title + '</span><br/>';
+
+				if( template.description )
+					html += '<span>' + template.description + '</span>';
+
+				html += '</td></tr></table>';
+
+				item.getFirst().setHtml( html );
+
+				item.on( 'click', function() { insertTemplate( template.html ); } );
+
+				return item;
+			}
+
+			/**
+			 * Insert the specified template content into editor.
+			 * @param {Number} index
+			 */
+			function insertTemplate( html )
+			{
+				var dialog = CKEDITOR.dialog.getCurrent(),
+					isInsert = dialog.getValueOf( 'selectTpl', 'chkInsertOpt' );
+
+				if( isInsert )
+				{
+					// Everything should happen after the document is loaded (#4073).
+					editor.on( 'contentDom', function( evt )
+					{
+						evt.removeListener();
+						dialog.hide();
+
+						// Place the cursor at the first editable place.
+						var range = new CKEDITOR.dom.range( editor.document );
+						range.moveToElementEditStart( editor.document.getBody() );
+						range.select( true );
+					} );
+					editor.setData( html );
+				}
+				else
+				{
+					editor.insertHtml( html );
+					dialog.hide();
+				}
+			}
+
+			function keyNavigation( evt )
+			{
+				var target = evt.data.getTarget(),
+						position = listContainer.getPosition( target );
+
+				// Keyboard navigation for template list.
+				if( position > CKEDITOR.POSITION_CONTAINS )
+				{
+					var keystroke = evt.data.getKeystroke(),
+							items = listContainer.getElementsByTag( 'a' ),
+							focusItem;
+
+					if( items )
+					{
+						switch ( keystroke )
+						{
+							case 40 :					// ARROW-DOWN
+								focusItem = target.getNext()
+										|| items.getItem( 0 );
+								break;
+
+							case 38 :					// ARROW-UP
+								focusItem = target.getPrevious()
+										|| items.getItem( items.count() - 1 );
+								break;
+
+							case 13 :					// ENTER
+							case 32 :					// SPACE
+								target.fire( 'click' );
+						}
+
+						if( focusItem )
+						{
+							focusItem.focus();
+							evt.data.preventDefault();
+						}
+					}
+				}
+			};
+
 			// Load skin at first.
 			CKEDITOR.skins.load( editor, 'templates' );
 
-			/**
-			 * Load templates once.
-			 */
-			var isLoaded = false;
+			var listContainer;
 
 			return {
@@ -138,7 +163,14 @@
 									},
 									{
+										id : "templatesList",
 										type : 'html',
+										focus: function()
+										{
+											// Move focus to the first list item if available.
+											try { this.getElement().getElementsByTag( 'a' ).getItem( 0 ).focus(); }
+											catch( er ){}
+										},
 										html :
-											'<div id="' + listId + '" class="cke_tpl_list">' +
+											'<div class="cke_tpl_list" tabIndex="-1" role="listbox" aria-label="' + editor.lang.templates.optionsArea +'">' +
 												'<div class="cke_tpl_loading"><span></span></div>' +
 											'</div>'
@@ -160,4 +192,7 @@
 				onShow : function()
 				{
+					var templatesListField = this.getContentElement( 'selectTpl' , 'templatesList' );
+					listContainer = templatesListField.getElement();
+
 					CKEDITOR.loadTemplates( editor.config.templates_files, function()
 						{
@@ -165,14 +200,23 @@
 
 							if ( templates.length )
-								renderTemplatesList( editor, templates );
+							{
+								renderTemplatesList( listContainer, templates );
+								templatesListField.focus();
+							}
 							else
 							{
-								var listCtEl = doc.getById( listId );
-								listCtEl.setHtml(
-									'<div class="cke_tpl_empty">' +
+								listContainer.setHtml(
+										'<div class="cke_tpl_empty">' +
 										'<span>' + editor.lang.templates.emptyListMsg + '</span>' +
-									'</div>' );
+										'</div>' );
 							}
 						});
+
+					this._.element.on( 'keydown', keyNavigation );
+				},
+
+				onHide : function ()
+				{
+					this._.element.removeListener( 'keydown', keyNavigation );
 				}
 			};
Index: /CKEditor/branches/features/aria/_source/skins/kama/templates.css
===================================================================
--- /CKEditor/branches/features/aria/_source/skins/kama/templates.css	(revision 4962)
+++ /CKEditor/branches/features/aria/_source/skins/kama/templates.css	(revision 4963)
@@ -12,5 +12,6 @@
 	border: #dcdcdc 2px solid;
 	background-color: #ffffff;
-	overflow: auto;
+	overflow-y: auto;
+	overflow-x: hidden;
 	width: 100%;
 	height: 220px;
@@ -50,5 +51,7 @@
 }
 
-.cke_skin_kama .cke_tpl_hover
+.cke_skin_kama .cke_tpl_list a:active .cke_tpl_item,
+.cke_skin_kama .cke_tpl_list a:hover .cke_tpl_item,
+.cke_skin_kama .cke_tpl_list a:focus .cke_tpl_item
 {
 	border: #ff9933 1px solid !important;
@@ -60,5 +63,7 @@
  * Fix property 'cursor' doesn't inherit on table
  */
-.cke_skin_kama .cke_tpl_hover *
+.cke_skin_kama .cke_tpl_list a:active *,
+.cke_skin_kama .cke_tpl_list a:hover *,
+.cke_skin_kama .cke_tpl_list a:focus *
 {
 	cursor: inherit;
