]>
Commit | Line | Data |
---|---|---|
1 | /**\r | |
2 | * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.\r | |
3 | * For licensing, see LICENSE.md or http://ckeditor.com/license\r | |
4 | */\r | |
5 | \r | |
6 | CKEDITOR.dialog.add( 'specialchar', function( editor ) {\r | |
7 | // Simulate "this" of a dialog for non-dialog events.\r | |
8 | // @type {CKEDITOR.dialog}\r | |
9 | var dialog,\r | |
10 | lang = editor.lang.specialchar;\r | |
11 | \r | |
12 | var onChoice = function( evt ) {\r | |
13 | var target, value;\r | |
14 | if ( evt.data )\r | |
15 | target = evt.data.getTarget();\r | |
16 | else\r | |
17 | target = new CKEDITOR.dom.element( evt );\r | |
18 | \r | |
19 | if ( target.getName() == 'a' && ( value = target.getChild( 0 ).getHtml() ) ) {\r | |
20 | target.removeClass( 'cke_light_background' );\r | |
21 | dialog.hide();\r | |
22 | \r | |
23 | // We must use "insertText" here to keep text styled.\r | |
24 | var span = editor.document.createElement( 'span' );\r | |
25 | span.setHtml( value );\r | |
26 | editor.insertText( span.getText() );\r | |
27 | }\r | |
28 | };\r | |
29 | \r | |
30 | var onClick = CKEDITOR.tools.addFunction( onChoice );\r | |
31 | \r | |
32 | var focusedNode;\r | |
33 | \r | |
34 | var onFocus = function( evt, target ) {\r | |
35 | var value;\r | |
36 | target = target || evt.data.getTarget();\r | |
37 | \r | |
38 | if ( target.getName() == 'span' )\r | |
39 | target = target.getParent();\r | |
40 | \r | |
41 | if ( target.getName() == 'a' && ( value = target.getChild( 0 ).getHtml() ) ) {\r | |
42 | // Trigger blur manually if there is focused node.\r | |
43 | if ( focusedNode )\r | |
44 | onBlur( null, focusedNode );\r | |
45 | \r | |
46 | var htmlPreview = dialog.getContentElement( 'info', 'htmlPreview' ).getElement();\r | |
47 | \r | |
48 | dialog.getContentElement( 'info', 'charPreview' ).getElement().setHtml( value );\r | |
49 | htmlPreview.setHtml( CKEDITOR.tools.htmlEncode( value ) );\r | |
50 | target.getParent().addClass( 'cke_light_background' );\r | |
51 | \r | |
52 | // Memorize focused node.\r | |
53 | focusedNode = target;\r | |
54 | }\r | |
55 | };\r | |
56 | \r | |
57 | var onBlur = function( evt, target ) {\r | |
58 | target = target || evt.data.getTarget();\r | |
59 | \r | |
60 | if ( target.getName() == 'span' )\r | |
61 | target = target.getParent();\r | |
62 | \r | |
63 | if ( target.getName() == 'a' ) {\r | |
64 | dialog.getContentElement( 'info', 'charPreview' ).getElement().setHtml( ' ' );\r | |
65 | dialog.getContentElement( 'info', 'htmlPreview' ).getElement().setHtml( ' ' );\r | |
66 | target.getParent().removeClass( 'cke_light_background' );\r | |
67 | \r | |
68 | focusedNode = undefined;\r | |
69 | }\r | |
70 | };\r | |
71 | \r | |
72 | var onKeydown = CKEDITOR.tools.addFunction( function( ev ) {\r | |
73 | ev = new CKEDITOR.dom.event( ev );\r | |
74 | \r | |
75 | // Get an Anchor element.\r | |
76 | var element = ev.getTarget();\r | |
77 | var relative, nodeToMove;\r | |
78 | var keystroke = ev.getKeystroke(),\r | |
79 | rtl = editor.lang.dir == 'rtl';\r | |
80 | \r | |
81 | switch ( keystroke ) {\r | |
82 | // UP-ARROW\r | |
83 | case 38:\r | |
84 | // relative is TR\r | |
85 | if ( ( relative = element.getParent().getParent().getPrevious() ) ) {\r | |
86 | nodeToMove = relative.getChild( [ element.getParent().getIndex(), 0 ] );\r | |
87 | nodeToMove.focus();\r | |
88 | onBlur( null, element );\r | |
89 | onFocus( null, nodeToMove );\r | |
90 | }\r | |
91 | ev.preventDefault();\r | |
92 | break;\r | |
93 | // DOWN-ARROW\r | |
94 | case 40:\r | |
95 | // relative is TR\r | |
96 | if ( ( relative = element.getParent().getParent().getNext() ) ) {\r | |
97 | nodeToMove = relative.getChild( [ element.getParent().getIndex(), 0 ] );\r | |
98 | if ( nodeToMove && nodeToMove.type == 1 ) {\r | |
99 | nodeToMove.focus();\r | |
100 | onBlur( null, element );\r | |
101 | onFocus( null, nodeToMove );\r | |
102 | }\r | |
103 | }\r | |
104 | ev.preventDefault();\r | |
105 | break;\r | |
106 | // SPACE\r | |
107 | // ENTER is already handled as onClick\r | |
108 | case 32:\r | |
109 | onChoice( { data: ev } );\r | |
110 | ev.preventDefault();\r | |
111 | break;\r | |
112 | \r | |
113 | // RIGHT-ARROW\r | |
114 | case rtl ? 37 : 39:\r | |
115 | // relative is TD\r | |
116 | if ( ( relative = element.getParent().getNext() ) ) {\r | |
117 | nodeToMove = relative.getChild( 0 );\r | |
118 | if ( nodeToMove.type == 1 ) {\r | |
119 | nodeToMove.focus();\r | |
120 | onBlur( null, element );\r | |
121 | onFocus( null, nodeToMove );\r | |
122 | ev.preventDefault( true );\r | |
123 | } else {\r | |
124 | onBlur( null, element );\r | |
125 | }\r | |
126 | }\r | |
127 | // relative is TR\r | |
128 | else if ( ( relative = element.getParent().getParent().getNext() ) ) {\r | |
129 | nodeToMove = relative.getChild( [ 0, 0 ] );\r | |
130 | if ( nodeToMove && nodeToMove.type == 1 ) {\r | |
131 | nodeToMove.focus();\r | |
132 | onBlur( null, element );\r | |
133 | onFocus( null, nodeToMove );\r | |
134 | ev.preventDefault( true );\r | |
135 | } else {\r | |
136 | onBlur( null, element );\r | |
137 | }\r | |
138 | }\r | |
139 | break;\r | |
140 | \r | |
141 | // LEFT-ARROW\r | |
142 | case rtl ? 39 : 37:\r | |
143 | // relative is TD\r | |
144 | if ( ( relative = element.getParent().getPrevious() ) ) {\r | |
145 | nodeToMove = relative.getChild( 0 );\r | |
146 | nodeToMove.focus();\r | |
147 | onBlur( null, element );\r | |
148 | onFocus( null, nodeToMove );\r | |
149 | ev.preventDefault( true );\r | |
150 | }\r | |
151 | // relative is TR\r | |
152 | else if ( ( relative = element.getParent().getParent().getPrevious() ) ) {\r | |
153 | nodeToMove = relative.getLast().getChild( 0 );\r | |
154 | nodeToMove.focus();\r | |
155 | onBlur( null, element );\r | |
156 | onFocus( null, nodeToMove );\r | |
157 | ev.preventDefault( true );\r | |
158 | } else {\r | |
159 | onBlur( null, element );\r | |
160 | }\r | |
161 | break;\r | |
162 | default:\r | |
163 | // Do not stop not handled events.\r | |
164 | return;\r | |
165 | }\r | |
166 | } );\r | |
167 | \r | |
168 | return {\r | |
169 | title: lang.title,\r | |
170 | minWidth: 430,\r | |
171 | minHeight: 280,\r | |
172 | buttons: [ CKEDITOR.dialog.cancelButton ],\r | |
173 | charColumns: 17,\r | |
174 | onLoad: function() {\r | |
175 | var columns = this.definition.charColumns,\r | |
176 | chars = editor.config.specialChars;\r | |
177 | \r | |
178 | var charsTableLabel = CKEDITOR.tools.getNextId() + '_specialchar_table_label';\r | |
179 | var html = [ '<table role="listbox" aria-labelledby="' + charsTableLabel + '"' +\r | |
180 | ' style="width: 320px; height: 100%; border-collapse: separate;"' +\r | |
181 | ' align="center" cellspacing="2" cellpadding="2" border="0">' ];\r | |
182 | \r | |
183 | var i = 0,\r | |
184 | size = chars.length,\r | |
185 | character, charDesc;\r | |
186 | \r | |
187 | while ( i < size ) {\r | |
188 | html.push( '<tr role="presentation">' );\r | |
189 | \r | |
190 | for ( var j = 0; j < columns; j++, i++ ) {\r | |
191 | if ( ( character = chars[ i ] ) ) {\r | |
192 | charDesc = '';\r | |
193 | \r | |
194 | if ( character instanceof Array ) {\r | |
195 | charDesc = character[ 1 ];\r | |
196 | character = character[ 0 ];\r | |
197 | } else {\r | |
198 | var _tmpName = character.replace( '&', '' ).replace( ';', '' ).replace( '#', '' );\r | |
199 | \r | |
200 | // Use character in case description unavailable.\r | |
201 | charDesc = lang[ _tmpName ] || character;\r | |
202 | }\r | |
203 | \r | |
204 | var charLabelId = 'cke_specialchar_label_' + i + '_' + CKEDITOR.tools.getNextNumber();\r | |
205 | \r | |
206 | html.push( '<td class="cke_dark_background" style="cursor: default" role="presentation">' +\r | |
207 | '<a href="javascript: void(0);" role="option"' +\r | |
208 | ' aria-posinset="' + ( i + 1 ) + '"', ' aria-setsize="' + size + '"', ' aria-labelledby="' + charLabelId + '"', ' class="cke_specialchar" title="', CKEDITOR.tools.htmlEncode( charDesc ), '"' +\r | |
209 | ' onkeydown="CKEDITOR.tools.callFunction( ' + onKeydown + ', event, this )"' +\r | |
210 | ' onclick="CKEDITOR.tools.callFunction(' + onClick + ', this); return false;"' +\r | |
211 | ' tabindex="-1">' +\r | |
212 | '<span style="margin: 0 auto;cursor: inherit">' +\r | |
213 | character +\r | |
214 | '</span>' +\r | |
215 | '<span class="cke_voice_label" id="' + charLabelId + '">' +\r | |
216 | charDesc +\r | |
217 | '</span></a>' );\r | |
218 | } else {\r | |
219 | html.push( '<td class="cke_dark_background"> ' );\r | |
220 | }\r | |
221 | \r | |
222 | html.push( '</td>' );\r | |
223 | }\r | |
224 | html.push( '</tr>' );\r | |
225 | }\r | |
226 | \r | |
227 | html.push( '</tbody></table>', '<span id="' + charsTableLabel + '" class="cke_voice_label">' + lang.options + '</span>' );\r | |
228 | \r | |
229 | this.getContentElement( 'info', 'charContainer' ).getElement().setHtml( html.join( '' ) );\r | |
230 | },\r | |
231 | contents: [ {\r | |
232 | id: 'info',\r | |
233 | label: editor.lang.common.generalTab,\r | |
234 | title: editor.lang.common.generalTab,\r | |
235 | padding: 0,\r | |
236 | align: 'top',\r | |
237 | elements: [ {\r | |
238 | type: 'hbox',\r | |
239 | align: 'top',\r | |
240 | widths: [ '320px', '90px' ],\r | |
241 | children: [ {\r | |
242 | type: 'html',\r | |
243 | id: 'charContainer',\r | |
244 | html: '',\r | |
245 | onMouseover: onFocus,\r | |
246 | onMouseout: onBlur,\r | |
247 | focus: function() {\r | |
248 | var firstChar = this.getElement().getElementsByTag( 'a' ).getItem( 0 );\r | |
249 | setTimeout( function() {\r | |
250 | firstChar.focus();\r | |
251 | onFocus( null, firstChar );\r | |
252 | }, 0 );\r | |
253 | },\r | |
254 | onShow: function() {\r | |
255 | var firstChar = this.getElement().getChild( [ 0, 0, 0, 0, 0 ] );\r | |
256 | setTimeout( function() {\r | |
257 | firstChar.focus();\r | |
258 | onFocus( null, firstChar );\r | |
259 | }, 0 );\r | |
260 | },\r | |
261 | onLoad: function( event ) {\r | |
262 | dialog = event.sender;\r | |
263 | }\r | |
264 | },\r | |
265 | {\r | |
266 | type: 'hbox',\r | |
267 | align: 'top',\r | |
268 | widths: [ '100%' ],\r | |
269 | children: [ {\r | |
270 | type: 'vbox',\r | |
271 | align: 'top',\r | |
272 | children: [\r | |
273 | {\r | |
274 | type: 'html',\r | |
275 | html: '<div></div>'\r | |
276 | },\r | |
277 | {\r | |
278 | type: 'html',\r | |
279 | id: 'charPreview',\r | |
280 | className: 'cke_dark_background',\r | |
281 | style: 'border:1px solid #eeeeee;font-size:28px;height:40px;width:70px;padding-top:9px;font-family:\'Microsoft Sans Serif\',Arial,Helvetica,Verdana;text-align:center;',\r | |
282 | html: '<div> </div>'\r | |
283 | },\r | |
284 | {\r | |
285 | type: 'html',\r | |
286 | id: 'htmlPreview',\r | |
287 | className: 'cke_dark_background',\r | |
288 | style: 'border:1px solid #eeeeee;font-size:14px;height:20px;width:70px;padding-top:2px;font-family:\'Microsoft Sans Serif\',Arial,Helvetica,Verdana;text-align:center;',\r | |
289 | html: '<div> </div>'\r | |
290 | }\r | |
291 | ]\r | |
292 | } ]\r | |
293 | } ]\r | |
294 | } ]\r | |
295 | } ]\r | |
296 | };\r | |
297 | } );\r |