Index: CKEditor/releases/latest/_source/plugins/tab/plugin.js
===================================================================
--- CKEditor/releases/latest/_source/plugins/tab/plugin.js	(revision 4887)
+++ CKEditor/releases/latest/_source/plugins/tab/plugin.js	(revision 5194)
@@ -6,9 +6,15 @@
 (function()
 {
+	var meta =
+	{
+		editorFocus : false,
+		modes : { wysiwyg:1, source:1 }
+	};
+
 	var blurCommand =
 		{
 			exec : function( editor )
 			{
-				editor.container.focusNext( true );
+				editor.container.focusNext( true, editor.tabIndex );
 			}
 		};
@@ -18,5 +24,5 @@
 			exec : function( editor )
 			{
-				editor.container.focusPrevious( true );
+				editor.container.focusPrevious( true, editor.tabIndex );
 			}
 		};
@@ -28,10 +34,5 @@
 		init : function( editor )
 		{
-			// Register the keystrokes.
-			var keystrokes = editor.keystrokeHandler.keystrokes;
-			keystrokes[ 9 /* TAB */ ] = 'tab';
-			keystrokes[ CKEDITOR.SHIFT + 9 /* TAB */ ] = 'shiftTab';
-
-			var tabSpaces = editor.config.tabSpaces,
+			var tabSpaces = editor.config.tabSpaces || 0,
 				tabText = '';
 
@@ -39,44 +40,38 @@
 				tabText += '\xa0';
 
-			// Register the "tab" and "shiftTab" commands.
-			editor.addCommand( 'tab',
-				{
-					exec : function( editor )
+			if ( tabText )
+			{
+				editor.on( 'key', function( ev )
 					{
-						// Fire the "tab" event, making it possible to
-						// customize the TAB key behavior on specific cases.
-						if ( !editor.fire( 'tab' ) )
+						if ( ev.data.keyCode == 9 )	// TAB
 						{
-							if ( tabText.length > 0 )
-								editor.insertHtml( tabText );
-							else
-							{
-								// All browsers jump to the next field on TAB,
-								// except Safari, so we have to do that manually
-								// here.
-								/// https://bugs.webkit.org/show_bug.cgi?id=20597
-								return editor.execCommand( 'blur' );
-							}
+							editor.insertHtml( tabText );
+							ev.cancel();
 						}
-
-						return true;
-					}
-				});
-
-			editor.addCommand( 'shiftTab',
-				{
-					exec : function( editor )
+					});
+			}
+
+			if ( CKEDITOR.env.webkit )
+			{
+				editor.on( 'key', function( ev )
 					{
-						// Fire the "tab" event, making it possible to
-						// customize the TAB key behavior on specific cases.
-						if ( !editor.fire( 'shiftTab' ) )
-							return editor.execCommand( 'blurBack' );
-
-						return true;
-					}
-				});
-
-			editor.addCommand( 'blur', blurCommand );
-			editor.addCommand( 'blurBack', blurBackCommand );
+						var keyCode = ev.data.keyCode;
+
+						if ( keyCode == 9 && !tabText )				// TAB
+						{
+							ev.cancel();
+							editor.execCommand( 'blur' );
+						}
+
+						if ( keyCode == ( CKEDITOR.SHIFT + 9 ) )	// SHIFT+TAB
+						{
+							editor.execCommand( 'blurBack' );
+							ev.cancel();
+						}
+					});
+			}
+
+			editor.addCommand( 'blur', CKEDITOR.tools.extend( blurCommand, meta ) );
+			editor.addCommand( 'blurBack', CKEDITOR.tools.extend( blurBackCommand, meta ) );
 		}
 	});
@@ -90,8 +85,8 @@
  * element.focusNext();
  */
-CKEDITOR.dom.element.prototype.focusNext = function( ignoreChildren )
+CKEDITOR.dom.element.prototype.focusNext = function( ignoreChildren, indexToUse )
 {
 	var $ = this.$,
-		curTabIndex = this.getTabIndex(),
+		curTabIndex = ( indexToUse === undefined ? this.getTabIndex() : indexToUse ),
 		passedCurrent, enteredCurrent,
 		elected, electedTabIndex,
@@ -105,5 +100,5 @@
 		element = this.getNextSourceNode( ignoreChildren, CKEDITOR.NODE_ELEMENT );
 
-		while( element )
+		while ( element )
 		{
 			if ( element.isVisible() && element.getTabIndex() === 0 )
@@ -126,5 +121,5 @@
 		element = this.getDocument().getBody().getFirst();
 
-		while( ( element = element.getNextSourceNode( false, CKEDITOR.NODE_ELEMENT ) ) )
+		while ( ( element = element.getNextSourceNode( false, CKEDITOR.NODE_ELEMENT ) ) )
 		{
 			if ( !passedCurrent )
@@ -178,8 +173,8 @@
  * element.focusPrevious();
  */
-CKEDITOR.dom.element.prototype.focusPrevious = function( ignoreChildren )
+CKEDITOR.dom.element.prototype.focusPrevious = function( ignoreChildren, indexToUse )
 {
 	var $ = this.$,
-		curTabIndex = this.getTabIndex(),
+		curTabIndex = ( indexToUse === undefined ? this.getTabIndex() : indexToUse ),
 		passedCurrent, enteredCurrent,
 		elected,
@@ -189,5 +184,5 @@
 	var element = this.getDocument().getBody().getLast();
 
-	while( ( element = element.getPreviousSourceNode( false, CKEDITOR.NODE_ELEMENT ) ) )
+	while ( ( element = element.getPreviousSourceNode( false, CKEDITOR.NODE_ELEMENT ) ) )
 	{
 		if ( !passedCurrent )
@@ -259,4 +254,5 @@
  * hitting the TAB key. If set to zero, the TAB key will be used to move the
  * cursor focus to the next element in the page, out of the editor focus.
+ * @name CKEDITOR.config.tabSpaces
  * @type Number
  * @default 0
@@ -264,3 +260,2 @@
  * config.tabSpaces = 4;
  */
-CKEDITOR.config.tabSpaces = 0 ;
