Index: _source/skins/v2/dialog.css
===================================================================
--- _source/skins/v2/dialog.css	(revision 3505)
+++ _source/skins/v2/dialog.css	Fri May 15 12:23:38 CEST 2009
@@ -1,4 +1,4 @@
-﻿/*
+/*
 Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.
 For licensing, see LICENSE.html or http://ckeditor.com/license
 */
@@ -476,22 +476,22 @@
 /*
  * Some utility CSS classes for dialog authors.
  */
-.cke_skin_v2 .cke_dialog .dark_background
+.cke_skin_v2 .cke_dialog .cke_dark_background
 {
 	background-color: #eaead1;
 }
 
-.cke_skin_v2 .cke_dialog .hand
+.cke_skin_v2 .cke_dialog .cke_hand
 {
 	cursor: pointer;
 }
 
-.cke_skin_v2 .cke_dialog .centered
+.cke_skin_v2 .cke_dialog .cke_centered
 {
 	text-align: center;
 }
 
-.cke_skin_v2 .cke_dialog .BtnReset
+.cke_skin_v2 .cke_dialog .cke_btn_reset
 {
 	float: right;
 	background-position: 0 -32px;
@@ -503,12 +503,13 @@
 	font-size: 1px;
 }
 
-.cke_skin_v2 .cke_rtl .cke_dialog .BtnReset
+.cke_skin_v2 .cke_rtl .cke_dialog .cke_btn_reset
 {
 	float: left;
 }
 
-.cke_skin_v2 .cke_dialog .BtnLocked, .BtnUnlocked
+.cke_skin_v2 .cke_dialog .cke_btn_locked,
+.cke_skin_v2 .cke_dialog .cke_btn_unlocked
 {
 	float: left;
 	background-position: 0 0;
@@ -520,18 +521,19 @@
 	font-size: 1px;
 }
 
-.cke_skin_v2 .cke_dialog .BtnLocked, .BtnUnlocked
+.cke_skin_v2 .cke_dialog .cke_btn_locked,
+.cke_skin_v2 .cke_dialog .cke_btn_unlocked
 {
 	float: right;
 }
 
-.cke_skin_v2 .cke_dialog .BtnUnlocked
+.cke_skin_v2 .cke_dialog .cke_btn_unlocked
 {
 	background-position: 0 -16px;
 	background-image: url(images/mini.gif);
 }
 
-.cke_skin_v2 .cke_dialog .BtnOver
+.cke_skin_v2 .cke_dialog .cke_btn_over
 {
 	border: outset 1px;
 	cursor: pointer;
@@ -574,26 +576,26 @@
 	background-color : white;
 }
 
-.cke_skin_v2 .cke_dialog .DarkBackground
+.cke_skin_v2 .cke_dialog .cke_dark_background
 {
 	text-align : center;
 	background-color: #eaead1;
 	font-size : 14px;
 }
 
-.cke_skin_v2 .cke_dialog .LightBackground
+.cke_skin_v2 .cke_dialog .cke_light_background
 {
 	text-align : center;
 	background-color: #ffffbe;
 }
 
-.cke_skin_v2 .cke_dialog .Hand
+.cke_skin_v2 .cke_dialog .cke_hand
 {
 	cursor: pointer;
 	cursor: hand;
 }
 
-.cke_skin_v2 .disabled
+.cke_skin_v2 .cke_disabled
 {
 	color: #a0a0a0;
 }
Index: _source/plugins/specialchar/dialogs/specialchar.js
===================================================================
--- _source/plugins/specialchar/dialogs/specialchar.js	(revision 3505)
+++ _source/plugins/specialchar/dialogs/specialchar.js	Fri May 15 10:13:29 CEST 2009
@@ -62,11 +62,11 @@
 							'<td width="1%"' +
 							' title="', chars[i].replace( /&/g, '&amp;' ), '"' +
 							' value="', chars[i].replace( /&/g, "&amp;" ), '"' +
-							' class="DarkBackground Hand">');
+							' class="cke_dark_background cke_hand">');
 						html.push( chars[i] );
 					}
 					else
-						html.push( '<td class="DarkBackground">&nbsp;' );
+						html.push( '<td class="cke_dark_background">&nbsp;' );
 
 					html.push( '</td>' );
 				}
