Index: /CKEditor/trunk/_source/core/dom/range.js
===================================================================
--- /CKEditor/trunk/_source/core/dom/range.js	(revision 3351)
+++ /CKEditor/trunk/_source/core/dom/range.js	(revision 3352)
@@ -260,16 +260,19 @@
 	var inlineChildReqElements = { abbr:1,acronym:1,b:1,bdo:1,big:1,cite:1,code:1,del:1,dfn:1,em:1,font:1,i:1,ins:1,label:1,kbd:1,q:1,samp:1,small:1,span:1,strike:1,strong:1,sub:1,sup:1,tt:1,u:1,'var':1 };
 
-	// Check every node between the block boundary and the startNode or endNode.
-	var getCheckStartEndBlockFunction = function( isStart )
+	// Creates the appropriate node evaluator for the dom walker used inside
+	// check(Start|End)OfBlock.
+	function getCheckStartEndBlockEvalFunction( isStart )
 	{
-		return function( evt )
-		{
-			// Don't check the block boundary itself.
-			if ( this.stopped() || !evt.data.node )
-				return;
-
-			var node = evt.data.node,
-				hadBr = false;
-			if ( node.type == CKEDITOR.NODE_ELEMENT )
+		return function( node )
+		{
+			var hadBr = false;
+
+			if ( node.type == CKEDITOR.NODE_TEXT )
+			{
+				// If there's any visible text, then we're not at the start.
+				if ( CKEDITOR.tools.trim( node.getText() ).length )
+					return false;
+			}
+			else
 			{
 				// If there are non-empty inline elements (e.g. <img />), then we're not
@@ -281,23 +284,9 @@
 						hadBr = true;
 					else
-					{
-						this.checkFailed = true;
-						this.stop();
-					}
-				}
-			}
-			else if ( node.type == CKEDITOR.NODE_TEXT )
-			{
-				// If there's any visible text, then we're not at the start.
-				var visibleText = CKEDITOR.tools.trim( node.getText() );
-				if ( visibleText.length > 0 )
-				{
-					this.checkFailed = true;
-					this.stop();
+						return false;
 				}
 			}
 		};
-	};
-
+	}
 
 	CKEDITOR.dom.range.prototype =
@@ -1416,23 +1405,41 @@
 		{
 			var startContainer = this.startContainer,
-				startOffset = this.startOffset;
-
-			// If the starting node is a text node, and non-empty before the offset,
-			// then we're surely not at the start of block.
-			if ( startContainer.type == CKEDITOR.NODE_TEXT )
-			{
-				var textBefore = CKEDITOR.tools.ltrim( startContainer.getText().substr( 0, startOffset ) );
-				if ( textBefore.length > 0 )
-					return false;
-			}
-
-			var startNode = this.getBoundaryNodes().startNode,
-				walker = new CKEDITOR.dom.domWalker( startNode );
-
-			// DFS backwards until the block boundary, with the checker function.
-			walker.on( 'step', getCheckStartEndBlockFunction( true ), null, null, 20 );
-			walker.reverse( CKEDITOR.dom.domWalker.blockBoundary() );
-
-			return !walker.checkFailed;
+				startOffset = this.startOffset,
+				startNode,
+				startInclusive;
+
+			if ( startOffset )
+			{
+				// If the starting node is a text node, and non-empty before the offset,
+				// then we're surely not at the start of block.
+				if ( startContainer.type == CKEDITOR.NODE_TEXT )
+				{
+					var textBefore = CKEDITOR.tools.ltrim( startContainer.substring( 0, startOffset ) );
+					if ( textBefore.length )
+						return false;
+				}
+				else
+				{
+					startNode = startContainer.getChild( startOffset - 1 );
+					startInclusive = true;
+				}
+			}
+			
+			if ( !startNode )
+				startNode = startContainer;
+
+			var path	= new CKEDITOR.dom.elementPath( startNode ),
+				walker	= new CKEDITOR.dom.walker( startNode, ( path.block || path.blockLimit ) );
+
+			if ( ( path.block && startNode.equals( path.block ) ) 
+				|| ( !path.block && startNode.equals( path.blockLimit ) ) )
+			{
+				return true;
+			}
+
+			walker.startInclusive = startInclusive;
+			walker.evaluator = getCheckStartEndBlockEvalFunction( true );
+			
+			return walker.checkBackward();
 		},
 
@@ -1440,5 +1447,7 @@
 		{
 			var endContainer = this.endContainer,
-				endOffset = this.endOffset;
+				endOffset = this.endOffset,
+				startNode,
+				startInclusive;
 
 			// If the ending node is a text node, and non-empty after the offset,
@@ -1446,17 +1455,30 @@
 			if ( endContainer.type == CKEDITOR.NODE_TEXT )
 			{
-				var textAfter = CKEDITOR.tools.rtrim( endContainer.getText().substr( endOffset ) );
-				if ( textAfter.length > 0 )
+				var textAfter = CKEDITOR.tools.rtrim( endContainer.substring( endOffset ) );
+				if ( textAfter.length )
 					return false;
 			}
-
-			var endNode = this.getBoundaryNodes().endNode,
-				walker = new CKEDITOR.dom.domWalker( endNode );
-
-			// DFS forward until the block boundary, with the checker function.
-			walker.on( 'step', getCheckStartEndBlockFunction( false ), null, null, 20 );
-			walker.forward( CKEDITOR.dom.domWalker.blockBoundary() );
-
-			return !walker.checkFailed;
+			else
+			{
+				startNode = endContainer.getChild( endOffset );
+				startInclusive = !!startNode;
+			}
+
+			if ( !startNode )
+				startNode = endContainer;
+
+			var path	= new CKEDITOR.dom.elementPath( startNode ),
+				walker	= new CKEDITOR.dom.walker( startNode, ( path.block || path.blockLimit ) );
+
+			if ( ( path.block && startNode.equals( path.block ) ) 
+				|| ( !path.block && startNode.equals( path.blockLimit ) ) )
+			{
+				return true;
+			}
+
+			walker.startInclusive = startInclusive;
+			walker.evaluator = getCheckStartEndBlockEvalFunction( false );
+			
+			return walker.checkForward();
 		},
 
Index: /CKEditor/trunk/_source/tests/core/dom/range.html
===================================================================
--- /CKEditor/trunk/_source/tests/core/dom/range.html	(revision 3351)
+++ /CKEditor/trunk/_source/tests/core/dom/range.html	(revision 3352)
@@ -1604,4 +1604,222 @@
 			assert.areSame( 5, range.endOffset, 'range.endOffset' );
 			assert.isFalse( range.collapsed, 'range.collapsed' );
