Do not notify editor state during executing command
[framework/web/webkit-efl.git] / Source / WebKit2 / WebProcess / WebPage / efl / WebPageEfl.cpp
index f74b956..4900176 100755 (executable)
@@ -339,17 +339,23 @@ void WebPage::setComposition(const String& compositionString, const Vector<WebCo
                             newUnderlines.last().endOffset = availableLength;
                     }
                 }
+
+                m_page->editorClient()->lockRespondToChangedSelection();
                 targetFrame->editor()->setComposition(newCompositionString, newUnderlines, cursorPosition, 0);
+                m_page->editorClient()->unlockRespondToChangedSelection();
+
                 return;
             }
         }
     }
+
+    m_page->editorClient()->lockRespondToChangedSelection();
 #endif
 
     targetFrame->editor()->setComposition(compositionString, underlines, cursorPosition, 0);
 
 #if ENABLE(TIZEN_ISF_PORT)
-    m_page->editorClient()->respondToChangedSelection(targetFrame);
+    m_page->editorClient()->unlockRespondToChangedSelection();
 #endif
 }
 
@@ -645,29 +651,6 @@ bool WebPage::setCaretPosition(const IntPoint& pos)
 
     return true;
 }
-
-void WebPage::getCaretPosition(IntRect& rect)
-{
-    Frame* frame = m_page->focusController()->focusedOrMainFrame();
-    if (!frame)
-        return;
-
-    FrameSelection* controller = frame->selection();
-    if (!controller)
-        return;
-
-    Node* node = controller->start().deprecatedNode();
-    if (!node || !node->renderer() || !node->isContentEditable())
-        return;
-
-    if (controller->isCaret()) {
-        FrameView* frameView = frame->view();
-        if (!frameView)
-            return;
-
-        rect = frameView->contentsToWindow(controller->absoluteCaretBounds());
-    }
-}
 #endif
 
 #if ENABLE(TIZEN_ISF_PORT)
@@ -684,7 +667,6 @@ void WebPage::didCancelComposition(Node* valueChangedNode)
 void WebPage::prepareKeyDownEvent()
 {
     m_prepareKeyDownEvent = true;
-    m_keyPressCommands.clear();
 }
 
 void WebPage::swapKeyPressCommands(Vector<OwnPtr<KeyPressCommand> >& commands)
@@ -692,55 +674,6 @@ void WebPage::swapKeyPressCommands(Vector<OwnPtr<KeyPressCommand> >& commands)
     m_keyPressCommands.swap(commands);
 }
 
-void WebPage::getCursorOffset(int& offset)
-{
-    offset = 0;
-    Frame* frame = m_page->focusController()->focusedOrMainFrame();
-    if (!frame || !frame->editor()->canEdit())
-        return;
-
-    Position base = frame->selection()->base();
-    Node* baseNode = base.containerNode();
-    if (baseNode)
-        offset = baseNode->isTextNode() ? base.offsetInContainerNode() : 0;
-}
-
-void WebPage::getSurroundingTextAndCursorOffset(String& text, int& offset)
-{
-    text = String();
-    offset = 0;
-
-    Frame* frame = m_page->focusController()->focusedOrMainFrame();
-    if (!frame || !frame->editor()->canEdit())
-        return;
-
-    Position base = frame->selection()->base();
-    Node* baseNode = base.containerNode();
-    if (baseNode && baseNode->isTextNode()) {
-        text = baseNode->textContent();
-        offset = base.offsetInContainerNode();
-    }
-}
-
-void WebPage::getSelectionRect(bool isOnlyEditable, IntRect& rect)
-{
-    rect = IntRect();
-
-    Frame* frame = m_page->focusController()->focusedFrame();
-    if (!frame || !frame->view())
-        return;
-
-    FrameSelection* selection = frame->selection();
-    Node* node = selection->start().deprecatedNode();
-    if (!node || !node->renderer() || (isOnlyEditable && !node->isContentEditable()))
-        return;
-
-    if (selection->isCaret())
-        rect = frame->view()->contentsToWindow(selection->absoluteCaretBounds());
-    else if (selection->isRange())
-        rect = frame->view()->contentsToWindow(enclosingIntRect(selection->bounds(false)));
-}
-
 void WebPage::deleteSurroundingText(int offset, int count)
 {
     Frame* frame = m_page->focusController()->focusedOrMainFrame();
@@ -764,6 +697,22 @@ void WebPage::deleteSurroundingText(int offset, int count)
     frame->selection()->setSelection(selection);
     frame->editor()->deleteWithDirection(DirectionBackward, CharacterGranularity, false, true);
 }
