Commit bf095e15 authored by tonikitoo@webkit.org's avatar tonikitoo@webkit.org

[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 <agomes@rim.com>

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):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@119679 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 3dec8ed2
......@@ -4633,23 +4633,23 @@ static Node* enclosingLayerNode(RenderLayer* layer)
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 @@ std::vector<Platform::ScrollViewBase> WebPagePrivate::inRegionScrollableAreasFor
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;
}
......
......@@ -99,7 +99,8 @@ public:
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;
......
......@@ -138,7 +138,7 @@ public:
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);
......
2012-06-05 Antonio Gomes <agomes@rim.com>
[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 <charles.wei@torchmobile.com.cn>
[BlackBerry] IndexedDB file should be sand-boxed to the application data directory.
......
......@@ -35,12 +35,14 @@ namespace WebKit {
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 @@ InRegionScrollableArea::InRegionScrollableArea(WebPagePrivate* webPage, RenderLa
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 @@ InRegionScrollableArea::InRegionScrollableArea(WebPagePrivate* webPage, RenderLa
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 @@ InRegionScrollableArea::InRegionScrollableArea(WebPagePrivate* webPage, RenderLa
}
}
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);
......
......@@ -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 @@ public:
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;
};
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment