templates.js 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. /**
  2. * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.md or http://ckeditor.com/license
  4. */
  5. ( function() {
  6. CKEDITOR.dialog.add( 'templates', function( editor ) {
  7. // Constructs the HTML view of the specified templates data.
  8. function renderTemplatesList( container, templatesDefinitions ) {
  9. // clear loading wait text.
  10. container.setHtml( '' );
  11. for ( var i = 0, totalDefs = templatesDefinitions.length; i < totalDefs; i++ ) {
  12. var definition = CKEDITOR.getTemplates( templatesDefinitions[ i ] ),
  13. imagesPath = definition.imagesPath,
  14. templates = definition.templates,
  15. count = templates.length;
  16. for ( var j = 0; j < count; j++ ) {
  17. var template = templates[ j ],
  18. item = createTemplateItem( template, imagesPath );
  19. item.setAttribute( 'aria-posinset', j + 1 );
  20. item.setAttribute( 'aria-setsize', count );
  21. container.append( item );
  22. }
  23. }
  24. }
  25. function createTemplateItem( template, imagesPath ) {
  26. var item = CKEDITOR.dom.element.createFromHtml( '<a href="javascript:void(0)" tabIndex="-1" role="option" >' +
  27. '<div class="cke_tpl_item"></div>' +
  28. '</a>' );
  29. // Build the inner HTML of our new item DIV.
  30. var html = '<table style="width:350px;" class="cke_tpl_preview" role="presentation"><tr>';
  31. if ( template.image && imagesPath ) {
  32. html += '<td class="cke_tpl_preview_img"><img src="' +
  33. CKEDITOR.getUrl( imagesPath + template.image ) + '"' +
  34. ( CKEDITOR.env.ie6Compat ? ' onload="this.width=this.width"' : '' ) + ' alt="" title=""></td>';
  35. }
  36. html += '<td style="white-space:normal;"><span class="cke_tpl_title">' + template.title + '</span><br/>';
  37. if ( template.description )
  38. html += '<span>' + template.description + '</span>';
  39. html += '</td></tr></table>';
  40. item.getFirst().setHtml( html );
  41. item.on( 'click', function() {
  42. insertTemplate( template.html );
  43. } );
  44. return item;
  45. }
  46. // Insert the specified template content into editor.
  47. // @param {Number} index
  48. function insertTemplate( html ) {
  49. var dialog = CKEDITOR.dialog.getCurrent(),
  50. isReplace = dialog.getValueOf( 'selectTpl', 'chkInsertOpt' );
  51. if ( isReplace ) {
  52. editor.fire( 'saveSnapshot' );
  53. // Everything should happen after the document is loaded (#4073).
  54. editor.setData( html, function() {
  55. dialog.hide();
  56. // Place the cursor at the first editable place.
  57. var range = editor.createRange();
  58. range.moveToElementEditStart( editor.editable() );
  59. range.select();
  60. setTimeout( function() {
  61. editor.fire( 'saveSnapshot' );
  62. }, 0 );
  63. } );
  64. } else {
  65. editor.insertHtml( html );
  66. dialog.hide();
  67. }
  68. }
  69. function keyNavigation( evt ) {
  70. var target = evt.data.getTarget(),
  71. onList = listContainer.equals( target );
  72. // Keyboard navigation for template list.
  73. if ( onList || listContainer.contains( target ) ) {
  74. var keystroke = evt.data.getKeystroke(),
  75. items = listContainer.getElementsByTag( 'a' ),
  76. focusItem;
  77. if ( items ) {
  78. // Focus not yet onto list items?
  79. if ( onList )
  80. focusItem = items.getItem( 0 );
  81. else {
  82. switch ( keystroke ) {
  83. case 40: // ARROW-DOWN
  84. focusItem = target.getNext();
  85. break;
  86. case 38: // ARROW-UP
  87. focusItem = target.getPrevious();
  88. break;
  89. case 13: // ENTER
  90. case 32: // SPACE
  91. target.fire( 'click' );
  92. }
  93. }
  94. if ( focusItem ) {
  95. focusItem.focus();
  96. evt.data.preventDefault();
  97. }
  98. }
  99. }
  100. }
  101. // Load skin at first.
  102. var plugin = CKEDITOR.plugins.get( 'templates' );
  103. CKEDITOR.document.appendStyleSheet( CKEDITOR.getUrl( plugin.path + 'dialogs/templates.css' ) );
  104. var listContainer;
  105. var templateListLabelId = 'cke_tpl_list_label_' + CKEDITOR.tools.getNextNumber(),
  106. lang = editor.lang.templates,
  107. config = editor.config;
  108. return {
  109. title: editor.lang.templates.title,
  110. minWidth: CKEDITOR.env.ie ? 440 : 400,
  111. minHeight: 340,
  112. contents: [ {
  113. id: 'selectTpl',
  114. label: lang.title,
  115. elements: [ {
  116. type: 'vbox',
  117. padding: 5,
  118. children: [ {
  119. id: 'selectTplText',
  120. type: 'html',
  121. html: '<span>' +
  122. lang.selectPromptMsg +
  123. '</span>'
  124. },
  125. {
  126. id: 'templatesList',
  127. type: 'html',
  128. focus: true,
  129. html: '<div class="cke_tpl_list" tabIndex="-1" role="listbox" aria-labelledby="' + templateListLabelId + '">' +
  130. '<div class="cke_tpl_loading"><span></span></div>' +
  131. '</div>' +
  132. '<span class="cke_voice_label" id="' + templateListLabelId + '">' + lang.options + '</span>'
  133. },
  134. {
  135. id: 'chkInsertOpt',
  136. type: 'checkbox',
  137. label: lang.insertOption,
  138. 'default': config.templates_replaceContent
  139. } ]
  140. } ]
  141. } ],
  142. buttons: [ CKEDITOR.dialog.cancelButton ],
  143. onShow: function() {
  144. var templatesListField = this.getContentElement( 'selectTpl', 'templatesList' );
  145. listContainer = templatesListField.getElement();
  146. CKEDITOR.loadTemplates( config.templates_files, function() {
  147. var templates = ( config.templates || 'default' ).split( ',' );
  148. if ( templates.length ) {
  149. renderTemplatesList( listContainer, templates );
  150. templatesListField.focus();
  151. } else {
  152. listContainer.setHtml( '<div class="cke_tpl_empty">' +
  153. '<span>' + lang.emptyListMsg + '</span>' +
  154. '</div>' );
  155. }
  156. } );
  157. this._.element.on( 'keydown', keyNavigation );
  158. },
  159. onHide: function() {
  160. this._.element.removeListener( 'keydown', keyNavigation );
  161. }
  162. };
  163. } );
  164. } )();