      1 ﻿/*
      2 Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.
      3 For licensing, see LICENSE.html or http://ckeditor.com/license
      4 */
      5
      6 CKEDITOR.dialog.add( 'smiley', function( editor )
      7 {
      8 	var config = editor.config,
      9 		images = config.smiley_images,
     10 		columns = config.smiley_columns,
     11 		i;
     12
     13 	/**
     14 	 * Simulate "this" of a dialog for non-dialog events.
     15 	 * @type {CKEDITOR.dialog}
     16 	 */
     17 	var dialog;
     18 	var onClick = function( evt )
     19 	{
     20 		var target = evt.data.getTarget(),
     21 			targetName = target.getName();
     22
     23 		if ( targetName == 'td' )
     24 			target = target.getChild( [ 0, 0 ] );
     25 		else if ( targetName == 'a' )
     26 			target = target.getChild( 0 );
     27 		else if ( targetName != 'img' )
     28 			return;
     29
     30 		var src = target.getAttribute( 'cke_src' ),
     31 			title = target.getAttribute( 'title' );
     32
     33 		var img = editor.document.createElement( 'img',
     34 			{
     35 				attributes :
     36 				{
     37 					src : src,
     38 					_cke_saved_src : src,
     39 					title : title,
     40 					alt : title
     41 				}
     42 			});
     43
     44 		editor.insertElement( img );
     45
     46 		dialog.hide();
     47 	};
     48
     49 	var onKeydown = CKEDITOR.tools.addFunction( function( ev, element )
     50 	{
     51 		ev = new CKEDITOR.dom.event( ev );
     52 		element = new CKEDITOR.dom.element( element );
     53 		var relative, nodeToMove;
     54
     55 		var keystroke = ev.getKeystroke();
     56 		switch ( keystroke )
     57 		{
     58 			// RIGHT-ARROW
     59 			case 39 :
     60 				// relative is TD
     61 				if ( ( relative = element.getParent().getNext() ) )
     62 				{
     63 					nodeToMove = relative.getChild( 0 );
     64 					nodeToMove.focus();
     65 				}
     66 				ev.preventDefault();
     67 				break;
     68 			// LEFT-ARROW
     69 			case 37 :
     70 				// relative is TD
     71 				if ( ( relative = element.getParent().getPrevious() ) )
     72 				{
     73 					nodeToMove = relative.getChild( 0 );
     74 					nodeToMove.focus();
     75 				}
     76 				ev.preventDefault();
     77 				break;
     78 			// UP-ARROW
     79 			case 38 :
     80 				// relative is TR
     81 				if ( ( relative = element.getParent().getParent().getPrevious() ) )
     82 				{
     83 					nodeToMove = relative.getChild( [element.getParent().getIndex(), 0] );
     84 					nodeToMove.focus();
     85 				}
     86 				ev.preventDefault();
     87 				break;
     88 			// DOWN-ARROW
     89 			case 40 :
     90 				// relative is TR
     91 				if ( ( relative = element.getParent().getParent().getNext() ) )
     92 				{
     93 					nodeToMove = relative.getChild( [element.getParent().getIndex(), 0] );
     94 					if ( nodeToMove )
     95 						nodeToMove.focus();
     96 				}
     97 				ev.preventDefault();
     98 				break;
     99 			// ENTER
    100 			// SPACE
    101 			case 32 :
    102 				onClick( { data: ev } );
    103 				ev.preventDefault();
    104 				break;
    105 			// TAB
    106 			case 9 :
    107 				// relative is TD
    108 				if ( ( relative = element.getParent().getNext() ) )
    109 				{
    110 					nodeToMove = relative.getChild( 0 );
    111 					nodeToMove.focus();
    112 					ev.preventDefault(true);
    113 				}
    114 				// relative is TR
    115 				else if ( ( relative = element.getParent().getParent().getNext() ) )
    116 				{
    117 					nodeToMove = relative.getChild( [0, 0] );
    118 					if ( nodeToMove )
    119 						nodeToMove.focus();
    120 					ev.preventDefault(true);
    121 				}
    122 				break;
    123 			// SHIFT + TAB
    124 			case CKEDITOR.SHIFT + 9 :
    125 				// relative is TD
    126 				if ( ( relative = element.getParent().getPrevious() ) )
    127 				{
    128 					nodeToMove = relative.getChild( 0 );
    129 					nodeToMove.focus();
    130 					ev.preventDefault(true);
    131 				}
    132 				// relative is TR
    133 				else if ( ( relative = element.getParent().getParent().getPrevious() ) )
    134 				{
    135 					nodeToMove = relative.getLast().getChild( 0 );
    136 					nodeToMove.focus();
    137 					ev.preventDefault(true);
    138 				}
    139 				break;
    140 			default :
    141 				// Do not stop not handled events.
    142 				return;
    143 		}
    144 	});
    145
    146 	// Build the HTML for the smiley images table.
    147 	var html =
    148 	[
    149 		'<table cellspacing="2" cellpadding="2"',
    150 		CKEDITOR.env.ie && CKEDITOR.env.quirks ? ' style="position:absolute;"' : '',
    151 		'><tbody>'
    152 	];
    153
    154 	for ( i = 0 ; i < images.length ; i++ )
    155 	{
    156 		if ( i % columns === 0 )
    157 			html.push( '<tr>' );
    158
    159 		html.push(
    160 			'<td class="cke_dark_background cke_hand cke_centered" style="vertical-align: middle;">' +
    161 				'<a href="javascript:void(0)" class="cke_smile" tabindex="-1" onkeydown="CKEDITOR.tools.callFunction( ', onKeydown, ', event, this );">',
    162 					'<img class="hand" title="', config.smiley_descriptions[i], '"' +
    163 						' cke_src="', CKEDITOR.tools.htmlEncode( config.smiley_path + images[ i ] ), '" alt="', config.smiley_descriptions[i], '"',
    164 						' src="', CKEDITOR.tools.htmlEncode( config.smiley_path + images[ i ] ), '"',
    165 						// IE BUG: Below is a workaround to an IE image loading bug to ensure the image sizes are correct.
    166 						( CKEDITOR.env.ie ? ' onload="this.setAttribute(\'width\', 2); this.removeAttribute(\'width\');" ' : '' ),
    167 					'>' +
    168 				'</a>',
    169  			'</td>' );
    170
    171 		if ( i % columns == columns - 1 )
    172 			html.push( '</tr>' );
    173 	}
    174
    175 	if ( i < columns - 1 )
    176 	{
    177 		for ( ; i < columns - 1 ; i++ )
    178 			html.push( '<td></td>' );
    179 		html.push( '</tr>' );
    180 	}
    181
    182 	html.push( '</tbody></table>' );
    183
    184 	var smileySelector =
    185 	{
    186 		type : 'html',
    187 		html : html.join( '' ),
    188 		onLoad : function( event )
    189 		{
    190 			dialog = event.sender;
    191 		},
    192 		focus : function()
    193  		{
    194 			var firstSmile = this.getElement().getChild( [0, 0, 0, 0] );
    195 			firstSmile.focus();
    196  		},
    197 		onClick : onClick,
    198 		style : 'width: 100%; height: 100%; border-collapse: separate;'
    199 	};
    200
    201 	return {
    202 		title : editor.lang.smiley.title,
    203 		minWidth : 270,
    204 		minHeight : 120,
    205 		contents : [
    206 			{
    207 				id : 'tab1',
    208 				label : '',
    209 				title : '',
    210 				expand : true,
    211 				padding : 0,
    212 				elements : [
    213 						smileySelector
    214 					]
    215 			}
    216 		],
    217 		buttons : [ CKEDITOR.dialog.cancelButton ]
    218 	};
    219 } );
    220