1 /*
  2 Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
  3 For licensing, see LICENSE.html or http://ckeditor.com/license
  4 */
  5 
  6 CKEDITOR.dialog.add( 'a11yHelp', function( editor )
  7 {
  8 	var lang = editor.lang.accessibilityHelp,
  9 		id = CKEDITOR.tools.getNextId();
 10 
 11 	// CharCode <-> KeyChar.
 12 	var keyMap =
 13 	{
 14 		8 : "BACKSPACE",
 15 		9 : "TAB" ,
 16 		13 : "ENTER" ,
 17 		16 : "SHIFT" ,
 18 		17 : "CTRL" ,
 19 		18 : "ALT" ,
 20 		19 : "PAUSE" ,
 21 		20 : "CAPSLOCK" ,
 22 		27 : "ESCAPE" ,
 23 		33 : "PAGE UP" ,
 24 		34 : "PAGE DOWN" ,
 25 		35 : "END" ,
 26 		36 : "HOME" ,
 27 		37 : "LEFT ARROW" ,
 28 		38 : "UP ARROW" ,
 29 		39 : "RIGHT ARROW" ,
 30 		40 : "DOWN ARROW" ,
 31 		45 : "INSERT" ,
 32 		46 : "DELETE" ,
 33 		91 : "LEFT WINDOW KEY" ,
 34 		92 : "RIGHT WINDOW KEY" ,
 35 		93 : "SELECT KEY" ,
 36 		96 : "NUMPAD  0" ,
 37 		97 : "NUMPAD  1" ,
 38 		98 : "NUMPAD  2" ,
 39 		99 : "NUMPAD  3" ,
 40 		100 : "NUMPAD  4" ,
 41 		101 : "NUMPAD  5" ,
 42 		102 : "NUMPAD  6" ,
 43 		103 : "NUMPAD  7" ,
 44 		104 : "NUMPAD  8" ,
 45 		105 : "NUMPAD  9" ,
 46 		106 : "MULTIPLY" ,
 47 		107 : "ADD" ,
 48 		109 : "SUBTRACT" ,
 49 		110 : "DECIMAL POINT" ,
 50 		111 : "DIVIDE" ,
 51 		112 : "F1" ,
 52 		113 : "F2" ,
 53 		114 : "F3" ,
 54 		115 : "F4" ,
 55 		116 : "F5" ,
 56 		117 : "F6" ,
 57 		118 : "F7" ,
 58 		119 : "F8" ,
 59 		120 : "F9" ,
 60 		121 : "F10" ,
 61 		122 : "F11" ,
 62 		123 : "F12" ,
 63 		144 : "NUM LOCK" ,
 64 		145 : "SCROLL LOCK" ,
 65 		186 : "SEMI-COLON" ,
 66 		187 : "EQUAL SIGN" ,
 67 		188 : "COMMA" ,
 68 		189 : "DASH" ,
 69 		190 : "PERIOD" ,
 70 		191 : "FORWARD SLASH" ,
 71 		192 : "GRAVE ACCENT" ,
 72 		219 : "OPEN BRACKET" ,
 73 		220 : "BACK SLASH" ,
 74 		221 : "CLOSE BRAKET" ,
 75 		222 : "SINGLE QUOTE"
 76 	};
 77 
 78 	// Modifier keys override.
 79 	keyMap[ CKEDITOR.ALT ] = 'ALT';
 80 	keyMap[ CKEDITOR.SHIFT ] = 'SHIFT';
 81 	keyMap[ CKEDITOR.CTRL ] = 'CTRL';
 82 
 83 	// Sort in desc.
 84 	var modifiers = [ CKEDITOR.ALT, CKEDITOR.SHIFT, CKEDITOR.CTRL ];
 85 
 86 	function representKeyStroke( keystroke )
 87 	{
 88 		var quotient,
 89 				modifier,
 90 				presentation = [];
 91 
 92 		for ( var i = 0; i < modifiers.length; i++ )
 93 		{
 94 			modifier = modifiers[ i ];
 95 			quotient = keystroke / modifiers[ i ];
 96 			if ( quotient > 1 && quotient <= 2 )
 97 			{
 98 				keystroke -= modifier;
 99 				presentation.push( keyMap[ modifier ] );
100 			}
101 		}
102 
103 		presentation.push( keyMap[ keystroke ]
104 			|| String.fromCharCode( keystroke ) );
105 
106 		return presentation.join( '+' );
107 	}
108 
109 	var variablesPattern = /\$\{(.*?)\}/g;
110 	function replaceVariables( match, name )
111 	{
112 		var keystrokes = editor.config.keystrokes,
113 				definition,
114 				length = keystrokes.length;
115 
116 		for ( var i = 0; i < length; i++ )
117 		{
118 			definition = keystrokes[ i ];
119 			if ( definition[ 1 ] == name )
120 				break;
121 		}
122 		return representKeyStroke( definition[ 0 ] );
123 	}
124 
125 	// Create the help list directly from lang file entries.
126 	function buildHelpContents()
127 	{
128 		var pageTpl = '<div class="cke_accessibility_legend" role="document" aria-labelledby="' + id + '_arialbl" tabIndex="-1">%1</div>' +
129 				'<span id="' + id + '_arialbl" class="cke_voice_label">' + lang.contents + ' </span>',
130 			sectionTpl = '<h1>%1</h1><dl>%2</dl>',
131 			itemTpl = '<dt>%1</dt><dd>%2</dd>';
132 
133 		var pageHtml = [],
134 			sections = lang.legend,
135 			sectionLength = sections.length;
136 
137 		for ( var i = 0; i < sectionLength; i++ )
138 		{
139 			var section = sections[ i ],
140 				sectionHtml = [],
141 				items = section.items,
142 				itemsLength = items.length;
143 
144 			for ( var j = 0; j < itemsLength; j++ )
145 			{
146 				var item = items[ j ],
147 					itemHtml;
148 				itemHtml = itemTpl.replace( '%1', item.name ).
149 					replace( '%2', item.legend.replace( variablesPattern, replaceVariables ) );
150 				sectionHtml.push( itemHtml );
151 			}
152 
153 			pageHtml.push( sectionTpl.replace( '%1', section.name ).replace( '%2', sectionHtml.join( '' ) ) );
154 		}
155 
156 		return pageTpl.replace( '%1', pageHtml.join( '' ) );
157 	}
158 
159 	return {
160 		title : lang.title,
161 		minWidth : 600,
162 		minHeight : 400,
163 		contents : [
164 			{
165 				id : 'info',
166 				label : editor.lang.common.generalTab,
167 				expand : true,
168 				elements :
169 				[
170 					{
171 						type : 'html',
172 						id : 'legends',
173 						style : 'white-space:normal;',
174 						focus : function() {},
175 						html : buildHelpContents() +
176 							'<style type="text/css">' +
177 							'.cke_accessibility_legend' +
178 							'{' +
179 								'width:600px;' +
180 								'height:400px;' +
181 								'padding-right:5px;' +
182 								'overflow-y:auto;' +
183 								'overflow-x:hidden;' +
184 							'}' +
185 							// Some adjustments are to be done for IE6 and Quirks to work "properly" (#5757)
186 							'.cke_browser_quirks .cke_accessibility_legend,' +
187 							'.cke_browser_ie6 .cke_accessibility_legend' +
188 							'{' +
189 								'height:390px' +
190 							'}' +
191 							// Override non-wrapping white-space rule in reset css.
192 							'.cke_accessibility_legend *' +
193 							'{' +
194 								'white-space:normal;' +
195 							'}' +
196 							'.cke_accessibility_legend h1' +
197 							'{' +
198 								'font-size: 20px;' +
199 								'border-bottom: 1px solid #AAA;' +
200 								'margin: 5px 0px 15px;' +
201 							'}' +
202 							'.cke_accessibility_legend dl' +
203 							'{' +
204 								'margin-left: 5px;' +
205 							'}' +
206 							'.cke_accessibility_legend dt' +
207 							'{' +
208 								'font-size: 13px;' +
209 								'font-weight: bold;' +
210 							'}' +
211 							'.cke_accessibility_legend dd' +
212 							'{' +
213 								'margin:10px' +
214 							'}' +
215 						'</style>'
216 					}
217 				]
218 			}
219 		],
220 		buttons : [ CKEDITOR.dialog.cancelButton ]
221 	};
222 });
223