Ticket #3299: 3299.patch

File 3299.patch, 11.4 KB (added by Frederico Caldeira Knabben, 15 years ago)
  • _source/core/dom/range.js

     
    259259
    260260        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 };
    261261
    262         // Check every node between the block boundary and the startNode or endNode.
    263         var getCheckStartEndBlockFunction = function( isStart )
     262        // Creates the appropriate node evaluator for the dom walker used inside
     263        // check(Start|End)OfBlock.
     264        function getCheckStartEndBlockEvalFunction( isStart )
    264265        {
    265                 return function( evt )
     266                return function( node )
    266267                {
    267                         // Don't check the block boundary itself.
    268                         if ( this.stopped() || !evt.data.node )
    269                                 return;
     268                        var hadBr = false;
    270269
    271                         var node = evt.data.node,
    272                                 hadBr = false;
    273                         if ( node.type == CKEDITOR.NODE_ELEMENT )
     270                        if ( node.type == CKEDITOR.NODE_TEXT )
    274271                        {
     272                                // If there's any visible text, then we're not at the start.
     273                                if ( CKEDITOR.tools.trim( node.getText() ).length )
     274                                        return false;
     275                        }
     276                        else
     277                        {
    275278                                // If there are non-empty inline elements (e.g. <img />), then we're not
    276279                                // at the start.
    277280                                if ( !inlineChildReqElements[ node.getName() ] )
     
    280283                                        if ( !isStart && node.getName() == 'br' && !hadBr )
    281284                                                hadBr = true;
    282285                                        else
    283                                         {
    284                                                 this.checkFailed = true;
    285                                                 this.stop();
    286                                         }
     286                                                return false;
    287287                                }
    288288                        }
    289                         else if ( node.type == CKEDITOR.NODE_TEXT )
    290                         {
    291                                 // If there's any visible text, then we're not at the start.
    292                                 var visibleText = CKEDITOR.tools.trim( node.getText() );
    293                                 if ( visibleText.length > 0 )
    294                                 {
    295                                         this.checkFailed = true;
    296                                         this.stop();
    297                                 }
    298                         }
    299289                };
    300         };
     290        }
    301291
    302 
    303292        CKEDITOR.dom.range.prototype =
    304293        {
    305294                clone : function()
     
    14151404                checkStartOfBlock : function()
    14161405                {
    14171406                        var startContainer = this.startContainer,
    1418                                 startOffset = this.startOffset;
     1407                                startOffset = this.startOffset,
     1408                                startNode,
     1409                                startInclusive;
    14191410
    1420                         // If the starting node is a text node, and non-empty before the offset,
    1421                         // then we're surely not at the start of block.
    1422                         if ( startContainer.type == CKEDITOR.NODE_TEXT )
     1411                        if ( startOffset )
    14231412                        {
    1424                                 var textBefore = CKEDITOR.tools.ltrim( startContainer.getText().substr( 0, startOffset ) );
    1425                                 if ( textBefore.length > 0 )
    1426                                         return false;
     1413                                // If the starting node is a text node, and non-empty before the offset,
     1414                                // then we're surely not at the start of block.
     1415                                if ( startContainer.type == CKEDITOR.NODE_TEXT )
     1416                                {
     1417                                        var textBefore = CKEDITOR.tools.ltrim( startContainer.substring( 0, startOffset ) );
     1418                                        if ( textBefore.length )
     1419                                                return false;
     1420                                }
     1421                                else
     1422                                {
     1423                                        startNode = startContainer.getChild( startOffset - 1 );
     1424                                        startInclusive = true;
     1425                                }
    14271426                        }
     1427                       
     1428                        if ( !startNode )
     1429                                startNode = startContainer;
    14281430
    1429                         var startNode = this.getBoundaryNodes().startNode,
    1430                                 walker = new CKEDITOR.dom.domWalker( startNode );
     1431                        var path        = new CKEDITOR.dom.elementPath( startNode ),
     1432                                walker  = new CKEDITOR.dom.walker( startNode, ( path.block || path.blockLimit ) );
    14311433
    1432                         // DFS backwards until the block boundary, with the checker function.
    1433                         walker.on( 'step', getCheckStartEndBlockFunction( true ), null, null, 20 );
    1434                         walker.reverse( CKEDITOR.dom.domWalker.blockBoundary() );
     1434                        if ( ( path.block && startNode.equals( path.block ) )
     1435                                || ( !path.block && startNode.equals( path.blockLimit ) ) )
     1436                        {
     1437                                return true;
     1438                        }
    14351439
    1436                         return !walker.checkFailed;
     1440                        walker.startInclusive = startInclusive;
     1441                        walker.evaluator = getCheckStartEndBlockEvalFunction( true );
     1442                       
     1443                        return walker.checkBackward();
    14371444                },
    14381445
    14391446                checkEndOfBlock : function()
    14401447                {
    14411448                        var endContainer = this.endContainer,
    1442                                 endOffset = this.endOffset;
     1449                                endOffset = this.endOffset,
     1450                                startNode,
     1451                                startInclusive;
    14431452
    14441453                        // If the ending node is a text node, and non-empty after the offset,
    14451454                        // then we're surely not at the end of block.
    14461455                        if ( endContainer.type == CKEDITOR.NODE_TEXT )
    14471456                        {
    1448                                 var textAfter = CKEDITOR.tools.rtrim( endContainer.getText().substr( endOffset ) );
    1449                                 if ( textAfter.length > 0 )
     1457                                var textAfter = CKEDITOR.tools.rtrim( endContainer.substring( endOffset ) );
     1458                                if ( textAfter.length )
    14501459                                        return false;
    14511460                        }
     1461                        else
     1462                        {
     1463                                startNode = endContainer.getChild( endOffset );
     1464                                startInclusive = !!startNode;
     1465                        }
    14521466
    1453                         var endNode = this.getBoundaryNodes().endNode,
    1454                                 walker = new CKEDITOR.dom.domWalker( endNode );
     1467                        if ( !startNode )
     1468                                startNode = endContainer;
    14551469
    1456                         // DFS forward until the block boundary, with the checker function.
    1457                         walker.on( 'step', getCheckStartEndBlockFunction( false ), null, null, 20 );
    1458                         walker.forward( CKEDITOR.dom.domWalker.blockBoundary() );
     1470                        var path        = new CKEDITOR.dom.elementPath( startNode ),
     1471                                walker  = new CKEDITOR.dom.walker( startNode, ( path.block || path.blockLimit ) );
    14591472
    1460                         return !walker.checkFailed;
     1473                        if ( ( path.block && startNode.equals( path.block ) )
     1474                                || ( !path.block && startNode.equals( path.blockLimit ) ) )
     1475                        {
     1476                                return true;
     1477                        }
     1478
     1479                        walker.startInclusive = startInclusive;
     1480                        walker.evaluator = getCheckStartEndBlockEvalFunction( false );
     1481                       
     1482                        return walker.checkForward();
    14611483                },
    14621484
    14631485                /**
  • _source/tests/core/dom/range.html

     
    16041604                        assert.areSame( 5, range.endOffset, 'range.endOffset' );
    16051605                        assert.isFalse( range.collapsed, 'range.collapsed' );
    16061606                },
     1607               
     1608                test_checkStartOfBlock1 : function()
     1609                {
     1610                        var p = doc.getById( 'playground' );
     1611                        p.setHtml( '<p>Test</p>' );
     1612                        p = p.getFirst();
    16071613
     1614                        var range = new CKEDITOR.dom.range( doc );
     1615
     1616                        range.setStartAt( p, CKEDITOR.POSITION_AFTER_START );
     1617                        range.collapse( true );
     1618                       
     1619                        assert.isTrue( range.checkStartOfBlock() );
     1620                },
     1621
     1622                test_checkStartOfBlock2 : function()
     1623                {
     1624                        var p = doc.getById( 'playground' );
     1625                        p.setHtml( '<p>Test</p>' );
     1626                        p = p.getFirst();
     1627
     1628                        var range = new CKEDITOR.dom.range( doc );
     1629
     1630                        range.setStartAt( p, CKEDITOR.POSITION_BEFORE_END );
     1631                        range.collapse( true );
     1632                       
     1633                        assert.isFalse( range.checkStartOfBlock() );
     1634                },
     1635
     1636                test_checkStartOfBlock3 : function()
     1637                {
     1638                        var p = doc.getById( 'playground' );
     1639                        p.setHtml( '<p>Test</p>' );
     1640                        p = p.getFirst();
     1641
     1642                        var range = new CKEDITOR.dom.range( doc );
     1643
     1644                        range.setStartAt( p.getFirst(), CKEDITOR.POSITION_AFTER_START );
     1645                        range.collapse( true );
     1646                       
     1647                        assert.isTrue( range.checkStartOfBlock() );
     1648                },
     1649
     1650                test_checkStartOfBlock4 : function()
     1651                {
     1652                        var p = doc.getById( 'playground' );
     1653                        p.setHtml( '<p>Test</p>' );
     1654                        p = p.getFirst();
     1655
     1656                        var range = new CKEDITOR.dom.range( doc );
     1657
     1658                        range.setStartAt( p.getFirst(), CKEDITOR.POSITION_BEFORE_END );
     1659                        range.collapse( true );
     1660                       
     1661                        assert.isFalse( range.checkStartOfBlock() );
     1662                },
     1663
     1664                test_checkStartOfBlock5 : function()
     1665                {
     1666                        var el = doc.getById( 'playground' );
     1667                        el.setHtml( '<p> Test </p>' );
     1668                        el = el.getFirst().getFirst();
     1669
     1670                        var range = new CKEDITOR.dom.range( doc );
     1671
     1672                        // IE trims the space in the beginning of text nodes in our case.
     1673                        // So, let's just check it and make it pass.
     1674                        range.setStart( el, ( el.substring( 0, 1 ) == 'T' ) ? 0 : 1 );
     1675                        range.collapse( true );
     1676                       
     1677                        assert.isTrue( range.checkStartOfBlock() );
     1678                },
     1679
     1680                test_checkStartOfBlock6 : function()
     1681                {
     1682                        var p = doc.getById( 'playground' );
     1683                        p.setHtml( '<p> Test </p>' );
     1684                        p = p.getFirst();
     1685
     1686                        var range = new CKEDITOR.dom.range( doc );
     1687
     1688                        range.setStart( p.getFirst(), 5 );
     1689                        range.collapse( true );
     1690                       
     1691                        assert.isFalse( range.checkStartOfBlock() );
     1692                },
     1693
     1694                test_checkStartOfBlock7 : function()
     1695                {
     1696                        var el = doc.getById( 'playground' );
     1697                        el.setHtml( '<p><b>Test</b></p>' );
     1698                        el = el.getFirst().getFirst();
     1699
     1700                        var range = new CKEDITOR.dom.range( doc );
     1701                        range.selectNodeContents( el );
     1702                       
     1703                        assert.isTrue( range.checkStartOfBlock() );
     1704                },
     1705
     1706                test_checkStartOfBlock8 : function()
     1707                {
     1708                        var el = doc.getById( 'playground' );
     1709                        el.setHtml( '<p>A<b>Test</b>B</p>' );
     1710                        el = el.getFirst().getFirst().getNext();
     1711
     1712                        var range = new CKEDITOR.dom.range( doc );
     1713                        range.selectNodeContents( el );
     1714                       
     1715                        assert.isFalse( range.checkStartOfBlock() );
     1716                },
     1717
     1718                test_checkEndOfBlock1 : function()
     1719                {
     1720                        var p = doc.getById( 'playground' );
     1721                        p.setHtml( '<p>Test</p>' );
     1722                        p = p.getFirst();
     1723
     1724                        var range = new CKEDITOR.dom.range( doc );
     1725
     1726                        range.setStartAt( p, CKEDITOR.POSITION_AFTER_START );
     1727                        range.collapse( true );
     1728                       
     1729                        assert.isFalse( range.checkEndOfBlock() );
     1730                },
     1731
     1732                test_checkEndOfBlock2 : function()
     1733                {
     1734                        var p = doc.getById( 'playground' );
     1735                        p.setHtml( '<p>Test</p>' );
     1736                        p = p.getFirst();
     1737
     1738                        var range = new CKEDITOR.dom.range( doc );
     1739
     1740                        range.setStartAt( p, CKEDITOR.POSITION_BEFORE_END );
     1741                        range.collapse( true );
     1742                       
     1743                        assert.isTrue( range.checkEndOfBlock() );
     1744                },
     1745
     1746                test_checkEndOfBlock3 : function()
     1747                {
     1748                        var p = doc.getById( 'playground' );
     1749                        p.setHtml( '<p>Test</p>' );
     1750                        p = p.getFirst();
     1751
     1752                        var range = new CKEDITOR.dom.range( doc );
     1753
     1754                        range.setStartAt( p.getFirst(), CKEDITOR.POSITION_AFTER_START );
     1755                        range.collapse( true );
     1756                       
     1757                        assert.isFalse( range.checkEndOfBlock() );
     1758                },
     1759
     1760                test_checkEndOfBlock4 : function()
     1761                {
     1762                        var p = doc.getById( 'playground' );
     1763                        p.setHtml( '<p>Test</p>' );
     1764                        p = p.getFirst();
     1765
     1766                        var range = new CKEDITOR.dom.range( doc );
     1767
     1768                        range.setStartAt( p.getFirst(), CKEDITOR.POSITION_BEFORE_END );
     1769                        range.collapse( true );
     1770                       
     1771                        assert.isTrue( range.checkEndOfBlock() );
     1772                },
     1773
     1774                test_checkEndOfBlock5 : function()
     1775                {
     1776                        var p = doc.getById( 'playground' );
     1777                        p.setHtml( '<p> Test </p>' );
     1778                        p = p.getFirst();
     1779
     1780                        var range = new CKEDITOR.dom.range( doc );
     1781
     1782                        range.setStart( p.getFirst(), 1 );
     1783                        range.collapse( true );
     1784                       
     1785                        assert.isFalse( range.checkEndOfBlock() );
     1786                },
     1787
     1788                test_checkEndOfBlock6 : function()
     1789                {
     1790                        var p = doc.getById( 'playground' );
     1791                        p.setHtml( '<p> Test </p>' );
     1792                        p = p.getFirst();
     1793
     1794                        var range = new CKEDITOR.dom.range( doc );
     1795
     1796                        range.setStart( p.getFirst(), 5 );
     1797                        range.collapse( true );
     1798                       
     1799                        assert.isTrue( range.checkEndOfBlock() );
     1800                },
     1801
     1802                test_checkEndOfBlock7 : function()
     1803                {
     1804                        var el = doc.getById( 'playground' );
     1805                        el.setHtml( '<p><b>Test</b></p>' );
     1806                        el = el.getFirst().getFirst();
     1807
     1808                        var range = new CKEDITOR.dom.range( doc );
     1809                        range.selectNodeContents( el );
     1810                       
     1811                        assert.isTrue( range.checkEndOfBlock() );
     1812                },
     1813
     1814                test_checkEndOfBlock8 : function()
     1815                {
     1816                        var el = doc.getById( 'playground' );
     1817                        el.setHtml( '<p>A<b>Test</b>B</p>' );
     1818                        el = el.getFirst().getFirst().getNext();
     1819
     1820                        var range = new CKEDITOR.dom.range( doc );
     1821                        range.selectNodeContents( el );
     1822                       
     1823                        assert.isFalse( range.checkEndOfBlock() );
     1824                },
     1825
    16081826                /////////////
    16091827
    16101828                setUp : function()
© 2003 – 2022, CKSource sp. z o.o. sp.k. All rights reserved. | Terms of use | Privacy policy