+
+void WebPage::updateEditorStateRect(const Frame* frame, EditorState& state) const
+{
+    ASSERT(frame->selection()->rootEditableElement());
+
+#if ENABLE(TIZEN_WEBKIT2_TEXT_SELECTION)
+    Vector<IntRect> rects;
+    calcFocusedRects(frame->selection()->rootEditableElement(), rects);
+    state.editorRect = unionRect(rects);
+#endif
+
+    if (frame->selection()->isCaret())
+        state.selectionRect = frame->view()->contentsToWindow(frame->selection()->absoluteCaretBounds());
+    else if (frame->selection()->isRange())
+        state.selectionRect = frame->view()->contentsToWindow(enclosingIntRect(frame->selection()->bounds(false)));
+}
 #endif
 
 #if ENABLE(TIZEN_INPUT_TAG_EXTENSION) || ENABLE(TIZEN_WEBKIT2_FORM_DATABASE)
@@ -899,7 +848,6 @@ static IntRect getNodeRect(Node* node, Node* focusableNode, bool isImage)
 
 #if ENABLE(TIZEN_WEBKIT2_HIT_TEST)
 #if ENABLE(TIZEN_WEBKIT2_FOCUS_RING)
-#if ENABLE(TOUCH_ADJUSTMENT)
 static bool isClickableOrFocusable(Node* focusableNode)
 {
 
@@ -927,16 +875,18 @@ static bool isClickableOrFocusable(Node* focusableNode)
    return false;
 }
 
-static IntRect getFocusedRect(HitTestResult hitTestResult, Page* page, const IntPoint& point, const IntSize& area)
+#if ENABLE(TOUCH_ADJUSTMENT)
+void WebPage::getFocusedRect(HitTestResult hitTestResult, Page* page, bool setFocus, Vector<IntRect>& rects, const IntPoint& point, const IntSize& area)
 #else
-static IntRect getFocusedRect(HitTestResult hitTestResult, Page* page)
+void WebPage::getFocusedRect(HitTestResult hitTestResult, Page* page, bool setFocus, Vector<IntRect>& rects)
 #endif
 {
     Node* node = hitTestResult.innerNode();
 #if ENABLE(TOUCH_ADJUSTMENT)
-    Node* adjustedNode = 0;
     IntPoint adustedPoint;
     Frame* mainFrame = page->mainFrame();
+    Node* adjustedNode = 0;
+    mainFrame->eventHandler()->bestClickableNodeForTouchPoint(point, IntSize(area.width() / 2, area.height() / 2), adustedPoint, adjustedNode);
     if (!isClickableOrFocusable(node))
         mainFrame->eventHandler()->bestClickableNodeForTouchPoint(point, IntSize(area.width() / 2, area.height() / 2), adustedPoint, adjustedNode);
 
@@ -944,7 +894,7 @@ static IntRect getFocusedRect(HitTestResult hitTestResult, Page* page)
         node = adjustedNode;
 #endif
     if (!node)
-        return IntRect();
+        return;
 
     bool isFocusRingDrawable = false;
     Node* focusableNode = node;
@@ -969,20 +919,22 @@ static IntRect getFocusedRect(HitTestResult hitTestResult, Page* page)
                 || child->hasEventListeners(eventNames().clickEvent)
                 || child->hasEventListeners(eventNames().mousedownEvent)
                 || child->hasEventListeners(eventNames().mouseupEvent)) {
-                return IntRect();
+                return;
             }
             child = child->traverseNextNode(focusableNode);
         }
     }
 
     if (!isFocusRingDrawable) {
-        if (node->hasTagName(HTMLNames::imgTag))
-            return getNodeRect(node, node, !hitTestResult.absoluteImageURL().isEmpty());
-
-        return IntRect();
+        if (!node->hasTagName(HTMLNames::imgTag))
+            return;
+        focusableNode = node;
     }
 
