{\r
var doc = CKEDITOR.document;\r
\r
- var listId = 'cke' + CKEDITOR.tools.getNextNumber();\r
-\r
- // Constructs the HTML view of the specified templates data.\r
- function renderTemplatesList( editor, templatesDefinitions )\r
- {\r
- var listDiv = doc.getById( listId );\r
+ CKEDITOR.dialog.add( 'templates', function( editor )\r
+ {\r
+ // Constructs the HTML view of the specified templates data.\r
+ function renderTemplatesList( container, templatesDefinitions )\r
+ {\r
+ // clear loading wait text.\r
+ container.setHtml( '' );\r
\r
- // clear loading wait text.\r
- listDiv.setHtml( '' );\r
+ for ( var i = 0 ; i < templatesDefinitions.length ; i++ )\r
+ {\r
+ var definition = CKEDITOR.getTemplates( templatesDefinitions[ i ] ),\r
+ imagesPath = definition.imagesPath,\r
+ templates = definition.templates,\r
+ count = templates.length;\r
\r
- for ( var i = 0 ; i < templatesDefinitions.length ; i++ )\r
- {\r
- var definition = CKEDITOR.getTemplates( templatesDefinitions[ i ] ),\r
- imagesPath = definition.imagesPath,\r
- templates = definition.templates;\r
+ for ( var j = 0 ; j < count ; j++ )\r
+ {\r
+ var template = templates[ j ],\r
+ item = createTemplateItem( template, imagesPath );\r
+ item.setAttribute( 'aria-posinset', j + 1 );\r
+ item.setAttribute( 'aria-setsize', count );\r
+ container.append( item );\r
+ }\r
+ }\r
+ }\r
\r
- for ( var j = 0 ; j < templates.length ; j++ )\r
+ function createTemplateItem( template, imagesPath )\r
{\r
- var template = templates[ j ];\r
- listDiv.append( createTemplateItem( editor, template, imagesPath ) );\r
- }\r
- }\r
- }\r
+ var item = CKEDITOR.dom.element.createFromHtml(\r
+ '<a href="javascript:void(0)" tabIndex="-1" role="option" >' +\r
+ '<div class="cke_tpl_item"></div>' +\r
+ '</a>' );\r
\r
- function createTemplateItem( editor, template, imagesPath )\r
- {\r
- var div = doc.createElement( 'div' );\r
- div.setAttribute( 'class', 'cke_tpl_item' );\r
+ // Build the inner HTML of our new item DIV.\r
+ var html = '<table style="width:350px;" class="cke_tpl_preview"><tr>';\r
\r
- // Build the inner HTML of our new item DIV.\r
- var html = '<table style="width:350px;" class="cke_tpl_preview"><tr>';\r
+ if ( template.image && imagesPath )\r
+ html += '<td class="cke_tpl_preview_img"><img src="' + CKEDITOR.getUrl( imagesPath + template.image ) + '"></td>';\r
\r
- if ( template.image && imagesPath )\r
- html += '<td class="cke_tpl_preview_img"><img src="' + CKEDITOR.getUrl( imagesPath + template.image ) + '"></td>';\r
+ html += '<td style="white-space:normal;"><span class="cke_tpl_title">' + template.title + '</span><br/>';\r
\r
- html += '<td style="white-space:normal;"><span class="cke_tpl_title">' + template.title + '</span><br/>';\r
+ if ( template.description )\r
+ html += '<span>' + template.description + '</span>';\r
\r
- if ( template.description )\r
- html += '<span>' + template.description + '</span>';\r
+ html += '</td></tr></table>';\r
\r
- html += '</td></tr></table>';\r
+ item.getFirst().setHtml( html );\r
\r
- div.setHtml( html );\r
+ item.on( 'click', function() { insertTemplate( template.html ); } );\r
\r
- div.on( 'mouseover', function()\r
- {\r
- div.addClass( 'cke_tpl_hover' );\r
- });\r
+ return item;\r
+ }\r
\r
- div.on( 'mouseout', function()\r
+ /**\r
+ * Insert the specified template content into editor.\r
+ * @param {Number} index\r
+ */\r
+ function insertTemplate( html )\r
{\r
- div.removeClass( 'cke_tpl_hover' );\r
- });\r
+ var dialog = CKEDITOR.dialog.getCurrent(),\r
+ isInsert = dialog.getValueOf( 'selectTpl', 'chkInsertOpt' );\r
\r
- div.on( 'click', function()\r
- {\r
- insertTemplate( editor, template.html );\r
- });\r
-\r
- return div;\r
- }\r
-\r
- /**\r
- * Insert the specified template content\r
- * to document.\r
- * @param {Number} index\r
- */\r
- function insertTemplate( editor, html )\r
- {\r
- var dialog = CKEDITOR.dialog.getCurrent(),\r
- isInsert = dialog.getValueOf( 'selectTpl', 'chkInsertOpt' );\r
-\r
- if ( isInsert )\r
- {\r
- // Everything should happen after the document is loaded (#4073).\r
- editor.on( 'contentDom', function( evt )\r
- {\r
- evt.removeListener();\r
- dialog.hide();\r
-\r
- // Place the cursor at the first editable place.\r
- var range = new CKEDITOR.dom.range( editor.document );\r
- range.moveToElementEditStart( editor.document.getBody() );\r
- range.select( true );\r
- setTimeout( function ()\r
+ if ( isInsert )\r
{\r
+ // Everything should happen after the document is loaded (#4073).\r
+ editor.on( 'contentDom', function( evt )\r
+ {\r
+ evt.removeListener();\r
+ dialog.hide();\r
+\r
+ // Place the cursor at the first editable place.\r
+ var range = new CKEDITOR.dom.range( editor.document );\r
+ range.moveToElementEditStart( editor.document.getBody() );\r
+ range.select( true );\r
+ setTimeout( function ()\r
+ {\r
+ editor.fire( 'saveSnapshot' );\r
+ }, 0 );\r
+ } );\r
+\r
editor.fire( 'saveSnapshot' );\r
- }, 0 );\r
- } );\r
+ editor.setData( html );\r
+ }\r
+ else\r
+ {\r
+ editor.insertHtml( html );\r
+ dialog.hide();\r
+ }\r
+ }\r
\r
- editor.fire( 'saveSnapshot' );\r
- editor.setData( html );\r
- }\r
- else\r
- {\r
- editor.insertHtml( html );\r
- dialog.hide();\r
- }\r
- }\r
+ function keyNavigation( evt )\r
+ {\r
+ var target = evt.data.getTarget(),\r
+ position = listContainer.getPosition( target );\r
+\r
+ // Keyboard navigation for template list.\r
+ if ( position > CKEDITOR.POSITION_CONTAINS )\r
+ {\r
+ var keystroke = evt.data.getKeystroke(),\r
+ items = listContainer.getElementsByTag( 'a' ),\r
+ focusItem;\r
+\r
+ if ( items )\r
+ {\r
+ switch ( keystroke )\r
+ {\r
+ case 40 : // ARROW-DOWN\r
+ focusItem = target.getNext();\r
+ break;\r
+\r
+ case 38 : // ARROW-UP\r
+ focusItem = target.getPrevious();\r
+ break;\r
+\r
+ case 13 : // ENTER\r
+ case 32 : // SPACE\r
+ target.fire( 'click' );\r
+ }\r
+\r
+ if ( focusItem )\r
+ {\r
+ focusItem.focus();\r
+ evt.data.preventDefault();\r
+ }\r
+ }\r
+ }\r
+ }\r
\r
- CKEDITOR.dialog.add( 'templates', function( editor )\r
- {\r
// Load skin at first.\r
CKEDITOR.skins.load( editor, 'templates' );\r
\r
- /**\r
- * Load templates once.\r
- */\r
- var isLoaded = false;\r
+ var listContainer;\r
\r
return {\r
title :editor.lang.templates.title,\r
'</span>'\r
},\r
{\r
+ id : "templatesList",\r
type : 'html',\r
+ focus: function()\r
+ {\r
+ // Move focus to the first list item if available.\r
+ try { this.getElement().getElementsByTag( 'a' ).getItem( 0 ).focus(); }\r
+ catch( er ){}\r
+ },\r
html :\r
- '<div id="' + listId + '" class="cke_tpl_list">' +\r
+ '<div class="cke_tpl_list" tabIndex="-1" role="listbox" aria-labelledby="cke_tpl_list_label">' +\r
'<div class="cke_tpl_loading"><span></span></div>' +\r
- '</div>'\r
+ '</div>' +\r
+ '<span class="cke_voice_label" id="cke_tpl_list_label">' + editor.lang.common.options+ '</span>'\r
},\r
{\r
id : 'chkInsertOpt',\r
\r
onShow : function()\r
{\r
+ var templatesListField = this.getContentElement( 'selectTpl' , 'templatesList' );\r
+ listContainer = templatesListField.getElement();\r
+\r
CKEDITOR.loadTemplates( editor.config.templates_files, function()\r
{\r
var templates = editor.config.templates.split( ',' );\r
\r
if ( templates.length )\r
- renderTemplatesList( editor, templates );\r
+ {\r
+ renderTemplatesList( listContainer, templates );\r
+ templatesListField.focus();\r
+ }\r
else\r
{\r
- var listCtEl = doc.getById( listId );\r
- listCtEl.setHtml(\r
+ listContainer.setHtml(\r
'<div class="cke_tpl_empty">' +\r
'<span>' + editor.lang.templates.emptyListMsg + '</span>' +\r
'</div>' );\r
}\r
});\r
+\r
+ this._.element.on( 'keydown', keyNavigation );\r
+ },\r
+\r
+ onHide : function ()\r
+ {\r
+ this._.element.removeListener( 'keydown', keyNavigation );\r
}\r
};\r
});\r