[webkit-changes] cvs commit: WebCore/kwq KWQKHTMLPart.mm KWQScrollView.h KWQScrollView.mm WebCoreBridge.mm

Adele adele at opensource.apple.com
Thu Nov 3 11:12:09 PST 2005


adele       05/11/03 11:12:08

  Modified:    .        ChangeLog
               .        ChangeLog
               khtml    khtml_part.cpp khtmlview.cpp
               khtml/rendering render_layer.cpp render_layer.h
               khtml/xml dom_elementimpl.cpp
               kwq      KWQKHTMLPart.mm KWQScrollView.h KWQScrollView.mm
                        WebCoreBridge.mm
  Added:       fast/overflow scrollRevealButton-expected.checksum
                        scrollRevealButton-expected.png
                        scrollRevealButton-expected.txt
                        scrollRevealButton.html
               fast/overflow/resources scrollButton1.html
  Log:
  LayoutTests:
  
          Test for...
          <rdar://problem/3612121> setting focus, by tabbing, searching, or with JavaScript does not scroll overflow:auto/scroll/overlay to reveal focused element (3480)
  
          * fast/overflow/resources/scrollButton1.html: Added.
          * fast/overflow/scrollRevealButton-expected.checksum: Added.
          * fast/overflow/scrollRevealButton-expected.png: Added.
          * fast/overflow/scrollRevealButton-expected.txt: Added.
          * fast/overflow/scrollRevealButton.html: Added.
  
  WebCore:
  
          Reviewed by Hyatt.
  
          Clean up of layer scrolling code.  Now we can clearly define what to do if a rectangle is fully visible, partially visible, or hidden.
          This also fixes a bug with the previous implementation where nested layers/frames would get passed a rect that was too large.
  
          Added fast/overflow/scrollRevealButton.html
  
          * khtml/rendering/render_layer.h: (khtml::RenderLayer::):
          Added ScrollBehavior enum, ScrollAlignment struct, and ScrollAlignment static members
          to describe specific scrolling behaviors depending on how visible the rectangle is.
          In the future, we can add other statics to easily describe desired behaviors.
          * khtml/rendering/render_layer.cpp:
          (khtml::): initialize ScrollAlignment static members:
          alignCenterIfNeeded, alignToEdgeIfNeeded, alignCenterAlways, alignTopAlways, alignBottomAlways
          (khtml::RenderLayer::scrollRectToVisible):
          alignCenterIfNeeded is the default behavior for both directions.
          Pass the original rect (adjusted if scrolling has occurred) when recursively calling this function.
          (khtml::RenderLayer::getRectToExpose): Adjusted for new ScrollAlignment parameters.
          * khtml/khtml_part.cpp:
          (KHTMLPart::gotoAnchor): Use the node's rect to determine where to scroll.
          We used to just use the origin, but this helps us match other browsers better.
          (KHTMLPart::setActiveNode): Removed scrolling code, since this is now also done in setFocusNode
          * khtml/xml/dom_elementimpl.cpp: (ElementImpl::scrollIntoView): Use new ScrollAlignment values to describe scrolling behavior.
          * kwq/KWQKHTMLPart.mm:
          (KWQKHTMLPart::nextKeyViewInFrame): Removed scrolling code, since this is now also done in setFocusNode
          (KWQKHTMLPart::centerSelectionInVisibleArea): Use new ScrollAlignment values to describe scrolling behavior.
          * kwq/WebCoreBridge.mm: (-[WebCoreBridge ensureSelectionVisible]): ditto.
          * kwq/KWQScrollView.h: Removed ensureRectVisible, since we no longer use this.
          * kwq/KWQScrollView.mm: ditto.
          * khtml/khtmlview.cpp:
          (KHTMLView::doAutoScroll): Removed unnecessary nil checks for enclosingLayer
          (KHTMLView::focusNextPrevNode): ditto.
  
  Revision  Changes    Path
  1.70      +11 -0     LayoutTests/ChangeLog
  
  Index: ChangeLog
  ===================================================================
  RCS file: /cvs/root/LayoutTests/ChangeLog,v
  retrieving revision 1.69
  retrieving revision 1.70
  diff -u -r1.69 -r1.70
  --- ChangeLog	3 Nov 2005 18:16:28 -0000	1.69
  +++ ChangeLog	3 Nov 2005 19:11:59 -0000	1.70
  @@ -1,3 +1,14 @@
  +2005-11-03  Adele Peterson  <adele at apple.com>
  +
  +        Test for...
  +        <rdar://problem/3612121> setting focus, by tabbing, searching, or with JavaScript does not scroll overflow:auto/scroll/overlay to reveal focused element (3480)
  +
  +        * fast/overflow/resources/scrollButton1.html: Added.
  +        * fast/overflow/scrollRevealButton-expected.checksum: Added.
  +        * fast/overflow/scrollRevealButton-expected.png: Added.
  +        * fast/overflow/scrollRevealButton-expected.txt: Added.
  +        * fast/overflow/scrollRevealButton.html: Added.
  +
   2005-11-03  David Harrison  <harrison at apple.com>
   
           Other files that should have been included with my previous commit.
  
  
  
  1.1                  LayoutTests/fast/overflow/scrollRevealButton-expected.checksum
  
  Index: scrollRevealButton-expected.checksum
  ===================================================================
  0f3f184a7c00cc47782d4e8464e97367
  
  
  1.1                  LayoutTests/fast/overflow/scrollRevealButton-expected.png
  
  	<<Binary file>>
  
  
  1.1                  LayoutTests/fast/overflow/scrollRevealButton-expected.txt
  
  Index: scrollRevealButton-expected.txt
  ===================================================================
  layer at (0,0) size 785x1184
    RenderCanvas at (0,0) size 785x600
  layer at (0,0) size 785x1184
    RenderBlock {HTML} at (0,0) size 785x1184
      RenderBody {BODY} at (8,8) size 769x1168
        RenderBlock (anonymous) at (0,0) size 769x18
          RenderText {TEXT} at (0,0) size 339x18
            text run at (0,0) width 339: "This test should scroll recursively to reveal the button."
          RenderText {TEXT} at (0,0) size 0x0
        RenderBlock {DIV} at (0,18) size 769x500
        RenderBlock (anonymous) at (0,518) size 769x150
          RenderPartObject {IFRAME} at (0,0) size 300x150
            layer at (0,0) size 308x316
              RenderCanvas at (0,0) size 285x135
            layer at (0,0) size 308x316
              RenderBlock {HTML} at (0,0) size 285x316
                RenderBody {BODY} at (8,8) size 269x300
            layer at (8,8) size 300x300 clip at (8,8) size 285x300 scrollY 535 scrollHeight 1268
              RenderBlock {DIV} at (0,0) size 300x300
                RenderBlock (anonymous) at (0,0) size 285x18
                  RenderText {TEXT} at (0,0) size 88x18
                    text run at (0,0) width 88: "overflow:auto"
                RenderBlock {DIV} at (0,18) size 285x600
                RenderBlock {DIV} at (0,768) size 285x500
            layer at (8,91) size 150x150 clip at (8,91) size 135x150 scrollY 480 scrollHeight 858
              RenderBlock {DIV} at (0,618) size 150x150
                RenderBlock (anonymous) at (0,0) size 135x18
                  RenderText {TEXT} at (0,0) size 88x18
                    text run at (0,0) width 88: "overflow:auto"
                RenderBlock {DIV} at (0,18) size 135x500
                RenderBlock (anonymous) at (0,518) size 135x40
                  RenderBR {BR} at (0,0) size 0x18
                  RenderButton {INPUT} at (2,20) size 51x18 [bgcolor=#C0C0C0]
                    RenderBlock (anonymous) at (8,2) size 35x13
                      RenderText at (0,0) size 35x13
                        text run at (0,0) width 35: "Button"
                  RenderText {TEXT} at (0,0) size 0x0
                RenderBlock {DIV} at (0,558) size 135x300
          RenderText {TEXT} at (0,0) size 0x0
        RenderBlock {DIV} at (0,668) size 769x500
  
  
  
  1.1                  LayoutTests/fast/overflow/scrollRevealButton.html
  
  Index: scrollRevealButton.html
  ===================================================================
  <html>This test should scroll recursively to reveal the button.
  <body onload="document.getElementById('fr').contentDocument.getElementById('bt').focus();">
  <div style="height:500px"></div>
  <iframe src="resources/scrollButton1.html" id="fr"></iframe>
  <div style="height:500px"></div>
  </body>
  </html>
  
  
  1.1                  LayoutTests/fast/overflow/resources/scrollButton1.html
  
  Index: scrollButton1.html
  ===================================================================
  <html>
  <div style="overflow:auto; width:300px; height:300px;">overflow:auto
  <div style="height:600px"></div>
  <div style="overflow:auto; width:150px; height:150px;">overflow:auto
  <div style="height:500px"></div>
  <br><input type="button" value="Button" id="bt"></input>
  <div style="height:300px"></div>
  </div>
  <div style="height:500px"></div>
  </div>
  </html>
  
  
  1.330     +35 -0     WebCore/ChangeLog
  
  Index: ChangeLog
  ===================================================================
  RCS file: /cvs/root/WebCore/ChangeLog,v
  retrieving revision 1.329
  retrieving revision 1.330
  diff -u -r1.329 -r1.330
  --- ChangeLog	3 Nov 2005 02:20:10 -0000	1.329
  +++ ChangeLog	3 Nov 2005 19:12:00 -0000	1.330
  @@ -1,3 +1,38 @@
  +2005-11-03  Adele Peterson  <adele at apple.com>
  +
  +        Reviewed by Hyatt.
  +
  +        Clean up of layer scrolling code.  Now we can clearly define what to do if a rectangle is fully visible, partially visible, or hidden.
  +        This also fixes a bug with the previous implementation where nested layers/frames would get passed a rect that was too large.
  +
  +        Added fast/overflow/scrollRevealButton.html
  +
  +        * khtml/rendering/render_layer.h: (khtml::RenderLayer::): 
  +        Added ScrollBehavior enum, ScrollAlignment struct, and ScrollAlignment static members
  +        to describe specific scrolling behaviors depending on how visible the rectangle is.
  +        In the future, we can add other statics to easily describe desired behaviors.
  +        * khtml/rendering/render_layer.cpp:
  +        (khtml::): initialize ScrollAlignment static members: 
  +        alignCenterIfNeeded, alignToEdgeIfNeeded, alignCenterAlways, alignTopAlways, alignBottomAlways
  +        (khtml::RenderLayer::scrollRectToVisible):
  +        alignCenterIfNeeded is the default behavior for both directions.
  +        Pass the original rect (adjusted if scrolling has occurred) when recursively calling this function.
  +        (khtml::RenderLayer::getRectToExpose): Adjusted for new ScrollAlignment parameters.
  +        * khtml/khtml_part.cpp:
  +        (KHTMLPart::gotoAnchor): Use the node's rect to determine where to scroll.  
  +        We used to just use the origin, but this helps us match other browsers better.
  +        (KHTMLPart::setActiveNode): Removed scrolling code, since this is now also done in setFocusNode
  +        * khtml/xml/dom_elementimpl.cpp: (ElementImpl::scrollIntoView): Use new ScrollAlignment values to describe scrolling behavior.
  +        * kwq/KWQKHTMLPart.mm:
  +        (KWQKHTMLPart::nextKeyViewInFrame): Removed scrolling code, since this is now also done in setFocusNode
  +        (KWQKHTMLPart::centerSelectionInVisibleArea): Use new ScrollAlignment values to describe scrolling behavior.
  +        * kwq/WebCoreBridge.mm: (-[WebCoreBridge ensureSelectionVisible]): ditto.
  +        * kwq/KWQScrollView.h: Removed ensureRectVisible, since we no longer use this.
  +        * kwq/KWQScrollView.mm: ditto.
  +        * khtml/khtmlview.cpp:
  +        (KHTMLView::doAutoScroll): Removed unnecessary nil checks for enclosingLayer
  +        (KHTMLView::focusNextPrevNode): ditto.
  +
   2005-11-02  David Harrison  <harrison at apple.com>
   
           Reviewed by Justin.
  
  
  
  1.356     +6 -17     WebCore/khtml/khtml_part.cpp
  
  Index: khtml_part.cpp
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/khtml_part.cpp,v
  retrieving revision 1.355
  retrieving revision 1.356
  diff -u -r1.355 -r1.356
  --- khtml_part.cpp	27 Oct 2005 22:34:43 -0000	1.355
  +++ khtml_part.cpp	3 Nov 2005 19:12:03 -0000	1.356
  @@ -132,6 +132,7 @@
   using khtml::plainText;
   using khtml::RenderObject;
   using khtml::RenderText;
  +using khtml::RenderLayer;
   using khtml::RenderWidget;
   using khtml::SelectionController;
   using khtml::Tokenizer;
  @@ -2286,18 +2287,12 @@
       }
     }
     
  -  int x = 0, y = 0;
  -  if (n) {
  -    static_cast<HTMLElementImpl *>(n)->getUpperLeftCorner(x, y);
  -  }
   #if APPLE_CHANGES
  -  // scrollRectToVisible will expose correctly from within nested layers and frames.
  -  if (n && n->renderer()) {
  -    khtml::RenderLayer *layer = n->renderer()->enclosingLayer();
  -    if (layer)
  -        // We used to align to the top left corner, but now, if the anchor is already horizontally visible, we won't scroll horizontally.
  -        n->renderer()->enclosingLayer()->scrollRectToVisible(QRect(x, y, 0, 0), alignTop, alignLeft);
  -  }
  +    // Scroll nested layers and frames to reveal the anchor.
  +    if (n && n->renderer()) {
  +        // Align to the top and to the closest side (this matches other browsers).
  +        n->renderer()->enclosingLayer()->scrollRectToVisible(n->getRect(), RenderLayer::gAlignToEdgeIfNeeded, RenderLayer::gAlignTopAlways);
  +    }
   #else
     d->m_view->setContentsPos(x, y);
   #endif
  @@ -5390,12 +5385,6 @@
   
       // Set the document's active node
       d->m_doc->setFocusNode(node.handle());
  -
  -    // Scroll the view if necessary to ensure that the new focus node is visible
  -    QRect rect  = node.handle()->getRect();    
  -    if (node.handle()->renderer() && node.handle()->renderer()->enclosingLayer()) {
  -        node.handle()->renderer()->enclosingLayer()->scrollRectToVisible(rect);
  -    }
   }
   
   DOM::Node KHTMLPart::activeNode() const
  
  
  
  1.152     +2 -2      WebCore/khtml/khtmlview.cpp
  
  Index: khtmlview.cpp
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/khtmlview.cpp,v
  retrieving revision 1.151
  retrieving revision 1.152
  diff -u -r1.151 -r1.152
  --- khtmlview.cpp	2 Nov 2005 18:54:03 -0000	1.151
  +++ khtmlview.cpp	3 Nov 2005 19:12:03 -0000	1.152
  @@ -1335,7 +1335,7 @@
            (pos.x() < 0) || (pos.x() > visibleWidth()) )
       {
           DocumentImpl *doc = m_part->xmlDocImpl();
  -        if (doc && doc->renderer() && doc->renderer()->enclosingLayer()) {
  +        if (doc && doc->renderer()) {
               doc->renderer()->enclosingLayer()->scrollRectToVisible(QRect(xm, ym, 0, 5));
           }
       }
  @@ -1497,7 +1497,7 @@
                   return;
           }
           else {
  -            if (doc->renderer() && doc->renderer()->enclosingLayer()) {
  +            if (doc->renderer()) {
                   doc->renderer()->enclosingLayer()->scrollRectToVisible(QRect(contentsX(), next ? 0: contentsHeight(), 0, 0));
               }
           }
  
  
  
  1.121     +80 -87    WebCore/khtml/rendering/render_layer.cpp
  
  Index: render_layer.cpp
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/rendering/render_layer.cpp,v
  retrieving revision 1.120
  retrieving revision 1.121
  diff -u -r1.120 -r1.121
  --- render_layer.cpp	27 Oct 2005 17:39:37 -0000	1.120
  +++ render_layer.cpp	3 Nov 2005 19:12:04 -0000	1.121
  @@ -82,6 +82,12 @@
   static bool inRenderLayerDestroy;
   #endif
   
  +RenderLayer::ScrollAlignment RenderLayer::gAlignCenterIfNeeded = { RenderLayer::noScroll, RenderLayer::alignCenter, RenderLayer::alignToClosestEdge };
  +RenderLayer::ScrollAlignment RenderLayer::gAlignToEdgeIfNeeded = { RenderLayer::noScroll, RenderLayer::alignToClosestEdge, RenderLayer::alignToClosestEdge };
  +RenderLayer::ScrollAlignment RenderLayer::gAlignCenterAlways = { RenderLayer::alignCenter, RenderLayer::alignCenter, RenderLayer::alignCenter };
  +RenderLayer::ScrollAlignment RenderLayer::gAlignTopAlways = { RenderLayer::alignTop, RenderLayer::alignTop, RenderLayer::alignTop };
  +RenderLayer::ScrollAlignment RenderLayer::gAlignBottomAlways = { RenderLayer::alignBottom, RenderLayer::alignBottom, RenderLayer::alignBottom };
  +
   void* ClipRects::operator new(size_t sz, RenderArena* renderArena) throw()
   {
       return renderArena->allocate(sz);
  @@ -551,130 +557,117 @@
       }
   }
   
  -void RenderLayer::scrollRectToVisible(const QRect &rect, ScrollAlignment verticalAlignment, ScrollAlignment horizontalAlignment)
  +void RenderLayer::scrollRectToVisible(const QRect &rect, ScrollAlignment alignX, ScrollAlignment alignY)
   {
       RenderLayer* parentLayer = 0;
  -    QRect newRect;
  +    QRect newRect = rect;
       
       if (m_object->hasOverflowClip()) {
           QRect layerBounds = QRect(m_x + m_scrollX, m_y + m_scrollY, m_width, m_height);
           QRect exposeRect = QRect(rect.x() + m_scrollX, rect.y() + m_scrollY, rect.width(), rect.height());
  -        QRect r = getRectToExpose(layerBounds, exposeRect, verticalAlignment, horizontalAlignment);
  +        QRect r = getRectToExpose(layerBounds, exposeRect, alignX, alignY);
           
           int xOffset = r.x() - m_x;
           int yOffset = r.y() - m_y;
  -        if (xOffset != m_scrollX || yOffset != m_scrollY)
  +        // Adjust offsets if they're outside of the allowable range.
  +        xOffset = kMax(0, kMin(m_scrollWidth - m_width, xOffset));
  +        yOffset = kMax(0, kMin(m_scrollHeight - m_height, yOffset));
  +        
  +        if (xOffset != m_scrollX || yOffset != m_scrollY) {
  +            int diffX = m_scrollX;
  +            int diffY = m_scrollY;
               scrollToOffset(xOffset, yOffset);
  +            diffX = m_scrollX - diffX;
  +            diffY = m_scrollY - diffY;
  +            newRect.setX(rect.x() - diffX);
  +            newRect.setY(rect.y() - diffY);
  +        }
       
  -        newRect = layerBounds;
           if (m_object->parent())
               parentLayer = m_object->parent()->enclosingLayer();
       } else {
           QScrollView* view = m_object->document()->view();
           QRect viewRect = QRect(view->contentsX(), view->contentsY(), view->visibleWidth(), view->visibleHeight());
           if (view) {
  -            QRect r = getRectToExpose(viewRect, rect, verticalAlignment, horizontalAlignment);
  -            view->ensureRectVisible(r);
  +            QRect r = getRectToExpose(viewRect, rect, alignX, alignY);
  +            view->setContentsPos(r.x(), r.y());
           }
           if (m_object->document() && m_object->document()->ownerElement() && m_object->document()->ownerElement()->renderer()) {
               parentLayer = m_object->document()->ownerElement()->renderer()->enclosingLayer();
  -            newRect = QRect(view->viewport()->x(), view->viewport()->y(), view->viewport()->width(), view->viewport()->height());
  +            newRect.setX(rect.x() - view->contentsX() + view->viewport()->x());
  +            newRect.setY(rect.y() - view->contentsY() + view->viewport()->y());
           }
       }
       
       if (parentLayer)
  -        parentLayer->scrollRectToVisible(newRect, verticalAlignment, horizontalAlignment);
  +        parentLayer->scrollRectToVisible(newRect, alignX, alignY);
   }
   
  -QRect RenderLayer::getRectToExpose(const QRect &visibleRect,  const QRect &exposeRect, ScrollAlignment verticalAlignment, ScrollAlignment horizontalAlignment) {
  +QRect RenderLayer::getRectToExpose(const QRect &visibleRect, const QRect &exposeRect, ScrollAlignment alignX, ScrollAlignment alignY) {
   
       int x, y, w, h;
       x = exposeRect.x();
       y = exposeRect.y();
       w = exposeRect.width();
       h = exposeRect.height();
  -
  -    int intersectWidth = visibleRect.intersect(exposeRect).width(); 
  -    if ((intersectWidth == w) && (horizontalAlignment == alignDefault))
  -        x = visibleRect.x();
  -    else {   
  -        switch (horizontalAlignment) {
  -            case alignLeft:
  -                // The x value is already equal to the left of the exposeRect
  -                break;
  -            case alignRight:
  -                x += exposeRect.width() - visibleRect.width();
  -                break;  //note- we don't have anything to test this right now.
  -            case alignCenter: 
  -                if (w < visibleRect.width())
  -                    x -= (visibleRect.width() - w) / 2;
  -                else {
  -                    if (visibleRect.x() >= x && exposeRect.right() >= visibleRect.right()) {
  -                        // Exposed rect fills the visible rect.
  -                        // We don't want the view to budge.
  -                        x = visibleRect.x();
  -                    }
  -                    else if (visibleRect.x() < x) {
  -                        // Scroll so left of visible region shows left of expose rect.
  -                        // Leave expose origin as it is to make this happen.
  -                    }
  -                    else {
  -                        // Scroll so right of visible region shows right of expose rect.
  -                        x = exposeRect.right() - visibleRect.width();
  -                    }
  -                }
  -                break;
  -            case alignDefault :
  -            default :
  -                // First check whether enough of the desired rect is already visible horizontally. If so, and we're not forcing centering,
  -                // we don't want to scroll horizontally because doing so is surprising.
  -                if (intersectWidth >= MIN_INTERSECT_FOR_REVEAL)
  -                    x = visibleRect.x();
  -                else if (w < visibleRect.width()) {
  -                    x -= (visibleRect.width() - w) / 2;
  -                }
  -        }
  +    
  +    // Find the appropriate X coordinate to scroll to.
  +    ScrollBehavior scrollX = getHiddenBehavior(alignX);
  +    int intersectWidth = visibleRect.intersect(exposeRect).width();
  +    // If the rectangle is fully visible, use the specified visible behavior.
  +    // If the rectangle is partially visible, but over a certain threshold, then treat it as fully visible to avoid unnecessary horizontal scrolling
  +    if (intersectWidth == w || intersectWidth >= MIN_INTERSECT_FOR_REVEAL)
  +        scrollX = getVisibleBehavior(alignX);
  +    else if (intersectWidth == visibleRect.width()) {
  +        // If the rect is bigger than the visible area, don't bother trying to center.  Other alignments will work.
  +        if (getVisibleBehavior(alignX) == alignCenter)
  +            scrollX = noScroll;
  +        else
  +            scrollX = getVisibleBehavior(alignX);
       }
  +    // If the rectangle is partially visible, but not above the minimum threshold, use the specified partial behavior
  +    else if (intersectWidth > 0)
  +        scrollX = getPartialBehavior(alignX);
  +        
  +    if (scrollX == noScroll) 
  +        x = visibleRect.x();
  +    // If we're trying to align to the closest edge, and the exposeRect is further right than the visibleRect, then alignRight.
  +    else if ((scrollX == alignRight) || ((scrollX == alignToClosestEdge) && exposeRect.right() > visibleRect.right()))
  +        x = exposeRect.right() - visibleRect.width();
  +    else if (scrollX == alignCenter)
  +        x -= (visibleRect.width() - w) / 2;
  +    // By default, x is set to the left of the exposeRect, so for the alignLeft case, 
  +    // or the alignToClosestEdge case where the closest edge is the left edge, then x does not need to be changed.
       w = visibleRect.width();
  -
  +    
  +    // Find the appropriate Y coordinate to scroll to.
  +    ScrollBehavior scrollY = getHiddenBehavior(alignY);
       int intersectHeight = visibleRect.intersect(exposeRect).height();
  -    if ((intersectHeight == h) && (verticalAlignment == alignDefault))
  -        y = visibleRect.y();
  -    else {
  -        switch (verticalAlignment) {
  -            case alignTop:
  -                // The y value is already equal to the top of the exposeRect
  -                break;
  -            case alignBottom: 
  -                y += exposeRect.height() - visibleRect.height();
  -                break;
  -            case alignCenter:
  -                if (h < visibleRect.height()) {
  -                    y -= (visibleRect.height() - h) / 2;
  -                } else {
  -                    if (visibleRect.y() >= y && exposeRect.bottom() >= visibleRect.bottom()) {
  -                        // Exposed rect fills the visible rect.
  -                        // We don't want the view to budge.
  -                        y = visibleRect.y();
  -                    }
  -                    else if (visibleRect.y() < y) {
  -                        // Scroll so top of visible region shows top of expose rect.
  -                        // Leave expose origin as it is to make this happen.
  -                    }
  -                    else {
  -                        // Scroll so bottom of visible region shows bottom of expose rect.
  -                        y = exposeRect.bottom() - visibleRect.height();
  -                    }
  -                }
  -            case alignDefault :
  -            default :
  -                if (h < visibleRect.height()) {
  -                    y -= (visibleRect.height() - h) / 2;
  -                }
  -        }
  +    // If the rectangle is fully visible, use the specified visible behavior.
  +    if (intersectHeight == h)
  +        scrollY = getVisibleBehavior(alignY);
  +    else if (intersectHeight == visibleRect.height()) {
  +        // If the rect is bigger than the visible area, don't bother trying to center.  Other alignments will work.
  +        if (getVisibleBehavior(alignY) == alignCenter)
  +            scrollY = noScroll;
  +        else
  +            scrollY = getVisibleBehavior(alignY);
       }
  +    // If the rectangle is partially visible, use the specified partial behavior
  +    else if (intersectHeight > 0)
  +        scrollY = getPartialBehavior(alignY);
  +        
  +    if (scrollY == noScroll) 
  +        y = visibleRect.y();
  +    // If we're trying to align to the closest edge, and the exposeRect is further down than the visibleRect, then alignBottom.
  +    else if ((scrollY == alignBottom) || ((scrollY == alignToClosestEdge) && exposeRect.bottom() > visibleRect.bottom()))
  +        y = exposeRect.bottom() - visibleRect.height();
  +    else if (scrollY == alignCenter)
  +        y -= (visibleRect.height() - h) / 2;
  +    // By default, y is set to the top of the exposeRect, so for the alignTop case, 
  +    // or the alignToEdgeY case where the closest edge is the top edge, then y does not need to be changed.
       h = visibleRect.height();
  -
  +    
       return QRect(x, y, w, h);
   }
   
  
  
  
  1.56      +28 -11    WebCore/khtml/rendering/render_layer.h
  
  Index: render_layer.h
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/rendering/render_layer.h,v
  retrieving revision 1.55
  retrieving revision 1.56
  diff -u -r1.55 -r1.56
  --- render_layer.h	2 Nov 2005 08:52:45 -0000	1.55
  +++ render_layer.h	3 Nov 2005 19:12:04 -0000	1.56
  @@ -50,15 +50,6 @@
   
   #include "render_object.h"
   
  -typedef enum {
  -    alignTop,
  -    alignBottom,
  -    alignLeft,
  -    alignRight,
  -    alignCenter,
  -    alignDefault // If the rect is visible in this dimension, we will not scroll.  Otherwise, we will center.  
  -} ScrollAlignment;
  -
   class QScrollBar;
   template <class T> class QPtrVector;
   
  @@ -168,6 +159,32 @@
   class RenderLayer
   {
   public:
  +    typedef enum {
  +        noScroll,
  +        alignCenter,
  +        alignTop,
  +        alignBottom, 
  +        alignLeft,
  +        alignRight,
  +        alignToClosestEdge
  +    } ScrollBehavior;
  +
  +    typedef struct {
  +        ScrollBehavior m_rectVisible;
  +        ScrollBehavior m_rectHidden;
  +        ScrollBehavior m_rectPartial;
  +    } ScrollAlignment;
  +
  +    static ScrollAlignment gAlignCenterIfNeeded;
  +    static ScrollAlignment gAlignToEdgeIfNeeded;
  +    static ScrollAlignment gAlignCenterAlways;
  +    static ScrollAlignment gAlignTopAlways;
  +    static ScrollAlignment gAlignBottomAlways;
  +    
  +    ScrollBehavior getVisibleBehavior(ScrollAlignment s) { return s.m_rectVisible; }
  +    ScrollBehavior getPartialBehavior(ScrollAlignment s) { return s.m_rectPartial; }
  +    ScrollBehavior getHiddenBehavior(ScrollAlignment s) { return s.m_rectHidden; }
  +
   #ifdef APPLE_CHANGES
       static QScrollBar* gScrollBar;
   #endif
  @@ -230,8 +247,8 @@
       void scrollToOffset(int x, int y, bool updateScrollbars = true, bool repaint = true);
       void scrollToXOffset(int x) { scrollToOffset(x, m_scrollY); }
       void scrollToYOffset(int y) { scrollToOffset(m_scrollX, y); }
  -    void scrollRectToVisible(const QRect &r, ScrollAlignment verticalAlignment = alignDefault, ScrollAlignment horizontalAlignment = alignDefault);
  -    QRect getRectToExpose(const QRect &visibleRect,  const QRect &exposeRect, ScrollAlignment verticalAlignment = alignDefault, ScrollAlignment horizontalAlignment = alignDefault);
  +    void scrollRectToVisible(const QRect &r, ScrollAlignment alignX = gAlignCenterIfNeeded, ScrollAlignment alignY = gAlignCenterIfNeeded);
  +    QRect getRectToExpose(const QRect &visibleRect,  const QRect &exposeRect, ScrollAlignment alignX, ScrollAlignment alignY);    
       void setHasHorizontalScrollbar(bool hasScrollbar);
       void setHasVerticalScrollbar(bool hasScrollbar);
       QScrollBar* horizontalScrollbar() { return m_hBar; }
  
  
  
  1.89      +4 -3      WebCore/khtml/xml/dom_elementimpl.cpp
  
  Index: dom_elementimpl.cpp
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/xml/dom_elementimpl.cpp,v
  retrieving revision 1.88
  retrieving revision 1.89
  diff -u -r1.88 -r1.89
  --- dom_elementimpl.cpp	26 Oct 2005 20:44:11 -0000	1.88
  +++ dom_elementimpl.cpp	3 Nov 2005 19:12:05 -0000	1.89
  @@ -352,11 +352,12 @@
   void ElementImpl::scrollIntoView(bool alignToTop) 
   {
       QRect bounds = this->getRect();    
  -    if (m_render && m_render->enclosingLayer()) {
  +    if (m_render) {
  +        // Align to the top / bottom and to the closest edge.
           if (alignToTop)
  -            m_render->enclosingLayer()->scrollRectToVisible(bounds, alignTop);
  +            m_render->enclosingLayer()->scrollRectToVisible(bounds, RenderLayer::gAlignToEdgeIfNeeded, RenderLayer::gAlignTopAlways);
           else
  -            m_render->enclosingLayer()->scrollRectToVisible(bounds, alignBottom);
  +            m_render->enclosingLayer()->scrollRectToVisible(bounds, RenderLayer::gAlignToEdgeIfNeeded, RenderLayer::gAlignBottomAlways);
       }
   }
   
  
  
  
  1.684     +1 -7      WebCore/kwq/KWQKHTMLPart.mm
  
  Index: KWQKHTMLPart.mm
  ===================================================================
  RCS file: /cvs/root/WebCore/kwq/KWQKHTMLPart.mm,v
  retrieving revision 1.683
  retrieving revision 1.684
  diff -u -r1.683 -r1.684
  --- KWQKHTMLPart.mm	2 Nov 2005 18:54:01 -0000	1.683
  +++ KWQKHTMLPart.mm	3 Nov 2005 19:12:06 -0000	1.684
  @@ -1277,12 +1277,6 @@
                   if (KHTMLPart::shouldChangeSelection(sel))
                       setSelection(sel);
               }
  -               
  -            if (node->renderer() && !node->renderer()->isRoot()) {
  -                RenderLayer *layer = node->renderer()->enclosingLayer();
  -                if (layer)
  -                    layer->scrollRectToVisible(node->getRect());
  -            }
    
               [_bridge makeFirstResponder:[_bridge documentView]];
               return [_bridge documentView];
  @@ -3441,7 +3435,7 @@
           RenderLayer *layer = selectionStart()->renderer()->enclosingLayer();
           if (layer) {
               ASSERT(!selectionEnd() || !selectionEnd()->renderer() || (selectionEnd()->renderer()->enclosingLayer() == layer));
  -            layer->scrollRectToVisible(rect, alignCenter, alignCenter);
  +            layer->scrollRectToVisible(rect, RenderLayer::gAlignCenterAlways, RenderLayer::gAlignCenterAlways);
           }
       }
   }
  
  
  
  1.41      +0 -2      WebCore/kwq/KWQScrollView.h
  
  Index: KWQScrollView.h
  ===================================================================
  RCS file: /cvs/root/WebCore/kwq/KWQScrollView.h,v
  retrieving revision 1.40
  retrieving revision 1.41
  diff -u -r1.40 -r1.41
  --- KWQScrollView.h	25 Oct 2005 21:14:48 -0000	1.40
  +++ KWQScrollView.h	3 Nov 2005 19:12:06 -0000	1.41
  @@ -87,8 +87,6 @@
       void setStaticBackground(bool);
   
       void resizeEvent(QResizeEvent *);
  -
  -    void ensureRectVisible(const QRect &r);
           
       NSView *getDocumentView() const;
   
  
  
  
  1.86      +0 -8      WebCore/kwq/KWQScrollView.mm
  
  Index: KWQScrollView.mm
  ===================================================================
  RCS file: /cvs/root/WebCore/kwq/KWQScrollView.mm,v
  retrieving revision 1.85
  retrieving revision 1.86
  diff -u -r1.85 -r1.86
  --- KWQScrollView.mm	25 Oct 2005 21:14:48 -0000	1.85
  +++ KWQScrollView.mm	3 Nov 2005 19:12:07 -0000	1.86
  @@ -446,14 +446,6 @@
   {
   }
   
  -void QScrollView::ensureRectVisible(const QRect &rect)
  -{
  -    KWQ_BLOCK_EXCEPTIONS;
  -    NSRect tempRect = { {rect.x(), rect.y()}, {rect.width(), rect.height()} }; // workaround for 4213314
  -    [getDocumentView() scrollRectToVisible:tempRect];
  -    KWQ_UNBLOCK_EXCEPTIONS;
  -}
  -
   NSView *QScrollView::getDocumentView() const
   {
       id view = getView();
  
  
  
  1.424     +1 -1      WebCore/kwq/WebCoreBridge.mm
  
  Index: WebCoreBridge.mm
  ===================================================================
  RCS file: /cvs/root/WebCore/kwq/WebCoreBridge.mm,v
  retrieving revision 1.423
  retrieving revision 1.424
  diff -u -r1.423 -r1.424
  --- WebCoreBridge.mm	1 Nov 2005 19:19:37 -0000	1.423
  +++ WebCoreBridge.mm	3 Nov 2005 19:12:07 -0000	1.424
  @@ -2108,7 +2108,7 @@
       QRect extentRect = renderer->caretRect(extent.offset(), _part->selection().extentAffinity());
       RenderLayer *layer = renderer->enclosingLayer();
       if (layer)
  -        layer->scrollRectToVisible(extentRect, alignCenter, alignCenter);
  +        layer->scrollRectToVisible(extentRect);
   }
   
   // [info draggingLocation] is in window coords
  
  
  



More information about the webkit-changes mailing list