Fix for focus issue about N_SE-51671
[framework/osp/web.git] / src / controls / FWebCtrl_WebImpl.cpp
index 857dbdb..76a7b0f 100755 (executable)
@@ -150,23 +150,6 @@ static const int DEFAULT_LIST_ITEM_COUNT = 4;
 
 
 Eina_Bool
-AddHttpHeaderData(const Eina_Hash* pHash, const void* pKey, void* pValue, void* pUserData)
-{
-       result r = E_SUCCESS;
-
-       String key(reinterpret_cast< const char* >(pKey));
-       String value(reinterpret_cast< char* >(pValue));
-
-       SysLog(NID_WEB_CTRL, "The current value of key is %ls, value is %ls", key.GetPointer(), value.GetPointer());
-
-       r = reinterpret_cast< HttpHeader* >(pUserData)->AddField(key, value);
-       SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, EINA_FALSE, r, "[%s] Propagating.", GetErrorMessage(r));
-
-       return EINA_TRUE;
-}
-
-
-Eina_Bool
 AddHttpAttributeData(const Eina_Hash* pHash, const void* pKey, void* pValue, void* pUserData)
 {
        result r = E_SUCCESS;
@@ -1124,11 +1107,26 @@ OnWebDataReceived(void* pUserData, Evas_Object* pView, void* pEventInfo)
                ILoadingListener* pLoadingListener = pImpl->GetLoadingListener();
                if (pLoadingListener)
                {
-                       const Eina_Hash* pHeader = ewk_policy_decision_response_headers_get(pPolicy);
                        HttpHeader httpHeader;
 
-                       eina_hash_foreach(pHeader, AddHttpHeaderData, &httpHeader);
-                       SysTryCatch(NID_WEB_CTRL, GetLastResult() == E_SUCCESS, , GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
+                       Eina_Iterator* iterator = eina_hash_iterator_tuple_new(ewk_policy_decision_response_headers_get(pPolicy));
+                       if (iterator)
+                       {
+                               Eina_Hash_Tuple *tuple = null;
+
+                               EINA_ITERATOR_FOREACH(iterator, tuple)
+                               {
+                                       String key(reinterpret_cast< const char* >(tuple->key));
+                                       String value(reinterpret_cast< char* >(tuple->data));
+
+                                       SysSecureLog(NID_WEB_CTRL, "The current value of key is %ls, value is %ls", key.GetPointer(), value.GetPointer());
+
+                                       r = httpHeader.AddField(key, value);
+                                       SysTryCatch(NID_WEB_CTRL, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
+                               }
+
+                               eina_iterator_free(iterator);
+                       }
 
                        pImpl->SetPolicyDecision(pLoadingListener->OnWebDataReceived(mime, httpHeader));
                }
@@ -1146,9 +1144,10 @@ OnWebDataReceived(void* pUserData, Evas_Object* pView, void* pEventInfo)
                String redirectUrl(pImpl->GetRedirectUri(url, currentUrl, mime));
                if (redirectUrl != L"")
                {
-                       pImpl->LoadUrl(redirectUrl);
                        ewk_policy_decision_ignore(pPolicy);
 
+                       pImpl->LoadUrl(redirectUrl);
+
                        return;
                }
 
@@ -1164,6 +1163,13 @@ OnWebDataReceived(void* pUserData, Evas_Object* pView, void* pEventInfo)
 
                        r = _AppControlImpl::FindAndStart(operationId, &url, &mime, null, null, null);
                        SysTryReturnVoidResult(NID_WEB_CTRL, r == E_SUCCESS || r == E_OBJ_NOT_FOUND, r, "[%s] Propagating.", GetErrorMessage(r));
+                       if (r == E_OBJ_NOT_FOUND)
+                       {
+                               String operationId(L"http://tizen.org/appcontrol/operation/download");
+
+                               r = _AppControlImpl::FindAndStart(operationId, &url, null, null, null, null);
+                               SysTryReturnVoidResult(NID_WEB_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
+                       }
 
                        return;
                }
@@ -1310,6 +1316,13 @@ OnLoadingCompleted(void* pUserData, Evas_Object* pView, void* pEventInfo)
 
 
 void
+OnLoadingCommitted(void* pUserData, Evas_Object* pView, void* pEventInfo)
+{
+       evas_object_focus_set(pView, EINA_FALSE);
+}
+
+
+void
 OnFaviconReceived(void* pUserData, Evas_Object* pView, void* pEventInfo)
 {
        _WebImpl* pImpl = reinterpret_cast< _WebImpl* >(pUserData);
@@ -1549,7 +1562,6 @@ FireWebPageBlockSelectedEventF(_WebImpl* pImpl)
        SysTryReturnResult(NID_WEB_CTRL, startPoint.get() && endPoint.get(), E_OUT_OF_MEMORY, "Memory Allocation failed.");
 
        pImpl->GetBlockRange(*startPoint.get(), *endPoint.get());
-
        if ((endPoint->x != 0.0f) && (endPoint->y != 0.0f))
        {
                std::unique_ptr<_WebUiEventArg> pEventArg(new (std::nothrow) _WebUiEventArg(WEB_EVENT_WEBUIEVENTLISTENER_PAGE_BLOCK_SELECTED_FLOAT));
@@ -1625,11 +1637,6 @@ OnWebKeypadStateChanged(void* pUserData, Evas_Object* pView, void* pEventInfo)
        Eina_Rectangle* pEinaRect = reinterpret_cast< Eina_Rectangle* >(pEventInfo);
        SysAssertf(pImpl && pEinaRect, "Failed to request");
 
-       if (pImpl->IsVisible() == false)
-       {
-               evas_object_focus_set(pView, EINA_FALSE);
-       }
-
        if (pImpl->GetSetting().GetInputStyle() == INPUT_STYLE_OVERLAY)
        {
                _ICoordinateSystemTransformer* pXformer = _CoordinateSystem::GetInstance()->GetInverseTransformer();
@@ -1646,12 +1653,6 @@ OnWebKeypadStateChanged(void* pUserData, Evas_Object* pView, void* pEventInfo)
                if (pFormImpl)
                {
                        pFormImpl->DeflateClientRectHeight(pXformer->TransformVertical(rect.height));
-
-                       if (pFormImpl->HasFooter())
-                       {
-                               pFormImpl->GetCore().SetKeypadShowState(true);
-                               pFormImpl->Draw();
-                       }                       
                }
 
                if (pImpl->GetWebKeypadEventListener())
@@ -1668,7 +1669,6 @@ OnWebKeypadStateChanged(void* pUserData, Evas_Object* pView, void* pEventInfo)
                                pImpl->GetWebKeypadEventListener()->OnWebKeypadWillOpen(*dynamic_cast< Web* >(&pImpl->GetPublic()));
                        }
                }
-               pImpl->SetKeypadVisibleState(true);
                pImpl->SetPreviousKeypadBounds(rect);
        }
        else
@@ -1685,6 +1685,23 @@ OnWebKeypadOpened(void* pUserData, Evas_Object* pView, void* pEventInfo)
        _WebImpl* pImpl = reinterpret_cast< _WebImpl* >(pUserData);
        SysAssertf(pImpl, "Failed to request");
 
+       pImpl->SetKeypadVisibleState(true);
+
+       _FormImpl* pFormImpl = pImpl->GetParentFormImpl(dynamic_cast< _ControlImpl* >(pImpl));
+       if (pFormImpl)
+       {
+               _ICoordinateSystemTransformer* pXformer = _CoordinateSystem::GetInstance()->GetInverseTransformer();
+               SysAssertf(pXformer, "Failed to get CoordinateTransformer");
+
+               pFormImpl->DeflateClientRectHeight(pXformer->TransformVertical(pImpl->GetPreviousKeypadBounds().height));
+
+               if (pFormImpl->HasFooter())
+               {
+                       pFormImpl->GetCore().SetKeypadShowState(true);
+                       pFormImpl->Draw();
+               }
+       }
+
        if (pImpl->GetWebKeypadEventListener())
        {
                pImpl->GetWebKeypadEventListener()->OnWebKeypadOpened(*static_cast< Web* >(&pImpl->GetPublic()));
@@ -1720,20 +1737,46 @@ OnWebKeypadClosed(void* pUserData, Evas_Object* pView, void* pEventInfo)
 
 
 void
+OnWindowObjectFocusLost(void* pUserData, Evas_Object* pWin, void* pEvent_info)
+{
+       _WebImpl* pImpl = reinterpret_cast< _WebImpl* >(pUserData);
+       SysAssertf(pImpl, "Failed to request");
+
+       pImpl->SetWinFocusLost(true);
+}
+
+
+void
 OnWindowObjectFocusGained(void* pUserData, Evas_Object* pWin, void* pEvent_info)
 {
        _WebImpl* pImpl = reinterpret_cast< _WebImpl* >(pUserData);
        SysAssertf(pImpl, "Failed to request");
 
-       if (pImpl->IsKeypadOpened() == true && pImpl->IsVisible() == true && pImpl->IsFocused() == true)
+       if (pImpl->IsVisible() == true && pImpl->IsFocused() == true)
        {
                _Web* pWebCore = dynamic_cast< _Web* >(&(pImpl->GetCore()));
                SysAssertf(pWebCore, "Failed to get Web core object");
 
-               evas_object_focus_set(pWebCore->GetWebNativeNode(), EINA_TRUE);
+               if (pImpl->IsWinFocusLost() == true)
+               {
+                       if (pImpl->IsKeypadOpened() == true)
+                       {
+                               evas_object_focus_set(pWebCore->GetWebNativeNode(), EINA_TRUE);
+                       }
 
-               pImpl->SetKeypadVisibleState(true);
+                       Ewk_Settings* pSettings = ewk_view_settings_get(pWebCore->GetWebNativeNode());
+                       SysAssertf(pSettings, "Failed to get settings instance.");
+
+                       if (ewk_settings_clear_text_selection_automatically_get(pSettings) == EINA_FALSE)
+                       {
+                               ewk_settings_clear_text_selection_automatically_set(pSettings, EINA_TRUE);
+
+                               evas_object_focus_set(pWebCore->GetWebNativeNode(), EINA_TRUE);
+                       }
+               }
        }
+
+       pImpl->SetWinFocusLost(false);
 }
 
 
@@ -1747,6 +1790,25 @@ OnWebNativeNodeFocusGained(void* pUserData, Evas* pCanvas, Evas_Object* pView, v
        {
                pImpl->SetKeypadOpened(false);
        }
+}
+
+
+void
+OnWebNativeNodeFocusLost(void* pUserData, Evas* pCanvas, Evas_Object* pView, void* pEventInfo)
+{
+       _WebImpl* pImpl = reinterpret_cast< _WebImpl* >(pUserData);
+       SysAssertf(pImpl, "Failed to request");
+
+       if (pImpl->IsWinFocusLost() == true)
+       {
+               _Web* pWebCore = dynamic_cast< _Web* >(&(pImpl->GetCore()));
+               SysAssertf(pWebCore, "Failed to get Web core object");
+
+               Ewk_Settings* pSettings = ewk_view_settings_get(pWebCore->GetWebNativeNode());
+               SysAssertf(pSettings, "Failed to get settings instance.");
+
+               ewk_settings_clear_text_selection_automatically_set(pSettings, EINA_FALSE);
+       }
 } 
 
 
@@ -2096,6 +2158,7 @@ _WebImpl::_WebImpl(Web* pWeb, Tizen::Ui::_Control* pCore)
        , __isFooterVisible(false)
        , __isKeypadVisible(false)
        , __isKeypadOpened(false)
+       , __isWinFocusLost(false)
        , __isLoadingErrorOccurred(false)
        , __isRedirectRequested(false)
        , __isCertificateRequested(false)
@@ -2769,10 +2832,6 @@ _WebImpl::SynchronizeSearch(_SearchType type, Evas_Object* pView, Ewk_Find_Optio
        std::unique_ptr<char[]> pText(_StringConverter::CopyToCharArrayN(text));
        SysTryReturn(NID_WEB_CTRL, pText.get(), GetLastResult(), GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
 
-       Ewk_Settings* pSettings = ewk_view_settings_get(__pWebCore->GetWebNativeNode());
-       SysAssertf(pSettings, "Failed to get webkit instance.");
-       ewk_settings_clear_text_selection_automatically_set(pSettings, true);
-
        switch (type)
        {
        case SEARCH_SYNC:
@@ -3508,10 +3567,12 @@ _WebImpl::SetEventListenerCallback(void) const
                evas_object_smart_callback_add(pWebNativeNode, "load,stop", OnLoadingCanceled, this);
                evas_object_smart_callback_add(pWebNativeNode, "load,error", OnLoadingErrorOccurred, this);
                evas_object_smart_callback_add(pWebNativeNode, "title,changed", OnPageTitleReceived, this);
+               evas_object_smart_callback_add(pWebNativeNode, "load,committed", OnLoadingCommitted, this);
 
                evas_object_smart_callback_add(pWebNativeNode, "requestToNative,json", OnHandleJavaScriptRequest, this);
 
                evas_object_smart_callback_add(pWinObject, "focus,in", OnWindowObjectFocusGained, this);
+               evas_object_smart_callback_add(pWinObject, "focus,out", OnWindowObjectFocusLost, this);
 
                evas_object_smart_callback_add(pWebNativeNode, "inputmethod,changed", OnWebKeypadStateChanged, this);
                evas_object_smart_callback_add(pWebNativeNode, "editorclient,ime,opened", OnWebKeypadOpened, this);
@@ -3548,7 +3609,7 @@ _WebImpl::SetEventListenerCallback(void) const
                evas_object_smart_callback_add(pWebNativeNode, "touchmove,handled", OnWebPreventDefaultTriggered, this);
                evas_object_smart_callback_add(pWebNativeNode, "icon,received", OnFaviconReceived, this);
 
-               evas_object_smart_callback_add(pWebNativeNode, "text,selected", OnWebPageBlockSelected, this);
+               evas_object_smart_callback_add(pWebNativeNode, "magnifier,hide", OnWebPageBlockSelected, this);
 
                evas_object_smart_callback_add(pWebNativeNode, "fullscreen,enterfullscreen", OnFullScreenEntered, this);
                evas_object_smart_callback_add(pWebNativeNode, "fullscreen,exitfullscreen", OnFullScreenExited, this);
@@ -3567,6 +3628,7 @@ _WebImpl::SetEventListenerCallback(void) const
                ewk_view_exceeded_local_file_system_quota_callback_set(pWebNativeNode, OnLocalFileSystemQuotaExceeded, const_cast< _WebImpl* >(this));
 
                evas_object_event_callback_add(pWebNativeNode, EVAS_CALLBACK_FOCUS_IN, OnWebNativeNodeFocusGained, this);
+               evas_object_event_callback_add(pWebNativeNode, EVAS_CALLBACK_FOCUS_OUT, OnWebNativeNodeFocusLost, this);
        }
 }
 
@@ -3594,10 +3656,12 @@ _WebImpl::RemoveEventListenerCallback(void) const
                evas_object_smart_callback_del(pWebNativeNode, "load,stop", OnLoadingCanceled);
                evas_object_smart_callback_del(pWebNativeNode, "load,error", OnLoadingErrorOccurred);
                evas_object_smart_callback_del(pWebNativeNode, "title,changed", OnPageTitleReceived);
+               evas_object_smart_callback_del(pWebNativeNode, "load,committed", OnLoadingCommitted);
 
                evas_object_smart_callback_del(pWebNativeNode, "requestToNative,json", OnHandleJavaScriptRequest);
 
                evas_object_smart_callback_del_full(pWinObject, "focus,in", OnWindowObjectFocusGained, this);
+               evas_object_smart_callback_del_full(pWinObject, "focus,out", OnWindowObjectFocusLost, this);
 
                evas_object_smart_callback_del(pWebNativeNode, "inputmethod,changed", OnWebKeypadStateChanged);
                evas_object_smart_callback_del(pWebNativeNode, "editorclient,ime,opened", OnWebKeypadOpened);
@@ -3634,7 +3698,7 @@ _WebImpl::RemoveEventListenerCallback(void) const
                evas_object_smart_callback_del(pWebNativeNode, "touchmove,handled", OnWebPreventDefaultTriggered);
                evas_object_smart_callback_del(pWebNativeNode, "icon,received", OnFaviconReceived);
 
-               evas_object_smart_callback_del(pWebNativeNode, "text,selected", OnWebPageBlockSelected);
+               evas_object_smart_callback_del(pWebNativeNode, "magnifier,hide", OnWebPageBlockSelected);
 
                evas_object_smart_callback_del(pWebNativeNode, "fullscreen,enterfullscreen", OnFullScreenEntered);
                evas_object_smart_callback_del(pWebNativeNode, "fullscreen,exitfullscreen", OnFullScreenExited);
@@ -3652,6 +3716,7 @@ _WebImpl::RemoveEventListenerCallback(void) const
                ewk_view_exceeded_local_file_system_quota_callback_set(pWebNativeNode, null, null);
 
                evas_object_event_callback_del(pWebNativeNode, EVAS_CALLBACK_FOCUS_IN, OnWebNativeNodeFocusGained);
+               evas_object_event_callback_del(pWebNativeNode, EVAS_CALLBACK_FOCUS_OUT, OnWebNativeNodeFocusLost);
        }
 }
 
@@ -3692,46 +3757,39 @@ _WebImpl::SetBlockSelectionPosition(const Point& startPoint)
 result
 _WebImpl::SetBlockSelectionPosition(const FloatPoint& startPoint)
 {
-       Evas_Object* pView = __pWebCore->GetWebNativeNode();
-       Ewk_View_Smart_Data* pSmartData = (Ewk_View_Smart_Data*) evas_object_smart_data_get(pView);
-       if (pSmartData && pSmartData->api)
+       Evas_Object* pWebview = __pWebCore->GetWebNativeNode();
+       if (!pWebview)
        {
-               Point absPoint( _CoordinateSystemUtils::ConvertToInteger(__pWebCore->GetAbsoluteCoordinate(startPoint)));
+               return E_SUCCESS;
+       }
 
-               Ewk_Settings* pSettings = ewk_view_settings_get(__pWebCore->GetWebNativeNode());
-               SysAssertf(pSettings, "Failed to get webkit instance.");
-               ewk_settings_clear_text_selection_automatically_set(pSettings, true);
+       SetFocused();
 
-               Eina_Bool ret = pSmartData->api->text_selection_down(pSmartData, absPoint.x, absPoint.y);
-               if (ret)
-               {
-                       pSmartData->api->text_selection_up(pSmartData, absPoint.x, absPoint.y);
+       Ewk_View_Smart_Data* pSmartData = reinterpret_cast< Ewk_View_Smart_Data* >(evas_object_smart_data_get(pWebview));
+       SysAssertf(pSmartData && pSmartData->api, "Failed to get webkit instance.");
+       Point absPoint(_CoordinateSystemUtils::ConvertToInteger(__pWebCore->GetAbsoluteCoordinate(startPoint)));
 
-                       Ewk_Hit_Test* pEwkHitTest = ewk_view_hit_test_new(pView, absPoint.x, absPoint.y, EWK_HIT_TEST_MODE_ALL);
-                       SysTryReturnResult(NID_WEB_CTRL, pEwkHitTest, E_SYSTEM, "Failed to get hit test.");
+       Eina_Bool ret = pSmartData->api->text_selection_down(pSmartData, absPoint.x, absPoint.y);
+       if (ret)
+       {
+               pSmartData->api->text_selection_up(pSmartData, absPoint.x, absPoint.y);
 
-                       String tagName(ewk_hit_test_tag_name_get(pEwkHitTest));
+               Ewk_Hit_Test* pEwkHitTest = ewk_view_hit_test_new(pWebview, absPoint.x, absPoint.y, EWK_HIT_TEST_MODE_ALL);
+               SysTryReturnResult(NID_WEB_CTRL, pEwkHitTest, E_SYSTEM, "Failed to get hit test.");
 
-                       if (tagName.Equals(L"INPUT", false) || tagName.Equals(L"TEXTAREA", false))
-                       {
-                               ewk_view_command_execute(pView, "SelectWord", 0);
-                       }
-                       else
-                       {
-                               Eina_Hash* pAttrHash = ewk_hit_test_attribute_hash_get(pEwkHitTest);
-                               char* pValue = reinterpret_cast< char* >(eina_hash_find(pAttrHash, "contenteditable"));
-                               if(pValue)
-                               {
-                                       ewk_view_command_execute(pView, "SelectWord", 0);
-                               }
-                       }
+               String tagName(ewk_hit_test_tag_name_get(pEwkHitTest));
+
+               Eina_Hash* pAttrHash = ewk_hit_test_attribute_hash_get(pEwkHitTest);
+               char* pValue = reinterpret_cast< char* >(eina_hash_find(pAttrHash, "contenteditable"));
+               if (tagName.Equals(L"INPUT", false) || tagName.Equals(L"TEXTAREA", false) || pValue)
+               {
+                       ewk_view_command_execute(pWebview, "SelectWord", 0);
+                       evas_object_smart_callback_call(pWebview, "magnifier,hide", NULL);
                }
        }
 
        SysTryReturnResult(NID_WEB_CTRL, GetTextFromBlock().GetLength() > 0, E_INVALID_ARG, "Failed to set text selection up.");
 
-       evas_object_smart_callback_call(pView, "text,selected", NULL);
-
        return E_SUCCESS;
 }
 
@@ -4035,6 +4093,20 @@ _WebImpl::SetKeypadOpened(bool isKeypadOpened)
 }
 
 
+bool
+_WebImpl::IsWinFocusLost(void) const
+{
+       return __isWinFocusLost;
+}
+
+
+void
+_WebImpl::SetWinFocusLost(bool isWinFocusLost)
+{
+       __isWinFocusLost = isWinFocusLost;
+}
+
+
 Rectangle
 _WebImpl::GetPreviousKeypadBounds(void) const
 {
@@ -4751,10 +4823,6 @@ _WebImpl::GetParentFormImpl(_ControlImpl* pControlImpl)
 bool 
 _WebImpl::OnFocusGained(const _ControlImpl& source)
 {
-       Ewk_Settings* pSettings = ewk_view_settings_get(__pWebCore->GetWebNativeNode());
-       SysAssertf(pSettings, "Failed to get webkit instance.");
-       ewk_settings_clear_text_selection_automatically_set(pSettings, true);
-
        return false;
 }
 
@@ -4762,19 +4830,17 @@ _WebImpl::OnFocusGained(const _ControlImpl& source)
 bool 
 _WebImpl::OnFocusLost(const _ControlImpl& source)
 {
+       Evas_Object* pWebview = __pWebCore->GetWebNativeNode();
+       if (!pWebview)
+       {
+               return false;
+       }
+
        if(IsKeypadVisible() == true)
        {
                SetKeypadOpened(true);
-
-               SetKeypadVisibleState(false);
        }
 
-       Ewk_Settings* pSettings = ewk_view_settings_get(__pWebCore->GetWebNativeNode());
-       SysAssertf(pSettings, "Failed to get webkit instance.");
-       ewk_settings_clear_text_selection_automatically_set(pSettings, false);
-
-       evas_object_focus_set(__pWebCore->GetWebNativeNode(), EINA_FALSE);
-
        return false;
 }