smiley.js 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  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. CKEDITOR.dialog.add( 'smiley', function( editor ) {
  6. var config = editor.config,
  7. lang = editor.lang.smiley,
  8. images = config.smiley_images,
  9. columns = config.smiley_columns || 8,
  10. i;
  11. // Simulate "this" of a dialog for non-dialog events.
  12. // @type {CKEDITOR.dialog}
  13. var dialog;
  14. var onClick = function( evt ) {
  15. var target = evt.data.getTarget(),
  16. targetName = target.getName();
  17. if ( targetName == 'a' )
  18. target = target.getChild( 0 );
  19. else if ( targetName != 'img' )
  20. return;
  21. var src = target.getAttribute( 'cke_src' ),
  22. title = target.getAttribute( 'title' );
  23. var img = editor.document.createElement( 'img', {
  24. attributes: {
  25. src: src,
  26. 'data-cke-saved-src': src,
  27. title: title,
  28. alt: title,
  29. width: target.$.width,
  30. height: target.$.height
  31. }
  32. } );
  33. editor.insertElement( img );
  34. dialog.hide();
  35. evt.data.preventDefault();
  36. };
  37. var onKeydown = CKEDITOR.tools.addFunction( function( ev, element ) {
  38. ev = new CKEDITOR.dom.event( ev );
  39. element = new CKEDITOR.dom.element( element );
  40. var relative, nodeToMove;
  41. var keystroke = ev.getKeystroke(),
  42. rtl = editor.lang.dir == 'rtl';
  43. switch ( keystroke ) {
  44. // UP-ARROW
  45. case 38:
  46. // relative is TR
  47. if ( ( relative = element.getParent().getParent().getPrevious() ) ) {
  48. nodeToMove = relative.getChild( [ element.getParent().getIndex(), 0 ] );
  49. nodeToMove.focus();
  50. }
  51. ev.preventDefault();
  52. break;
  53. // DOWN-ARROW
  54. case 40:
  55. // relative is TR
  56. if ( ( relative = element.getParent().getParent().getNext() ) ) {
  57. nodeToMove = relative.getChild( [ element.getParent().getIndex(), 0 ] );
  58. if ( nodeToMove )
  59. nodeToMove.focus();
  60. }
  61. ev.preventDefault();
  62. break;
  63. // ENTER
  64. // SPACE
  65. case 32:
  66. onClick( { data: ev } );
  67. ev.preventDefault();
  68. break;
  69. // RIGHT-ARROW
  70. case rtl ? 37 : 39:
  71. // relative is TD
  72. if ( ( relative = element.getParent().getNext() ) ) {
  73. nodeToMove = relative.getChild( 0 );
  74. nodeToMove.focus();
  75. ev.preventDefault( true );
  76. }
  77. // relative is TR
  78. else if ( ( relative = element.getParent().getParent().getNext() ) ) {
  79. nodeToMove = relative.getChild( [ 0, 0 ] );
  80. if ( nodeToMove )
  81. nodeToMove.focus();
  82. ev.preventDefault( true );
  83. }
  84. break;
  85. // LEFT-ARROW
  86. case rtl ? 39 : 37:
  87. // relative is TD
  88. if ( ( relative = element.getParent().getPrevious() ) ) {
  89. nodeToMove = relative.getChild( 0 );
  90. nodeToMove.focus();
  91. ev.preventDefault( true );
  92. }
  93. // relative is TR
  94. else if ( ( relative = element.getParent().getParent().getPrevious() ) ) {
  95. nodeToMove = relative.getLast().getChild( 0 );
  96. nodeToMove.focus();
  97. ev.preventDefault( true );
  98. }
  99. break;
  100. default:
  101. // Do not stop not handled events.
  102. return;
  103. }
  104. } );
  105. // Build the HTML for the smiley images table.
  106. var labelId = CKEDITOR.tools.getNextId() + '_smiley_emtions_label';
  107. var html = [
  108. '<div>' +
  109. '<span id="' + labelId + '" class="cke_voice_label">' + lang.options + '</span>',
  110. '<table role="listbox" aria-labelledby="' + labelId + '" style="width:100%;height:100%;border-collapse:separate;" cellspacing="2" cellpadding="2"',
  111. CKEDITOR.env.ie && CKEDITOR.env.quirks ? ' style="position:absolute;"' : '',
  112. '><tbody>'
  113. ];
  114. var size = images.length;
  115. for ( i = 0; i < size; i++ ) {
  116. if ( i % columns === 0 )
  117. html.push( '<tr role="presentation">' );
  118. var smileyLabelId = 'cke_smile_label_' + i + '_' + CKEDITOR.tools.getNextNumber();
  119. html.push(
  120. '<td class="cke_dark_background cke_centered" style="vertical-align: middle;" role="presentation">' +
  121. '<a href="javascript:void(0)" role="option"', ' aria-posinset="' + ( i + 1 ) + '"', ' aria-setsize="' + size + '"', ' aria-labelledby="' + smileyLabelId + '"',
  122. ' class="cke_smile cke_hand" tabindex="-1" onkeydown="CKEDITOR.tools.callFunction( ', onKeydown, ', event, this );">',
  123. '<img class="cke_hand" title="', config.smiley_descriptions[ i ], '"' +
  124. ' cke_src="', CKEDITOR.tools.htmlEncode( config.smiley_path + images[ i ] ), '" alt="', config.smiley_descriptions[ i ], '"',
  125. ' src="', CKEDITOR.tools.htmlEncode( config.smiley_path + images[ i ] ), '"',
  126. // IE BUG: Below is a workaround to an IE image loading bug to ensure the image sizes are correct.
  127. ( CKEDITOR.env.ie ? ' onload="this.setAttribute(\'width\', 2); this.removeAttribute(\'width\');" ' : '' ), '>' +
  128. '<span id="' + smileyLabelId + '" class="cke_voice_label">' + config.smiley_descriptions[ i ] + '</span>' +
  129. '</a>', '</td>'
  130. );
  131. if ( i % columns == columns - 1 )
  132. html.push( '</tr>' );
  133. }
  134. if ( i < columns - 1 ) {
  135. for ( ; i < columns - 1; i++ )
  136. html.push( '<td></td>' );
  137. html.push( '</tr>' );
  138. }
  139. html.push( '</tbody></table></div>' );
  140. var smileySelector = {
  141. type: 'html',
  142. id: 'smileySelector',
  143. html: html.join( '' ),
  144. onLoad: function( event ) {
  145. dialog = event.sender;
  146. },
  147. focus: function() {
  148. var self = this;
  149. // IE need a while to move the focus (#6539).
  150. setTimeout( function() {
  151. var firstSmile = self.getElement().getElementsByTag( 'a' ).getItem( 0 );
  152. firstSmile.focus();
  153. }, 0 );
  154. },
  155. onClick: onClick,
  156. style: 'width: 100%; border-collapse: separate;'
  157. };
  158. return {
  159. title: editor.lang.smiley.title,
  160. minWidth: 270,
  161. minHeight: 120,
  162. contents: [ {
  163. id: 'tab1',
  164. label: '',
  165. title: '',
  166. expand: true,
  167. padding: 0,
  168. elements: [
  169. smileySelector
  170. ]
  171. } ],
  172. buttons: [ CKEDITOR.dialog.cancelButton ]
  173. };
  174. } );