Index: /CKEditor/trunk/_source/core/dom/node.js
===================================================================
--- /CKEditor/trunk/_source/core/dom/node.js	(revision 3531)
+++ /CKEditor/trunk/_source/core/dom/node.js	(revision 3532)
@@ -425,46 +425,49 @@
 				return CKEDITOR.POSITION_IDENTICAL;
 
-			// Handle non element nodes (don't support contains nor sourceIndex).
-			if ( this.type != CKEDITOR.NODE_ELEMENT || otherNode.type != CKEDITOR.NODE_ELEMENT )
-			{
-				if ( $.parentNode == $other )
-					return CKEDITOR.POSITION_IS_CONTAINED + CKEDITOR.POSITION_FOLLOWING;
-				else if ( $other.parentNode == $ )
-					return CKEDITOR.POSITION_CONTAINS + CKEDITOR.POSITION_PRECEDING;
-				else if ( $.parentNode == $other.parentNode )
-					return this.getIndex() < otherNode.getIndex() ? CKEDITOR.POSITION_PRECEDING : CKEDITOR.POSITION_FOLLOWING;
-				else
-				{
-					$ = $.parentNode;
-					$other = $other.parentNode;
+			// Only element nodes support contains and sourceIndex.
+			if ( this.type == CKEDITOR.NODE_ELEMENT && otherNode.type == CKEDITOR.NODE_ELEMENT )
+			{
+				if ( $.contains )
+				{
+					if ( $.contains( $other ) )
+						return CKEDITOR.POSITION_CONTAINS + CKEDITOR.POSITION_PRECEDING;
+
+					if ( $other.contains( $ ) )
+						return CKEDITOR.POSITION_IS_CONTAINED + CKEDITOR.POSITION_FOLLOWING;
 				}
-			}
-
-			if ( $.contains( $other ) )
-				return CKEDITOR.POSITION_CONTAINS + CKEDITOR.POSITION_PRECEDING;
-
-			if ( $other.contains( $ ) )
-				return CKEDITOR.POSITION_IS_CONTAINED + CKEDITOR.POSITION_FOLLOWING;
-
-			if ( 'sourceIndex' in $ )
-			{
-				return ( $.sourceIndex < 0 || $other.sourceIndex < 0 ) ? CKEDITOR.POSITION_DISCONNECTED :
-					( $.sourceIndex < $other.sourceIndex ) ? CKEDITOR.POSITION_PRECEDING :
-					CKEDITOR.POSITION_FOLLOWING;
-			}
-
-			// WebKit has no support for sourceIndex.
-
-			var doc = this.getDocument().$;
-
-			var range1 = doc.createRange();
-			var range2 = doc.createRange();
-
-			range1.selectNode( $ );
-			range2.selectNode( $other );
-
-			return range1.compareBoundaryPoints( 1, range2 ) > 0 ?
-				CKEDITOR.POSITION_FOLLOWING :
-				CKEDITOR.POSITION_PRECEDING;
+
+				if ( 'sourceIndex' in $ )
+				{
+					return ( $.sourceIndex < 0 || $other.sourceIndex < 0 ) ? CKEDITOR.POSITION_DISCONNECTED :
+						( $.sourceIndex < $other.sourceIndex ) ? CKEDITOR.POSITION_PRECEDING :
+						CKEDITOR.POSITION_FOLLOWING;
+				}
+			}
+			
+			// For nodes that don't support compareDocumentPosition, contains
+			// or sourceIndex, their "address" is compared.
+
+			var addressOfThis = this.getAddress(),
+				addressOfOther = otherNode.getAddress(),
+				minLevel = Math.min( addressOfThis.length, addressOfOther.length );
+
+				// Determinate preceed/follow relationship.
+				for ( var i = 0 ; i <= minLevel - 1 ; i++ )
+ 				{
+					if ( addressOfThis[ i ] != addressOfOther[ i ] )
+					{
+						if ( i < minLevel )
+						{
+							return addressOfThis[ i ] < addressOfOther[ i ] ?
+						            CKEDITOR.POSITION_PRECEDING : CKEDITOR.POSITION_FOLLOWING;
+						}
+						break;
+					}
+ 				}
+
+				// Determinate contains/contained relationship.
+				return ( addressOfThis.length < addressOfOther.length ) ?
+							CKEDITOR.POSITION_CONTAINS + CKEDITOR.POSITION_PRECEDING :
+							CKEDITOR.POSITION_IS_CONTAINED + CKEDITOR.POSITION_FOLLOWING;
 		},
 
Index: /CKEditor/trunk/_source/tests/core/dom/node.html
===================================================================
--- /CKEditor/trunk/_source/tests/core/dom/node.html	(revision 3531)
+++ /CKEditor/trunk/_source/tests/core/dom/node.html	(revision 3532)
@@ -10,6 +10,6 @@
 	<script type="text/javascript">
 	//<![CDATA[
-
-CKEDITOR.test.addTestCase( (function()
+var tc;
+CKEDITOR.test.addTestCase( tc = (function()
 {
 	// Local reference to the "assert" object.
@@ -69,5 +69,4 @@
 			var node1 = new CKEDITOR.dom.node( document.getElementsByTagName( 'h1' )[0] );
 			var node2 = new CKEDITOR.dom.node( document.getElementsByTagName( 'h1' )[0].firstChild );
-
 			assert.areSame( CKEDITOR.POSITION_IS_CONTAINED + CKEDITOR.POSITION_FOLLOWING, node2.getPosition( node1 ) );
 		},
@@ -105,4 +104,15 @@
 		},
 
+		/**
+		 *  Test 'preceding' position.
+		 */
+		test_getPosition_3240: function()
+		{
+			var node1 = new CKEDITOR.dom.node( document.getElementsByTagName( 'b' )[0].firstChild );
+			var node2 = new CKEDITOR.dom.node( document.getElementsByTagName( 'span' )[0].firstChild );
+
+			assert.areSame( CKEDITOR.POSITION_PRECEDING, node1.getPosition( node2 ) );
+		},
+
 		name : document.title
 	};
@@ -116,5 +126,5 @@
 //	alert( node1.getPosition( node2 ) );
 //};
-
+//window.onload =  tc.test_getPosition6;
 	//]]>
 	</script>
@@ -125,4 +135,5 @@
 		<p><b>Sample</b> <i>Text</i></p>
 	</div>
+	<span>Another</span>
 </body>
 </html>
