2008-08-08 Maxime Britto <britto@apple.com>
authorbritto@apple.com <britto@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 9 Aug 2008 00:15:05 +0000 (00:15 +0000)
committerbritto@apple.com <britto@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 9 Aug 2008 00:15:05 +0000 (00:15 +0000)
        Reviewed by Adele.

        Test: fast/events/scroll-to-anchor-in-overflow-hidden.html
        https://bugs.webkit.org/show_bug.cgi?id=20270
        Jump to an anchor wasn't working when the overflow:hidden CSS attribute was set on the page.

        * WebCore.base.exp:
        * dom/Element.cpp:
        (WebCore::Element::scrollIntoView):
        (WebCore::Element::scrollIntoViewIfNeeded):
        * loader/FrameLoader.cpp:
        (WebCore::FrameLoader::gotoAnchor):
        * page/EventHandler.cpp:
        (WebCore::EventHandler::handleMousePressEvent):
        (WebCore::EventHandler::handleMouseDraggedEvent):
        * page/Frame.cpp:
        (WebCore::Frame::revealSelection):
        (WebCore::Frame::revealCaret):
        * rendering/RenderLayer.cpp:
        (WebCore::RenderLayer::scrollRectToVisible): Takes a new parameter "scrollToAnchor" since it's a special case of scroll. It passes this new bool to canBeProgrammaticallyScrolled.
        (WebCore::RenderLayer::autoscroll):
        * rendering/RenderLayer.h:
        * rendering/RenderListBox.h:
        (WebCore::RenderListBox::canBeProgramaticallyScrolled):
        * rendering/RenderObject.cpp:
        (WebCore::RenderObject::canBeProgramaticallyScrolled): If the call is coming from a scrollToAnchor we don't need scrollBars to accept.
        * rendering/RenderObject.h:
        * rendering/RenderTextControl.h:
        (WebCore::RenderTextControl::canBeProgramaticallyScrolled):

2008-08-08  Maxime Britto  <britto@apple.com>

        Reviewed by Adele.

        * WebView/WebFrame.mm:
        (-[WebFrame _scrollDOMRangeToVisible:]):

2008-08-08  Maxime Britto  <britto@apple.com>

        Reviewed by Adele.
        https://bugs.webkit.org/show_bug.cgi?id=20270
        This test is automatic and can also be run manually.

        * fast/events/scroll-to-anchor-in-overflow-hidden-expected.txt: Added.
        * fast/events/scroll-to-anchor-in-overflow-hidden.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@35648 268f45cc-cd09-0410-ab3c-d52691b4dbfc

17 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/events/scroll-to-anchor-in-overflow-hidden-expected.txt [new file with mode: 0644]
LayoutTests/fast/events/scroll-to-anchor-in-overflow-hidden.html [new file with mode: 0644]
WebCore/ChangeLog
WebCore/WebCore.base.exp
WebCore/dom/Element.cpp
WebCore/loader/FrameLoader.cpp
WebCore/page/EventHandler.cpp
WebCore/page/Frame.cpp
WebCore/rendering/RenderLayer.cpp
WebCore/rendering/RenderLayer.h
WebCore/rendering/RenderListBox.h
WebCore/rendering/RenderObject.cpp
WebCore/rendering/RenderObject.h
WebCore/rendering/RenderTextControl.h
WebKit/mac/ChangeLog
WebKit/mac/WebView/WebFrame.mm

index 210163a..d46a7d3 100644 (file)
@@ -1,3 +1,12 @@
+2008-08-08  Maxime Britto  <britto@apple.com>
+
+        Reviewed by Adele.
+        https://bugs.webkit.org/show_bug.cgi?id=20270
+        This test is automatic and can also be run manually.
+
+        * fast/events/scroll-to-anchor-in-overflow-hidden-expected.txt: Added.
+        * fast/events/scroll-to-anchor-in-overflow-hidden.html: Added.
+
 2008-08-05  David D. Kilzer  <ddkilzer@apple.com>
 
         Bug 20038: REGRESSION (r35151): Can't post comments on flickr.com
