Changeset 3065
- Timestamp:
- 02/17/09 12:15:24 (4 years ago)
- Location:
- CKEditor/trunk/_source
- Files:
-
- 4 edited
-
core/dom/document.js (modified) (1 diff)
-
core/dom/node.js (modified) (1 diff)
-
core/dom/range.js (modified) (1 diff)
-
tests/core/dom/range.html (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
CKEditor/trunk/_source/core/dom/document.js
r2948 r3065 88 88 }, 89 89 90 getByAddress : function( address, normalized ) 91 { 92 var $ = this.$.documentElement; 93 94 for ( var i = 0 ; $ && i < address.length ; i++ ) 95 { 96 var target = address[ i ]; 97 98 if ( !normalized ) 99 { 100 $ = $.childNodes[ target ]; 101 continue; 102 } 103 104 var currentIndex = -1; 105 106 for (var j = 0 ; j < $.childNodes.length ; j++ ) 107 { 108 var candidate = $.childNodes[ j ]; 109 110 if ( normalized === true && 111 candidate.nodeType == 3 && 112 candidate.previousSibling && 113 candidate.previousSibling.nodeType == 3 ) 114 { 115 continue; 116 } 117 118 currentIndex++; 119 120 if ( currentIndex == target ) 121 { 122 $ = candidate; 123 break; 124 } 125 } 126 } 127 128 return $ ? new CKEDITOR.dom.node( $ ) : null; 129 }, 130 90 131 /** 91 132 * Gets the <head> element for this document. -
CKEditor/trunk/_source/core/dom/node.js
r3051 r3065 150 150 151 151 /** 152 * Retrieves a uniquely identifiable tree address for this node. 153 * The tree address returns is an array of integers, with each integer 154 * indicating a child index of a DOM node, starting from 155 * document.documentElement. 156 * 157 * For example, assuming <body> is the second child from <html> (<head> 158 * being the first), and we'd like to address the third child under the 159 * fourth child of body, the tree address returned would be: 160 * [1, 3, 2] 161 * 162 * The tree address cannot be used for finding back the DOM tree node once 163 * the DOM tree structure has been modified. 164 */ 165 getAddress : function( normalized ) 166 { 167 var address = []; 168 var $documentElement = this.getDocument().$.documentElement; 169 var node = this.$; 170 171 while ( node && node != $documentElement ) 172 { 173 var parentNode = node.parentNode; 174 var currentIndex = -1; 175 176 for ( var i = 0 ; i < parentNode.childNodes.length ; i++ ) 177 { 178 var candidate = parentNode.childNodes[i]; 179 180 if ( normalized && 181 candidate.nodeType == 3 && 182 candidate.previousSibling && 183 candidate.previousSibling.nodeType == 3 ) 184 { 185 continue; 186 } 187 188 currentIndex++; 189 190 if ( candidate == node ) 191 break; 192 } 193 194 address.unshift( currentIndex ); 195 196 node = node.parentNode; 197 } 198 199 return address; 200 }, 201 202 /** 152 203 * Gets a DOM tree descendant under the current node. 153 204 * @param {Array|Number} indices The child index or array of child indices under the node. -
CKEditor/trunk/_source/core/dom/range.js
r3059 r3065 430 430 }, 431 431 432 /** 433 * Creates a "non intrusive" and "mutation sensible" bookmark. This 434 * kind of bookmark should be used only when the DOM is supposed to 435 * remain stable after its creation. 436 * @param {Boolean} [normalized] Indicates that the bookmark must 437 * normalized. When normalized, the successive text nodes are 438 * considered a single node. To sucessful load a normalized 439 * bookmark, the DOM tree must be also normalized before calling 440 * moveToBookmark. 441 * @returns {Object} An object representing the bookmark. 442 */ 443 createBookmark2 : function( normalized ) 444 { 445 var startContainer = this.startContainer, 446 endContainer = this.endContainer; 447 448 var startOffset = this.startOffset, 449 endOffset = this.endOffset; 450 451 var child, previous; 452 453 // If there is no range then get out of here. 454 // It happens on initial load in Safari #962 and if the editor it's 455 // hidden also in Firefox 456 if ( !startContainer || !endContainer ) 457 return { start : 0, end : 0 }; 458 459 if ( normalized ) 460 { 461 // Find out if the start is pointing to a text node that will 462 // be normalized. 463 if ( startContainer.type == CKEDITOR.NODE_ELEMENT ) 464 { 465 var child = startContainer.getChild( startOffset ); 466 467 // In this case, move the start information to that text 468 // node. 469 if ( child && child.type == CKEDITOR.NODE_TEXT && child.getPrevious().type == CKEDITOR.NODE_TEXT ) 470 { 471 startContainer = child; 472 startOffset = 0; 473 } 474 } 475 476 // Normalize the start. 477 while ( startContainer.type == CKEDITOR.NODE_TEXT 478 && ( previous = startContainer.getPrevious() ) 479 && previous.type == CKEDITOR.NODE_TEXT ) 480 { 481 startContainer = previous; 482 startOffset += previous.getLength(); 483 } 484 485 // Process the end only if not normalized. 486 if ( !this.isCollapsed ) 487 { 488 // Find out if the start is pointing to a text node that 489 // will be normalized. 490 if ( endContainer.type == CKEDITOR.NODE_ELEMENT ) 491 { 492 child = endContainer.getChild( endOffset ); 493 494 // In this case, move the start information to that 495 // text node. 496 if ( child && child.type == CKEDITOR.NODE_TEXT && child.getPrevious().type == CKEDITOR.NODE_TEXT ) 497 { 498 endContainer = child; 499 endOffset = 0; 500 } 501 } 502 503 // Normalize the end. 504 while ( endContainer.type == CKEDITOR.NODE_TEXT 505 && ( previous = endContainer.getPrevious() ) 506 && previous.type == CKEDITOR.NODE_TEXT ) 507 { 508 endContainer = previous; 509 endOffset += previous.getLength(); 510 } 511 } 512 } 513 514 return { 515 start : startContainer.getAddress( normalized ), 516 end : this.isCollapsed ? null : endContainer.getAddress( normalized ), 517 startOffset : startOffset, 518 endOffset : endOffset, 519 normalized : normalized, 520 is2 : true // It's a createBookmark2 bookmark. 521 }; 522 }, 523 432 524 moveToBookmark : function( bookmark ) 433 525 { 434 var serializable = bookmark.serializable, 435 startNode = serializable ? this.document.getById( bookmark.startNode ) : bookmark.startNode, 436 endNode = serializable ? this.document.getById( bookmark.endNode ) : bookmark.endNode; 437 438 // Set the range start at the bookmark start node position. 439 this.setStartBefore( startNode ); 440 441 // Remove it, because it may interfere in the setEndBefore call. 442 startNode.remove(); 443 444 // Set the range end at the bookmark end node position, or simply 445 // collapse it if it is not available. 446 if ( endNode ) 447 { 448 this.setEndBefore( endNode ); 449 endNode.remove(); 450 } 451 else 452 this.collapse( true ); 526 if ( bookmark.is2 ) // Created with createBookmark2(). 527 { 528 // Get the start information. 529 var startContainer = this.document.getByAddress( bookmark.start, bookmark.normalized ), 530 startOffset = bookmark.startOffset; 531 532 // Get the end information. 533 var endContainer = bookmark.end && this.document.getByAddress( bookmark.end, bookmark.normalized ), 534 endOffset = bookmark.endOffset; 535 536 // Set the start boundary. 537 this.setStart( startContainer, startOffset ); 538 539 // Set the end boundary. If not available, collapse it. 540 if ( endContainer ) 541 this.setEnd( endContainer, endOffset ); 542 else 543 this.collapse( true ); 544 } 545 else // Created with createBookmark(). 546 { 547 var serializable = bookmark.serializable, 548 startNode = serializable ? this.document.getById( bookmark.startNode ) : bookmark.startNode, 549 endNode = serializable ? this.document.getById( bookmark.endNode ) : bookmark.endNode; 550 551 // Set the range start at the bookmark start node position. 552 this.setStartBefore( startNode ); 553 554 // Remove it, because it may interfere in the setEndBefore call. 555 startNode.remove(); 556 557 // Set the range end at the bookmark end node position, or simply 558 // collapse it if it is not available. 559 if ( endNode ) 560 { 561 this.setEndBefore( endNode ); 562 endNode.remove(); 563 } 564 else 565 this.collapse( true ); 566 } 453 567 }, 454 568 -
CKEditor/trunk/_source/tests/core/dom/range.html
r3017 r3065 12 12 13 13 var html1, html2; 14 var tests; 14 15 15 16 CKEDITOR.test.addTestCase( (function() … … 21 22 var doc = new CKEDITOR.dom.document( document ); 22 23 23 return {24 return tests = { 24 25 test__constructor : function() 25 26 { … … 1511 1512 }, 1512 1513 1514 test_createBookmark2_1 : function() 1515 { 1516 doc.getById( 'playground' ).setHtml( '<p id="P">This is <b id="B">a test</b></p>' ); 1517 1518 var range = new CKEDITOR.dom.range( doc ); 1519 1520 range.setStart( doc.getById( 'P' ), 0 ); 1521 range.setEnd( doc.getById( 'B' ).getFirst(), 3 ); 1522 1523 var bookmark = range.createBookmark2(); 1524 1525 range = new CKEDITOR.dom.range( doc ); 1526 range.moveToBookmark( bookmark ); 1527 1528 assert.areSame( document.getElementById('P'), range.startContainer.$, 'range.startContainer' ); 1529 assert.areSame( 0, range.startOffset, 'range.startOffset' ); 1530 assert.areSame( document.getElementById('B').firstChild, range.endContainer.$, 'range.endContainer' ); 1531 assert.areSame( 3, range.endOffset, 'range.endOffset' ); 1532 assert.isFalse( range.collapsed, 'range.collapsed' ); 1533 }, 1534 1535 // This test is just like test_createBookmark2_3, but uses a "non 1536 // normalized" bookmark. 1537 test_createBookmark2_2 : function() 1538 { 1539 var html = '<p id="P">A B <b>C </b>D E</p>'; 1540 1541 doc.getById( 'playground' ).setHtml( html ); 1542 1543 var p = doc.getById( 'P' ); 1544 1545 // Split the text nodes. 1546 p.getFirst().split( 2 ); // Right before "B" 1547 p.getChild( 3 ).split( 2 ); // Right before "E" 1548 1549 assert.areSame( 5, p.getChildCount(), 'The number of nodes after split doesn\'t match' ); 1550 1551 var range = new CKEDITOR.dom.range( doc ); 1552 1553 // Create a range that enbraces "E". 1554 range.setStartBefore( p.getChild( 4 ) ); 1555 range.setEndAfter( p.getChild( 4 ) ); 1556 1557 var bookmark = range.createBookmark2(); 1558 1559 range = new CKEDITOR.dom.range( doc ); 1560 range.moveToBookmark( bookmark ); 1561 1562 assert.areSame( document.getElementById('P'), range.startContainer.$, 'range.startContainer' ); 1563 assert.areSame( 4, range.startOffset, 'range.startOffset' ); 1564 assert.areSame( document.getElementById('P'), range.endContainer.$, 'range.endContainer' ); 1565 assert.areSame( 5, range.endOffset, 'range.endOffset' ); 1566 assert.isFalse( range.collapsed, 'range.collapsed' ); 1567 }, 1568 1569 test_createBookmark2_3 : function() 1570 { 1571 var html = '<p id="P">A B <b>C </b>D E</p>'; 1572 1573 doc.getById( 'playground' ).setHtml( html ); 1574 1575 var p = doc.getById( 'P' ); 1576 1577 // Split the text nodes. 1578 p.getFirst().split( 2 ); // Right before "B" 1579 p.getChild( 3 ).split( 2 ); // Right before "E" 1580 1581 assert.areSame( 5, p.getChildCount(), 'The number of nodes after split doesn\'t match' ); 1582 1583 var range = new CKEDITOR.dom.range( doc ); 1584 1585 // Create a range that enbraces "E". 1586 range.setStartBefore( p.getChild( 4 ) ); 1587 range.setEndAfter( p.getChild( 4 ) ); 1588 1589 var bookmark = range.createBookmark2( true ); 1590 1591 // Normalize the contents. 1592 doc.getById( 'playground' ).setHtml( html ); 1593 1594 range = new CKEDITOR.dom.range( doc ); 1595 range.moveToBookmark( bookmark ); 1596 1597 assert.areSame( document.getElementById('P').childNodes[2], range.startContainer.$, 'range.startContainer' ); 1598 assert.areSame( 2, range.startOffset, 'range.startOffset' ); 1599 assert.areSame( document.getElementById('P'), range.endContainer.$, 'range.endContainer' ); 1600 1601 // Note that the endOffset doesn't get normalized as it's not 1602 // needed. Any offset pointing over the container size is meant to 1603 // be at the end of it. 1604 assert.areSame( 5, range.endOffset, 'range.endOffset' ); 1605 assert.isFalse( range.collapsed, 'range.collapsed' ); 1606 }, 1607 1513 1608 ///////////// 1514 1609 … … 1525 1620 //window.onload = function() 1526 1621 //{ 1527 // // Local references. 1528 // var assert = CKEDITOR.test.assert; 1529 // var getInnerHtml = CKEDITOR.test.getInnerHtml; 1530 1531 // var doc = new CKEDITOR.dom.document( document ); 1532 1533 // doc.getById( '_EnlargeP' ).setHtml( 'this <i>is some </i>sample text' ); 1534 1535 // var range = new CKEDITOR.dom.range( doc ); 1536 // range.setStart( doc.getById( '_EnlargeP' ), 0 ); 1537 // range.setEnd( doc.getById( '_EnlargeP' ).getChild( 1 ), 0 ); 1538 1539 // range.enlarge( CKEDITOR.ENLARGE_ELEMENT ); 1622 // tests.test_createBookmark2_3(); 1540 1623 //} 1541 1624
Note: See TracChangeset
for help on using the changeset viewer.
