Adjusted magnifier position properly in case that touched position is outside of...
authorYuni Jeong <yhnet.jung@samsung.com>
Wed, 5 Jun 2013 08:04:43 +0000 (17:04 +0900)
committerYuni Jeong <yhnet.jung@samsung.com>
Wed, 5 Jun 2013 08:25:49 +0000 (17:25 +0900)
[Title] Adjusted magnifier position properly in case that touched position is outside of the editor box.
[Issue#] N_SE-40154, N_SE-38039
[Problem] When touched position is outside of the editor box,
          magnifier is displayed in the center of the editor box.
[Cause] Magnifier position is set to the center of the editor box
        in case that touched position is outside of the editor box.
[Solution] Adjusted magnifier position properly like below:
            - If Y of the touched position < Y of the editor box, set to Y of the editor box.
            - If Y of the touched position > maxY of the editor box, set to maxY of the editor box.

Change-Id: I33059e7971915f56192bc00727ec10dfe8e2a0c6

Source/WebKit2/UIProcess/API/efl/tizen/TextSelection.cpp
Source/WebKit2/UIProcess/WebPageProxy.h
Source/WebKit2/UIProcess/efl/WebPageProxyEfl.cpp
Source/WebKit2/WebProcess/WebPage/WebPage.cpp
Source/WebKit2/WebProcess/WebPage/WebPage.h
Source/WebKit2/WebProcess/WebPage/WebPage.messages.in
Source/WebKit2/WebProcess/WebPage/efl/WebPageEfl.cpp

index 33dae6a..75f80ba 100755 (executable)
@@ -503,6 +503,8 @@ bool TextSelection::textSelectionDown(const IntPoint& point, bool isStartedTextS
     return true;
 }
 
+static int s_textSelectionMargin = 5;
+
 void TextSelection::textSelectionMove(const IntPoint& point, bool isStartedTextSelectionFromOutside)
 {
     // text selection should be ignored when longtap on handle from osp
@@ -519,18 +521,37 @@ void TextSelection::textSelectionMove(const IntPoint& point, bool isStartedTextS
     if (editorState.isContentEditable) {
         IntRect mapRect = m_viewImpl->transformToScene().mapRect(editorState.editorRect);
         IntPoint updatedPoint = point;
-        if ((point.y() < mapRect.y()) || (point.y() > ((mapRect.y()) + (mapRect.height()))))
-            updatedPoint.setY((mapRect.y()) + ((mapRect.height())/2) );
+        bool scrolledY = false;
+        if (point.y() < mapRect.y()) {
+            updatedPoint.setY(mapRect.y() + s_textSelectionMargin);
+            if (m_viewImpl->page()->scrollContentByLine(point,WebCore::DirectionBackward)) {
+                scrolledY = true;
+                updateMagnifier(updatedPoint);
+            }
+        } else if (point.y() > mapRect.maxY()) {
+            updatedPoint.setY(mapRect.maxY() - s_textSelectionMargin);
+            if (m_viewImpl->page()->scrollContentByLine(point,WebCore::DirectionForward)) {
+                scrolledY = true;
+                updateMagnifier(updatedPoint);
+            }
+        }
 
+        bool scrolledX = false;
         if (point.x() < mapRect.x()) {
-            updatedPoint.setX(mapRect.x());
-            if (m_viewImpl->page()->scrollContentByCharacter(point,WebCore::DirectionBackward))
+            updatedPoint.setX(mapRect.x() + s_textSelectionMargin);
+            if (m_viewImpl->page()->scrollContentByCharacter(point,WebCore::DirectionBackward)) {
+                scrolledX = true;
                 updateMagnifier(updatedPoint);
-        } else if (point.x() > ((mapRect.x()) + (mapRect.width()))) {
-            updatedPoint.setX((mapRect.x()) + (mapRect.width()));
-            if (m_viewImpl->page()->scrollContentByCharacter(point,WebCore::DirectionForward))
+            }
+        } else if (point.x() > mapRect.maxX()) {
+            updatedPoint.setX(mapRect.maxX() - s_textSelectionMargin);
+            if (m_viewImpl->page()->scrollContentByCharacter(point,WebCore::DirectionForward)) {
+                scrolledX = true;
                 updateMagnifier(updatedPoint);
-        } else {
+            }
+        }
+
+        if (!scrolledX && !scrolledY) {
             viewPoint = m_viewImpl->transformFromScene().mapPoint(updatedPoint);
             m_viewImpl->page()->selectClosestWord(viewPoint, isStartedTextSelectionFromOutside);
             updateMagnifier(updatedPoint);
index f27ad6d..4c10e19 100755 (executable)
@@ -1010,6 +1010,7 @@ public:
     String getSelectionText();
     bool selectionRangeClear();
     bool scrollContentByCharacter(const WebCore::IntPoint&, WebCore::SelectionDirection direction);
+    bool scrollContentByLine(const WebCore::IntPoint&, WebCore::SelectionDirection direction);
 #endif
 
 #if ENABLE(TIZEN_LINK_MAGNIFIER)
index abc0c31..eb778d4 100755 (executable)
@@ -935,6 +935,16 @@ bool WebPageProxy::scrollContentByCharacter(const IntPoint& point, SelectionDire
     process()->sendSync(Messages::WebPage::ScrollContentByCharacter(point, direction), Messages::WebPage::ScrollContentByCharacter::Reply(result), m_pageID);
     return result;
 }
+
+bool WebPageProxy::scrollContentByLine(const IntPoint& point, SelectionDirection direction)
+{
+    if (!isValid())
+        return false;
+
+    bool result = false;
+    process()->sendSync(Messages::WebPage::ScrollContentByLine(point, direction), Messages::WebPage::ScrollContentByLine::Reply(result), m_pageID);
+    return result;
+}
 #endif
 
 #if ENABLE(TIZEN_LINK_MAGNIFIER)
index 3e25309..38d645b 100755 (executable)
@@ -562,7 +562,7 @@ EditorState WebPage::editorState() const
     if (!rootEditableElement)
         return result;
 
-    result.editorRect = frame->view()->contentsToWindow(rootEditableElement->getPixelSnappedRect());
+    result.editorRect = nodeRect(rootEditableElement);
 
 #if ENABLE(TIZEN_WEBKIT2_GET_TEXT_STYLE_FOR_SELECTION)
     result.bgColor = frame->editor()->selectionStartCSSPropertyValue(CSSPropertyBackgroundColor);
index c0ade44..2e356ad 100644 (file)
@@ -301,6 +301,7 @@ public:
     void selectionRangeClear(bool& result);
     void selectionClearAllSelection(WebCore::Frame* frame);
     void scrollContentByCharacter(const WebCore::IntPoint&, int direction, bool& result);
+    void scrollContentByLine(const WebCore::IntPoint&, int direction, bool& result);
 #endif
 
 #if ENABLE(TIZEN_OFFLINE_PAGE_SAVE)
@@ -760,6 +761,10 @@ public:
     void clearScreenReader();
 #endif
 
+#if ENABLE(TIZEN_SCREEN_READER) || ENABLE(TIZEN_FOCUS_UI) || ENABLE(TIZEN_WEBKIT2_TEXT_SELECTION)
+    WebCore::IntRect nodeRect(WebCore::Node*) const;
+#endif
+
 #if ENABLE(TIZEN_WEBKIT2_POPUP_INTERNAL)
     void notifyTransitionToCommitted(bool);
 #endif
index 69d0d62..042ea43 100644 (file)
@@ -381,6 +381,7 @@ messages -> WebPage {
     GetSelectionText() -> (String result)
     SelectionRangeClear() -> (bool result)
     ScrollContentByCharacter(WebCore::IntPoint point, int direction) -> (bool result)
+    ScrollContentByLine(WebCore::IntPoint point, int direction) -> (bool result)
 #endif
 
 #if ENABLE(TIZEN_OFFLINE_PAGE_SAVE)
index 6f4aeb6..bce00e5 100644 (file)
 #include "WebEventConversion.h"
 #endif
 
+#if ENABLE(TIZEN_SCREEN_READER) || ENABLE(TIZEN_FOCUS_UI) || ENABLE(TIZEN_WEBKIT2_TEXT_SELECTION)
+#include <WebCore/HTMLAreaElement.h>
+#endif
+
 #if ENABLE(TIZEN_CSP)
 #include <WebCore/ContentSecurityPolicy.h>
 #endif
 #include "fontconfig/fontconfig.h"
 #include <WebCore/FontCache.h>
 #endif
+
+#if ENABLE(TIZEN_WEBKIT2_TEXT_SELECTION)
+#include "visible_units.h"
+#endif
 #endif // #if OS(TIZEN)
 
 using namespace WebCore;
@@ -1517,10 +1525,51 @@ void WebPage::scrollContentByCharacter(const IntPoint&, int direction, bool& res
     result = false;
 
     Frame* focusedFrame = m_page->focusController()->focusedOrMainFrame();
-    if (direction)
-        result = focusedFrame->selection()->modify(FrameSelection::AlterationMove, DirectionBackward, CharacterGranularity, UserTriggered);
-    else
-        result = focusedFrame->selection()->modify(FrameSelection::AlterationMove, DirectionForward, CharacterGranularity, UserTriggered);
+    if (!focusedFrame)
+        return;
+
+    FrameSelection* frameSelection = focusedFrame->selection();
+    if (!frameSelection)
+        return;
+
+    VisiblePosition currentPosition = frameSelection->selection().visibleStart();
+    if (direction) {
+        if (isStartOfLine(currentPosition))
+            return;
+
+        focusedFrame->selection()->modify(FrameSelection::AlterationMove, DirectionBackward, CharacterGranularity, UserTriggered);
+    } else {
+        if (isEndOfLine(currentPosition))
+            return;
+
+        focusedFrame->selection()->modify(FrameSelection::AlterationMove, DirectionForward, CharacterGranularity, UserTriggered);
+    }
+}
+
+void WebPage::scrollContentByLine(const IntPoint&, int direction, bool& result)
+{
+    result = false;
+
+    Frame* focusedFrame = m_page->focusController()->focusedOrMainFrame();
+    if (!focusedFrame)
+        return;
+
+    FrameSelection* frameSelection = focusedFrame->selection();
+    if (!frameSelection)
+        return;
+
+    VisiblePosition currentPosition = frameSelection->selection().visibleStart();
+    if (direction) {
+        if (inSameLine(currentPosition, previousLinePosition(currentPosition, 0)))
+            return;
+
+        focusedFrame->selection()->modify(FrameSelection::AlterationMove, DirectionBackward, LineGranularity, UserTriggered);
+    } else {
+        if (inSameLine(currentPosition, nextLinePosition(currentPosition, 0)))
+            return;
+
+        focusedFrame->selection()->modify(FrameSelection::AlterationMove, DirectionForward, LineGranularity, UserTriggered);
+    }
 }
 #endif
 
@@ -1616,6 +1665,53 @@ void WebPage::clearScreenReader()
 }
 #endif
 
+#if ENABLE(TIZEN_SCREEN_READER) || ENABLE(TIZEN_FOCUS_UI) || ENABLE(TIZEN_WEBKIT2_TEXT_SELECTION)
+static LayoutRect rectToAbsoluteCoordinates(Frame* initialFrame, const LayoutRect& initialRect)
+{
+    LayoutRect rect = initialRect;
+    for (Frame* frame = initialFrame; frame; frame = frame->tree()->parent()) {
+        RenderBoxModelObject* renderer;
+        if (frame->ownerElement() && (renderer = frame->ownerElement()->renderBoxModelObject())) {
+            do {
+                rect.move(renderer->offsetLeft(), renderer->offsetTop());
+            } while ((renderer = renderer->offsetParent()));
+            rect.move(-frame->view()->scrollOffset());
+        }
+    }
+    return rect;
+}
+
+IntRect WebPage::nodeRect(Node* node) const
+{
+    if (!node)
+        return IntRect();
+
+    LayoutRect rect;
+    if (node->hasTagName(HTMLNames::areaTag)) {
+        HTMLAreaElement* area = static_cast<HTMLAreaElement*>(node);
+        HTMLImageElement* image = area->imageElement();
+        if (!image || !image->renderer())
+            return IntRect();
+
+        rect = rectToAbsoluteCoordinates(area->document()->frame(), area->computeRect(area->imageElement()->renderer()));
+    } else if (node->renderer()) {
+        if (node->isDocumentNode())
+            rect = rectToAbsoluteCoordinates(static_cast<Document*>(node)->frame(), static_cast<Document*>(node)->frame()->view()->visibleContentRect());
+        else {
+            rect = node->getRect();
+            rect.intersect(node->renderer()->absoluteClippedOverflowRect());
+            rect = rectToAbsoluteCoordinates(node->document()->frame(), rect);
+
+            rect.move(node->renderer()->style()->borderLeftWidth(), node->renderer()->style()->borderTopWidth());
+            rect.setWidth(rect.width() - node->renderer()->style()->borderLeftWidth() - node->renderer()->style()->borderRightWidth());
+            rect.setHeight(rect.height() - node->renderer()->style()->borderTopWidth() - node->renderer()->style()->borderBottomWidth());
+        }
+    }
+
+    return pixelSnappedIntRect(rect);
+}
+#endif
+
 #if ENABLE(TIZEN_WEBKIT2_POPUP_INTERNAL)
 // FIXME: Currently with cached pages, hiding Popup list menu is not working correctly.
 // This patch is a fix allowing any popup list menu to get close for any page navigation.