- Revision
- 119679
- Author
- [email protected]
- Date
- 2012-06-06 21:34:23 -0700 (Wed, 06 Jun 2012)
Log Message
[BlackBerry] Implement a top-down in-region boundary detection in InRegionScrollableArea
https://bugs.webkit.org/show_bug.cgi?id=88254
PR #125237
Reviewed by Rob Buis.
Patch by Antonio Gomes <[email protected]>
Patch implements a top-down visibleWindowRect calculation for all scrollable
elements hit-tested by a given point.
The reason on why this approach is better is that it calculates the visible
window rect from the outtermost scrollable element towards the inner ones, and
that allows it to use the visible window rect of the previous scrollable element
as the clipping rect for the current one.
Patch also changes the return vector to store ScrollViewBase pointers, so
we can make use of static_cast properly.
Internally reviewed by Jakob Petsovits.
* Api/WebPage.cpp:
(BlackBerry::WebKit::pushBackInRegionScrollable):
(BlackBerry::WebKit::WebPagePrivate::inRegionScrollableAreasForPoint):
* Api/WebPageClient.h:
* Api/WebPage_p.h:
(WebPagePrivate):
* WebKitSupport/InRegionScrollableArea.cpp:
(BlackBerry::WebKit::InRegionScrollableArea::InRegionScrollableArea):
(BlackBerry::WebKit::InRegionScrollableArea::setVisibleWindowRect):
(WebKit):
(BlackBerry::WebKit::InRegionScrollableArea::visibleWindowRect):
* WebKitSupport/InRegionScrollableArea.h:
(InRegionScrollableArea):
Modified Paths
Diff
Modified: trunk/Source/WebKit/blackberry/Api/WebPage.cpp (119678 => 119679)
--- trunk/Source/WebKit/blackberry/Api/WebPage.cpp 2012-06-07 04:26:23 UTC (rev 119678)
+++ trunk/Source/WebKit/blackberry/Api/WebPage.cpp 2012-06-07 04:34:23 UTC (rev 119679)
@@ -4633,23 +4633,23 @@
return 0;
}
-static void pushBackInRegionScrollable(std::vector<Platform::ScrollViewBase>& vector, InRegionScrollableArea scroller, WebPagePrivate* webPage)
+static void pushBackInRegionScrollable(std::vector<Platform::ScrollViewBase*>& vector, InRegionScrollableArea* scroller, WebPagePrivate* webPage)
{
ASSERT(webPage);
ASSERT(!scroller.isNull());
- scroller.setCanPropagateScrollingToEnclosingScrollable(!isNonRenderViewFixedPositionedContainer(scroller.layer()));
+ scroller->setCanPropagateScrollingToEnclosingScrollable(!isNonRenderViewFixedPositionedContainer(scroller->layer()));
vector.push_back(scroller);
if (vector.size() == 1) {
// FIXME: Use RenderLayer::renderBox()->node() instead?
- webPage->m_inRegionScrollStartingNode = enclosingLayerNode(scroller.layer());
+ webPage->m_inRegionScrollStartingNode = enclosingLayerNode(scroller->layer());
}
}
-std::vector<Platform::ScrollViewBase> WebPagePrivate::inRegionScrollableAreasForPoint(const Platform::IntPoint& point)
+std::vector<Platform::ScrollViewBase*> WebPagePrivate::inRegionScrollableAreasForPoint(const Platform::IntPoint& point)
{
- std::vector<Platform::ScrollViewBase> validReturn;
- std::vector<Platform::ScrollViewBase> emptyReturn;
+ std::vector<Platform::ScrollViewBase*> validReturn;
+ std::vector<Platform::ScrollViewBase*> emptyReturn;
HitTestResult result = m_mainFrame->eventHandler()->hitTestResultAtPoint(mapFromViewportToContents(point), false /*allowShadowContent*/);
Node* node = result.innerNonSharedNode();
@@ -4672,26 +4672,63 @@
return emptyReturn;
if (canScrollInnerFrame(view->frame())) {
- pushBackInRegionScrollable(validReturn, InRegionScrollableArea(this, layer), this);
+ pushBackInRegionScrollable(validReturn, new InRegionScrollableArea(this, layer), this);
continue;
}
}
} else if (canScrollRenderBox(layer->renderBox())) {
- pushBackInRegionScrollable(validReturn, InRegionScrollableArea(this, layer), this);
+ pushBackInRegionScrollable(validReturn, new InRegionScrollableArea(this, layer), this);
continue;
}
// If we run into a fix positioned layer, set the last scrollable in-region object
// as not able to propagate scroll to its parent scrollable.
if (isNonRenderViewFixedPositionedContainer(layer) && validReturn.size()) {
- Platform::ScrollViewBase& end = validReturn.back();
- end.setCanPropagateScrollingToEnclosingScrollable(false);
+ Platform::ScrollViewBase* end = validReturn.back();
+ end->setCanPropagateScrollingToEnclosingScrollable(false);
}
} while (layer = parentLayer(layer));
+
if (validReturn.empty())
return emptyReturn;
+ // Post-calculate the visible window rects in reverse hit test order so
+ // we account for all and any clipping rects.
+ WebCore::IntRect recursiveClippingRect(WebCore::IntPoint::zero(), transformedViewportSize());
+
+ std::vector<Platform::ScrollViewBase*>::reverse_iterator rend = validReturn.rend();
+ for (std::vector<Platform::ScrollViewBase*>::reverse_iterator rit = validReturn.rbegin(); rit != rend; ++rit) {
+
+ InRegionScrollableArea* curr = static_cast<InRegionScrollableArea*>(*rit);
+ RenderLayer* layer = curr->layer();
+
+ if (layer && layer->renderer()->isRenderView()) { // #document case
+ FrameView* view = toRenderView(layer->renderer())->frameView();
+ ASSERT(view);
+ ASSERT(canScrollInnerFrame(view->frame()));
+
+ WebCore::IntRect frameWindowRect = mapToTransformed(getRecursiveVisibleWindowRect(view));
+ frameWindowRect.intersect(recursiveClippingRect);
+ curr->setVisibleWindowRect(frameWindowRect);
+ recursiveClippingRect = frameWindowRect;
+
+ } else { // RenderBox-based elements case (scrollable boxes (div's, p's, textarea's, etc)).
+
+ RenderBox* box = layer->renderBox();
+ ASSERT(box);
+ ASSERT(canScrollRenderBox(box));
+
+ WebCore::IntRect visibleWindowRect = box->absoluteClippedOverflowRect();
+ visibleWindowRect = box->frame()->view()->contentsToWindow(visibleWindowRect);
+ visibleWindowRect = mapToTransformed(visibleWindowRect);
+ visibleWindowRect.intersect(recursiveClippingRect);
+
+ curr->setVisibleWindowRect(visibleWindowRect);
+ recursiveClippingRect = visibleWindowRect;
+ }
+ }
+
return validReturn;
}
Modified: trunk/Source/WebKit/blackberry/Api/WebPageClient.h (119678 => 119679)
--- trunk/Source/WebKit/blackberry/Api/WebPageClient.h 2012-06-07 04:26:23 UTC (rev 119678)
+++ trunk/Source/WebKit/blackberry/Api/WebPageClient.h 2012-06-07 04:34:23 UTC (rev 119679)
@@ -99,7 +99,8 @@
virtual void notifyRunLayoutTestsFinished() = 0;
- virtual void notifyInRegionScrollingStartingPointChanged(std::vector<Platform::ScrollViewBase>) = 0;
+ // Client is responsible for deleting the vector elements.
+ virtual void notifyInRegionScrollingStartingPointChanged(std::vector<Platform::ScrollViewBase*>) = 0;
virtual void notifyDocumentOnLoad() = 0;
Modified: trunk/Source/WebKit/blackberry/Api/WebPage_p.h (119678 => 119679)
--- trunk/Source/WebKit/blackberry/Api/WebPage_p.h 2012-06-07 04:26:23 UTC (rev 119678)
+++ trunk/Source/WebKit/blackberry/Api/WebPage_p.h 2012-06-07 04:34:23 UTC (rev 119679)
@@ -138,7 +138,7 @@
bool scrollBy(int deltaX, int deltaY, bool scrollMainFrame = true);
void enqueueRenderingOfClippedContentOfScrollableNodeAfterInRegionScrolling(WebCore::Node*);
- std::vector<Platform::ScrollViewBase> inRegionScrollableAreasForPoint(const Platform::IntPoint&);
+ std::vector<Platform::ScrollViewBase*> inRegionScrollableAreasForPoint(const Platform::IntPoint&);
void notifyInRegionScrollStatusChanged(bool status);
void setScrollOriginPoint(const Platform::IntPoint&);
void setHasInRegionScrollableAreas(bool);
Modified: trunk/Source/WebKit/blackberry/ChangeLog (119678 => 119679)
--- trunk/Source/WebKit/blackberry/ChangeLog 2012-06-07 04:26:23 UTC (rev 119678)
+++ trunk/Source/WebKit/blackberry/ChangeLog 2012-06-07 04:34:23 UTC (rev 119679)
@@ -1,3 +1,40 @@
+2012-06-05 Antonio Gomes <[email protected]>
+
+ [BlackBerry] Implement a top-down in-region boundary detection in InRegionScrollableArea
+ https://bugs.webkit.org/show_bug.cgi?id=88254
+ PR #125237
+
+ Reviewed by Rob Buis.
+
+ Patch implements a top-down visibleWindowRect calculation for all scrollable
+ elements hit-tested by a given point.
+
+ The reason on why this approach is better is that it calculates the visible
+ window rect from the outermost scrollable element towards the inner ones, and
+ that allows it to use the visible window rect of the previous scrollable element
+ as the clipping rect for the current one.
+
+ Patch also changes the return vector to store ScrollViewBase pointers, so
+ we can make use of static_cast properly. As now also stated in the header
+ file, the client is responsible for deleting the ScrollViewBase
+ elements in the vector.
+
+ Internally reviewed by Jakob Petsovits.
+
+ * Api/WebPage.cpp:
+ (BlackBerry::WebKit::pushBackInRegionScrollable):
+ (BlackBerry::WebKit::WebPagePrivate::inRegionScrollableAreasForPoint):
+ * Api/WebPageClient.h:
+ * Api/WebPage_p.h:
+ (WebPagePrivate):
+ * WebKitSupport/InRegionScrollableArea.cpp:
+ (BlackBerry::WebKit::InRegionScrollableArea::InRegionScrollableArea):
+ (BlackBerry::WebKit::InRegionScrollableArea::setVisibleWindowRect):
+ (WebKit):
+ (BlackBerry::WebKit::InRegionScrollableArea::visibleWindowRect):
+ * WebKitSupport/InRegionScrollableArea.h:
+ (InRegionScrollableArea):
+
2012-06-06 Charles Wei <[email protected]>
[BlackBerry] IndexedDB file should be sand-boxed to the application data directory.
Modified: trunk/Source/WebKit/blackberry/WebKitSupport/InRegionScrollableArea.cpp (119678 => 119679)
--- trunk/Source/WebKit/blackberry/WebKitSupport/InRegionScrollableArea.cpp 2012-06-07 04:26:23 UTC (rev 119678)
+++ trunk/Source/WebKit/blackberry/WebKitSupport/InRegionScrollableArea.cpp 2012-06-07 04:34:23 UTC (rev 119679)
@@ -35,12 +35,14 @@
InRegionScrollableArea::InRegionScrollableArea()
: m_webPage(0)
, m_layer(0)
+ , m_hasWindowVisibleRectCalculated(false)
{
}
InRegionScrollableArea::InRegionScrollableArea(WebPagePrivate* webPage, RenderLayer* layer)
: m_webPage(webPage)
, m_layer(layer)
+ , m_hasWindowVisibleRectCalculated(false)
{
ASSERT(webPage);
ASSERT(layer);
@@ -63,10 +65,6 @@
m_contentsSize = m_webPage->mapToTransformed(view->contentsSize());
m_viewportSize = m_webPage->mapToTransformed(view->visibleContentRect(false /*includeScrollbars*/)).size();
- m_visibleWindowRect = m_webPage->mapToTransformed(m_webPage->getRecursiveVisibleWindowRect(view));
- IntRect transformedWindowRect = IntRect(IntPoint::zero(), m_webPage->transformedViewportSize());
- m_visibleWindowRect.intersect(transformedWindowRect);
-
m_scrollsHorizontally = view->contentsWidth() > view->visibleWidth();
m_scrollsVertically = view->contentsHeight() > view->visibleHeight();
@@ -82,14 +80,6 @@
m_contentsSize = m_webPage->mapToTransformed(scrollableArea->contentsSize());
m_viewportSize = m_webPage->mapToTransformed(scrollableArea->visibleContentRect(false /*includeScrollbars*/)).size();
- m_visibleWindowRect = m_layer->renderer()->absoluteClippedOverflowRect();
- m_visibleWindowRect = m_layer->renderer()->frame()->view()->contentsToWindow(m_visibleWindowRect);
- IntRect visibleFrameWindowRect = m_webPage->getRecursiveVisibleWindowRect(m_layer->renderer()->frame()->view());
- m_visibleWindowRect.intersect(visibleFrameWindowRect);
- m_visibleWindowRect = m_webPage->mapToTransformed(m_visibleWindowRect);
- IntRect transformedWindowRect = IntRect(IntPoint::zero(), m_webPage->transformedViewportSize());
- m_visibleWindowRect.intersect(transformedWindowRect);
-
m_scrollsHorizontally = box->scrollWidth() != box->clientWidth() && box->scrollsOverflowX();
m_scrollsVertically = box->scrollHeight() != box->clientHeight() && box->scrollsOverflowY();
@@ -97,6 +87,18 @@
}
}
+void InRegionScrollableArea::setVisibleWindowRect(const WebCore::IntRect& rect)
+{
+ m_hasWindowVisibleRectCalculated = true;
+ m_visibleWindowRect = rect;
+}
+
+Platform::IntRect InRegionScrollableArea::visibleWindowRect() const
+{
+ ASSERT(m_hasWindowVisibleRectCalculated);
+ return m_visibleWindowRect;
+}
+
RenderLayer* InRegionScrollableArea::layer() const
{
ASSERT(!m_isNull);
Modified: trunk/Source/WebKit/blackberry/WebKitSupport/InRegionScrollableArea.h (119678 => 119679)
--- trunk/Source/WebKit/blackberry/WebKitSupport/InRegionScrollableArea.h 2012-06-07 04:26:23 UTC (rev 119678)
+++ trunk/Source/WebKit/blackberry/WebKitSupport/InRegionScrollableArea.h 2012-06-07 04:34:23 UTC (rev 119679)
@@ -19,7 +19,8 @@
#ifndef InRegionScrollableArea_h
#define InRegionScrollableArea_h
-#include <BlackBerryPlatformPrimitives.h>
+#include "IntRect.h"
+
#include <interaction/ScrollViewBase.h>
namespace WebCore {
@@ -37,11 +38,15 @@
InRegionScrollableArea();
InRegionScrollableArea(WebPagePrivate*, WebCore::RenderLayer*);
+ void setVisibleWindowRect(const WebCore::IntRect&);
+ Platform::IntRect visibleWindowRect() const;
+
WebCore::RenderLayer* layer() const;
private:
WebPagePrivate* m_webPage;
WebCore::RenderLayer* m_layer;
+ bool m_hasWindowVisibleRectCalculated;
};
}