diff --git a/LayoutTests/fast/events/scroll-to-anchor-in-overflow-hidden-expected.txt b/LayoutTests/fast/events/scroll-to-anchor-in-overflow-hidden-expected.txt
new file mode 100644 (file)
index 0000000..7ac75de
--- /dev/null
@@ -0,0 +1,10 @@
+Link to Bottom of the page
+https://bugs.webkit.org/show_bug.cgi?id=20270 
+This test verifies that a anchor link overrides the overflow:hidden attribute by scrolling somewhere on a page.
+To do the test manually you have to click on the anchor link above. If the scroll occurs to the bottom of the page : the test has PASSED.
+If you stay here after the click, the test has failed. 
+
+
+
+Automated test : PASSED
+Bottom of the page Manual Test : PASSED
diff --git a/LayoutTests/fast/events/scroll-to-anchor-in-overflow-hidden.html b/LayoutTests/fast/events/scroll-to-anchor-in-overflow-hidden.html
new file mode 100644 (file)
index 0000000..d7c6cd6
--- /dev/null
@@ -0,0 +1,65 @@
+<html>
+    <head>
+       <style type="text/css">   
+          html { overflow: hidden; }
+          #top { margin: 100em 3em 0; padding: 2em 0 0 .5em; }
+       </style>
+        <script>
+       function log(msg)
+       {
+           document.getElementById('console').appendChild(document.createTextNode(msg + '\n'));
+       }
+
+
+      function logMousePosition(event) {
+   log ("Mouse:x = " + event.x + " , y = " + event.y);
+}
+
+       function test()
+       {
+           if (window.layoutTestController) {
+               layoutTestController.waitUntilDone();
+               layoutTestController.dumpAsText();
+               setTimeout(scrollToAnchor, 0);
+           }
+       }
+
+       function scrollToAnchor()
+       {
+           if (window.eventSender) {
+               var input = document.getElementById('ANCHORLINK');
+               var x = input.offsetLeft;
+               var y = input.offsetTop;
+               eventSender.mouseMoveTo(x, y);
+               eventSender.mouseDown();
+               eventSender.mouseUp();
+           }
+
+           if (document.body.scrollTop == 0)
+               log("Automated test : FAILED  : no scroll has occured ");
+           else
+               log("Automated test : PASSED");
+
+           if (window.layoutTestController)
+               layoutTestController.notifyDone();
+       }     
+        </script>
+    </head>
+<body onload="test()">
+
+    
+    <div id="ANCHORLINK">
+        <a href="#bottom">Link to Bottom of the page</a>
+   </div>
+   
+       https://bugs.webkit.org/show_bug.cgi?id=20270 <br>
+       This test verifies that a anchor link overrides the overflow:hidden attribute by scrolling somewhere on a page.<br>
+       To do the test manually you have to click on the anchor link above. If the scroll occurs to the bottom of the page : the test has PASSED.<br>
+       If you stay here after the click, the test has failed. <br><br><br><br>
+<div id="console" style="height: 1000px;"></div>
+<a name="bottom">Bottom of the page</a>
+Manual Test : PASSED
+   
+    
+</body>
+</html>
index 1803632..0b8aec1 100644 (file)
@@ -2,6 +2,38 @@
 
         Reviewed by Adele.
 
+        Test: fast/events/scroll-to-anchor-in-overflow-hidden.html
+        https://bugs.webkit.org/show_bug.cgi?id=20270
+        Jump to an anchor wasn't working when the overflow:hidden CSS attribute was set on the page.
+
+        * WebCore.base.exp:
+        * dom/Element.cpp:
+        (WebCore::Element::scrollIntoView):
+        (WebCore::Element::scrollIntoViewIfNeeded):
+        * loader/FrameLoader.cpp:
+        (WebCore::FrameLoader::gotoAnchor):
+        * page/EventHandler.cpp:
+        (WebCore::EventHandler::handleMousePressEvent):
+        (WebCore::EventHandler::handleMouseDraggedEvent):
+        * page/Frame.cpp:
+        (WebCore::Frame::revealSelection):
+        (WebCore::Frame::revealCaret):
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::scrollRectToVisible): Takes a new parameter "scrollToAnchor" since it's a special case of scroll. It passes this new bool to canBeProgrammaticallyScrolled. 
+        (WebCore::RenderLayer::autoscroll):
+        * rendering/RenderLayer.h:
+        * rendering/RenderListBox.h:
+        (WebCore::RenderListBox::canBeProgramaticallyScrolled):
+        * rendering/RenderObject.cpp:
+        (WebCore::RenderObject::canBeProgramaticallyScrolled): If the call is coming from a scrollToAnchor we don't need scrollBars to accept.
+        * rendering/RenderObject.h:
+        * rendering/RenderTextControl.h:
+        (WebCore::RenderTextControl::canBeProgramaticallyScrolled):
+
+2008-08-08  Maxime Britto  <britto@apple.com>
+
+        Reviewed by Adele.
+
         <rdar://problem/6137022>
         <https://bugs.webkit.org/show_bug.cgi?id=20331>
         REGRESSION(r35177-r35203): Scrolling slowly over a scrollable field scrolls the page instead of the field (20331)
