Changeset 109013 in webkit


Ignore:
Timestamp:
Feb 27, 2012 12:03:09 PM (12 years ago)
Author:
commit-queue@webkit.org
Message:

[BlackBerry] Dragging a selection handle outside of the content bounding box does not update the selection range correctly
https://bugs.webkit.org/show_bug.cgi?id=78608

Ensure that when selection handles leave the content bounding box that
the handle not being dragged remains fixed. Do not apply padding to a
direction that would cause the selection to shrink when performing the
handle direction detection.

Patch by Ed Baker <edbaker@rim.com> on 2012-02-27
Reviewed by Antonio Gomes.

  • WebKitSupport/DOMSupport.cpp:

(BlackBerry::WebKit::DOMSupport::convertPointToFrame):

  • WebKitSupport/DOMSupport.h:
  • WebKitSupport/SelectionHandler.cpp:

(BlackBerry::WebKit::clamp):
(BlackBerry::WebKit::directionalVisiblePositionAtExtentOfBox):
(BlackBerry::WebKit::SelectionHandler::extendSelectionToFieldBoundary):
(BlackBerry::WebKit::SelectionHandler::setSelection):
(BlackBerry::WebKit::SelectionHandler::clipPointToVisibleContainer):

  • WebKitSupport/SelectionHandler.h:
