Do not notify editor state during executing command
[framework/web/webkit-efl.git] / Source / WebKit2 / WebProcess / WebPage / efl / WebPageEfl.cpp
index 015d5ea..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,43 +848,101 @@ static IntRect getNodeRect(Node* node, Node* focusableNode, bool isImage)
 
 #if ENABLE(TIZEN_WEBKIT2_HIT_TEST)
 #if ENABLE(TIZEN_WEBKIT2_FOCUS_RING)
-static IntRect getFocusedRect(HitTestResult hitTestResult, Page* page)
+static bool isClickableOrFocusable(Node* focusableNode)
+{
+
+   if (!focusableNode)
+       return false;
+   if (focusableNode->disabled())
+        return false;
+   if (!focusableNode->inDocument())
+        return false;
+   if (!focusableNode->renderer() || focusableNode->renderer()->style()->visibility() != VISIBLE)
+        return false;
+   if (focusableNode->isFocusable()) {
+       if (focusableNode->isLink()
+           || focusableNode->hasTagName(HTMLNames::inputTag)
+           || focusableNode->hasTagName(HTMLNames::selectTag)
+           || focusableNode->hasTagName(HTMLNames::buttonTag))
+           return true;
+   }
+   if (focusableNode->supportsFocus()
+       || focusableNode->hasEventListeners(eventNames().clickEvent)
+       || focusableNode->hasEventListeners(eventNames().mousedownEvent)
+       || focusableNode->hasEventListeners(eventNames().mouseupEvent)) {
+       return true;
+   }
+   return false;
+}
+
+#if ENABLE(TOUCH_ADJUSTMENT)
+void WebPage::getFocusedRect(HitTestResult hitTestResult, Page* page, bool setFocus, Vector<IntRect>& rects, const IntPoint& point, const IntSize& area)
+#else
+void WebPage::getFocusedRect(HitTestResult hitTestResult, Page* page, bool setFocus, Vector<IntRect>& rects)
+#endif
 {
     Node* node = hitTestResult.innerNode();
+#if ENABLE(TOUCH_ADJUSTMENT)
+    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);
+
+    if (adjustedNode)
+        node = adjustedNode;
+#endif
     if (!node)