@@ -106,7 +106,7 @@
 
 										dialog.getContentElement( 'info', 'charPreview' ).getElement().setHtml( value );
 										htmlPreview.setHtml( CKEDITOR.tools.htmlEncode( value ) );
-										target.addClass( "LightBackground" );
+										target.addClass( "cke_light_background" );
 									}
 								},
 								onMouseout : function( evt )
@@ -117,7 +117,7 @@
 										var dialog = this.getDialog();
 										dialog.getContentElement( 'info', 'charPreview' ).getElement().setHtml( '&nbsp;' );
 										dialog.getContentElement( 'info', 'htmlPreview' ).getElement().setHtml( '&nbsp;' );
-										target.removeClass( "LightBackground" );
+										target.removeClass( "cke_light_background" );
 									}
 								},
 								onClick : function( evt )
@@ -127,7 +127,7 @@
 									if ( target.getName() == 'td' && ( value = target.$.getAttribute( 'value' )) )
 									{
 										var dialog = this.getDialog();
-										target.removeClass( "LightBackground" );
+										target.removeClass( "cke_light_background" );
 										dialog.getParentEditor().insertHtml( value );
 										dialog.hide();
 									}
Index: _source/plugins/find/dialogs/find.js
===================================================================
--- _source/plugins/find/dialogs/find.js	(revision 3505)
+++ _source/plugins/find/dialogs/find.js	Fri May 15 09:44:55 CEST 2009
@@ -26,14 +26,13 @@
 	 */
 	var cursorStep = function()
 	{
-		var obj = {
+		return {
 			textNode : this.textNode,
 			offset : this.offset,
 			character : this.textNode ?
 				this.textNode.getText().charAt( this.offset ) : null,
 			hitMatchBoundary : this._.matchBoundary
 		};
-		return obj;
 	};
 
 	var pages = [ 'find', 'replace' ],
@@ -72,10 +71,11 @@
 		var highlightStyle = new CKEDITOR.style( editor.config.find_highlight );
 
 		/**
-		 * Iterator which walk through document char by char.
-		 * @param {Object} start
-		 * @param {Number} offset
-		 * @param {Boolean} isStrict
+		 * Iterator which walk through the specified range char by char. By
+		 * default the walking will not stop at the character boundaries, until
+		 * the end of the range is encountered.
+		 * @param { CKEDITOR.dom.range } range
+		 * @param {Boolean} matchWord Whether the walking will stop at character boundary.
 		 */
 		var characterWalker = function( range , matchWord )
 		{
@@ -193,58 +193,21 @@
 				range.setEnd( last.textNode, last.offset + 1 );
 				return range;
 			},
-
+			/**
+			 * Reflect the latest changes from dom range.
+			 */
 			updateFromDomRange : function( domRange )
 			{
-				var startNode = domRange.startContainer,
-					startIndex = domRange.startOffset,
-					endNode = domRange.endContainer,
-					endIndex = domRange.endOffset,
-					boundaryNodes = domRange.getBoundaryNodes();
-
-				if ( startNode.type != CKEDITOR.NODE_TEXT )
-				{
-					startNode = boundaryNodes.startNode;
-					while ( startNode.type != CKEDITOR.NODE_TEXT )
-						startNode = startNode.getFirst();
-					startIndex = 0;
-				}
-
-				if ( endNode.type != CKEDITOR.NODE_TEXT )
-				{
-					endNode = boundaryNodes.endNode;
-					while ( endNode.type != CKEDITOR.NODE_TEXT )
-						endNode = endNode.getLast();
-					endIndex = endNode.getLength();
-				}
-
-				// If the endNode is an empty text node, our walker would just walk through
-				// it without stopping. So need to backtrack to the nearest non-emtpy text
-				// node.
-				if ( endNode.getLength() < 1 )
-				{
-					while ( ( endNode = endNode.getPreviousSourceNode() )
-						   && !( endNode.type == CKEDITOR.NODE_TEXT
-									&& endNode.getLength() > 0 ) )
-					{ /*jsl:pass*/ }
-
-					endIndex = endNode.getLength();
-				}
-
-				// Rebuild the character range.
 				var cursor,
-						walker = new characterWalker(
-								getRangeAfterCursor(
-													( { textNode: startNode, offset : startIndex } ),
-													true ) );
+						walker = new characterWalker( domRange );
 				this._.cursors = [];
 				do
 				{
 					cursor = walker.next();
+					if ( cursor.character )
-					this._.cursors.push( cursor );
+						this._.cursors.push( cursor );
 				}
-				while ( !( cursor.textNode.equals( endNode )
-							 && cursor.offset == endIndex - 1 ) );
+				while ( cursor.character );
 				this._.rangeLength = this._.cursors.length;
 			},
 
@@ -439,7 +402,6 @@
 						this._.state = this._.overlap[ this._.state ];
 				}
 
