Changeset 3065


Ignore:
Timestamp:
02/17/09 12:15:24 (5 years ago)
Author:
fredck
Message:

#2909 : Introduced createBookmark2.

Location:
CKEditor/trunk/_source
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • CKEditor/trunk/_source/core/dom/document.js

    r2948 r3065  
    8888                }, 
    8989 
     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 
    90131                /** 
    91132                 * Gets the &lt;head&gt; element for this document. 
  • CKEditor/trunk/_source/core/dom/node.js

    r3051 r3065  
    150150 
    151151                /** 
     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                /** 
    152203                 * Gets a DOM tree descendant under the current node. 
    153204                 * @param {Array|Number} indices The child index or array of child indices under the node. 
  • CKEditor/trunk/_source/core/dom/range.js

    r3059 r3065  
    430430                }, 
    431431 
     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 
    432524                moveToBookmark : function( bookmark ) 
    433525                { 
    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                        } 
    453567                }, 
    454568 
  • CKEditor/trunk/_source/tests/core/dom/range.html

    r3017 r3065  
    1212 
    1313var html1, html2; 
     14var tests; 
    1415 
    1516CKEDITOR.test.addTestCase( (function() 
     
    2122        var doc = new CKEDITOR.dom.document( document ); 
    2223 
    23         return { 
     24        return tests = { 
    2425                test__constructor : function() 
    2526                { 
     
    15111512                }, 
    15121513 
     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 
    15131608                ///////////// 
    15141609 
     
    15251620//window.onload = function() 
    15261621//{ 
    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(); 
    15401623//} 
    15411624 
Note: See TracChangeset for help on using the changeset viewer.
© 2003 – 2012 CKSource – Frederico Knabben. All rights reserved. | Terms of use | Privacy policy