Changeset 7399


Ignore:
Timestamp:
03/19/2012 12:42:27 PM (3 years ago)
Author:
garry.yao
Message:

#7946: New impl for element::scrollIntoView to make it work with host page scrolling.

Location:
CKEditor/trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • CKEditor/trunk/CHANGES.html

    r7398 r7399  
    6868                <li><a href="http://dev.ckeditor.com/ticket/8632">#8632</a> : Fix cursor panic when backspace is used in list item.</li> 
    6969                <li><a href="http://dev.ckeditor.com/ticket/8324">#8324</a> : [IE8] Fix undo generate error when control type element is selected.</li> 
     70                <li><a href="http://dev.ckeditor.com/ticket/7946">#7946</a> : Fix find dialog result doesn't scroll into view when editor is off the view port.</li> 
    7071        </ul> 
    7172        <h3> 
  • CKEditor/trunk/_source/core/dom/element.js

    r7394 r7399  
    13981398                }, 
    13991399 
    1400                 scrollIntoView : function( alignTop ) 
    1401                 { 
    1402                         // Get the element window. 
    1403                         var win = this.getWindow(), 
    1404                                 winHeight = win.getViewPaneSize().height; 
    1405  
    1406                         // Starts from the offset that will be scrolled with the negative value of 
    1407                         // the visible window height. 
    1408                         var offset = winHeight * -1; 
    1409  
    1410                         // Append the view pane's height if align to top. 
    1411                         // Append element height if we are aligning to the bottom. 
    1412                         if ( alignTop ) 
    1413                                 offset += winHeight; 
    1414                         else 
    1415                         { 
    1416                                 offset += this.$.offsetHeight || 0; 
    1417  
    1418                                 // Consider the margin in the scroll, which is ok for our current needs, but 
    1419                                 // needs investigation if we will be using this function in other places. 
    1420                                 offset += parseInt( this.getComputedStyle( 'marginBottom' ) || 0, 10 ) || 0; 
    1421                         } 
    1422  
    1423                         // Append the offsets for the entire element hierarchy. 
    1424                         var elementPosition = this.getDocumentPosition(); 
    1425                         offset += elementPosition.y; 
    1426  
    1427                         // offset value might be out of range(nagative), fix it(#3692). 
    1428                         offset = offset < 0 ? 0 : offset; 
    1429  
    1430                         // Scroll the window to the desired position, if not already visible(#3795). 
    1431                         var currentScroll = win.getScrollPosition().y; 
    1432                         if ( offset > currentScroll || offset < currentScroll - winHeight ) 
    1433                                 win.$.scrollTo( 0, offset ); 
     1400                /** 
     1401                 * Make any page element visible inside of the browser viewport. 
     1402                 * @param {Boolean} [alignToTop] 
     1403                 */ 
     1404                scrollIntoView : function( alignToTop ) 
     1405                { 
     1406                        var parent = this.getParent(); 
     1407                        if ( !parent ) return; 
     1408 
     1409                        // Scroll the element into parent container from the inner out. 
     1410                        do 
     1411                        { 
     1412                                // Check ancestors that overflows. 
     1413                                var overflowed = 
     1414                                        parent.$.clientWidth && parent.$.clientWidth < parent.$.scrollWidth 
     1415                                        || parent.$.clientHeight && parent.$.clientHeight < parent.$.scrollHeight; 
     1416 
     1417                                if ( overflowed ) 
     1418                                        this.scrollIntoParent( parent, alignToTop, 1 ); 
     1419 
     1420                                // Walk across the frame. 
     1421                                if ( parent.is( 'html' ) ) 
     1422                                { 
     1423                                        var win = parent.getWindow(); 
     1424 
     1425                                        // Avoid security error. 
     1426                                        try 
     1427                                        { 
     1428                                                var iframe = win.$.frameElement; 
     1429                                                iframe && ( parent = new CKEDITOR.dom.element( iframe ) ); 
     1430                                        } 
     1431                                        catch(er){} 
     1432                                } 
     1433                        } 
     1434                        while ( parent = parent.getParent() ); 
     1435                }, 
     1436 
     1437                /** 
     1438                 * Make any page element visible inside one of the ancestor by scrolling the parent. 
     1439                 * @param {CKEDITOR.dom.element|CKEDITOR.dom.window} parent The container to scroll into. 
     1440                 * @param {Boolean} [alignToTop] Align the element's top side with the container's 
     1441                 * when "true" is specified, align the bottom with viewport bottom when "false" is specified, 
     1442                 * other wise scroll on either side with the minimum amount to show the element. 
     1443                 * @param {Boolean} [hscroll] Whether horizontal overflow should be considered. 
     1444                 */ 
     1445                scrollIntoParent : function( parent, alignToTop, hscroll ) 
     1446                { 
     1447                        !parent && ( parent = this.getWindow() ); 
     1448 
     1449                        var doc = parent.getDocument(); 
     1450                        var isQuirks = doc.$.compatMode == 'BackCompat'; 
     1451 
     1452                        // On window <html> is scrolled while quirks scrolls <body>. 
     1453                        if ( parent instanceof CKEDITOR.dom.window ) 
     1454                                parent = isQuirks ? doc.getBody() : doc.getDocumentElement(); 
     1455 
     1456                        // Scroll the parent by the specified amount. 
     1457                        function scrollBy( x, y ) 
     1458                        { 
     1459                                // Webkit doesn't support "scrollTop/scrollLeft" 
     1460                                // on documentElement/body element. 
     1461                                if ( /body|html/.test( parent.getName() ) ) 
     1462                                        parent.getWindow().$.scrollBy( x, y ); 
     1463                                else 
     1464                                { 
     1465                                        parent.$[ 'scrollLeft' ] += x; 
     1466                                        parent.$[ 'scrollTop' ] += y; 
     1467                                } 
     1468                        } 
     1469 
     1470                        // Figure out the element position relative to the specified window. 
     1471                        function screenPos( element, refWin ) 
     1472                        { 
     1473                                var pos = { x: 0, y: 0 }; 
     1474 
     1475                                if ( !( element.is( isQuirks ? 'body' : 'html' ) ) ) 
     1476                                { 
     1477                                        var box = element.$.getBoundingClientRect(); 
     1478                                        pos.x = box.left, pos.y = box.top; 
     1479                                } 
     1480 
     1481                                var win = element.getWindow(); 
     1482                                if ( !win.equals( refWin ) ) 
     1483                                { 
     1484                                        var outerPos = screenPos( CKEDITOR.dom.element.get( win.$.frameElement ), refWin ); 
     1485                                        pos.x += outerPos.x, pos.y += outerPos.y; 
     1486                                } 
     1487 
     1488                                return pos; 
     1489                        } 
     1490 
     1491                        // calculated margin size. 
     1492                        function margin( element, side ) 
     1493                        { 
     1494                                return parseInt( element.getComputedStyle( 'margin-' + side ) || 0, 10 ) || 0; 
     1495                        } 
     1496 
     1497                        var win = parent.getWindow(); 
     1498 
     1499                        var thisPos = screenPos( this, win ), 
     1500                                parentPos = screenPos( parent, win ), 
     1501                                eh = this.$.offsetHeight, 
     1502                                ew = this.$.offsetWidth, 
     1503                                ch = parent.$.clientHeight, 
     1504                                cw = parent.$.clientWidth, 
     1505                                lt, 
     1506                                br; 
     1507 
     1508                        // Left-top margins. 
     1509                        lt = 
     1510                        { 
     1511                                x : thisPos.x - margin( this, 'left' ) - parentPos.x || 0, 
     1512                                y : thisPos.y - margin( this, 'top' ) - parentPos.y|| 0 
     1513                        }; 
     1514 
     1515                        // Bottom-right margins. 
     1516                        br = 
     1517                        { 
     1518                                x : thisPos.x + ew + margin( this, 'right' ) - ( ( parentPos.x ) + cw ) || 0, 
     1519                                y : thisPos.y + eh + margin( this, 'bottom' ) - ( ( parentPos.y ) + ch ) || 0 
     1520                        }; 
     1521 
     1522                        // 1. Do the specified alignment as much as possible; 
     1523                        // 2. Otherwise be smart to scroll only the minimum amount; 
     1524                        // 3. Never cut at the top; 
     1525                        // 4. DO NOT scroll when already visible. 
     1526                        if ( lt.y < 0 || br.y > 0 ) 
     1527                        { 
     1528                                scrollBy( 0, 
     1529                                                  alignToTop === true ? lt.y : 
     1530                                                  alignToTop === false ? br.y : 
     1531                                                  lt.y < 0 ? lt.y : br.y ); 
     1532                        } 
     1533 
     1534                        if ( hscroll && ( lt.x < 0 || br.x > 0 ) ) 
     1535                                scrollBy( lt.x < 0 ? lt.x : br.x, 0 ); 
    14341536                }, 
    14351537 
Note: See TracChangeset for help on using the changeset viewer.
© 2003 – 2012 CKSource – Frederico Knabben. All rights reserved. | Terms of use | Privacy policy