[BlackBerry] Upstream selection start animation.
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 4 Mar 2013 17:41:24 +0000 (17:41 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 4 Mar 2013 17:41:24 +0000 (17:41 +0000)
https://bugs.webkit.org/show_bug.cgi?id=111335

Patch by Iris Wu <shuwu@rim.com> on 2013-03-04
Reviewed by Rob Buis.

PR 219960

To indicate selection starts, we draw an overlay rect larger than
the selected word at the start of selection. Then shrink it down
to the actual size.

Reviewed Internally by Genevieve Mak and Andrew Lo and Mike Fenton.

* Api/WebAnimation.cpp:
(BlackBerry::WebKit::WebAnimation::shrinkAnimation):
(WebKit):
* Api/WebAnimation.h:
* Api/WebPage.cpp:
(BlackBerry::WebKit::WebPagePrivate::init):
(BlackBerry::WebKit::WebPage::selectionHighlight):
(WebKit):
* Api/WebPage.h:
* Api/WebPage_p.h:
(WebPagePrivate):
* Api/WebTapHighlight.h:
* WebKitSupport/DefaultTapHighlight.cpp:
(WebKit):
(BlackBerry::WebKit::shrinkAnimationName):
(BlackBerry::WebKit::DefaultTapHighlight::draw):
* WebKitSupport/DefaultTapHighlight.h:
(DefaultTapHighlight):
* WebKitSupport/SelectionHandler.cpp:
(BlackBerry::WebKit::SelectionHandler::cancelSelection):
(BlackBerry::WebKit::textGranularityFromSelectionExpansionType):
(WebKit):
(BlackBerry::WebKit::SelectionHandler::selectNodeIfFatFingersResultIsLink):
(BlackBerry::WebKit::SelectionHandler::selectAtPoint):
* WebKitSupport/SelectionHandler.h:
(SelectionHandler):
* WebKitSupport/TouchEventHandler.cpp:
(BlackBerry::WebKit::TouchEventHandler::handleTouchPoint):

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

12 files changed:
Source/WebKit/blackberry/Api/WebAnimation.cpp
Source/WebKit/blackberry/Api/WebAnimation.h
Source/WebKit/blackberry/Api/WebPage.cpp
Source/WebKit/blackberry/Api/WebPage.h
Source/WebKit/blackberry/Api/WebPage_p.h
Source/WebKit/blackberry/Api/WebTapHighlight.h
Source/WebKit/blackberry/ChangeLog
Source/WebKit/blackberry/WebKitSupport/DefaultTapHighlight.cpp
Source/WebKit/blackberry/WebKitSupport/DefaultTapHighlight.h
Source/WebKit/blackberry/WebKitSupport/SelectionHandler.cpp
Source/WebKit/blackberry/WebKitSupport/SelectionHandler.h
Source/WebKit/blackberry/WebKitSupport/TouchEventHandler.cpp

index 4ae50de..38cb36c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 Research In Motion Limited. All rights reserved.
+ * Copyright (C) 2012, 2013 Research In Motion Limited. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -24,6 +24,7 @@
 #include "GraphicsLayer.h"
 #include "LayerCompositingThread.h"
 #include "LayerWebKitThread.h"
+#include "ScaleTransformOperation.h"
 #include "WebAnimation_p.h"
 
 #include <BlackBerryPlatformMessageClient.h>
@@ -47,6 +48,25 @@ WebAnimation WebAnimation::fadeAnimation(const BlackBerry::Platform::String& nam
     return tmp;
 }
 
+WebAnimation WebAnimation::shrinkAnimation(const BlackBerry::Platform::String& name, float from, float to, double duration)
+{
+    WebAnimation tmp;
+    tmp.d->name = name;
+    tmp.d->animation = Animation::create();
+    tmp.d->animation->setDuration(duration);
+    tmp.d->keyframes = KeyframeValueList(AnimatedPropertyWebkitTransform);
+
+    TransformOperations startOperation;
+    startOperation.operations().append(ScaleTransformOperation::create(from, from, TransformOperation::SCALE));
+    tmp.d->keyframes.insert(new TransformAnimationValue(0, &startOperation));
+
+    TransformOperations endOperation;
+    endOperation.operations().append(ScaleTransformOperation::create(to, to, TransformOperation::SCALE));
+    tmp.d->keyframes.insert(new TransformAnimationValue(1.0, &endOperation));
+
+    return tmp;
+}
+
 BlackBerry::Platform::String WebAnimation::name() const
 {
     return d->name;
index 1ff4d61..7506783 100644 (file)
@@ -38,6 +38,7 @@ class WebAnimationPrivate;
 class BLACKBERRY_EXPORT WebAnimation {
 public:
     static WebAnimation fadeAnimation(const BlackBerry::Platform::String& name, float from, float to, double duration);
+    static WebAnimation shrinkAnimation(const BlackBerry::Platform::String& name, float from, float to, double duration);
 
     WebAnimation();
     WebAnimation(const WebAnimation&);
index 4817b8f..c436fda 100644 (file)
@@ -584,6 +584,7 @@ void WebPagePrivate::init(const BlackBerry::Platform::String& pageGroupName)
 
 #if USE(ACCELERATED_COMPOSITING)
     m_tapHighlight = DefaultTapHighlight::create(this);
+    m_selectionHighlight = DefaultTapHighlight::create(this);
     m_selectionOverlay = SelectionOverlay::create(this);
     m_page->settings()->setAcceleratedCompositingForFixedPositionEnabled(true);
 #endif
@@ -6102,6 +6103,11 @@ WebTapHighlight* WebPage::tapHighlight() const
     return d->m_tapHighlight.get();
 }
 
+WebTapHighlight* WebPage::selectionHighlight() const
+{
+    return d->m_selectionHighlight.get();
+}
+
 void WebPage::addOverlay(WebOverlay* overlay)
 {
 #if USE(ACCELERATED_COMPOSITING)
index 2047b34..fb9d259 100644 (file)
@@ -354,6 +354,7 @@ public:
     void resetUserViewportArguments();
 
     WebTapHighlight* tapHighlight() const;
+    WebTapHighlight* selectionHighlight() const;
 
     // Adds an overlay that can be modified on the WebKit thread, and
     // whose attributes can be overridden on the compositing thread.
index 7c67f63..17fece8 100644 (file)
@@ -483,6 +483,7 @@ public:
     WebSettings* m_webSettings;
     WebCookieJar* m_cookieJar;
     OwnPtr<WebTapHighlight> m_tapHighlight;
+    OwnPtr<WebTapHighlight> m_selectionHighlight;
     OwnPtr<SelectionOverlay> m_selectionOverlay;
 
     bool m_visible;
index b48a52f..9d78311 100644 (file)
@@ -30,7 +30,7 @@ class BLACKBERRY_EXPORT WebTapHighlight {
 public:
     virtual ~WebTapHighlight() { }
 
-    virtual void draw(const Platform::IntRectRegion&, int red, int green, int blue, int alpha, bool hideAfterScroll) = 0;
+    virtual void draw(const Platform::IntRectRegion&, int red, int green, int blue, int alpha, bool hideAfterScroll, bool isStartOfSelection = false) = 0;
     virtual void hide() = 0;
 
     virtual bool isVisible() const = 0;
index 1d9f937..24e69d0 100644 (file)
@@ -1,3 +1,47 @@
+2013-03-04  Iris Wu  <shuwu@rim.com>
+
+        [BlackBerry] Upstream selection start animation.
+        https://bugs.webkit.org/show_bug.cgi?id=111335
+
+        Reviewed by Rob Buis.
+
+        PR 219960
+
+        To indicate selection starts, we draw an overlay rect larger than
+        the selected word at the start of selection. Then shrink it down
+        to the actual size.
+
+        Reviewed Internally by Genevieve Mak and Andrew Lo and Mike Fenton.
+
+        * Api/WebAnimation.cpp:
+        (BlackBerry::WebKit::WebAnimation::shrinkAnimation):
+        (WebKit):
+        * Api/WebAnimation.h:
+        * Api/WebPage.cpp:
+        (BlackBerry::WebKit::WebPagePrivate::init):
+        (BlackBerry::WebKit::WebPage::selectionHighlight):
+        (WebKit):
+        * Api/WebPage.h:
+        * Api/WebPage_p.h:
+        (WebPagePrivate):
+        * Api/WebTapHighlight.h:
+        * WebKitSupport/DefaultTapHighlight.cpp:
+        (WebKit):
+        (BlackBerry::WebKit::shrinkAnimationName):
+        (BlackBerry::WebKit::DefaultTapHighlight::draw):
+        * WebKitSupport/DefaultTapHighlight.h:
+        (DefaultTapHighlight):
+        * WebKitSupport/SelectionHandler.cpp:
+        (BlackBerry::WebKit::SelectionHandler::cancelSelection):
+        (BlackBerry::WebKit::textGranularityFromSelectionExpansionType):
+        (WebKit):
+        (BlackBerry::WebKit::SelectionHandler::selectNodeIfFatFingersResultIsLink):
+        (BlackBerry::WebKit::SelectionHandler::selectAtPoint):
+        * WebKitSupport/SelectionHandler.h:
+        (SelectionHandler):
+        * WebKitSupport/TouchEventHandler.cpp:
+        (BlackBerry::WebKit::TouchEventHandler::handleTouchPoint):
+
 2013-03-02  Benjamin Poulain  <bpoulain@apple.com>
 
         Move computedStyleIncludingVisitedInfo from TestRunner to Internals
index 77b2c75..d5efe0b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 Research In Motion Limited. All rights reserved.
+ * Copyright (C) 2012, 2013 Research In Motion Limited. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -36,8 +36,11 @@ namespace BlackBerry {
 namespace WebKit {
 
 const double ActiveTextFadeAnimationDuration = 0.3;
+const double OverlayShrinkAnimationDuration = 0.5;
+const double OverlayInitialScale = 2.0;
 
 static const char* fadeAnimationName() { return "fade"; }
+static const char* shrinkAnimationName() { return "shrink"; }
 
 DefaultTapHighlight::DefaultTapHighlight(WebPagePrivate* page)
     : m_page(page)
@@ -50,7 +53,7 @@ DefaultTapHighlight::~DefaultTapHighlight()
 {
 }
 
-void DefaultTapHighlight::draw(const Platform::IntRectRegion& region, int red, int green, int blue, int alpha, bool hideAfterScroll)
+void DefaultTapHighlight::draw(const Platform::IntRectRegion& region, int red, int green, int blue, int alpha, bool hideAfterScroll, bool isStartOfSelection)
 {
     ASSERT(BlackBerry::Platform::webKitThreadMessageClient()->isCurrentThread());
 
@@ -77,6 +80,7 @@ void DefaultTapHighlight::draw(const Platform::IntRectRegion& region, int red, i
         m_page->m_webPage->addOverlay(m_overlay.get());
     }
 
+    m_overlay->removeAnimation(shrinkAnimationName());
     m_overlay->resetOverrides();
     m_overlay->setPosition(rect.location());
     m_overlay->setSize(rect.size());
@@ -84,6 +88,12 @@ void DefaultTapHighlight::draw(const Platform::IntRectRegion& region, int red, i
     m_overlay->removeAnimation(fadeAnimationName());
     m_overlay->setOpacity(1.0);
     m_overlay->invalidate();
+
+    // Animate overlay scale to indicate selection is started.
+    if (isStartOfSelection) {
+        WebAnimation shrinkAnimation = WebAnimation::shrinkAnimation(shrinkAnimationName(), OverlayInitialScale, 1, OverlayShrinkAnimationDuration);
+        m_overlay->addAnimation(shrinkAnimation);
+    }
 }
 
 void DefaultTapHighlight::hide()
index 90af94c..b5b34b9 100644 (file)
@@ -47,7 +47,7 @@ public:
 
     virtual ~DefaultTapHighlight();
 
-    virtual void draw(const Platform::IntRectRegion&, int red, int green, int blue, int alpha, bool hideAfterScroll);
+    virtual void draw(const Platform::IntRectRegion&, int red, int green, int blue, int alpha, bool hideAfterScroll, bool isStartOfSelection = false);
     virtual void hide();
 
     virtual bool isVisible() const { return m_visible; }
index 815684a..7e2ade7 100644 (file)
@@ -84,8 +84,6 @@ void SelectionHandler::cancelSelection()
 {
     m_selectionActive = false;
     m_lastSelectionRegion = IntRectRegion();
-    m_currentOverlayRegion = IntRectRegion();
-    m_nextOverlayRegion = IntRectRegion();
 
     if (m_webPage->m_selectionOverlay)
         m_webPage->m_selectionOverlay->hide();
@@ -590,6 +588,25 @@ static Node* enclosingLinkEventParentForNode(Node* node)
     return linkNode && linkNode->isLink() ? linkNode : 0;
 }
 
+TextGranularity textGranularityFromSelectionExpansionType(SelectionExpansionType selectionExpansionType)
+{
+    TextGranularity granularity;
+    switch (selectionExpansionType) {
+    case Word:
+    default:
+        granularity = WordGranularity;
+        break;
+    case Sentence:
+        granularity = SentenceGranularity;
+        break;
+    case Paragraph:
+        granularity = ParagraphGranularity;
+        break;
+    }
+    return granularity;
+}
+
+
 bool SelectionHandler::selectNodeIfFatFingersResultIsLink(FatFingersResult fatFingersResult)
 {
     if (!fatFingersResult.isValid())
@@ -598,7 +615,14 @@ bool SelectionHandler::selectNodeIfFatFingersResultIsLink(FatFingersResult fatFi
     ASSERT(targetNode);
     // If the node at the point is a link, focus on the entire link, not a word.
     if (Node* link = enclosingLinkEventParentForNode(targetNode)) {
+        Element* element = fatFingersResult.nodeAsElementIfApplicable();
+        if (!element)
+            return false;
+        m_animationHighlightColor = element->renderStyle()->initialTapHighlightColor();
+
         selectObject(link);
+        // If selected object is a link, no need to wait for further expansion.
+        m_webPage->m_client->stopExpandingSelection();
         return true;
     }
     return false;
@@ -606,6 +630,13 @@ bool SelectionHandler::selectNodeIfFatFingersResultIsLink(FatFingersResult fatFi
 
 void SelectionHandler::selectAtPoint(const WebCore::IntPoint& location, SelectionExpansionType selectionExpansionType)
 {
+    if (selectionExpansionType == Word) {
+        m_animationOverlayStartPos = VisiblePosition();
+        m_animationOverlayEndPos = VisiblePosition();
+        m_currentAnimationOverlayRegion = IntRectRegion();
+        m_nextAnimationOverlayRegion = IntRectRegion();
+    }
+
     // If point is invalid trigger selection based expansion.
     if (location == DOMSupport::InvalidPoint) {
         selectObject(WordGranularity);
@@ -613,27 +644,25 @@ void SelectionHandler::selectAtPoint(const WebCore::IntPoint& location, Selectio
     }
 
     WebCore::IntPoint targetPosition;
-    // FIXME: Factory this get right fat finger code into a helper.
-    const FatFingersResult lastFatFingersResult = m_webPage->m_touchEventHandler->lastFatFingersResult();
-    if (selectNodeIfFatFingersResultIsLink(lastFatFingersResult))
-        return;
-
-    if (lastFatFingersResult.resultMatches(location, FatFingers::Text) && lastFatFingersResult.positionWasAdjusted() && lastFatFingersResult.nodeAsElementIfApplicable()) {
-        targetNode = lastFatFingersResult.node(FatFingersResult::ShadowContentNotAllowed);
-        targetPosition = lastFatFingersResult.adjustedPosition();
-    } else {
-        FatFingersResult newFatFingersResult = FatFingers(m_webPage, location, FatFingers::Text).findBestPoint();
-        if (!newFatFingersResult.positionWasAdjusted())
-            return;
 
-        if (selectNodeIfFatFingersResultIsLink(newFatFingersResult))
-            return;
-
-        targetPosition = newFatFingersResult.adjustedPosition();
+    FatFingersResult fatFingersResult = m_webPage->m_touchEventHandler->lastFatFingersResult();
+    if (selectNodeIfFatFingersResultIsLink(fatFingersResult))
+        return;
+    if (!fatFingersResult.resultMatches(location, FatFingers::Text) || !fatFingersResult.positionWasAdjusted() || !fatFingersResult.nodeAsElem
+        fatFingersResult = FatFingers(m_webPage, location, FatFingers::Text).findBestPoint();
+
+    if (!fatFingersResult.positionWasAdjusted()) {
+        if (isSelectionActive())
+            cancelSelection();
+        m_webPage->m_client->notifySelectionDetailsChanged(SelectionDetails());
+        m_webPage->m_touchEventHandler->sendClickAtFatFingersPoint();
+        return;
     }
 
-    m_currentOverlayRegion = IntRectRegion();
-    m_nextOverlayRegion = IntRectRegion();
+    targetPosition = fatFingersResult.adjustedPosition();
+    if (selectNodeIfFatFingersResultIsLink(fatFingersResult))
+        return;
+
     selectObject(targetPosition, textGranularityFromSelectionExpansionType(selectionExpansionType));
 }
 
@@ -663,7 +692,7 @@ void SelectionHandler::selectNextParagraph()
     endPos = endOfParagraph(endPos); // find the end of paragraph
 
     // Set selection if the paragraph is covered by overlay and endPos is not null.
-    if (m_currentOverlayRegion.extents().bottom() >= endPos.absoluteCaretBounds().maxY() && endPos.isNotNull()) {
+    if (m_currentAnimationOverlayRegion.extents().bottom() >= endPos.absoluteCaretBounds().maxY() && endPos.isNotNull()) {
         VisibleSelection selection = VisibleSelection(startPos, endPos);
         selection.setAffinity(controller->affinity());
         controller->setSelection(selection);
@@ -674,53 +703,58 @@ void SelectionHandler::selectNextParagraph()
     }
 }
 
-void SelectionHandler::drawOverlay(IntRectRegion overlayRegion, bool isExpandingOverlayAtConstantRate)
+void SelectionHandler::drawAnimationOverlay(IntRectRegion overlayRegion, bool isExpandingOverlayAtConstantRate, bool isStartOfSelection)
 {
-    Element* element = m_overlayStartPos.deepEquivalent().element();
-    if (!element)
-        return;
-
     if (isExpandingOverlayAtConstantRate) {
         // When overlay expands at a constant rate, the current overlay height increases
         // m_overlayExpansionHeight each time and the width is always same as next overlay region.
-        WebCore::IntRect currentOverlayRect = m_currentOverlayRegion.extents();
-        WebCore::IntRect nextOverlayRect = m_nextOverlayRegion.extents();
+        WebCore::IntRect currentOverlayRect = m_currentAnimationOverlayRegion.extents();
+        WebCore::IntRect nextOverlayRect = m_nextAnimationOverlayRegion.extents();
         WebCore::IntRect overlayRect(WebCore::IntRect(nextOverlayRect.location(), WebCore::IntSize(nextOverlayRect.width(), currentOverlayRect.height() + m_overlayExpansionHeight)));
         overlayRegion = IntRectRegion(overlayRect);
     }
 
-    Color highlightColor = element->renderStyle()->initialTapHighlightColor();
-    m_webPage->m_tapHighlight->draw(overlayRegion,
-        highlightColor.red(), highlightColor.green(), highlightColor.blue(), highlightColor.alpha(),
-        false /* do not hide after scroll */);
-    m_currentOverlayRegion = overlayRegion;
+    m_webPage->m_selectionHighlight->draw(overlayRegion,
+        m_animationHighlightColor.red(), m_animationHighlightColor.green(), m_animationHighlightColor.blue(), m_animationHighlightColor.alpha(),
+        false /* do not hide after scroll */,
+        isStartOfSelection);
+    m_currentAnimationOverlayRegion = overlayRegion;
+}
+
+IntRectRegion SelectionHandler::regionForSelectionQuads(VisibleSelection selection)
+{
+    Vector<FloatQuad> quads;
+    DOMSupport::visibleTextQuads(selection, quads);
+    IntRectRegion region;
+    regionForTextQuads(quads, region);
+    return region;
 }
 
-bool SelectionHandler::findNextOverlayRegion()
+bool SelectionHandler::findNextAnimationOverlayRegion()
 {
     // If overlay is at the end of document, stop overlay expansion.
-    if (isEndOfDocument(m_overlayEndPos.deepEquivalent()) || m_overlayEndPos.isNull())
+    if (isEndOfDocument(m_animationOverlayEndPos.deepEquivalent()) || m_animationOverlayEndPos.isNull())
         return false;
 
-    m_overlayEndPos = m_overlayEndPos.next();
-    while (!isEndOfDocument(m_overlayEndPos.deepEquivalent()) && m_overlayEndPos.isNotNull() && isInvalidLine(m_overlayEndPos))
-        m_overlayEndPos = m_overlayEndPos.next(); // go to next position
-    m_overlayEndPos = endOfLine(m_overlayEndPos); // find end of line
+    m_animationOverlayEndPos = m_animationOverlayEndPos.next();
+    while (!isEndOfDocument(m_animationOverlayEndPos.deepEquivalent()) && m_animationOverlayEndPos.isNotNull() && isInvalidLine(m_animationOverlayEndPos))
+        m_animationOverlayEndPos = m_animationOverlayEndPos.next(); // go to next position
+    m_animationOverlayEndPos = endOfLine(m_animationOverlayEndPos); // find end of line
 
-    VisibleSelection selection(m_overlayStartPos, m_overlayEndPos);
-    Vector<FloatQuad> quads;
-    DOMSupport::visibleTextQuads(selection, quads);
-    regionForTextQuads(quads, m_nextOverlayRegion);
+    VisibleSelection selection(m_animationOverlayStartPos, m_animationOverlayEndPos);
+    m_nextAnimationOverlayRegion = regionForSelectionQuads(selection);
     return true;
 }
 
 void SelectionHandler::expandSelection(bool isScrollStarted)
 {
-    WebCore::IntPoint nextOverlayBottomRightPoint = WebCore::IntPoint(m_currentOverlayRegion.extents().bottomRight()) + WebCore::IntPoint(0, m_overlayExpansionHeight);
-    if (nextOverlayBottomRightPoint.y() > m_nextOverlayRegion.extents().bottom())
+    if (m_currentAnimationOverlayRegion.isEmpty() || m_nextAnimationOverlayRegion.isEmpty())
+        return;
+    WebCore::IntPoint nextOverlayBottomRightPoint = WebCore::IntPoint(m_currentAnimationOverlayRegion.extents().bottomRight()) + WebCore::IntPoint(0, m_overlayExpansionHeight);
+    if (nextOverlayBottomRightPoint.y() > m_nextAnimationOverlayRegion.extents().bottom())
         // Find next overlay region so that we can update overlay region's width while expanding.
-        if (!findNextOverlayRegion()) {
-            drawOverlay(m_nextOverlayRegion, false);
+        if (!findNextAnimationOverlayRegion()) {
+            drawAnimationOverlay(m_nextAnimationOverlayRegion, false);
             selectNextParagraph();
             m_webPage->m_client->stopExpandingSelection();
             return;
@@ -728,8 +762,8 @@ void SelectionHandler::expandSelection(bool isScrollStarted)
 
     // Draw overlay if the position is in the viewport and is not null.
     // Otherwise, start scrolling if it hasn't started.
-    if (ensureSelectedTextVisible(nextOverlayBottomRightPoint, false /* do not scroll */) && m_overlayEndPos.isNotNull())
-        drawOverlay(IntRectRegion(), true /* isExpandingOverlayAtConstantRate */);
+    if (ensureSelectedTextVisible(nextOverlayBottomRightPoint, false /* do not scroll */) && m_animationOverlayEndPos.isNotNull())
+        drawAnimationOverlay(IntRectRegion(), true /* isExpandingOverlayAtConstantRate */);
     else if (!isScrollStarted) {
         m_webPage->m_client->startSelectionScroll();
         return;
@@ -747,8 +781,15 @@ bool SelectionHandler::ensureSelectedTextVisible(const WebCore::IntPoint& point,
     if (!scrollIfNeeded)
         return actualScreenRect.maxY() >= point.y() + m_scrollMargin.height();
 
-    WebCore::IntRect endLocation = m_overlayEndPos.absoluteCaretBounds();
-    Node* anchorNode = m_overlayEndPos.deepEquivalent().anchorNode();
+    WebCore::IntRect endLocation = m_animationOverlayEndPos.absoluteCaretBounds();
+
+    Frame* focusedFrame = m_webPage->focusedOrMainFrame();
+    Frame* mainFrame = m_webPage->mainFrame();
+    // If we are selecting within an iframe, translate coordinates to main frame.
+    if (focusedFrame && focusedFrame->view() && mainFrame && mainFrame->view() && focusedFrame != mainFrame)
+        endLocation = mainFrame->view()->windowToContents(focusedFrame->view()->contentsToWindow(endLocation));
+
+    Node* anchorNode = m_animationOverlayEndPos.deepEquivalent().anchorNode();
     if (!anchorNode || !anchorNode->renderer())
         return false;
 
@@ -763,15 +804,8 @@ bool SelectionHandler::ensureSelectedTextVisible(const WebCore::IntPoint& point,
     revealRect.setX(std::min(std::max(revealRect.x(), 0), m_webPage->maximumScrollPosition().x()));
     revealRect.setY(std::min(std::max(revealRect.y(), 0), m_webPage->maximumScrollPosition().y()));
 
-    if (revealRect.location() != scrollPosition) {
-        // Animate scroll position to revealRect.
-        m_webPage->m_finalBlockPoint = WebCore::FloatPoint(revealRect.x(), revealRect.y());
-        m_webPage->m_blockZoomFinalScale = m_webPage->m_webPage->currentScale(); // Don't zoom.
-        m_webPage->m_shouldReflowBlock = false;
-        m_webPage->m_userPerformedManualZoom = true;
-        m_webPage->m_userPerformedManualScroll = true;
-        m_webPage->client()->animateBlockZoom(m_webPage->m_webPage->currentScale(), m_webPage->m_finalBlockPoint);
-    }
+    // Animate scroll position to revealRect.
+    m_webPage->animateToScaleAndDocumentScrollPosition(m_webPage->currentScale() /* Don't zoom */, WebCore::FloatPoint(revealRect.x(), revealRect.y()));
     return true;
 }
 
@@ -798,17 +832,21 @@ bool SelectionHandler::expandSelectionToGranularity(Frame* frame, VisibleSelecti
     if (isInputMode && !frame->selection()->shouldChangeSelection(selection))
         return false;
 
-    m_overlayStartPos = selection.visibleStart();
-    m_overlayEndPos = selection.visibleEnd();
-    Vector<FloatQuad> quads;
-    DOMSupport::visibleTextQuads(selection, quads);
-    regionForTextQuads(quads, m_currentOverlayRegion);
+    m_animationOverlayStartPos = selection.visibleStart();
+    m_animationOverlayEndPos = selection.visibleEnd();
+
+    if (granularity == WordGranularity) {
+        Element* element = m_animationOverlayStartPos.deepEquivalent().element();
+        if (!element)
+            return false;
+        m_animationHighlightColor = element->renderStyle()->initialTapHighlightColor();
+    }
 
     ensureSelectedTextVisible(WebCore::IntPoint(), true /* scroll if needed */);
-    drawOverlay(m_currentOverlayRegion, false /* isExpandingOverlayAtConstantRate */);
+    drawAnimationOverlay(regionForSelectionQuads(selection), false /* isExpandingOverlayAtConstantRate */, granularity == WordGranularity /* isStartOfSelection */);
     frame->selection()->setSelection(selection);
     if (granularity == ParagraphGranularity)
-        findNextOverlayRegion();
+        findNextAnimationOverlayRegion();
 
     return true;
 }
@@ -875,6 +913,7 @@ void SelectionHandler::selectObject(Node* node)
     SelectionLog(Platform::LogLevelInfo, "SelectionHandler::selectNode");
 
     VisibleSelection selection = VisibleSelection::selectionFromContentsOfNode(node);
+    drawAnimationOverlay(regionForSelectionQuads(selection), false /* isExpandingOverlayAtConstantRate */, true /* isStartOfSelection */);
     focusedFrame->selection()->setSelection(selection);
 }
 
index 8d0cd2c..3388e9a 100644 (file)
@@ -22,6 +22,7 @@
 #include "BlackBerryPlatformIntRectRegion.h"
 #include "BlackBerryPlatformPrimitives.h"
 #include "BlackBerryPlatformStopWatch.h"
+#include "Color.h"
 #include "TextGranularity.h"
 
 #include <wtf/Vector.h>
@@ -93,8 +94,9 @@ private:
     WebCore::IntPoint clipPointToVisibleContainer(const WebCore::IntPoint&) const;
 
     void selectNextParagraph();
-    void drawOverlay(BlackBerry::Platform::IntRectRegion, bool);
-    bool findNextOverlayRegion();
+    void drawAnimationOverlay(BlackBerry::Platform::IntRectRegion, bool isExpandingOverlayAtConstantRate, bool isStartOfSelection = false);
+    Platform::IntRectRegion regionForSelectionQuads(WebCore::VisibleSelection);
+    bool findNextAnimationOverlayRegion();
     bool ensureSelectedTextVisible(const WebCore::IntPoint&, bool scrollIfNeeded);
     bool expandSelectionToGranularity(WebCore::Frame*, WebCore::VisibleSelection, WebCore::TextGranularity, bool isInputMode);
 
@@ -110,11 +112,12 @@ private:
     bool m_lastUpdatedEndPointIsValid;
     bool m_didSuppressCaretPositionChangedNotification;
     BlackBerry::Platform::IntRectRegion m_lastSelectionRegion;
-    WebCore::VisiblePosition m_overlayStartPos;
-    WebCore::VisiblePosition m_overlayEndPos;
-    BlackBerry::Platform::IntRectRegion m_currentOverlayRegion;
-    BlackBerry::Platform::IntRectRegion m_nextOverlayRegion;
+    WebCore::VisiblePosition m_animationOverlayStartPos;
+    WebCore::VisiblePosition m_animationOverlayEndPos;
+    BlackBerry::Platform::IntRectRegion m_currentAnimationOverlayRegion;
+    BlackBerry::Platform::IntRectRegion m_nextAnimationOverlayRegion;
     int m_overlayExpansionHeight;
+    WebCore::Color m_animationHighlightColor;
 
     BlackBerry::Platform::StopWatch m_timer;
 
index 492aa89..e26a2ec 100644 (file)
@@ -136,6 +136,7 @@ void TouchEventHandler::handleTouchPoint(const Platform::TouchPoint& point, unsi
                 m_webPage->m_inputHandler->notifyClientOfKeyboardVisibilityChange(true);
 
             m_webPage->m_tapHighlight->hide();
+            m_webPage->m_selectionHighlight->hide();
 
             IntPoint adjustedPoint = m_webPage->mapFromContentsToViewport(m_lastFatFingersResult.adjustedPosition());
             PlatformMouseEvent mouseEvent(adjustedPoint, m_lastScreenPoint, PlatformEvent::MouseReleased, 1, LeftButton, shiftActive, ctrlActive, altActive, TouchScreen);