+		},
+		
+		test_checkStartOfBlock1 : function()
+		{
+			var p = doc.getById( 'playground' );
+			p.setHtml( '<p>Test</p>' );
+			p = p.getFirst();
+
+			var range = new CKEDITOR.dom.range( doc );
+
+			range.setStartAt( p, CKEDITOR.POSITION_AFTER_START );
+			range.collapse( true );
+			
+			assert.isTrue( range.checkStartOfBlock() );
+		},
+
+		test_checkStartOfBlock2 : function()
+		{
+			var p = doc.getById( 'playground' );
+			p.setHtml( '<p>Test</p>' );
+			p = p.getFirst();
+
+			var range = new CKEDITOR.dom.range( doc );
+
+			range.setStartAt( p, CKEDITOR.POSITION_BEFORE_END );
+			range.collapse( true );
+			
+			assert.isFalse( range.checkStartOfBlock() );
+		},
+
+		test_checkStartOfBlock3 : function()
+		{
+			var p = doc.getById( 'playground' );
+			p.setHtml( '<p>Test</p>' );
+			p = p.getFirst();
+
+			var range = new CKEDITOR.dom.range( doc );
+
+			range.setStartAt( p.getFirst(), CKEDITOR.POSITION_AFTER_START );
+			range.collapse( true );
+			
+			assert.isTrue( range.checkStartOfBlock() );
+		},
+
+		test_checkStartOfBlock4 : function()
+		{
+			var p = doc.getById( 'playground' );
+			p.setHtml( '<p>Test</p>' );
+			p = p.getFirst();
+
+			var range = new CKEDITOR.dom.range( doc );
+
+			range.setStartAt( p.getFirst(), CKEDITOR.POSITION_BEFORE_END );
+			range.collapse( true );
+			
+			assert.isFalse( range.checkStartOfBlock() );
+		},
+
+		test_checkStartOfBlock5 : function()
+		{
+			var el = doc.getById( 'playground' );
+			el.setHtml( '<p> Test </p>' );
+			el = el.getFirst().getFirst();
+
+			var range = new CKEDITOR.dom.range( doc );
+
+			// IE trims the space in the beginning of text nodes in our case.
+			// So, let's just check it and make it pass.
+			range.setStart( el, ( el.substring( 0, 1 ) == 'T' ) ? 0 : 1 );
+			range.collapse( true );
+			
+			assert.isTrue( range.checkStartOfBlock() );
+		},
+
+		test_checkStartOfBlock6 : function()
+		{
+			var p = doc.getById( 'playground' );
+			p.setHtml( '<p> Test </p>' );
+			p = p.getFirst();
+
+			var range = new CKEDITOR.dom.range( doc );
+
+			range.setStart( p.getFirst(), 5 );
+			range.collapse( true );
+			
+			assert.isFalse( range.checkStartOfBlock() );
+		},
+
+		test_checkStartOfBlock7 : function()
+		{
+			var el = doc.getById( 'playground' );
+			el.setHtml( '<p><b>Test</b></p>' );
+			el = el.getFirst().getFirst();
+
+			var range = new CKEDITOR.dom.range( doc );
+			range.selectNodeContents( el );
+			
+			assert.isTrue( range.checkStartOfBlock() );
+		},
+
+		test_checkStartOfBlock8 : function()
+		{
+			var el = doc.getById( 'playground' );
+			el.setHtml( '<p>A<b>Test</b>B</p>' );
+			el = el.getFirst().getFirst().getNext();
+
+			var range = new CKEDITOR.dom.range( doc );
+			range.selectNodeContents( el );
+			
+			assert.isFalse( range.checkStartOfBlock() );
+		},
+
+		test_checkEndOfBlock1 : function()
+		{
+			var p = doc.getById( 'playground' );
+			p.setHtml( '<p>Test</p>' );
+			p = p.getFirst();
+
+			var range = new CKEDITOR.dom.range( doc );
+
+			range.setStartAt( p, CKEDITOR.POSITION_AFTER_START );
+			range.collapse( true );
+			
+			assert.isFalse( range.checkEndOfBlock() );
+		},
+
+		test_checkEndOfBlock2 : function()
+		{
+			var p = doc.getById( 'playground' );
+			p.setHtml( '<p>Test</p>' );
+			p = p.getFirst();
+
+			var range = new CKEDITOR.dom.range( doc );
+
+			range.setStartAt( p, CKEDITOR.POSITION_BEFORE_END );
+			range.collapse( true );
+			
+			assert.isTrue( range.checkEndOfBlock() );
+		},
+
+		test_checkEndOfBlock3 : function()
+		{
+			var p = doc.getById( 'playground' );
+			p.setHtml( '<p>Test</p>' );
+			p = p.getFirst();
+
+			var range = new CKEDITOR.dom.range( doc );
+
+			range.setStartAt( p.getFirst(), CKEDITOR.POSITION_AFTER_START );
+			range.collapse( true );
+			
+			assert.isFalse( range.checkEndOfBlock() );
+		},
+
+		test_checkEndOfBlock4 : function()
+		{
+			var p = doc.getById( 'playground' );
+			p.setHtml( '<p>Test</p>' );
+			p = p.getFirst();
+
+			var range = new CKEDITOR.dom.range( doc );
+
+			range.setStartAt( p.getFirst(), CKEDITOR.POSITION_BEFORE_END );
+			range.collapse( true );
+			
+			assert.isTrue( range.checkEndOfBlock() );
+		},
+
+		test_checkEndOfBlock5 : function()
+		{
+			var p = doc.getById( 'playground' );
+			p.setHtml( '<p> Test </p>' );
+			p = p.getFirst();
+
+			var range = new CKEDITOR.dom.range( doc );
+
+			range.setStart( p.getFirst(), 1 );
+			range.collapse( true );
+			
+			assert.isFalse( range.checkEndOfBlock() );
+		},
+
+		test_checkEndOfBlock6 : function()
+		{
+			var p = doc.getById( 'playground' );
+			p.setHtml( '<p> Test </p>' );
+			p = p.getFirst();
+
+			var range = new CKEDITOR.dom.range( doc );
+
+			range.setStart( p.getFirst(), 5 );
+			range.collapse( true );
+			
+			assert.isTrue( range.checkEndOfBlock() );
+		},
+
+		test_checkEndOfBlock7 : function()
+		{
+			var el = doc.getById( 'playground' );
+			el.setHtml( '<p><b>Test</b></p>' );
+			el = el.getFirst().getFirst();
+
+			var range = new CKEDITOR.dom.range( doc );
+			range.selectNodeContents( el );
+			
+			assert.isTrue( range.checkEndOfBlock() );
+		},
+
+		test_checkEndOfBlock8 : function()
+		{
+			var el = doc.getById( 'playground' );
+			el.setHtml( '<p>A<b>Test</b>B</p>' );
+			el = el.getFirst().getFirst().getNext();
+
+			var range = new CKEDITOR.dom.range( doc );
+			range.selectNodeContents( el );
+			
+			assert.isFalse( range.checkEndOfBlock() );
 		},
 