Location:
trunk/Source/WebKit/blackberry
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit/blackberry/ChangeLog

    r108963 r109013  
     12012-02-27  Ed Baker  <edbaker@rim.com>
     2
     3        [BlackBerry] Dragging a selection handle outside of the content bounding box does not update the selection range correctly
     4        https://bugs.webkit.org/show_bug.cgi?id=78608
     5
     6        Ensure that when selection handles leave the content bounding box that
     7        the handle not being dragged remains fixed. Do not apply padding to a
     8        direction that would cause the selection to shrink when performing the
     9        handle direction detection.
     10
     11        Reviewed by Antonio Gomes.
     12
     13        * WebKitSupport/DOMSupport.cpp:
     14        (BlackBerry::WebKit::DOMSupport::convertPointToFrame):
     15        * WebKitSupport/DOMSupport.h:
     16        * WebKitSupport/SelectionHandler.cpp:
     17        (BlackBerry::WebKit::clamp):
     18        (BlackBerry::WebKit::directionalVisiblePositionAtExtentOfBox):
     19        (BlackBerry::WebKit::SelectionHandler::extendSelectionToFieldBoundary):
     20        (BlackBerry::WebKit::SelectionHandler::setSelection):
     21        (BlackBerry::WebKit::SelectionHandler::clipPointToVisibleContainer):
     22        * WebKitSupport/SelectionHandler.h:
     23
    1242012-02-27  Leo Yang  <leo.yang@torchmobile.com.cn>
    225
  • trunk/Source/WebKit/blackberry/WebKitSupport/DOMSupport.cpp

    r107743 r109013  
    337337}
    338338
    339 IntPoint convertPointToFrame(const Frame* sourceFrame, const Frame* targetFrame, const IntPoint& point)
     339IntPoint convertPointToFrame(const Frame* sourceFrame, const Frame* targetFrame, const IntPoint& point, const bool clampToTargetFrame)
    340340{
    341341    ASSERT(sourceFrame && targetFrame);
     
    348348    Frame* targetFrameParent = targetFrame->tree()->parent();
    349349    IntRect targetFrameRect = targetFrame->view()->frameRect();
     350    IntPoint targetPoint = point;
    350351
    351352    // Convert the target frame rect to source window content coordinates. This is only required
     
    356357
    357358    // Requested point is outside of target frame, return InvalidPoint.
    358     if (!targetFrameRect.contains(point))
     359    if (clampToTargetFrame && !targetFrameRect.contains(targetPoint))
     360        targetPoint = IntPoint(targetPoint.x() < targetFrameRect.x() ? targetFrameRect.x() : std::min(targetPoint.x(), targetFrameRect.maxX()),
     361                targetPoint.y() < targetFrameRect.y() ? targetFrameRect.y() : std::min(targetPoint.y(), targetFrameRect.maxY()));
     362    else if (!targetFrameRect.contains(targetPoint))
    359363        return InvalidPoint;
    360364
    361365    // Adjust the points to be relative to the target.
    362     return targetFrame->view()->windowToContents(sourceFrame->view()->contentsToWindow(point));
     366    return targetFrame->view()->windowToContents(sourceFrame->view()->contentsToWindow(targetPoint));
    363367}
    364368
  • trunk/Source/WebKit/blackberry/WebKitSupport/DOMSupport.h

    r107743 r109013  
    7373bool elementIdOrNameIndicatesNoAutocomplete(const WebCore::Element*);
    7474
    75 WebCore::IntPoint convertPointToFrame(const WebCore::Frame* sourceFrame, const WebCore::Frame* targetFrame, const WebCore::IntPoint& sourcePoint);
     75WebCore::IntPoint convertPointToFrame(const WebCore::Frame* sourceFrame, const WebCore::Frame* targetFrame, const WebCore::IntPoint& sourcePoint, const bool clampToTargetFrame = false);
    7676
    7777static const WebCore::IntPoint InvalidPoint = WebCore::IntPoint(-1, -1);
  • trunk/Source/WebKit/blackberry/WebKitSupport/SelectionHandler.cpp

    r108796 r109013  
    272272}
    273273
     274static int clamp(const int min, const int value, const int max)
     275{
     276    return value < min ? min : std::min(value, max);
     277}
     278
    274279static VisiblePosition directionalVisiblePositionAtExtentOfBox(Frame* frame, const WebCore::IntRect& boundingBox, unsigned short direction, const WebCore::IntPoint& basePoint)
    275280{
     
    281286    switch (direction) {
    282287    case KEYCODE_LEFT:
    283         // Extend x to start without modifying y.
    284         return frame->visiblePositionForPoint(WebCore::IntPoint(boundingBox.x(), basePoint.y()));
     288        // Extend x to start and clamp y to the edge of bounding box.
     289        return frame->visiblePositionForPoint(WebCore::IntPoint(boundingBox.x(), clamp(boundingBox.y(), basePoint.y(), boundingBox.maxY())));
    285290    case KEYCODE_RIGHT:
    286         // Extend x to end without modifying y.
    287         return frame->visiblePositionForPoint(WebCore::IntPoint(boundingBox.maxX(), basePoint.y()));
     291        // Extend x to end and clamp y to the edge of bounding box.
     292        return frame->visiblePositionForPoint(WebCore::IntPoint(boundingBox.maxX(), clamp(boundingBox.y(), basePoint.y(), boundingBox.maxY())));
    288293    case KEYCODE_UP:
    289         // Extend y to top without modifying x.
    290         return frame->visiblePositionForPoint(WebCore::IntPoint(basePoint.x(), boundingBox.y()));
     294        // Extend y to top and clamp x to the edge of bounding box.
     295        return frame->visiblePositionForPoint(WebCore::IntPoint(clamp(boundingBox.x(), basePoint.x(), boundingBox.maxX()), boundingBox.y()));
    291296    case KEYCODE_DOWN:
    292         // Extend y to bottom without modifying x.
    293         return frame->visiblePositionForPoint(WebCore::IntPoint(basePoint.x(), boundingBox.maxY()));
     297        // Extend y to bottom and clamp x to the edge of bounding box.
     298        return frame->visiblePositionForPoint(WebCore::IntPoint(clamp(boundingBox.x(), basePoint.x(), boundingBox.maxX()), boundingBox.maxY()));
    294299    default:
    295300        break;
     
    326331    // Start handle is outside of the field. Treat it as the changed handle and move
    327332    // relative to the start caret rect.
    328     unsigned short character = directionOfPointRelativeToRect(selectionPoint, caretRect, isStartHandle /*useTopPadding*/, !isStartHandle /*useBottomPadding*/);
     333    unsigned short character = directionOfPointRelativeToRect(selectionPoint, caretRect, isStartHandle /* useTopPadding */, !isStartHandle /* useBottomPadding */);
    329334
    330335    // Prevent incorrect movement, handles can only extend the selection this way
     
    341346
    342347    if (isStartHandle)
    343         newSelection = VisibleSelection(newVisiblePosition, newSelection.extent(), true /*isDirectional*/);
     348        newSelection = VisibleSelection(newVisiblePosition, newSelection.extent(), true /* isDirectional */);
    344349    else
    345         newSelection = VisibleSelection(newSelection.base(), newVisiblePosition, true /*isDirectional*/);
     350        newSelection = VisibleSelection(newSelection.base(), newVisiblePosition, true /* isDirectional */);
    346351
    347352    // If no selection will be changed, return the character to extend using navigation.
     
    413418}
    414419
    415 WebCore::IntPoint SelectionHandler::clipPointToFocusNode(const WebCore::IntPoint& point)
    416 {
    417     // Clipping should only happen if we are in an input field.
    418     if (!m_webPage->m_inputHandler->isInputMode())
    419         return point;
    420 
    421     Frame* focusedFrame = m_webPage->focusedOrMainFrame();
    422     if (!focusedFrame->document()->focusedNode() || !focusedFrame->document()->focusedNode()->renderer())
    423         return point;
    424 
    425     WebCore::IntRect focusedNodeBoundingBox = focusedFrame->document()->focusedNode()->renderer()->absoluteBoundingBoxRect();
    426     focusedNodeBoundingBox.inflate(-1);
    427 
    428     WebCore::IntPoint clippedPoint = point;
    429     if (!focusedNodeBoundingBox.contains(clippedPoint))
    430         clippedPoint = WebCore::IntPoint(
    431             point.x() < focusedNodeBoundingBox.x() ? focusedNodeBoundingBox.x() : std::min(focusedNodeBoundingBox.maxX(), point.x()),
    432             point.y() < focusedNodeBoundingBox.y() ? focusedNodeBoundingBox.y() : std::min(focusedNodeBoundingBox.maxY(), point.y()));
    433 
    434     return clippedPoint;
    435 }
    436 
    437420void SelectionHandler::setSelection(const WebCore::IntPoint& start, const WebCore::IntPoint& end)
    438421{
     
    469452
    470453        // Set the selection with validation.
    471         newSelection.setBase(visiblePositionForPointIgnoringClipping(*focusedFrame, clipPointToFocusNode(relativeStart)));
     454        newSelection.setBase(visiblePositionForPointIgnoringClipping(*focusedFrame, clipPointToVisibleContainer(start)));
    472455
    473456        // Reset the selection using the existing extent without validation.
     
    479462
    480463        // Set the selection with validation.
    481         newSelection.setExtent(visiblePositionForPointIgnoringClipping(*focusedFrame, clipPointToFocusNode(relativeEnd)));
     464        newSelection.setExtent(visiblePositionForPointIgnoringClipping(*focusedFrame, clipPointToVisibleContainer(end)));
    482465
    483466        // Reset the selection using the existing base without validation.
     
    777760}
    778761
     762WebCore::IntPoint SelectionHandler::clipPointToVisibleContainer(const WebCore::IntPoint& point) const
     763{
     764    ASSERT(m_webPage->m_mainFrame && m_webPage->m_mainFrame->view());
     765
     766    Frame* frame = m_webPage->focusedOrMainFrame();
     767    WebCore::IntPoint clippedPoint = DOMSupport::convertPointToFrame(m_webPage->mainFrame(), frame, point, true /* clampToTargetFrame */);
     768
     769    if (m_webPage->m_inputHandler->isInputMode()
     770            && frame->document()->focusedNode()
     771            && frame->document()->focusedNode()->renderer()) {
     772        WebCore::IntRect boundingBox(frame->document()->focusedNode()->renderer()->absoluteBoundingBoxRect());
     773        boundingBox.inflate(-1);
     774        clippedPoint = WebCore::IntPoint(clamp(boundingBox.x(), clippedPoint.x(), boundingBox.maxX()), clamp(boundingBox.y(), clippedPoint.y(), boundingBox.maxY()));
     775    }
     776
     777    return clippedPoint;
     778}
     779
    779780static WebCore::IntPoint referencePoint(const VisiblePosition& position, const WebCore::IntRect& boundingRect, const WebCore::IntPoint& framePosition, bool isStartCaret, bool isRTL)
    780781{
  • trunk/Source/WebKit/blackberry/WebKitSupport/SelectionHandler.h

    r107736 r109013  
    7777    bool shouldUpdateSelectionOrCaretForPoint(const WebCore::IntPoint&, const WebCore::IntRect&, bool startCaret = true) const;
    7878    unsigned short extendSelectionToFieldBoundary(bool isStartHandle, const WebCore::IntPoint& selectionPoint, WebCore::VisibleSelection& newSelection);
    79     WebCore::IntPoint clipPointToFocusNode(const WebCore::IntPoint&);
     79    WebCore::IntPoint clipPointToVisibleContainer(const WebCore::IntPoint&) const;
    8080
    8181    WebPagePrivate* m_webPage;
Note: See TracChangeset for help on using the changeset viewer.