-				return null;
 			},
 
 			reset : function()
@@ -557,14 +519,6 @@
 		};
 
 		/**
-		 * Get the default cursor which is the start of this document.
-		 */
-		function getDefaultStartCursor()
-		{
-			return { textNode : editor.document.getBody(), offset: 0 };
-		}
-
-		/**
 		 * The range in which find/replace happened, receive from user
 		 * selection prior.
 		 */
Index: _source/plugins/smiley/dialogs/smiley.js
===================================================================
--- _source/plugins/smiley/dialogs/smiley.js	(revision 3506)
+++ _source/plugins/smiley/dialogs/smiley.js	Fri May 15 12:36:19 CEST 2009
@@ -1,4 +1,4 @@
-﻿/*
+/*
 Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.
 For licensing, see LICENSE.html or http://ckeditor.com/license
 */
@@ -10,6 +10,140 @@
 		columns = config.smiley_columns,
 		i;
 
+	/**
+	 * Simulate "this" of a dialog for non-dialog events.
+	 * @type {CKEDITOR.dialog}
+	 */
+	var dialog;
+	var onClick = function( evt )
+	{
+		var target = evt.data.getTarget(),
+			targetName = target.getName();
+
+		if ( targetName == 'td' )
+			target = target.getChild( [ 0, 0 ] );
+		else if ( targetName == 'a' )
+			target = target.getChild( 0 );
+		else if ( targetName != 'img' )
+			return;
+
+		var src = target.getAttribute( 'cke_src' ),
+			title = target.getAttribute( 'title' );
+
+		var img = editor.document.createElement( 'img',
+			{
+				attributes :
+				{
+					src : src,
+					_cke_saved_src : src,
+					title : title,
+					alt : title
+				}
+			});
+
+		editor.insertElement( img );
+
+		dialog.hide();
+	}
+
+	var onKeydown = CKEDITOR.tools.addFunction( function( ev, element )
+	{
+		ev = new CKEDITOR.dom.event( ev );
+		element = new CKEDITOR.dom.element( element );
+		var relative, nodeToMove;
+
+		var keystroke = ev.getKeystroke();
+		switch ( keystroke )
+		{
+			// RIGHT-ARROW
+			case 39 :
+				// relative is TD
+				if ( ( relative = element.getParent().getNext() ) )
+				{
+					nodeToMove = relative.getChild( 0 );
+					nodeToMove.focus();
+				}
+				ev.preventDefault();
+				break;
+			// LEFT-ARROW
+			case 37 :
+				// relative is TD
+				if ( ( relative = element.getParent().getPrevious() ) )
+				{
+					nodeToMove = relative.getChild( 0 );
+					nodeToMove.focus();
+				}
+				ev.preventDefault();
+				break;
+			// UP-ARROW
+			case 38 :
+				// relative is TR
+				if ( ( relative = element.getParent().getParent().getPrevious() ) )
+				{
+					nodeToMove = relative.getChild( [element.getParent().getIndex(), 0] );
+					nodeToMove.focus();
+				}
+				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.focus();
+				}
+				ev.preventDefault();
+				break;
+			// ENTER
+			// SPACE
+			case 13 :
+			case 32 :
+				onClick( { data: ev } );
+				ev.preventDefault();
+				break;
+			// TAB
+			case 9 :
+				// relative is TD
+				if ( ( relative = element.getParent().getNext() ) )
+				{
+					nodeToMove = relative.getChild( 0 );
+					nodeToMove.focus();
+					ev.preventDefault(true);
+				}
+				// relative is TR
+				else if ( ( relative = element.getParent().getParent().getNext() ) )
+				{
+					nodeToMove = relative.getChild( [0, 0] );
+					if ( nodeToMove )
+						nodeToMove.focus();
+					ev.preventDefault(true);
+				}
+				break;
+			// SHIFT + TAB
+			case CKEDITOR.SHIFT + 9 :
+				// relative is TD
+				if ( ( relative = element.getParent().getPrevious() ) )
+				{
+					nodeToMove = relative.getChild( 0 );
+					nodeToMove.focus();
+					ev.preventDefault(true);
+				}
+				// relative is TR
+				else if ( ( relative = element.getParent().getParent().getPrevious() ) )
+				{
+					nodeToMove = relative.getLast().getChild( 0 );
+					nodeToMove.focus();
+					ev.preventDefault(true);
+				}
+				break;
+			default :
+				// Do not stop not handled events.
+				return;
+		}
+	});
+
 	// Build the HTML for the smiley images table.
 	var html =
 	[
@@ -25,13 +159,15 @@
 
 		html.push(
 			'<td class="dark_background hand centered" style="vertical-align: middle;">' +
-				'<img border="0" class="hand" title="', config.smiley_descriptions[i], '"' +
+				'<a class="cke_smile" tabindex="-1" onkeydown="CKEDITOR.tools.callFunction( ', onKeydown, ', event, this );">',
+					'<img class="hand" title="', config.smiley_descriptions[i], '"' +
-					' cke_src="', CKEDITOR.tools.htmlEncode( config.smiley_path + images[ i ] ), '"',
-					' src="', CKEDITOR.tools.htmlEncode( config.smiley_path + images[ i ] ), '"',
-					// IE BUG: Below is a workaround to an IE image loading bug to ensure the image sizes are correct.
-					( CKEDITOR.env.ie ? ' onload="this.setAttribute(\'width\', 2); this.removeAttribute(\'width\');" ' : '' ),
-				'>' +
+						' cke_src="', CKEDITOR.tools.htmlEncode( config.smiley_path + images[ i ] ), '"',
+						' src="', CKEDITOR.tools.htmlEncode( config.smiley_path + images[ i ] ), '"',
+						// IE BUG: Below is a workaround to an IE image loading bug to ensure the image sizes are correct.
+						( CKEDITOR.env.ie ? ' onload="this.setAttribute(\'width\', 2); this.removeAttribute(\'width\');" ' : '' ),
+					'>' +
+				'</a>',
-			'</td>' );
+ 			'</td>' );
 
 		if ( i % columns == columns - 1 )
 			html.push( '</tr>' );
