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