-    return getNodeRect(node, focusableNode, !hitTestResult.absoluteImageURL().isEmpty());
+    if (setFocus)
+        setFocusedNode(focusableNode);
+
+    calcFocusedRects(focusableNode, rects);
 }
 #endif
 
@@ -1027,17 +979,19 @@ void WebPage::hitTestResultAtPoint(const IntPoint& point, int hitTestMode, WebHi
     hitTestResultData.hitTestMode = hitTestMode;
 
 #if ENABLE(TIZEN_WEBKIT2_FOCUS_RING)
+    bool setFocus = hitTestResultData.hitTestMode & WebHitTestResult::HitTestModeSetFocus;
 #if ENABLE(TOUCH_ADJUSTMENT)
-    hitTestResultData.focusedRect = getFocusedRect(hitTestResult, m_page.get(), point, area);
+    getFocusedRect(hitTestResult, m_page.get(), setFocus, hitTestResultData.focusedRects, point, area);
 #else
-    hitTestResultData.focusedRect = getFocusedRect(hitTestResult, m_page.get());
+    getFocusedRect(hitTestResult, m_page.get(), setFocus, hitTestResultData.focusedRects);
 #endif
 
     // Don't display FocusRect if the size is too big..
     IntRect framerect = frameView->visibleContentRect(true);
-    if (hitTestResultData.focusedRect.width() > (0.8 * framerect.width())
-        && hitTestResultData.focusedRect.height() > (0.8 * framerect.height())) {
-        hitTestResultData.focusedRect = IntRect();
+    for (size_t i = 0; i < hitTestResultData.focusedRects.size(); ++i) {
+        if (hitTestResultData.focusedRects[i].width() > (0.8 * framerect.width())
+            && hitTestResultData.focusedRects[i].height() > (0.8 * framerect.height()))
+            hitTestResultData.focusedRects.clear();
     }
 
     if (hitTestResult.innerNode() && hitTestResult.innerNode()->renderer() && hitTestResult.innerNode()->renderer()->style()) {
@@ -1325,17 +1279,8 @@ void WebPage::selectClosestWord(const IntPoint& point, bool& result)
     HTMLInputElement* inputElement = node->toInputElement();
 
     if (hitTestResult.isContentEditable()) {
-#if ENABLE(TIZEN_INPUT_TAG_EXTENSION)
-        if (!inputElement || (inputElement
-            && !inputElement->isDateField() && !inputElement->isDateTimeField() && !inputElement->isDateTimeLocalField()
-            && !inputElement->isMonthField() && !inputElement->isTimeField() && !inputElement->isWeekField())) {
-            result = setCaretPosition(point);
-            return;
-        }
-#else
         result = setCaretPosition(point);
         return;
-#endif
     }
 
 #if ENABLE(TIZEN_INPUT_TAG_EXTENSION)
@@ -1578,7 +1523,9 @@ void WebPage::getSelectionHandlers(IntRect& leftRect, IntRect& rightRect)
         if (size == 1) {
             Element* rootEditableElement = focusedFrame->selection()->rootEditableElement();
             if (rootEditableElement) {
-                IntRect editorRect = nodeRect(rootEditableElement);
+                Vector<IntRect> rects;
+                calcFocusedRects(rootEditableElement, rects);
+                IntRect editorRect = unionRect(rects);
 
 #if ENABLE(TIZEN_WEBKIT2_TEXT_SELECTION)
                 if (m_editorState.editorRect != editorRect) {
@@ -1723,30 +1670,12 @@ void WebPage::getLinkMagnifierRect(const IntPoint& position, const IntSize& size
 #endif
 
 #if ENABLE(TIZEN_SCREEN_READER)
-static void sendScreenReaderFocusRect(WebPage* page, Node* node)
-{
-    bool isImage = false;
-    if (node->isElementNode()) {
-        Element* element = static_cast<Element*>(node);
-        isImage = !element->getAttribute(element->imageSourceAttributeName()).isEmpty();
-    }
-
-    page->send(Messages::WebPageProxy::DidScreenReaderFocusRectChanged(getNodeRect(node, node, isImage)));
-}
-
 void WebPage::moveScreenReaderFocus(bool forward, bool& result)
 {
     if (!m_screenReader)
         m_screenReader = ScreenReader::create(this);
 
-    if (!m_screenReader->moveFocus(forward)) {
-        result = false;
-        send(Messages::WebPageProxy::DidScreenReaderFocusRectChanged(IntRect()));
-        return;
-    } else {
-        result = true;
-        sendScreenReaderFocusRect(this, m_screenReader->getFocusedNode());
-    }
+    result = m_screenReader->moveFocus(forward);
 }
 
 void WebPage::moveScreenReaderFocusByPoint(const IntPoint& point)
@@ -1756,8 +1685,6 @@ void WebPage::moveScreenReaderFocusByPoint(const IntPoint& point)
 
     if (!m_screenReader->moveFocus(point))
         return;
-
-    sendScreenReaderFocusRect(this, m_screenReader->getFocusedNode());
 }
 
 void WebPage::clearScreenReaderFocus()
@@ -1798,22 +1725,14 @@ void WebPage::raiseTapEvent(const IntPoint& position, const IntPoint& globalPosi
 
 void WebPage::adjustScreenReaderFocusedObjectValue(bool up)
 {
-    if (!m_screenReader || !m_screenReader->getFocusedNode() || !m_screenReader->getFocusedNode()->toInputElement())
+    if (!m_screenReader || !m_focusedNode || !m_focusedNode->toInputElement())
         return;
 
     ExceptionCode ec;
     if (up)
-        m_screenReader->getFocusedNode()->toInputElement()->stepUp(ec);
+        m_focusedNode->toInputElement()->stepUp(ec);
     else
-        m_screenReader->getFocusedNode()->toInputElement()->stepDown(ec);
-}
-
-void WebPage::recalcScreenReaderFocusRect()
-{
-    if (!m_screenReader || !m_screenReader->getFocusedNode())
-        return;
-
-    sendScreenReaderFocusRect(this, m_screenReader->getFocusedNode());
+        m_focusedNode->toInputElement()->stepDown(ec);
 }
 
 void WebPage::updateScreenReaderFocus(RenderObject* object)
@@ -1825,8 +1744,6 @@ void WebPage::updateScreenReaderFocus(RenderObject* object)
         m_screenReader->clearFocus();
     else if (!m_screenReader->rendererWillBeDestroyed(object))
         return;
-
-    send(Messages::WebPageProxy::DidScreenReaderFocusRectChanged(IntRect()));
 }
 
 void WebPage::clearScreenReader()
@@ -1835,7 +1752,7 @@ void WebPage::clearScreenReader()
 }
 #endif
 
-#if ENABLE(TIZEN_SCREEN_READER) || ENABLE(TIZEN_FOCUS_UI) || ENABLE(TIZEN_WEBKIT2_TEXT_SELECTION)
+#if ENABLE(TIZEN_WEBKIT2_FOCUS_RING) || ENABLE(TIZEN_WEBKIT2_TEXT_SELECTION)
 static LayoutRect rectToAbsoluteCoordinates(Frame* initialFrame, const LayoutRect& initialRect)
 {
     LayoutRect rect = initialRect;
@@ -1851,17 +1768,27 @@ static LayoutRect rectToAbsoluteCoordinates(Frame* initialFrame, const LayoutRec
     return rect;
 }
 
-IntRect WebPage::nodeRect(Node* node) const
+void WebPage::calcFocusedRects(Node* node, Vector<IntRect>& rects) const
 {
-    if (!node)
-        return IntRect();
+    if (!node || !node->renderer())
+        return;
+
+    RenderObject* renderer = node->renderer();
+    FrameView* view = node->document()->frame()->view();
+
+    IntPoint absolutePoint;
+    absolutePoint = view->convertToContainingWindow(view->convertFromRenderer(renderer, absolutePoint));
+    renderer->addFocusRingRects(rects, absolutePoint);
+
+    if (!rects.isEmpty())
+        return;
 
     LayoutRect rect;
     if (node->hasTagName(HTMLNames::areaTag)) {
         HTMLAreaElement* area = static_cast<HTMLAreaElement*>(node);
         HTMLImageElement* image = area->imageElement();
         if (!image || !image->renderer())
-            return IntRect();
+            return;
 
         rect = rectToAbsoluteCoordinates(area->document()->frame(), area->computeRect(area->imageElement()->renderer()));
     } else if (node->renderer()) {
@@ -1878,7 +1805,34 @@ IntRect WebPage::nodeRect(Node* node) const
         }
     }
 
-    return pixelSnappedIntRect(rect);
+    rects.append(pixelSnappedIntRect(rect));
+}
+#endif
+
+#if ENABLE(TIZEN_WEBKIT2_FOCUS_RING)
+void WebPage::setFocusedNode(Node* node)
+{
+    m_focusedNode = node;
+    didChangeFocusedRects();
+}
+
+void WebPage::didChangeFocusedRects()
+{
+    Vector<IntRect> rects;
+    calcFocusedRects(m_focusedNode.get(), rects);
+    if (m_focusedRects == rects)
+        return;
+
+    m_focusedRects = rects;
+    send(Messages::WebPageProxy::DidChangeFocusedRects(m_focusedRects));
+}
+
+void WebPage::recalcFocusedRects()
+{
+    if (!m_focusedNode)
+        return;
+
+    didChangeFocusedRects();
 }
 #endif
 
@@ -1952,15 +1906,33 @@ void WebPage::didChangeContents(const IntRect& rect)
 
 #if ENABLE(TIZEN_ISF_PORT) || ENABLE(TIZEN_WEBKIT2_TEXT_SELECTION)
     if (m_editorState.isContentEditable && rect.intersects(m_editorState.editorRect) && frame->selection()->rootEditableElement()) {
-        IntRect currentEditorRect = nodeRect(frame->selection()->rootEditableElement());
-        if (m_editorState.editorRect != currentEditorRect) {
-            m_editorState.editorRect = currentEditorRect;
+        IntRect previousEditorRect = m_editorState.editorRect;
+        updateEditorStateRect(frame, m_editorState);
+
+        if (m_editorState.editorRect != previousEditorRect) {
             m_editorState.updateEditorRectOnly = true;
             send(Messages::WebPageProxy::EditorStateChanged(m_editorState));
         }
     }
 #endif
+
+#if ENABLE(TIZEN_WEBKIT2_FOCUS_RING)
+    didChangeFocusedRects();
+#endif
 }
+
+#if ENABLE(TIZEN_FOCUS_UI)
+void WebPage::setSpatialNavigationEnabled(bool enabled)
+{
+    m_page->settings()->setSpatialNavigationEnabled(enabled);
+
+    if (m_focusedNode && m_focusedNode->renderer())
+        m_focusedNode->renderer()->repaint();
+
+    if (!enabled)
+        setFocusedNode(0);
+}
+#endif
 #endif // #if OS(TIZEN)
 
 } // namespace WebKit