Ticket #3240: 3240_3.patch
File 3240_3.patch, 6.2 KB (added by , 16 years ago) |
---|
-
core/dom/node.js
413 413 414 414 getPosition : function( otherNode ) 415 415 { 416 var $ = this.$; 417 var $other = otherNode.$; 416 function standard( a, b ){ 417 return a.compareDocumentPosition ? 418 a.compareDocumentPosition( b ) : 419 a.contains ? 420 ( a != b && a.contains( b ) && CKEDITOR.POSITION_CONTAINS ) + 421 ( a != b && b.contains( a ) && CKEDITOR.POSITION_IS_CONTAINED ) + 422 ( a.sourceIndex >= 0 && b.sourceIndex >= 0 ? 423 ( a.sourceIndex < b.sourceIndex && CKEDITOR.POSITION_PRECEDING ) + 424 ( a.sourceIndex > b.sourceIndex && CKEDITOR.POSITION_FOLLOWING ) : 425 CKEDITOR.POSITION_DISCONNECTED ) + 426 CKEDITOR.POSITION_IDENTICAL : 427 CKEDITOR.POSITION_IDENTICAL; 428 } 418 429 419 if ( $.compareDocumentPosition ) 420 return $.compareDocumentPosition( $other ); 421 422 // IE and Safari have no support for compareDocumentPosition. 423 424 if ( $ == $other ) 425 return CKEDITOR.POSITION_IDENTICAL; 426 427 // Handle non element nodes (don't support contains nor sourceIndex). 428 if ( this.type != CKEDITOR.NODE_ELEMENT || otherNode.type != CKEDITOR.NODE_ELEMENT ) 430 var hasSupportOn = CKEDITOR.env.support.compareDocumentPositionOn; 431 if ( hasSupportOn( this ) && hasSupportOn( otherNode ) ) 432 return standard( this.$, otherNode.$ ); 433 else 429 434 { 430 if ( $.parentNode == $other ) 431 return CKEDITOR.POSITION_IS_CONTAINED + CKEDITOR.POSITION_FOLLOWING; 432 else if ( $other.parentNode == $ ) 433 return CKEDITOR.POSITION_CONTAINS + CKEDITOR.POSITION_PRECEDING; 434 else if ( $.parentNode == $other.parentNode ) 435 return this.getIndex() < otherNode.getIndex() ? CKEDITOR.POSITION_PRECEDING : CKEDITOR.POSITION_FOLLOWING; 436 else 435 var addressOfThis = this.getAddress(), 436 addressOfOther = otherNode.getAddress(), 437 minLevel = Math.min( addressOfThis.length, addressOfOther.length ), 438 maxLevel = Math.max ( addressOfThis.length, addressOfOther.length ), 439 position = 0; 440 441 // Determinate preceed/follow relationship. 442 for ( var i = 0; i <= minLevel - 1 ; i++ ) 437 443 { 438 $ = $.parentNode; 439 $other = $other.parentNode; 444 if ( addressOfThis[ i ] != addressOfOther[ i ] ) 445 { 446 position = addressOfThis[ i ] < addressOfOther[ i ] ? 447 CKEDITOR.POSITION_PRECEDING : CKEDITOR.POSITION_FOLLOWING; 448 break; 449 } 440 450 } 441 }442 451 443 if ( $.contains( $other ) ) 444 return CKEDITOR.POSITION_CONTAINS + CKEDITOR.POSITION_PRECEDING; 445 446 if ( $other.contains( $ ) ) 447 return CKEDITOR.POSITION_IS_CONTAINED + CKEDITOR.POSITION_FOLLOWING; 448 449 if ( 'sourceIndex' in $ ) 450 { 451 return ( $.sourceIndex < 0 || $other.sourceIndex < 0 ) ? CKEDITOR.POSITION_DISCONNECTED : 452 ( $.sourceIndex < $other.sourceIndex ) ? CKEDITOR.POSITION_PRECEDING : 453 CKEDITOR.POSITION_FOLLOWING; 452 // Determinate contains/contained relationship. 453 position = ( i < minLevel ) ? position : 454 ( minLevel == maxLevel ? CKEDITOR.POSITION_IDENTICAL : 455 ( addressOfThis.length < addressOfOther.length ? 456 CKEDITOR.POSITION_CONTAINS + CKEDITOR.POSITION_PRECEDING : 457 CKEDITOR.POSITION_IS_CONTAINED + CKEDITOR.POSITION_FOLLOWING ) ); 458 return position; 454 459 } 455 456 // WebKit has no support for sourceIndex.457 458 var doc = this.getDocument().$;459 460 var range1 = doc.createRange();461 var range2 = doc.createRange();462 463 range1.selectNode( $ );464 range2.selectNode( $other );465 466 return range1.compareBoundaryPoints( 1, range2 ) > 0 ?467 CKEDITOR.POSITION_FOLLOWING :468 CKEDITOR.POSITION_PRECEDING;469 460 }, 470 461 471 462 /** -
core/env.js
192 192 if ( env.gecko && version < 10900 ) 193 193 env.cssClass += ' cke_browser_gecko18'; 194 194 195 // Feature detections below for capabilities of certain native API 196 // we rely on. 197 env.support = 198 { 199 //1. DOMNode.compareDocumentPosition is completely available in Firefox and Opera. 200 //2. IE doesn't support .contains() and .sourceIndex property on any DOM element type node. 201 //3. Webkit support only .contains() but no .sourceIndex. 202 compareDocumentPositionOn : function( node ) 203 { 204 return env.gecko || env.opera || ( env.ie && node.type == CKEDITOR.NODE_ELEMENT ); 205 } 206 }; 195 207 return env; 196 208 })(); 197 209 } -
tests/core/dom/node.html
9 9 <script type="text/javascript" src="../../test.js"></script> 10 10 <script type="text/javascript"> 11 11 //<![CDATA[ 12 13 CKEDITOR.test.addTestCase( (function()12 var tc; 13 CKEDITOR.test.addTestCase( tc = (function() 14 14 { 15 15 // Local reference to the "assert" object. 16 16 var assert = CKEDITOR.test.assert; … … 68 68 { 69 69 var node1 = new CKEDITOR.dom.node( document.getElementsByTagName( 'h1' )[0] ); 70 70 var node2 = new CKEDITOR.dom.node( document.getElementsByTagName( 'h1' )[0].firstChild ); 71 72 71 assert.areSame( CKEDITOR.POSITION_IS_CONTAINED + CKEDITOR.POSITION_FOLLOWING, node2.getPosition( node1 ) ); 73 72 }, 74 73 … … 104 103 assert.areSame( CKEDITOR.POSITION_FOLLOWING, node2.getPosition( node1 ) ); 105 104 }, 106 105 106 /** 107 * Test 'preceding' position. 108 */ 109 test_getPosition_3240: function() 110 { 111 var node1 = new CKEDITOR.dom.node( document.getElementsByTagName( 'b' )[0].firstChild ); 112 var node2 = new CKEDITOR.dom.node( document.getElementsByTagName( 'span' )[0].firstChild ); 113 114 assert.areSame( CKEDITOR.POSITION_PRECEDING, node1.getPosition( node2 ) ); 115 }, 116 107 117 name : document.title 108 118 }; 109 119 })() ); … … 115 125 // 116 126 // alert( node1.getPosition( node2 ) ); 117 127 //}; 118 128 //window.onload = tc.test_getPosition6; 119 129 //]]> 120 130 </script> 121 131 </head> … … 124 134 <h1>Title</h1> 125 135 <p><b>Sample</b> <i>Text</i></p> 126 136 </div> 137 <span>Another</span> 127 138 </body> 128 139 </html>