summaryrefslogtreecommitdiff
path: root/Source/WebKit/blackberry/Api/InRegionScroller.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebKit/blackberry/Api/InRegionScroller.cpp')
-rw-r--r--Source/WebKit/blackberry/Api/InRegionScroller.cpp116
1 files changed, 89 insertions, 27 deletions
diff --git a/Source/WebKit/blackberry/Api/InRegionScroller.cpp b/Source/WebKit/blackberry/Api/InRegionScroller.cpp
index 09012c1fd..205ef898b 100644
--- a/Source/WebKit/blackberry/Api/InRegionScroller.cpp
+++ b/Source/WebKit/blackberry/Api/InRegionScroller.cpp
@@ -26,9 +26,11 @@
#include "InRegionScrollableArea.h"
#include "InRegionScroller_p.h"
#include "LayerCompositingThread.h"
+#include "LayerWebKitThread.h"
#include "Page.h"
#include "RenderBox.h"
#include "RenderLayer.h"
+#include "RenderLayerBacking.h"
#include "RenderObject.h"
#include "RenderView.h"
#include "WebPage_p.h"
@@ -43,7 +45,6 @@ static bool canScrollRenderBox(RenderBox*);
static RenderLayer* parentLayer(RenderLayer*);
static Node* enclosingLayerNode(RenderLayer*);
static bool isNonRenderViewFixedPositionedContainer(RenderLayer*);
-static void pushBackInRegionScrollable(std::vector<Platform::ScrollViewBase*>&, InRegionScrollableArea*, InRegionScrollerPrivate*);
InRegionScroller::InRegionScroller(WebPagePrivate* webPagePrivate)
: d(new InRegionScrollerPrivate(webPagePrivate))
@@ -56,10 +57,20 @@ InRegionScroller::~InRegionScroller()
delete d;
}
-bool InRegionScroller::compositedSetScrollPosition(unsigned camouflagedLayer, const Platform::IntPoint& scrollPosition)
+bool InRegionScroller::setScrollPositionCompositingThread(unsigned camouflagedLayer, const Platform::IntPoint& scrollPosition)
{
ASSERT(Platform::userInterfaceThreadMessageClient()->isCurrentThread());
- return d->compositedSetScrollPosition(camouflagedLayer, d->m_webPage->mapFromTransformed(scrollPosition));
+
+ // FIXME: Negative values won't work with map{To,From}Transform methods.
+ return d->setScrollPositionCompositingThread(camouflagedLayer, d->m_webPage->mapFromTransformed(scrollPosition));
+}
+
+bool InRegionScroller::setScrollPositionWebKitThread(unsigned camouflagedLayer, const Platform::IntPoint& scrollPosition)
+{
+ ASSERT(Platform::webKitThreadMessageClient()->isCurrentThread());
+
+ // FIXME: Negative values won't work with map{To,From}Transform methods.
+ return d->setScrollPositionWebKitThread(camouflagedLayer, d->m_webPage->mapFromTransformed(scrollPosition));
}
InRegionScrollerPrivate::InRegionScrollerPrivate(WebPagePrivate* webPagePrivate)
@@ -80,6 +91,10 @@ WebCore::Node* InRegionScrollerPrivate::node() const
void InRegionScrollerPrivate::reset()
{
setNode(0);
+
+ for (size_t i = 0; i < m_activeInRegionScrollableAreas.size(); ++i)
+ delete m_activeInRegionScrollableAreas[i];
+ m_activeInRegionScrollableAreas.clear();
}
bool InRegionScrollerPrivate::hasNode() const
@@ -92,15 +107,36 @@ bool InRegionScrollerPrivate::canScroll() const
return hasNode();
}
-bool InRegionScrollerPrivate::compositedSetScrollPosition(unsigned camouflagedLayer, const WebCore::IntPoint& scrollPosition)
+bool InRegionScrollerPrivate::setScrollPositionCompositingThread(unsigned camouflagedLayer, const WebCore::IntPoint& scrollPosition)
{
- LayerCompositingThread* scrollLayer = reinterpret_cast<LayerCompositingThread*>(camouflagedLayer);
- scrollLayer->override()->setBoundsOrigin(WebCore::FloatPoint(scrollPosition.x(), scrollPosition.y()));
+ LayerCompositingThread* scrollLayer = reinterpret_cast<LayerWebKitThread*>(camouflagedLayer)->layerCompositingThread();
+
+ // FIXME: Clamp maximum and minimum scroll positions as a last attempt to fix round errors.
+ scrollLayer->override()->setBoundsOrigin(scrollPosition);
- m_webPage->scheduleCompositingRun();
+ // The client is going to blitVisibleContens, which allow us benefit from "defer blits" technique.
return true;
}
+bool InRegionScrollerPrivate::setScrollPositionWebKitThread(unsigned camouflagedLayer, const WebCore::IntPoint& scrollPosition)
+{
+ RenderLayer* layer = 0;
+
+ LayerWebKitThread* layerWebKitThread = reinterpret_cast<LayerWebKitThread*>(camouflagedLayer);
+ ASSERT(layerWebKitThread);
+ if (layerWebKitThread->owner()) {
+ GraphicsLayer* graphicsLayer = layerWebKitThread->owner();
+ RenderLayerBacking* backing = static_cast<RenderLayerBacking*>(graphicsLayer->client());
+ layer = backing->owningLayer();
+ }
+
+ if (!layer)
+ return false;
+
+ // FIXME: Clamp maximum and minimum scroll positions as a last attempt to fix round errors.
+ return setLayerScrollPosition(layer, scrollPosition);
+}
+
bool InRegionScrollerPrivate::scrollBy(const Platform::IntSize& delta)
{
ASSERT(Platform::webkitThreadMessageClient()->isCurrentThread());
@@ -111,15 +147,14 @@ bool InRegionScrollerPrivate::scrollBy(const Platform::IntSize& delta)
return scrollNodeRecursively(node(), delta);
}
-std::vector<Platform::ScrollViewBase*> InRegionScrollerPrivate::inRegionScrollableAreasForPoint(const WebCore::IntPoint& point)
+void InRegionScrollerPrivate::calculateInRegionScrollableAreasForPoint(const WebCore::IntPoint& point)
{
- std::vector<Platform::ScrollViewBase*> validReturn;
- std::vector<Platform::ScrollViewBase*> emptyReturn;
+ ASSERT(m_activeInRegionScrollableAreas.empty());
HitTestResult result = m_webPage->m_mainFrame->eventHandler()->hitTestResultAtPoint(m_webPage->mapFromViewportToContents(point), false /*allowShadowContent*/);
Node* node = result.innerNonSharedNode();
if (!node || !node->renderer())
- return emptyReturn;
+ return;
RenderLayer* layer = node->renderer()->enclosingLayer();
do {
@@ -128,37 +163,39 @@ std::vector<Platform::ScrollViewBase*> InRegionScrollerPrivate::inRegionScrollab
if (renderer->isRenderView()) {
if (RenderView* renderView = toRenderView(renderer)) {
FrameView* view = renderView->frameView();
- if (!view)
- return emptyReturn;
+ if (!view) {
+ reset();
+ return;
+ }
if (canScrollInnerFrame(view->frame())) {
- pushBackInRegionScrollable(validReturn, new InRegionScrollableArea(m_webPage, layer), this);
+ pushBackInRegionScrollable(new InRegionScrollableArea(m_webPage, layer));
continue;
}
}
} else if (canScrollRenderBox(layer->renderBox())) {
- pushBackInRegionScrollable(validReturn, new InRegionScrollableArea(m_webPage, layer), this);
+ pushBackInRegionScrollable(new InRegionScrollableArea(m_webPage, layer));
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();
+ if (isNonRenderViewFixedPositionedContainer(layer) && m_activeInRegionScrollableAreas.size()) {
+ Platform::ScrollViewBase* end = m_activeInRegionScrollableAreas.back();
end->setCanPropagateScrollingToEnclosingScrollable(false);
}
} while (layer = parentLayer(layer));
- if (validReturn.empty())
- return emptyReturn;
+ if (m_activeInRegionScrollableAreas.empty())
+ return;
// 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(), m_webPage->transformedViewportSize());
- std::vector<Platform::ScrollViewBase*>::reverse_iterator rend = validReturn.rend();
- for (std::vector<Platform::ScrollViewBase*>::reverse_iterator rit = validReturn.rbegin(); rit != rend; ++rit) {
+ std::vector<Platform::ScrollViewBase*>::reverse_iterator rend = m_activeInRegionScrollableAreas.rend();
+ for (std::vector<Platform::ScrollViewBase*>::reverse_iterator rit = m_activeInRegionScrollableAreas.rbegin(); rit != rend; ++rit) {
InRegionScrollableArea* curr = static_cast<InRegionScrollableArea*>(*rit);
RenderLayer* layer = curr->layer();
@@ -188,8 +225,34 @@ std::vector<Platform::ScrollViewBase*> InRegionScrollerPrivate::inRegionScrollab
recursiveClippingRect = visibleWindowRect;
}
}
+}
+
+const std::vector<Platform::ScrollViewBase*>& InRegionScrollerPrivate::activeInRegionScrollableAreas() const
+{
+ return m_activeInRegionScrollableAreas;
+}
+
+bool InRegionScrollerPrivate::setLayerScrollPosition(RenderLayer* layer, const IntPoint& scrollPosition)
+{
+ RenderObject* layerRenderer = layer->renderer();
+ ASSERT(layerRenderer);
+
+ if (layerRenderer->isRenderView()) { // #document case.
+ FrameView* view = toRenderView(layerRenderer)->frameView();
+ ASSERT(view);
+
+ Frame* frame = view->frame();
+ ASSERT_UNUSED(frame, frame);
+
+ view->setScrollPosition(scrollPosition);
+ return true;
+ }
- return validReturn;
+ // RenderBox-based elements case (scrollable boxes (div's, p's, textarea's, etc)).
+ layer->scrollToOffset(scrollPosition.x(), scrollPosition.y());
+ // FIXME_agomes: Please recheck if it is needed still!
+ layer->renderer()->repaint(true);
+ return true;
}
bool InRegionScrollerPrivate::scrollNodeRecursively(WebCore::Node* node, const WebCore::IntSize& delta)
@@ -376,16 +439,15 @@ static bool isNonRenderViewFixedPositionedContainer(RenderLayer* layer)
return o->isOutOfFlowPositioned() && o->style()->position() == FixedPosition;
}
-static void pushBackInRegionScrollable(std::vector<Platform::ScrollViewBase*>& vector, InRegionScrollableArea* scrollableArea, InRegionScrollerPrivate* scroller)
+void InRegionScrollerPrivate::pushBackInRegionScrollable(InRegionScrollableArea* scrollableArea)
{
- ASSERT(scroller);
ASSERT(!scrollableArea->isNull());
scrollableArea->setCanPropagateScrollingToEnclosingScrollable(!isNonRenderViewFixedPositionedContainer(scrollableArea->layer()));
- vector.push_back(scrollableArea);
- if (vector.size() == 1) {
+ m_activeInRegionScrollableAreas.push_back(scrollableArea);
+ if (m_activeInRegionScrollableAreas.size() == 1) {
// FIXME: Use RenderLayer::renderBox()->node() instead?
- scroller->setNode(enclosingLayerNode(scrollableArea->layer()));
+ setNode(enclosingLayerNode(scrollableArea->layer()));
}
}