index 8dbb6eb..3d465bc 100644 (file)
@@ -196,7 +196,7 @@ __ZN7WebCore11HistoryItemD1Ev
 __ZN7WebCore11IconFetcher6cancelEv
 __ZN7WebCore11IconFetcher6createEPNS_5FrameEPNS_17IconFetcherClientE
 __ZN7WebCore11RenderLayer18gAlignCenterAlwaysE
-__ZN7WebCore11RenderLayer19scrollRectToVisibleERKNS_7IntRectERKNS0_15ScrollAlignmentES6_
+__ZN7WebCore11RenderLayer19scrollRectToVisibleERKNS_7IntRectEbRKNS0_15ScrollAlignmentES6_
 __ZN7WebCore11RenderLayer20gAlignToEdgeIfNeededE
 __ZN7WebCore11currentTimeEv
 __ZN7WebCore11globalPointERK8_NSPointP8NSWindow
index 8be0848..c0f90db 100644 (file)
@@ -248,9 +248,9 @@ void Element::scrollIntoView(bool alignToTop)
     if (renderer()) {
         // Align to the top / bottom and to the closest edge.
         if (alignToTop)
-            renderer()->enclosingLayer()->scrollRectToVisible(bounds, RenderLayer::gAlignToEdgeIfNeeded, RenderLayer::gAlignTopAlways);
+            renderer()->enclosingLayer()->scrollRectToVisible(bounds, false, RenderLayer::gAlignToEdgeIfNeeded, RenderLayer::gAlignTopAlways);
         else
-            renderer()->enclosingLayer()->scrollRectToVisible(bounds, RenderLayer::gAlignToEdgeIfNeeded, RenderLayer::gAlignBottomAlways);
+            renderer()->enclosingLayer()->scrollRectToVisible(bounds, false, RenderLayer::gAlignToEdgeIfNeeded, RenderLayer::gAlignBottomAlways);
     }
 }
 
@@ -260,9 +260,9 @@ void Element::scrollIntoViewIfNeeded(bool centerIfNeeded)
     IntRect bounds = getRect();    
     if (renderer()) {
         if (centerIfNeeded)
-            renderer()->enclosingLayer()->scrollRectToVisible(bounds, RenderLayer::gAlignCenterIfNeeded, RenderLayer::gAlignCenterIfNeeded);
+            renderer()->enclosingLayer()->scrollRectToVisible(bounds, false, RenderLayer::gAlignCenterIfNeeded, RenderLayer::gAlignCenterIfNeeded);
         else
-            renderer()->enclosingLayer()->scrollRectToVisible(bounds, RenderLayer::gAlignToEdgeIfNeeded, RenderLayer::gAlignToEdgeIfNeeded);
+            renderer()->enclosingLayer()->scrollRectToVisible(bounds, false, RenderLayer::gAlignToEdgeIfNeeded, RenderLayer::gAlignToEdgeIfNeeded);
     }
 }
 
index f04902a..a6b4de0 100644 (file)
@@ -1660,7 +1660,7 @@ bool FrameLoader::gotoAnchor(const String& name)
         rect = anchorNode->getRect();
     }
     if (renderer)
-        renderer->enclosingLayer()->scrollRectToVisible(rect, RenderLayer::gAlignToEdgeIfNeeded, RenderLayer::gAlignTopAlways);
+        renderer->enclosingLayer()->scrollRectToVisible(rect, true, RenderLayer::gAlignToEdgeIfNeeded, RenderLayer::gAlignTopAlways);
 
     return true;
 }
index 9f9e626..b347a62 100644 (file)
@@ -368,7 +368,7 @@ bool EventHandler::handleMousePressEvent(const MouseEventWithHitTestResults& eve
     }
     
    m_mouseDownMayStartAutoscroll = m_mouseDownMayStartSelect || 
-        (m_mousePressNode && m_mousePressNode->renderer() && m_mousePressNode->renderer()->canBeProgramaticallyScrolled());
+        (m_mousePressNode && m_mousePressNode->renderer() && m_mousePressNode->renderer()->canBeProgramaticallyScrolled(true));
 
    return swallowEvent;
 }
@@ -395,7 +395,7 @@ bool EventHandler::handleMouseDraggedEvent(const MouseEventWithHitTestResults& e
         // If the selection is contained in a layer that can scroll, that layer should handle the autoscroll
         // Otherwise, let the bridge handle it so the view can scroll itself.
         RenderObject* renderer = targetNode->renderer();
-        while (renderer && !renderer->canBeProgramaticallyScrolled())
+        while (renderer && !renderer->canBeProgramaticallyScrolled(true))
             renderer = renderer->parent();
         if (renderer) {
             m_autoscrollInProgress = true;
@@ -981,7 +981,7 @@ bool EventHandler::handleMousePressEvent(const PlatformMouseEvent& mouseEvent)
     if (mouseEvent.button() == MiddleButton && !mev.isOverLink()) {
         RenderObject* renderer = mev.targetNode()->renderer();
 
-        while (renderer && !renderer->canBeProgramaticallyScrolled())
+        while (renderer && !renderer->canBeProgramaticallyScrolled(true))
             renderer = renderer->parent();
 
         if (renderer) {
index 3deb8c0..a51f980 100644 (file)
@@ -1208,7 +1208,7 @@ void Frame::revealSelection(const RenderLayer::ScrollAlignment& alignment) const
         // the selection rect could intersect more than just that. 
         // See <rdar://problem/4799899>.
         if (RenderLayer *layer = start.node()->renderer()->enclosingLayer())
-            layer->scrollRectToVisible(rect, alignment, alignment);
+            layer->scrollRectToVisible(rect, false, alignment, alignment);
     }
 }
 
@@ -1222,7 +1222,7 @@ void Frame::revealCaret(const RenderLayer::ScrollAlignment& alignment) const
         IntRect extentRect = VisiblePosition(extent).caretRect();
         RenderLayer* layer = extent.node()->renderer()->enclosingLayer();
         if (layer)
-            layer->scrollRectToVisible(extentRect, alignment, alignment);
+            layer->scrollRectToVisible(extentRect, false, alignment, alignment);
     }
 }
 
index e59a097..e40be4b 100644 (file)
@@ -809,7 +809,7 @@ void RenderLayer::scrollToOffset(int x, int y, bool updateScrollbars, bool repai
     }
 }
 
-void RenderLayer::scrollRectToVisible(const IntRect &rect, const ScrollAlignment& alignX, const ScrollAlignment& alignY)
+void RenderLayer::scrollRectToVisible(const IntRect &rect, bool scrollToAnchor, const ScrollAlignment& alignX, const ScrollAlignment& alignY)
 {
     RenderLayer* parentLayer = 0;
     IntRect newRect = rect;
@@ -854,7 +854,7 @@ void RenderLayer::scrollRectToVisible(const IntRect &rect, const ScrollAlignment
             newRect.setX(rect.x() - diffX);
             newRect.setY(rect.y() - diffY);
         }
-    } else if (!parentLayer && renderer()->canBeProgramaticallyScrolled()) {
+    } else if (!parentLayer && renderer()->canBeProgramaticallyScrolled(scrollToAnchor)) {
         if (frameView) {
             if (m_object->document() && m_object->document()->ownerElement() && m_object->document()->ownerElement()->renderer()) {
                 IntRect viewRect = enclosingIntRect(frameView->visibleContentRect());
@@ -882,7 +882,7 @@ void RenderLayer::scrollRectToVisible(const IntRect &rect, const ScrollAlignment
     }
     
     if (parentLayer)
-        parentLayer->scrollRectToVisible(newRect, alignX, alignY);
+        parentLayer->scrollRectToVisible(newRect, scrollToAnchor, alignX, alignY);
 
     if (frameView)
         frameView->resumeScheduledEvents();
@@ -974,7 +974,7 @@ void RenderLayer::autoscroll()
     frame->eventHandler()->updateSelectionForMouseDrag();
 
     IntPoint currentDocumentPosition = frameView->windowToContents(frame->eventHandler()->currentMousePosition());
-    scrollRectToVisible(IntRect(currentDocumentPosition, IntSize(1, 1)), gAlignToEdgeIfNeeded, gAlignToEdgeIfNeeded);    
+    scrollRectToVisible(IntRect(currentDocumentPosition, IntSize(1, 1)), false, gAlignToEdgeIfNeeded, gAlignToEdgeIfNeeded);    
 }
 
 void RenderLayer::resize(const PlatformMouseEvent& evt, const IntSize& oldOffset)
index ac136c1..d42a366 100644 (file)
@@ -212,7 +212,7 @@ public:
     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 + m_scrollOriginX, y); }
