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