@@ -50,34 +186,16 @@
 	{
 		type : 'html',
 		html : html.join( '' ),
-		onClick : function( evt )
+		onLoad : function( event )
 		{
-			var target = evt.data.getTarget(),
-				targetName = target.getName();
-
-			if ( targetName == 'td' )
-				target = target.getChild(0);
-			else if ( targetName != 'img' )
-				return;
-
-			var src = target.getAttribute( 'cke_src' ),
-				title = target.getAttribute( 'title' );
-
-			var img = editor.document.createElement( 'img',
+			dialog = event.sender;
+		},
+		focus : function()
-				{
+ 		{
-					attributes :
-					{
-						src : src,
-						_cke_saved_src : src,
-						title : title,
-						alt : title
-					}
-				});
-
-			editor.insertElement( img );
-
-			this.getDialog().hide();
+			var firstSmile = this.getElement().getChild( [0, 0, 0, 0] );
+			firstSmile.focus();
-		},
+ 		},
+		onClick : onClick,
 		style : 'width: 100%; height: 100%; border-collapse: separate;'
 	};
 
Index: _source/plugins/image/dialogs/image.js
===================================================================
--- _source/plugins/image/dialogs/image.js	(revision 3505)
+++ _source/plugins/image/dialogs/image.js	Fri May 15 10:04:46 CEST 2009
@@ -93,9 +93,9 @@
 			dialog.lockRatio = false;
 
 		if ( dialog.lockRatio )
-			ratioButton.removeClass( 'BtnUnlocked' );
+			ratioButton.removeClass( 'cke_btn_unlocked' );
 		else