-        return IntRect();
+        return;
 
     bool isFocusRingDrawable = false;
     Node* focusableNode = node;
     while (focusableNode) {
         RenderObject* renderer = focusableNode->renderer();
-        if (renderer && renderer->isRoot())
+        if (renderer && (renderer->isBody() || renderer->isRenderView() || renderer->isRoot()))
             break;
 
-        if (focusableNode->isFocusable()) {
-            if (focusableNode->isLink()
-                || focusableNode->hasTagName(HTMLNames::inputTag)
-                || focusableNode->hasTagName(HTMLNames::selectTag)
-                || focusableNode->hasTagName(HTMLNames::buttonTag))
-                isFocusRingDrawable = true;
+        if (isClickableOrFocusable(focusableNode)) {
+            isFocusRingDrawable = true;
             break;
         }
 
         focusableNode = focusableNode->parentNode();
     }
 
-    if (!isFocusRingDrawable) {
-        if (node->hasTagName(HTMLNames::imgTag))
-            return getNodeRect(node, node, !hitTestResult.absoluteImageURL().isEmpty());
+    // Don't draw focus ring if child is focusable or has trigger
+    if (focusableNode && focusableNode->isContainerNode() && !focusableNode->isLink()) {
+        WebCore::Node *child = static_cast<const ContainerNode*>(focusableNode)->firstChild();
+        while(child) {
+            if( child->supportsFocus()
+                || child->hasEventListeners(eventNames().clickEvent)
+                || child->hasEventListeners(eventNames().mousedownEvent)
+                || child->hasEventListeners(eventNames().mouseupEvent)) {
+                return;
+            }
+            child = child->traverseNextNode(focusableNode);
+        }
+    }
 
-        return IntRect();
+    if (!isFocusRingDrawable) {
+        if (!node->hasTagName(HTMLNames::imgTag))
+            return;
+        focusableNode = node;
     }
 
-    return getNodeRect(node, focusableNode, !hitTestResult.absoluteImageURL().isEmpty());
+    if (setFocus)
+        setFocusedNode(focusableNode);
+
+    calcFocusedRects(focusableNode, rects);
 }
 #endif
 
+#if ENABLE(TOUCH_ADJUSTMENT)
+void WebPage::hitTestResultAtPoint(const IntPoint& point, int hitTestMode, const IntSize& area, WebHitTestResult::Data& hitTestResultData)
+#else
 void WebPage::hitTestResultAtPoint(const IntPoint& point, int hitTestMode, WebHitTestResult::Data& hitTestResultData)
+#endif
 {
     Frame* frame = m_page->mainFrame();
     FrameView* frameView = frame->view();
@@ -972,7 +979,21 @@ void WebPage::hitTestResultAtPoint(const IntPoint& point, int hitTestMode, WebHi
     hitTestResultData.hitTestMode = hitTestMode;
 
 #if ENABLE(TIZEN_WEBKIT2_FOCUS_RING)
-    hitTestResultData.focusedRect = getFocusedRect(hitTestResult, m_page.get());
+    bool setFocus = hitTestResultData.hitTestMode & WebHitTestResult::HitTestModeSetFocus;
+#if ENABLE(TOUCH_ADJUSTMENT)
+    getFocusedRect(hitTestResult, m_page.get(), setFocus, hitTestResultData.focusedRects, point, area);
+#else
+    getFocusedRect(hitTestResult, m_page.get(), setFocus, hitTestResultData.focusedRects);
+#endif
+
+    // Don't display FocusRect if the size is too big..
+    IntRect framerect = frameView->visibleContentRect(true);
+    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()) {
         hitTestResultData.focusedColor = hitTestResult.innerNode()->renderer()->style()->tapHighlightColor();
         if (!hitTestResultData.focusedColor.hasAlpha())
@@ -1258,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)
@@ -1332,9 +1344,9 @@ void WebPage::selectClosestWord(const IntPoint& point, bool& result)
     result = true;
 }
 
-void WebPage::setLeftSelection(const IntPoint& point, bool& result)
+void WebPage::setLeftSelection(const IntPoint& point, const int direction, int& result)
 {
-    result = false;
+    result = HandleMovingDirectionNone;
 
     Frame* focusedFrame = m_page->focusController()->focusedOrMainFrame();
     FrameSelection* frameSelection = focusedFrame->selection();
@@ -1352,8 +1364,6 @@ void WebPage::setLeftSelection(const IntPoint& point, bool& result)
     IntPoint pos = frameView->windowToContents(point);
     IntRect leftRect, rightRect;
     getSelectionHandlers(leftRect, rightRect);
-    if ((rightRect.y() + rightRect.height()) < pos.y())
-        pos.setY(rightRect.y() + (rightRect.height()/2));
 
     if (selectionEndNode->rendererIsEditable() && !selectionEndNode->rendererIsRichlyEditable()) {
         const int boundariesWidth = 2;
@@ -1367,6 +1377,7 @@ void WebPage::setLeftSelection(const IntPoint& point, bool& result)
     }
 
     OwnPtr<VisiblePosition> position = adoptPtr(new VisiblePosition(focusedFrame->visiblePositionForPoint(pos)));
+    Position base = frameSelection->base();
     Position extent = frameSelection->extent();
 
     Node* newSelectionStartNode = position->deepEquivalent().deprecatedNode();
@@ -1374,8 +1385,7 @@ void WebPage::setLeftSelection(const IntPoint& point, bool& result)
     // both start and end nodes should be in the same area type: both should be editable or both should be not editable
     // Check if the new position is before the extent's position
     if (newSelectionStartNode
-        && selectionEndNode->isContentEditable() == newSelectionStartNode->isContentEditable()
-        && comparePositions(position->deepEquivalent(), extent) < 0) {
+        && selectionEndNode->isContentEditable() == newSelectionStartNode->isContentEditable()) {
         // Change the 'base' and 'extent' positions to 'start' and 'end' positions.
         // We do it, because without this, the other modification of the selection
         // would destroy the 'start' and/or 'end' positions and set them to
@@ -1386,20 +1396,35 @@ void WebPage::setLeftSelection(const IntPoint& point, bool& result)
         bool oldProhibitsScrolling = focusedFrame->view()->prohibitsScrolling();
         focusedFrame->view()->setProhibitsScrolling(true);
 
-        frameSelection->setBase(*position);
+        if (direction == HandleMovingDirectionNormal) {
+            if (comparePositions(position->deepEquivalent(), extent) < 0) {
+                frameSelection->setBase(*position);
+                result = HandleMovingDirectionNormal;
+            } else if (comparePositions(position->deepEquivalent(), extent) > 0) {
+                frameSelection->setExtent(*position);
+                frameSelection->setBase(extent);
+                result = HandleMovingDirectionReverse;
+            }
+        } else if (direction == HandleMovingDirectionReverse) {
+            if (comparePositions(position->deepEquivalent(), base) > 0) {
+                frameSelection->setExtent(*position);
+                result = HandleMovingDirectionReverse;
+            } else if (comparePositions(position->deepEquivalent(), base) < 0) {
+                frameSelection->setBase(*position);
+                frameSelection->setExtent(base);
+                result = HandleMovingDirectionNormal;
+            }
+        }
 
         focusedFrame->view()->setProhibitsScrolling(oldProhibitsScrolling);
         // This forces webkit to show selection
         // m_coreFrame->invalidateSelection();
-
-        result = true;
     }
 }
 
-
-void WebPage::setRightSelection(const IntPoint& point, bool& result)
+void WebPage::setRightSelection(const IntPoint& point, const int direction, int& result)
 {
-    result = false;
+    result = HandleMovingDirectionNone;
 
     Frame* focusedFrame = m_page->focusController()->focusedOrMainFrame();
     FrameSelection* frameSelection = focusedFrame->selection();
@@ -1429,14 +1454,14 @@ void WebPage::setRightSelection(const IntPoint& point, bool& result)
 
     OwnPtr<VisiblePosition> position = adoptPtr(new VisiblePosition(focusedFrame->visiblePositionForPoint(pos)));
     Position base = frameSelection->base();
+    Position extent = frameSelection->extent();
 
     Node* newSelectionEndNode = position->deepEquivalent().deprecatedNode();
 
     // both start and end nodes should be in the same area type: both should be editable or both should be not editable
     // Check if the new position is after the base's position
     if (newSelectionEndNode
-        && selectionStartNode->isContentEditable() == newSelectionEndNode->isContentEditable()
-        && comparePositions(position->deepEquivalent(), base) > 0) {
+        && selectionStartNode->isContentEditable() == newSelectionEndNode->isContentEditable()) {
         // Change the 'base' and 'extent' positions to 'start' and 'end' positions.
         // We do it, because without this, the other modifications of the selection
         // would destroy the 'start' and/or 'end' positions and set them to
@@ -1448,11 +1473,27 @@ void WebPage::setRightSelection(const IntPoint& point, bool& result)
         bool oldProhibitsScrolling = focusedFrame->view()->prohibitsScrolling();
         focusedFrame->view()->setProhibitsScrolling(true);
 
-        frameSelection->setExtent(*position);
+        if (direction == HandleMovingDirectionNormal) {
+            if (comparePositions(position->deepEquivalent(), base) > 0) {
+                frameSelection->setExtent(*position);
+                result = HandleMovingDirectionNormal;
+            } else if (comparePositions(position->deepEquivalent(), base) < 0) {
+                frameSelection->setBase(*position);
+                frameSelection->setExtent(base);
+                result = HandleMovingDirectionReverse;
+            }
+        } else if (direction == HandleMovingDirectionReverse) {
+            if (comparePositions(position->deepEquivalent(), extent) < 0) {
+                frameSelection->setBase(*position);
+                result = HandleMovingDirectionReverse;
+            } else if (comparePositions(position->deepEquivalent(), extent) > 0) {
+                frameSelection->setExtent(*position);
+                frameSelection->setBase(extent);
+                result = HandleMovingDirectionNormal;
+            }
+        }
 
         focusedFrame->view()->setProhibitsScrolling(oldProhibitsScrolling);
-
-        result = true;
     }
 }
 
@@ -1482,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) {
@@ -1627,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)
@@ -1660,8 +1685,6 @@ void WebPage::moveScreenReaderFocusByPoint(const IntPoint& point)
 
     if (!m_screenReader->moveFocus(point))
         return;
-
-    sendScreenReaderFocusRect(this, m_screenReader->getFocusedNode());
 }
 
 void WebPage::clearScreenReaderFocus()
@@ -1702,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)
@@ -1729,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()
@@ -1739,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;
@@ -1755,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()) {
@@ -1782,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
 
@@ -1856,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