/*\r
-Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved.\r
+Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved.\r
For licensing, see LICENSE.html or http://ckeditor.com/license\r
*/\r
\r
* Simulate "this" of a dialog for non-dialog events.\r
* @type {CKEDITOR.dialog}\r
*/\r
- var dialog;\r
+ var dialog,\r
+ lang = editor.lang.specialChar;\r
+\r
var onChoice = function( evt )\r
{\r
var target, value;\r
{\r
target.removeClass( "cke_light_background" );\r
dialog.hide();\r
- editor.insertHtml( value );\r
+\r
+ // We must use "insertText" here to keep text styled.\r
+ var span = editor.document.createElement( 'span' );\r
+ span.setHtml( value );\r
+ editor.insertText( span.getText() );\r
}\r
};\r
\r
// Get an Anchor element.\r
var element = ev.getTarget();\r
var relative, nodeToMove;\r
- var keystroke = ev.getKeystroke();\r
+ var keystroke = ev.getKeystroke(),\r
+ rtl = editor.lang.dir == 'rtl';\r
\r
switch ( keystroke )\r
{\r
- // RIGHT-ARROW\r
- case 39 :\r
- // relative is TD\r
- if ( ( relative = element.getParent().getNext() ) )\r
- {\r
- nodeToMove = relative.getChild( 0 );\r
- if ( nodeToMove.type == 1 )\r
- {\r
- nodeToMove.focus();\r
- onBlur( null, element );\r
- onFocus( null, nodeToMove );\r
- }\r
- }\r
- ev.preventDefault();\r
- break;\r
- // LEFT-ARROW\r
- case 37 :\r
- // relative is TD\r
- if ( ( relative = element.getParent().getPrevious() ) )\r
- {\r
- nodeToMove = relative.getChild( 0 );\r
- nodeToMove.focus();\r
- onBlur( null, element );\r
- onFocus( null, nodeToMove );\r
- }\r
- ev.preventDefault();\r
- break;\r
// UP-ARROW\r
case 38 :\r
// relative is TR\r
onChoice( { data: ev } );\r
ev.preventDefault();\r
break;\r
+\r
+ // RIGHT-ARROW\r
+ case rtl ? 37 : 39 :\r
// TAB\r
case 9 :\r
// relative is TD\r
onBlur( null, element );\r
}\r
break;\r
+\r
+ // LEFT-ARROW\r
+ case rtl ? 39 : 37 :\r
// SHIFT + TAB\r
case CKEDITOR.SHIFT + 9 :\r
// relative is TD\r
});\r
\r
return {\r
- title : editor.lang.specialChar.title,\r
+ title : lang.title,\r
minWidth : 430,\r
minHeight : 280,\r
buttons : [ CKEDITOR.dialog.cancelButton ],\r
charColumns : 17,\r
- chars :\r
- [\r
- '!','"','#','$','%','&',"'",'(',')','*','+','-','.','/',\r
- '0','1','2','3','4','5','6','7','8','9',':',';',\r
- '<','=','>','?','@',\r
- 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O',\r
- 'P','Q','R','S','T','U','V','W','X','Y','Z',\r
- '[',']','^','_','`',\r
- 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p',\r
- 'q','r','s','t','u','v','w','x','y','z',\r
- '{','|','}','~','€','‘','’','’','“',\r
- '”','–','—','¡','¢','£',\r
- '¤','¥','¦','§','¨','©','ª',\r
- '«','¬','®','¯','°','±','²',\r
- '³','´','µ','¶','·','¸',\r
- '¹','º','»','¼','½','¾',\r
- '¿','À','Á','Â','Ã','Ä',\r
- 'Å','Æ','Ç','È','É','Ê',\r
- 'Ë','Ì','Í','Î','Ï','Ð',\r
- 'Ñ','Ò','Ó','Ô','Õ','Ö',\r
- '×','Ø','Ù','Ú','Û','Ü',\r
- 'Ý','Þ','ß','à','á','â',\r
- 'ã','ä','å','æ','ç','è',\r
- 'é','ê','ë','ì','í','î',\r
- 'ï','ð','ñ','ò','ó','ô',\r
- 'õ','ö','÷','ø','ù','ú',\r
- 'û','ü','ü','ý','þ','ÿ',\r
- 'Œ','œ','Ŵ','Ŷ','ŵ','ŷ','‚',\r
- '‛','„','…','™','►','•',\r
- '→','⇒','⇔','♦','≈'\r
- ],\r
onLoad : function()\r
{\r
var columns = this.definition.charColumns,\r
- chars = this.definition.chars;\r
+ extraChars = editor.config.extraSpecialChars,\r
+ chars = editor.config.specialChars;\r
+\r
+ var charsTableLabel = CKEDITOR.tools.getNextId() + '_specialchar_table_label';\r
+ var html = [ '<table role="listbox" aria-labelledby="' + charsTableLabel + '"' +\r
+ ' style="width: 320px; height: 100%; border-collapse: separate;"' +\r
+ ' align="center" cellspacing="2" cellpadding="2" border="0">' ];\r
\r
- var html = [ '<table style="width: 320px; height: 100%; border-collapse: separate;" align="center" cellspacing="2" cellpadding="2" border="0">' ];\r
+ var i = 0,\r
+ size = chars.length,\r
+ character,\r
+ charDesc;\r
\r
- var i = 0 ;\r
- while ( i < chars.length )\r
+ while ( i < size )\r
{\r
html.push( '<tr>' ) ;\r
\r
for ( var j = 0 ; j < columns ; j++, i++ )\r
{\r
- if ( chars[ i ] )\r
+ if ( ( character = chars[ i ] ) )\r
{\r
+ charDesc = '';\r
+\r
+ if ( character instanceof Array )\r
+ {\r
+ charDesc = character[ 1 ];\r
+ character = character[ 0 ];\r
+ }\r
+ else\r
+ {\r
+ var _tmpName = character.toLowerCase().replace( '&', '' ).replace( ';', '' ).replace( '#', '' );\r
+\r
+ // Use character in case description unavailable.\r
+ charDesc = lang[ _tmpName ] || character;\r
+ }\r
+\r
+ var charLabelId = 'cke_specialchar_label_' + i + '_' + CKEDITOR.tools.getNextNumber();\r
+\r
html.push(\r
- '<td class="cke_dark_background" style="cursor: default">' +\r
- '<a href="javascript: void(0);" style="cursor: inherit; display: block; height: 1.25em; margin-top: 0.25em; text-align: center;" title="', chars[i].replace( /&/g, '&' ), '"' +\r
+ '<td class="cke_dark_background" style="cursor: default" role="presentation">' +\r
+ '<a href="javascript: void(0);" role="option"' +\r
+ ' aria-posinset="' + ( i +1 ) + '"',\r
+ ' aria-setsize="' + size + '"',\r
+ ' aria-labelledby="' + charLabelId + '"',\r
+ ' style="cursor: inherit; display: block; height: 1.25em; margin-top: 0.25em; text-align: center;" title="', CKEDITOR.tools.htmlEncode( charDesc ), '"' +\r
' onkeydown="CKEDITOR.tools.callFunction( ' + onKeydown + ', event, this )"' +\r
' onclick="CKEDITOR.tools.callFunction(' + onClick + ', this); return false;"' +\r
' tabindex="-1">' +\r
'<span style="margin: 0 auto;cursor: inherit">' +\r
- chars[i] +\r
+ character +\r
+ '</span>' +\r
+ '<span class="cke_voice_label" id="' + charLabelId + '">' +\r
+ charDesc +\r
'</span></a>');\r
}\r
else\r
html.push( '</tr>' );\r
}\r
\r
- html.push( '</tbody></table>' );\r
+ html.push( '</tbody></table>', '<span id="' + charsTableLabel + '" class="cke_voice_label">' + lang.options +'</span>' );\r
\r
this.getContentElement( 'info', 'charContainer' ).getElement().setHtml( html.join( '' ) );\r
},\r
onMouseout : onBlur,\r
focus : function()\r
{\r
- var firstChar = this.getElement().getChild( [0, 0, 0, 0, 0] );\r
- setTimeout(function()\r
+ var firstChar = this.getElement().getElementsByTag( 'a' ).getItem( 0 );\r
+ setTimeout( function()\r
{\r
firstChar.focus();\r
onFocus( null, firstChar );\r
- });\r
+ }, 0 );\r
},\r
- // Needed only for webkit.\r
onShow : function()\r
{\r
- var firstChar = this.getElement().getChild( [0, 0, 0, 0, 0] );\r
- setTimeout(function()\r
- {\r
- firstChar.focus();\r
- onFocus( null, firstChar );\r
- });\r
+ var firstChar = this.getElement().getChild( [ 0, 0, 0, 0, 0 ] );\r
+ setTimeout( function()\r
+ {\r
+ firstChar.focus();\r
+ onFocus( null, firstChar );\r
+ }, 0 );\r
},\r
onLoad : function( event )\r
{\r