-			ratioButton.addClass( 'BtnUnlocked' );
+			ratioButton.addClass( 'cke_btn_unlocked' );
 
 		return dialog.lockRatio;
 	};
@@ -650,9 +650,9 @@
 													},
 													html : '<div>'+
 														'<div title="' + editor.lang.image.lockRatio +
-														'" class="BtnLocked" id="btnLockSizes"></div>' +
+														'" class="cke_btn_locked" id="btnLockSizes"></div>' +
 														'<div title="' + editor.lang.image.resetSize +
-														'" class="BtnReset" id="btnResetSize"></div>'+
+														'" class="cke_btn_reset" id="btnResetSize"></div>'+
 														'</div>'
 												}
 											]
Index: _source/skins/office2003/dialog.css
===================================================================
--- _source/skins/office2003/dialog.css	(revision 3505)
+++ _source/skins/office2003/dialog.css	Fri May 15 09:57:28 CEST 2009
@@ -1,4 +1,4 @@
-﻿/*
+/*
 Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.
 For licensing, see LICENSE.html or http://ckeditor.com/license
 */
@@ -477,22 +477,22 @@
 /*
  * Some utility CSS classes for dialog authors.
  */
-.cke_skin_office2003 .cke_dialog .dark_background
+.cke_skin_office2003 .cke_dialog .cke_dark_background
 {
 	background-color: #eaead1;
 }
 
-.cke_skin_office2003 .cke_dialog .hand
+.cke_skin_office2003 .cke_dialog .cke_hand
 {
 	cursor: pointer;
 }
 
-.cke_skin_office2003 .cke_dialog .centered
+.cke_skin_office2003 .cke_dialog .cke_centered
 {
 	text-align: center;
 }
 
-.cke_skin_office2003 .cke_dialog .BtnReset
+.cke_skin_office2003 .cke_dialog .cke_btn_reset
 {
 	float: right;
 	background-position: 0 -32px;
@@ -504,12 +504,13 @@
 	font-size: 1px;
 }
 
-.cke_skin_office2003 .cke_rtl .cke_dialog .BtnReset
+.cke_skin_office2003 .cke_rtl .cke_dialog .cke_btn_reset
 {
 	float: left;
 }
 
-.cke_skin_office2003 .cke_dialog .BtnLocked, .BtnUnlocked
+.cke_skin_office2003 .cke_dialog .cke_btn_locked,
+.cke_skin_office2003 .cke_dialog .cke_btn_unlocked
 {
 	float: left;
 	background-position: 0 0;
@@ -521,18 +522,19 @@
 	font-size: 1px;
 }
 
-.cke_skin_office2003 .cke_dialog .BtnLocked, .BtnUnlocked
+.cke_skin_office2003 .cke_dialog .cke_btn_locked,
+.cke_skin_office2003 .cke_dialog .cke_btn_unlocked
 {
 	float: right;
 }
 
-.cke_skin_office2003 .cke_dialog .BtnUnlocked
+.cke_skin_office2003 .cke_dialog .cke_btn_unlocked
 {
 	background-position: 0 -16px;
 	background-image: url(images/mini.gif);
 }
 
-.cke_skin_office2003 .cke_dialog .BtnOver
+.cke_skin_office2003 .cke_dialog .cke_btn_over
 {
 	border: outset 1px;
 	cursor: pointer;
@@ -575,26 +577,26 @@
 	background-color : white;
 }
 
-.cke_skin_office2003 .cke_dialog .DarkBackground
+.cke_skin_office2003 .cke_dialog .cke_dark_background
 {
 	text-align : center;
 	background-color: #eaead1;
 	font-size : 14px;
 }
 
-.cke_skin_office2003 .cke_dialog .LightBackground
+.cke_skin_office2003 .cke_dialog .cke_light_background
 {
 	text-align : center;
 	background-color: #ffffbe;
 }
 
-.cke_skin_office2003 .cke_dialog .Hand
+.cke_skin_office2003 .cke_dialog .cke_hand
 {
 	cursor: pointer;
 	cursor: hand;
 }
 
-.cke_skin_office2003 .disabled
+.cke_skin_office2003 .cke_disabled
 {
 	color: #a0a0a0;
 }
