a11yhelp.js 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  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( 'a11yHelp', function( editor ) {
  6. var lang = editor.lang.a11yhelp,
  7. id = CKEDITOR.tools.getNextId();
  8. // CharCode <-> KeyChar.
  9. var keyMap = {
  10. 8: lang.backspace,
  11. 9: lang.tab,
  12. 13: lang.enter,
  13. 16: lang.shift,
  14. 17: lang.ctrl,
  15. 18: lang.alt,
  16. 19: lang.pause,
  17. 20: lang.capslock,
  18. 27: lang.escape,
  19. 33: lang.pageUp,
  20. 34: lang.pageDown,
  21. 35: lang.end,
  22. 36: lang.home,
  23. 37: lang.leftArrow,
  24. 38: lang.upArrow,
  25. 39: lang.rightArrow,
  26. 40: lang.downArrow,
  27. 45: lang.insert,
  28. 46: lang[ 'delete' ],
  29. 91: lang.leftWindowKey,
  30. 92: lang.rightWindowKey,
  31. 93: lang.selectKey,
  32. 96: lang.numpad0,
  33. 97: lang.numpad1,
  34. 98: lang.numpad2,
  35. 99: lang.numpad3,
  36. 100: lang.numpad4,
  37. 101: lang.numpad5,
  38. 102: lang.numpad6,
  39. 103: lang.numpad7,
  40. 104: lang.numpad8,
  41. 105: lang.numpad9,
  42. 106: lang.multiply,
  43. 107: lang.add,
  44. 109: lang.subtract,
  45. 110: lang.decimalPoint,
  46. 111: lang.divide,
  47. 112: lang.f1,
  48. 113: lang.f2,
  49. 114: lang.f3,
  50. 115: lang.f4,
  51. 116: lang.f5,
  52. 117: lang.f6,
  53. 118: lang.f7,
  54. 119: lang.f8,
  55. 120: lang.f9,
  56. 121: lang.f10,
  57. 122: lang.f11,
  58. 123: lang.f12,
  59. 144: lang.numLock,
  60. 145: lang.scrollLock,
  61. 186: lang.semiColon,
  62. 187: lang.equalSign,
  63. 188: lang.comma,
  64. 189: lang.dash,
  65. 190: lang.period,
  66. 191: lang.forwardSlash,
  67. 192: lang.graveAccent,
  68. 219: lang.openBracket,
  69. 220: lang.backSlash,
  70. 221: lang.closeBracket,
  71. 222: lang.singleQuote
  72. };
  73. // Modifier keys override.
  74. keyMap[ CKEDITOR.ALT ] = lang.alt;
  75. keyMap[ CKEDITOR.SHIFT ] = lang.shift;
  76. keyMap[ CKEDITOR.CTRL ] = lang.ctrl;
  77. // Sort in desc.
  78. var modifiers = [ CKEDITOR.ALT, CKEDITOR.SHIFT, CKEDITOR.CTRL ];
  79. function representKeyStroke( keystroke ) {
  80. var quotient, modifier,
  81. presentation = [];
  82. for ( var i = 0; i < modifiers.length; i++ ) {
  83. modifier = modifiers[ i ];
  84. quotient = keystroke / modifiers[ i ];
  85. if ( quotient > 1 && quotient <= 2 ) {
  86. keystroke -= modifier;
  87. presentation.push( keyMap[ modifier ] );
  88. }
  89. }
  90. presentation.push( keyMap[ keystroke ] || String.fromCharCode( keystroke ) );
  91. return presentation.join( '+' );
  92. }
  93. var variablesPattern = /\$\{(.*?)\}/g;
  94. var replaceVariables = ( function() {
  95. // Swaps keystrokes with their commands in object literal.
  96. // This makes searching keystrokes by command much easier.
  97. var keystrokesByCode = editor.keystrokeHandler.keystrokes,
  98. keystrokesByName = {};
  99. for ( var i in keystrokesByCode )
  100. keystrokesByName[ keystrokesByCode[ i ] ] = i;
  101. return function( match, name ) {
  102. // Return the keystroke representation or leave match untouched
  103. // if there's no keystroke for such command.
  104. return keystrokesByName[ name ] ? representKeyStroke( keystrokesByName[ name ] ) : match;
  105. };
  106. } )();
  107. // Create the help list directly from lang file entries.
  108. function buildHelpContents() {
  109. var pageTpl = '<div class="cke_accessibility_legend" role="document" aria-labelledby="' + id + '_arialbl" tabIndex="-1">%1</div>' +
  110. '<span id="' + id + '_arialbl" class="cke_voice_label">' + lang.contents + ' </span>',
  111. sectionTpl = '<h1>%1</h1><dl>%2</dl>',
  112. itemTpl = '<dt>%1</dt><dd>%2</dd>';
  113. var pageHtml = [],
  114. sections = lang.legend,
  115. sectionLength = sections.length;
  116. for ( var i = 0; i < sectionLength; i++ ) {
  117. var section = sections[ i ],
  118. sectionHtml = [],
  119. items = section.items,
  120. itemsLength = items.length;
  121. for ( var j = 0; j < itemsLength; j++ ) {
  122. var item = items[ j ],
  123. itemLegend = item.legend.replace( variablesPattern, replaceVariables );
  124. // (#9765) If some commands haven't been replaced in the legend,
  125. // most likely their keystrokes are unavailable and we shouldn't include
  126. // them in our help list.
  127. if ( itemLegend.match( variablesPattern ) )
  128. continue;
  129. sectionHtml.push( itemTpl.replace( '%1', item.name ).replace( '%2', itemLegend ) );
  130. }
  131. pageHtml.push( sectionTpl.replace( '%1', section.name ).replace( '%2', sectionHtml.join( '' ) ) );
  132. }
  133. return pageTpl.replace( '%1', pageHtml.join( '' ) );
  134. }
  135. return {
  136. title: lang.title,
  137. minWidth: 600,
  138. minHeight: 400,
  139. contents: [ {
  140. id: 'info',
  141. label: editor.lang.common.generalTab,
  142. expand: true,
  143. elements: [
  144. {
  145. type: 'html',
  146. id: 'legends',
  147. style: 'white-space:normal;',
  148. focus: function() {
  149. this.getElement().focus();
  150. },
  151. html: buildHelpContents() + '<style type="text/css">' +
  152. '.cke_accessibility_legend' +
  153. '{' +
  154. 'width:600px;' +
  155. 'height:400px;' +
  156. 'padding-right:5px;' +
  157. 'overflow-y:auto;' +
  158. 'overflow-x:hidden;' +
  159. '}' +
  160. // Some adjustments are to be done for Quirks to work "properly" (#5757)
  161. '.cke_browser_quirks .cke_accessibility_legend,' +
  162. '{' +
  163. 'height:390px' +
  164. '}' +
  165. // Override non-wrapping white-space rule in reset css.
  166. '.cke_accessibility_legend *' +
  167. '{' +
  168. 'white-space:normal;' +
  169. '}' +
  170. '.cke_accessibility_legend h1' +
  171. '{' +
  172. 'font-size: 20px;' +
  173. 'border-bottom: 1px solid #AAA;' +
  174. 'margin: 5px 0px 15px;' +
  175. '}' +
  176. '.cke_accessibility_legend dl' +
  177. '{' +
  178. 'margin-left: 5px;' +
  179. '}' +
  180. '.cke_accessibility_legend dt' +
  181. '{' +
  182. 'font-size: 13px;' +
  183. 'font-weight: bold;' +
  184. '}' +
  185. '.cke_accessibility_legend dd' +
  186. '{' +
  187. 'margin:10px' +
  188. '}' +
  189. '</style>'
  190. }
  191. ]
  192. } ],
  193. buttons: [ CKEDITOR.dialog.cancelButton ]
  194. };
  195. } );