-    void scrollRectToVisible(const IntRect&, const ScrollAlignment& alignX = gAlignCenterIfNeeded, const ScrollAlignment& alignY = gAlignCenterIfNeeded);
+    void scrollRectToVisible(const IntRect&, bool scrollToAnchor = false, const ScrollAlignment& alignX = gAlignCenterIfNeeded, const ScrollAlignment& alignY = gAlignCenterIfNeeded);
 
     IntRect getRectToExpose(const IntRect& visibleRect, const IntRect& exposeRect, const ScrollAlignment& alignX, const ScrollAlignment& alignY);    
 
index b050675..9e644e4 100644 (file)
@@ -77,7 +77,7 @@ public:
     bool scrollToRevealElementAtListIndex(int index);
     bool listIndexIsVisible(int index);
 
-    virtual bool canBeProgramaticallyScrolled() const { return true; }
+    virtual bool canBeProgramaticallyScrolled(bool) const { return true; }
     virtual void autoscroll();
     virtual void stopAutoscroll();
 
index 1278afa..b030140 100644 (file)
@@ -636,9 +636,9 @@ bool RenderObject::scroll(ScrollDirection direction, ScrollGranularity granulari
     return false;
 }
     
-bool RenderObject::canBeProgramaticallyScrolled() const
+bool RenderObject::canBeProgramaticallyScrolled(bool scrollToAnchor) const
 {
-    return (hasOverflowClip() && (scrollsOverflow() || (node() && node()->isContentEditable()))) || ((node() && node()->isDocumentNode()) && hasScrollableView());
+    return (hasOverflowClip() && (scrollsOverflow() || (node() && node()->isContentEditable()))) || ((node() && node()->isDocumentNode()) && (hasScrollableView() || scrollToAnchor));
 }
     
 bool RenderObject::hasScrollableView() const
index a902a05..a8a7180 100644 (file)
@@ -650,7 +650,7 @@ public:
     virtual void setScrollTop(int);
 
     virtual bool scroll(ScrollDirection, ScrollGranularity, float multiplier = 1.0f);
-    virtual bool canBeProgramaticallyScrolled() const;
+    virtual bool canBeProgramaticallyScrolled(bool) const;
     bool hasScrollableView() const;
     virtual void autoscroll();
     virtual void stopAutoscroll() { }
index 891a2e6..d6491e9 100644 (file)
@@ -78,7 +78,7 @@ public:
     void forwardEvent(Event*);
     void selectionChanged(bool userTriggered);
 
-    virtual bool canBeProgramaticallyScrolled() const { return true; }
+    virtual bool canBeProgramaticallyScrolled(bool) const { return true; }
     virtual void autoscroll();
 
     // Subclassed to forward to our inner div.
index 06a0cd6..e941691 100644 (file)
@@ -1,3 +1,10 @@
+2008-08-08  Maxime Britto  <britto@apple.com>
+
+        Reviewed by Adele.
+
+        * WebView/WebFrame.mm:
+        (-[WebFrame _scrollDOMRangeToVisible:]):
+
 2008-08-08  Brady Eidson  <beidson@apple.com>
 
         Reviewed by Sam Weinig
index 42a7491..9eb0fb9 100644 (file)
@@ -67,6 +67,7 @@
 #import <WebCore/Page.h>
 #import <WebCore/PluginData.h>
 #import <WebCore/RenderView.h>
+#import <WebCore/RenderLayer.h>
 #import <WebCore/ReplaceSelectionCommand.h>
 #import <WebCore/SmartReplace.h>
 #import <WebCore/SystemTime.h>
@@ -643,7 +644,7 @@ static inline WebDataSource *dataSource(DocumentLoader* loader)
     if (startNode && startNode->renderer()) {
         RenderLayer *layer = startNode->renderer()->enclosingLayer();
         if (layer)
-            layer->scrollRectToVisible(enclosingIntRect(rangeRect), RenderLayer::gAlignToEdgeIfNeeded, RenderLayer::gAlignToEdgeIfNeeded);
+            layer->scrollRectToVisible(enclosingIntRect(rangeRect), false, RenderLayer::gAlignToEdgeIfNeeded, RenderLayer::gAlignToEdgeIfNeeded);
     }
 }