2014-04-11 20:19:54 +00:00
/ * *
2018-06-17 16:07:19 +00:00
* @ license Copyright ( c ) 2003 - 2018 , CKSource - Frederico Knabben . All rights reserved .
* For licensing , see LICENSE . md or https : //ckeditor.com/legal/ckeditor-oss-license
2014-04-11 20:19:54 +00:00
* /
CKEDITOR . dialog . add ( 'specialchar' , function ( editor ) {
// Simulate "this" of a dialog for non-dialog events.
// @type {CKEDITOR.dialog}
var dialog ,
lang = editor . lang . specialchar ;
var onChoice = function ( evt ) {
var target , value ;
if ( evt . data )
target = evt . data . getTarget ( ) ;
else
target = new CKEDITOR . dom . element ( evt ) ;
if ( target . getName ( ) == 'a' && ( value = target . getChild ( 0 ) . getHtml ( ) ) ) {
2018-06-17 16:07:19 +00:00
target . removeClass ( 'cke_light_background' ) ;
2014-04-11 20:19:54 +00:00
dialog . hide ( ) ;
// We must use "insertText" here to keep text styled.
var span = editor . document . createElement ( 'span' ) ;
span . setHtml ( value ) ;
editor . insertText ( span . getText ( ) ) ;
}
} ;
var onClick = CKEDITOR . tools . addFunction ( onChoice ) ;
var focusedNode ;
var onFocus = function ( evt , target ) {
var value ;
target = target || evt . data . getTarget ( ) ;
if ( target . getName ( ) == 'span' )
target = target . getParent ( ) ;
if ( target . getName ( ) == 'a' && ( value = target . getChild ( 0 ) . getHtml ( ) ) ) {
// Trigger blur manually if there is focused node.
if ( focusedNode )
onBlur ( null , focusedNode ) ;
var htmlPreview = dialog . getContentElement ( 'info' , 'htmlPreview' ) . getElement ( ) ;
dialog . getContentElement ( 'info' , 'charPreview' ) . getElement ( ) . setHtml ( value ) ;
htmlPreview . setHtml ( CKEDITOR . tools . htmlEncode ( value ) ) ;
2018-06-17 16:07:19 +00:00
target . getParent ( ) . addClass ( 'cke_light_background' ) ;
2014-04-11 20:19:54 +00:00
// Memorize focused node.
focusedNode = target ;
}
} ;
var onBlur = function ( evt , target ) {
target = target || evt . data . getTarget ( ) ;
if ( target . getName ( ) == 'span' )
target = target . getParent ( ) ;
if ( target . getName ( ) == 'a' ) {
dialog . getContentElement ( 'info' , 'charPreview' ) . getElement ( ) . setHtml ( ' ' ) ;
dialog . getContentElement ( 'info' , 'htmlPreview' ) . getElement ( ) . setHtml ( ' ' ) ;
2018-06-17 16:07:19 +00:00
target . getParent ( ) . removeClass ( 'cke_light_background' ) ;
2014-04-11 20:19:54 +00:00
focusedNode = undefined ;
}
} ;
var onKeydown = CKEDITOR . tools . addFunction ( function ( ev ) {
ev = new CKEDITOR . dom . event ( ev ) ;
// Get an Anchor element.
var element = ev . getTarget ( ) ;
var relative , nodeToMove ;
var keystroke = ev . getKeystroke ( ) ,
rtl = editor . lang . dir == 'rtl' ;
switch ( keystroke ) {
// UP-ARROW
case 38 :
// relative is TR
if ( ( relative = element . getParent ( ) . getParent ( ) . getPrevious ( ) ) ) {
nodeToMove = relative . getChild ( [ element . getParent ( ) . getIndex ( ) , 0 ] ) ;
nodeToMove . focus ( ) ;
onBlur ( null , element ) ;
onFocus ( null , nodeToMove ) ;
}
ev . preventDefault ( ) ;
break ;
// DOWN-ARROW
case 40 :
// relative is TR
if ( ( relative = element . getParent ( ) . getParent ( ) . getNext ( ) ) ) {
nodeToMove = relative . getChild ( [ element . getParent ( ) . getIndex ( ) , 0 ] ) ;
if ( nodeToMove && nodeToMove . type == 1 ) {
nodeToMove . focus ( ) ;
onBlur ( null , element ) ;
onFocus ( null , nodeToMove ) ;
}
}
ev . preventDefault ( ) ;
break ;
// SPACE
// ENTER is already handled as onClick
case 32 :
onChoice ( { data : ev } ) ;
ev . preventDefault ( ) ;
break ;
// RIGHT-ARROW
case rtl ? 37 : 39 :
// relative is TD
if ( ( relative = element . getParent ( ) . getNext ( ) ) ) {
nodeToMove = relative . getChild ( 0 ) ;
if ( nodeToMove . type == 1 ) {
nodeToMove . focus ( ) ;
onBlur ( null , element ) ;
onFocus ( null , nodeToMove ) ;
ev . preventDefault ( true ) ;
2018-06-17 16:07:19 +00:00
} else {
2014-04-11 20:19:54 +00:00
onBlur ( null , element ) ;
2018-06-17 16:07:19 +00:00
}
2014-04-11 20:19:54 +00:00
}
// relative is TR
else if ( ( relative = element . getParent ( ) . getParent ( ) . getNext ( ) ) ) {
nodeToMove = relative . getChild ( [ 0 , 0 ] ) ;
if ( nodeToMove && nodeToMove . type == 1 ) {
nodeToMove . focus ( ) ;
onBlur ( null , element ) ;
onFocus ( null , nodeToMove ) ;
ev . preventDefault ( true ) ;
2018-06-17 16:07:19 +00:00
} else {
2014-04-11 20:19:54 +00:00
onBlur ( null , element ) ;
2018-06-17 16:07:19 +00:00
}
2014-04-11 20:19:54 +00:00
}
break ;
// LEFT-ARROW
case rtl ? 39 : 37 :
// relative is TD
if ( ( relative = element . getParent ( ) . getPrevious ( ) ) ) {
nodeToMove = relative . getChild ( 0 ) ;
nodeToMove . focus ( ) ;
onBlur ( null , element ) ;
onFocus ( null , nodeToMove ) ;
ev . preventDefault ( true ) ;
}
// relative is TR
else if ( ( relative = element . getParent ( ) . getParent ( ) . getPrevious ( ) ) ) {
nodeToMove = relative . getLast ( ) . getChild ( 0 ) ;
nodeToMove . focus ( ) ;
onBlur ( null , element ) ;
onFocus ( null , nodeToMove ) ;
ev . preventDefault ( true ) ;
2018-06-17 16:07:19 +00:00
} else {
2014-04-11 20:19:54 +00:00
onBlur ( null , element ) ;
2018-06-17 16:07:19 +00:00
}
2014-04-11 20:19:54 +00:00
break ;
default :
// Do not stop not handled events.
return ;
}
} ) ;
return {
title : lang . title ,
minWidth : 430 ,
minHeight : 280 ,
buttons : [ CKEDITOR . dialog . cancelButton ] ,
charColumns : 17 ,
onLoad : function ( ) {
var columns = this . definition . charColumns ,
chars = editor . config . specialChars ;
var charsTableLabel = CKEDITOR . tools . getNextId ( ) + '_specialchar_table_label' ;
var html = [ '<table role="listbox" aria-labelledby="' + charsTableLabel + '"' +
' style="width: 320px; height: 100%; border-collapse: separate;"' +
' align="center" cellspacing="2" cellpadding="2" border="0">' ] ;
var i = 0 ,
size = chars . length ,
character , charDesc ;
while ( i < size ) {
html . push ( '<tr role="presentation">' ) ;
for ( var j = 0 ; j < columns ; j ++ , i ++ ) {
if ( ( character = chars [ i ] ) ) {
charDesc = '' ;
if ( character instanceof Array ) {
charDesc = character [ 1 ] ;
character = character [ 0 ] ;
} else {
var _tmpName = character . replace ( '&' , '' ) . replace ( ';' , '' ) . replace ( '#' , '' ) ;
// Use character in case description unavailable.
charDesc = lang [ _tmpName ] || character ;
}
var charLabelId = 'cke_specialchar_label_' + i + '_' + CKEDITOR . tools . getNextNumber ( ) ;
html . push ( '<td class="cke_dark_background" style="cursor: default" role="presentation">' +
'<a href="javascript: void(0);" role="option"' +
' aria-posinset="' + ( i + 1 ) + '"' , ' aria-setsize="' + size + '"' , ' aria-labelledby="' + charLabelId + '"' , ' class="cke_specialchar" title="' , CKEDITOR . tools . htmlEncode ( charDesc ) , '"' +
' onkeydown="CKEDITOR.tools.callFunction( ' + onKeydown + ', event, this )"' +
' onclick="CKEDITOR.tools.callFunction(' + onClick + ', this); return false;"' +
' tabindex="-1">' +
'<span style="margin: 0 auto;cursor: inherit">' +
character +
'</span>' +
'<span class="cke_voice_label" id="' + charLabelId + '">' +
charDesc +
'</span></a>' ) ;
2018-06-17 16:07:19 +00:00
} else {
2014-04-11 20:19:54 +00:00
html . push ( '<td class="cke_dark_background"> ' ) ;
2018-06-17 16:07:19 +00:00
}
2014-04-11 20:19:54 +00:00
html . push ( '</td>' ) ;
}
html . push ( '</tr>' ) ;
}
html . push ( '</tbody></table>' , '<span id="' + charsTableLabel + '" class="cke_voice_label">' + lang . options + '</span>' ) ;
this . getContentElement ( 'info' , 'charContainer' ) . getElement ( ) . setHtml ( html . join ( '' ) ) ;
} ,
2018-06-17 16:07:19 +00:00
contents : [ {
2014-04-11 20:19:54 +00:00
id : 'info' ,
label : editor . lang . common . generalTab ,
title : editor . lang . common . generalTab ,
padding : 0 ,
align : 'top' ,
2018-06-17 16:07:19 +00:00
elements : [ {
2014-04-11 20:19:54 +00:00
type : 'hbox' ,
align : 'top' ,
widths : [ '320px' , '90px' ] ,
2018-06-17 16:07:19 +00:00
children : [ {
2014-04-11 20:19:54 +00:00
type : 'html' ,
id : 'charContainer' ,
html : '' ,
onMouseover : onFocus ,
onMouseout : onBlur ,
focus : function ( ) {
var firstChar = this . getElement ( ) . getElementsByTag ( 'a' ) . getItem ( 0 ) ;
setTimeout ( function ( ) {
firstChar . focus ( ) ;
onFocus ( null , firstChar ) ;
} , 0 ) ;
} ,
onShow : function ( ) {
var firstChar = this . getElement ( ) . getChild ( [ 0 , 0 , 0 , 0 , 0 ] ) ;
setTimeout ( function ( ) {
firstChar . focus ( ) ;
onFocus ( null , firstChar ) ;
} , 0 ) ;
} ,
onLoad : function ( event ) {
dialog = event . sender ;
}
} ,
2018-06-17 16:07:19 +00:00
{
2014-04-11 20:19:54 +00:00
type : 'hbox' ,
align : 'top' ,
widths : [ '100%' ] ,
2018-06-17 16:07:19 +00:00
children : [ {
2014-04-11 20:19:54 +00:00
type : 'vbox' ,
align : 'top' ,
children : [
{
2018-06-17 16:07:19 +00:00
type : 'html' ,
html : '<div></div>'
} ,
2014-04-11 20:19:54 +00:00
{
2018-06-17 16:07:19 +00:00
type : 'html' ,
id : 'charPreview' ,
className : 'cke_dark_background' ,
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;' ,
html : '<div> </div>'
} ,
2014-04-11 20:19:54 +00:00
{
2018-06-17 16:07:19 +00:00
type : 'html' ,
id : 'htmlPreview' ,
className : 'cke_dark_background' ,
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;' ,
html : '<div> </div>'
}
2014-04-11 20:19:54 +00:00
]
2018-06-17 16:07:19 +00:00
} ]
} ]
} ]
} ]
2014-04-11 20:19:54 +00:00
} ;
} ) ;