Merge "[Tizen] Add an API for 'create,window' event." into tizen_7.0
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / web-view / web-view-impl.cpp
index e3f2406..d2fe130 100755 (executable)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 #include "web-view-impl.h"
 
 // EXTERNAL INCLUDES
-#include <dali/devel-api/adaptor-framework/web-engine-back-forward-list.h>
-#include <dali/devel-api/adaptor-framework/web-engine-certificate.h>
-#include <dali/devel-api/adaptor-framework/web-engine-console-message.h>
-#include <dali/devel-api/adaptor-framework/web-engine-context-menu-item.h>
-#include <dali/devel-api/adaptor-framework/web-engine-context-menu.h>
-#include <dali/devel-api/adaptor-framework/web-engine-context.h>
-#include <dali/devel-api/adaptor-framework/web-engine-cookie-manager.h>
-#include <dali/devel-api/adaptor-framework/web-engine-form-repost-decision.h>
-#include <dali/devel-api/adaptor-framework/web-engine-hit-test.h>
-#include <dali/devel-api/adaptor-framework/web-engine-http-auth-handler.h>
-#include <dali/devel-api/adaptor-framework/web-engine-load-error.h>
-#include <dali/devel-api/adaptor-framework/web-engine-policy-decision.h>
-#include <dali/devel-api/adaptor-framework/web-engine-settings.h>
+#include <dali/devel-api/adaptor-framework/web-engine/web-engine-back-forward-list.h>
+#include <dali/devel-api/adaptor-framework/web-engine/web-engine-certificate.h>
+#include <dali/devel-api/adaptor-framework/web-engine/web-engine-console-message.h>
+#include <dali/devel-api/adaptor-framework/web-engine/web-engine-context-menu-item.h>
+#include <dali/devel-api/adaptor-framework/web-engine/web-engine-context-menu.h>
+#include <dali/devel-api/adaptor-framework/web-engine/web-engine-context.h>
+#include <dali/devel-api/adaptor-framework/web-engine/web-engine-cookie-manager.h>
+#include <dali/devel-api/adaptor-framework/web-engine/web-engine-form-repost-decision.h>
+#include <dali/devel-api/adaptor-framework/web-engine/web-engine-hit-test.h>
+#include <dali/devel-api/adaptor-framework/web-engine/web-engine-http-auth-handler.h>
+#include <dali/devel-api/adaptor-framework/web-engine/web-engine-load-error.h>
+#include <dali/devel-api/adaptor-framework/web-engine/web-engine-policy-decision.h>
+#include <dali/devel-api/adaptor-framework/web-engine/web-engine-settings.h>
 #include <dali/devel-api/common/stage.h>
 #include <dali/devel-api/scripting/enum-helper.h>
 #include <dali/devel-api/scripting/scripting.h>
 #include <dali/public-api/object/type-registry-helper.h>
 #include <dali/public-api/object/type-registry.h>
 #include <cstring>
-#include <memory>
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/devel-api/controls/control-devel.h>
 #include <dali-toolkit/devel-api/controls/web-view/web-back-forward-list.h>
-#include <dali-toolkit/devel-api/controls/web-view/web-context.h>
-#include <dali-toolkit/devel-api/controls/web-view/web-cookie-manager.h>
 #include <dali-toolkit/devel-api/controls/web-view/web-settings.h>
 #include <dali-toolkit/internal/visuals/visual-factory-impl.h>
 #include <dali-toolkit/public-api/image-loader/image.h>
 #include <dali-toolkit/public-api/image-loader/image-url.h>
 #include <dali-toolkit/public-api/visuals/image-visual-properties.h>
 
+#include <functional>
+#include <memory>
+
 namespace Dali
 {
 namespace Toolkit
@@ -91,11 +91,7 @@ DALI_TYPE_REGISTRATION_END()
 
 } // namespace
 
-#define GET_ENUM_STRING(structName, inputExp) \
-  Scripting::GetLinearEnumerationName<Toolkit::WebView::structName::Type>(static_cast<Toolkit::WebView::structName::Type>(inputExp), structName##_TABLE, structName##_TABLE_COUNT)
-
-#define GET_ENUM_VALUE(structName, inputExp, outputExp) \
-  Scripting::GetEnumerationProperty<Toolkit::WebView::structName::Type>(inputExp, structName##_TABLE, structName##_TABLE_COUNT, outputExp)
+std::unordered_map<Dali::WebEnginePlugin*, Dali::WeakHandle<Toolkit::WebView>> WebView::mPluginWebViewMap;
 
 WebView::WebView(const std::string& locale, const std::string& timezoneId)
 : Control(ControlBehaviour(ACTOR_BEHAVIOUR_DEFAULT | DISABLE_STYLE_CHANGE_SIGNALS)),
@@ -106,7 +102,8 @@ WebView::WebView(const std::string& locale, const std::string& timezoneId)
   mVideoHoleEnabled(false),
   mMouseEventsEnabled(true),
   mKeyEventsEnabled(true),
-  mScreenshotCapturedCallback(nullptr)
+  mScreenshotCapturedCallback{nullptr},
+  mFrameRenderedCallback{nullptr}
 {
   mWebEngine = Dali::WebEngine::New();
 
@@ -126,7 +123,8 @@ WebView::WebView(uint32_t argc, char** argv)
   mVideoHoleEnabled(false),
   mMouseEventsEnabled(true),
   mKeyEventsEnabled(true),
-  mScreenshotCapturedCallback(nullptr)
+  mScreenshotCapturedCallback{nullptr},
+  mFrameRenderedCallback{nullptr}
 {
   mWebEngine = Dali::WebEngine::New();
 
@@ -146,7 +144,11 @@ WebView::~WebView()
 {
   if(mWebEngine)
   {
-    mWebEngine.FrameRenderedSignal().Disconnect(this, &WebView::OnFrameRendered);
+    auto iter = mPluginWebViewMap.find(mWebEngine.GetPlugin());
+    if (iter != mPluginWebViewMap.end())
+    {
+      mPluginWebViewMap.erase(iter);
+    }
     mWebEngine.Destroy();
   }
 }
@@ -155,7 +157,10 @@ Toolkit::WebView WebView::New()
 {
   WebView*         impl   = new WebView();
   Toolkit::WebView handle = Toolkit::WebView(*impl);
-
+  if (impl->GetPlugin())
+  {
+    mPluginWebViewMap[impl->GetPlugin()] = handle;
+  }
   impl->Initialize();
   return handle;
 }
@@ -164,7 +169,10 @@ Toolkit::WebView WebView::New(const std::string& locale, const std::string& time
 {
   WebView*         impl   = new WebView(locale, timezoneId);
   Toolkit::WebView handle = Toolkit::WebView(*impl);
-
+  if (impl->GetPlugin())
+  {
+    mPluginWebViewMap[impl->GetPlugin()] = handle;
+  }
   impl->Initialize();
   return handle;
 }
@@ -173,11 +181,34 @@ Toolkit::WebView WebView::New(uint32_t argc, char** argv)
 {
   WebView*         impl   = new WebView(argc, argv);
   Toolkit::WebView handle = Toolkit::WebView(*impl);
-
+  if (impl->GetPlugin())
+  {
+    mPluginWebViewMap[impl->GetPlugin()] = handle;
+  }
   impl->Initialize();
   return handle;
 }
 
+Toolkit::WebView WebView::FindWebView(Dali::WebEnginePlugin* plugin)
+{
+  auto iter = mPluginWebViewMap.find(plugin);
+  if (iter != mPluginWebViewMap.end())
+  {
+    return iter->second.GetHandle();
+  }
+  return Toolkit::WebView();
+}
+
+Dali::WebEngineContext* WebView::GetContext()
+{
+  return Dali::WebEngine::GetContext();
+}
+
+Dali::WebEngineCookieManager* WebView::GetCookieManager()
+{
+  return Dali::WebEngine::GetCookieManager();
+}
+
 void WebView::OnInitialize()
 {
   Actor self = Self();
@@ -192,15 +223,13 @@ void WebView::OnInitialize()
   mPositionUpdateNotification = self.AddPropertyNotification(Actor::Property::WORLD_POSITION, StepCondition(1.0f, 1.0f));
   mSizeUpdateNotification     = self.AddPropertyNotification(Actor::Property::SIZE, StepCondition(1.0f, 1.0f));
   mScaleUpdateNotification    = self.AddPropertyNotification(Actor::Property::WORLD_SCALE, StepCondition(0.1f, 1.0f));
-  mPositionUpdateNotification.NotifySignal().Connect(this, &WebView::UpdateDisplayArea);
-  mSizeUpdateNotification.NotifySignal().Connect(this, &WebView::UpdateDisplayArea);
-  mScaleUpdateNotification.NotifySignal().Connect(this, &WebView::UpdateDisplayArea);
+  mPositionUpdateNotification.NotifySignal().Connect(this, &WebView::OnDisplayAreaUpdated);
+  mSizeUpdateNotification.NotifySignal().Connect(this, &WebView::OnDisplayAreaUpdated);
+  mScaleUpdateNotification.NotifySignal().Connect(this, &WebView::OnDisplayAreaUpdated);
 
   if(mWebEngine)
   {
-    mWebEngine.FrameRenderedSignal().Connect(this, &WebView::OnFrameRendered);
-    mWebContext         = std::unique_ptr<Dali::Toolkit::WebContext>(new WebContext(mWebEngine.GetContext()));
-    mWebCookieManager   = std::unique_ptr<Dali::Toolkit::WebCookieManager>(new WebCookieManager(mWebEngine.GetCookieManager()));
+    mWebEngine.RegisterFrameRenderedCallback(std::bind(&WebView::OnFrameRendered, this));
     mWebSettings        = std::unique_ptr<Dali::Toolkit::WebSettings>(new WebSettings(mWebEngine.GetSettings()));
     mWebBackForwardList = std::unique_ptr<Dali::Toolkit::WebBackForwardList>(new WebBackForwardList(mWebEngine.GetBackForwardList()));
   }
@@ -218,19 +247,14 @@ Dali::Toolkit::WebSettings* WebView::GetSettings() const
   return mWebSettings.get();
 }
 
-Dali::Toolkit::WebContext* WebView::GetContext() const
-{
-  return mWebContext.get();
-}
-
-Dali::Toolkit::WebCookieManager* WebView::GetCookieManager() const
+Dali::Toolkit::WebBackForwardList* WebView::GetBackForwardList() const
 {
-  return mWebCookieManager.get();
+  return mWebBackForwardList.get();
 }
 
-Dali::Toolkit::WebBackForwardList* WebView::GetBackForwardList() const
+Dali::WebEnginePlugin* WebView::GetPlugin() const
 {
-  return mWebBackForwardList.get();
+  return mWebEngine ? mWebEngine.GetPlugin() : nullptr;
 }
 
 Dali::Toolkit::ImageView WebView::GetFavicon() const
@@ -248,11 +272,6 @@ void WebView::LoadUrl(const std::string& url)
 {
   if(mWebEngine)
   {
-    if(!mVisual)
-    {
-      mWebEngine.FrameRenderedSignal().Connect(this, &WebView::OnInitialFrameRendered);
-    }
-
     mWebEngine.LoadUrl(url);
   }
 }
@@ -261,11 +280,6 @@ void WebView::LoadHtmlString(const std::string& htmlString)
 {
   if(mWebEngine)
   {
-    if(!mVisual)
-    {
-      mWebEngine.FrameRenderedSignal().Connect(this, &WebView::OnInitialFrameRendered);
-    }
-
     mWebEngine.LoadHtmlString(htmlString);
   }
 }
@@ -275,11 +289,6 @@ bool WebView::LoadHtmlStringOverrideCurrentEntry(const std::string& html, const
   if(!mWebEngine)
     return false;
 
-  if(!mVisual)
-  {
-    mWebEngine.FrameRenderedSignal().Connect(this, &WebView::OnInitialFrameRendered);
-  }
-
   return mWebEngine.LoadHtmlStringOverrideCurrentEntry(html, basicUri, unreachableUrl);
 }
 
@@ -288,11 +297,6 @@ bool WebView::LoadContents(const std::string& contents, uint32_t contentSize, co
   if(!mWebEngine)
     return false;
 
-  if(!mVisual)
-  {
-    mWebEngine.FrameRenderedSignal().Connect(this, &WebView::OnInitialFrameRendered);
-  }
-
   return mWebEngine.LoadContents(contents, contentSize, mimeType, encoding, baseUri);
 }
 
@@ -581,37 +585,6 @@ void WebView::SetTtsFocus(bool focused)
   }
 }
 
-void WebView::UpdateDisplayArea(Dali::PropertyNotification& /*source*/)
-{
-  if(!mWebEngine)
-    return;
-
-  Actor self(Self());
-
-  bool    positionUsesAnchorPoint = self.GetProperty<bool>(Actor::Property::POSITION_USES_ANCHOR_POINT);
-  Vector3 actorSize               = self.GetCurrentProperty<Vector3>(Actor::Property::SIZE) * self.GetCurrentProperty<Vector3>(Actor::Property::SCALE);
-  Vector3 anchorPointOffSet       = actorSize * (positionUsesAnchorPoint ? self.GetCurrentProperty<Vector3>(Actor::Property::ANCHOR_POINT) : AnchorPoint::TOP_LEFT);
-  Vector2 screenPosition          = self.GetProperty<Vector2>(Actor::Property::SCREEN_POSITION);
-
-  Dali::Rect<int32_t> displayArea;
-  displayArea.x      = screenPosition.x - anchorPointOffSet.x;
-  displayArea.y      = screenPosition.y - anchorPointOffSet.y;
-  displayArea.width  = actorSize.x;
-  displayArea.height = actorSize.y;
-
-  Size displaySize = Size(displayArea.width, displayArea.height);
-  if(mWebViewSize != displaySize)
-  {
-    mWebViewSize = displaySize;
-  }
-
-  if(mWebViewArea != displayArea)
-  {
-    mWebViewArea = displayArea;
-    mWebEngine.UpdateDisplayArea(mWebViewArea);
-  }
-}
-
 void WebView::EnableVideoHole(bool enabled)
 {
   mVideoHoleEnabled = enabled;
@@ -732,6 +705,14 @@ void WebView::RegisterNavigationPolicyDecidedCallback(Dali::WebEnginePlugin::Web
   }
 }
 
+void WebView::RegisterNewWindowCreatedCallback(Dali::WebEnginePlugin::WebEngineNewWindowCreatedCallback callback)
+{
+  if(mWebEngine)
+  {
+    mWebEngine.RegisterNewWindowCreatedCallback(callback);
+  }
+}
+
 void WebView::RegisterCertificateConfirmedCallback(Dali::WebEnginePlugin::WebEngineCertificateCallback callback)
 {
   if(mWebEngine)
@@ -786,15 +767,13 @@ void WebView::OnFrameRendered()
   {
     mFrameRenderedCallback();
   }
-}
 
-void WebView::OnInitialFrameRendered()
-{
-  mWebEngine.FrameRenderedSignal().Disconnect(this, &WebView::OnInitialFrameRendered);
+  // Make sure that mVisual is created only once.
+  if (mVisual)
+    return;
 
   Dali::Toolkit::ImageUrl nativeImageUrl = Dali::Toolkit::Image::GenerateUrl(mWebEngine.GetNativeImageSource());
   mVisual                                = Toolkit::VisualFactory::Get().CreateVisual({{Toolkit::Visual::Property::TYPE, Toolkit::Visual::IMAGE}, {Toolkit::ImageVisual::Property::URL, nativeImageUrl.GetUrl()}});
-
   if(mVisual)
   {
     DevelControl::RegisterVisual(*this, Toolkit::WebView::Property::URL, mVisual);
@@ -802,6 +781,37 @@ void WebView::OnInitialFrameRendered()
   }
 }
 
+void WebView::OnDisplayAreaUpdated(Dali::PropertyNotification& /*source*/)
+{
+  if(!mWebEngine)
+    return;
+
+  Actor self(Self());
+
+  bool    positionUsesAnchorPoint = self.GetProperty<bool>(Actor::Property::POSITION_USES_ANCHOR_POINT);
+  Vector3 actorSize               = self.GetCurrentProperty<Vector3>(Actor::Property::SIZE) * self.GetCurrentProperty<Vector3>(Actor::Property::SCALE);
+  Vector3 anchorPointOffSet       = actorSize * (positionUsesAnchorPoint ? self.GetCurrentProperty<Vector3>(Actor::Property::ANCHOR_POINT) : AnchorPoint::TOP_LEFT);
+  Vector2 screenPosition          = self.GetProperty<Vector2>(Actor::Property::SCREEN_POSITION);
+
+  Dali::Rect<int32_t> displayArea;
+  displayArea.x      = screenPosition.x - anchorPointOffSet.x;
+  displayArea.y      = screenPosition.y - anchorPointOffSet.y;
+  displayArea.width  = actorSize.x;
+  displayArea.height = actorSize.y;
+
+  Size displaySize = Size(displayArea.width, displayArea.height);
+  if(mWebViewSize != displaySize)
+  {
+    mWebViewSize = displaySize;
+  }
+
+  if(mWebViewArea != displayArea)
+  {
+    mWebViewArea = displayArea;
+    mWebEngine.UpdateDisplayArea(mWebViewArea);
+  }
+}
+
 void WebView::OnVisibilityChanged(Actor actor, bool isVisible, Dali::DevelActor::VisibilityChange::Type type)
 {
   if(type == Dali::DevelActor::VisibilityChange::Type::SELF)
@@ -1261,10 +1271,25 @@ WebView::WebViewAccessible::WebViewAccessible(Dali::Actor self, Dali::WebEngine&
   }
 }
 
+Dali::Accessibility::Attributes WebView::WebViewAccessible::GetAttributes() const
+{
+  auto attributes = DevelControl::ControlAccessible::GetAttributes();
+
+  if(mRemoteChild.GetAddress())
+  {
+    attributes.insert_or_assign("child_bus", mRemoteChild.GetAddress().GetBus());
+  }
+
+  return attributes;
+}
+
 void WebView::WebViewAccessible::DoGetChildren(std::vector<Dali::Accessibility::Accessible*>& children)
 {
   if(mRemoteChild.GetAddress())
   {
+    // DoGetChildren is called at most once per every OnChildrenChanged.
+    // We have only one OnChildrenChanged in this case, so EmbedAtkSocket will be called only once.
+    Accessibility::Bridge::GetCurrentBridge()->EmbedAtkSocket(GetAddress(), mRemoteChild.GetAddress());
     children.push_back(&mRemoteChild);
   }
 }
@@ -1293,13 +1318,10 @@ void WebView::WebViewAccessible::OnAccessibilityDisabled()
 
 void WebView::WebViewAccessible::SetRemoteChildAddress(Dali::Accessibility::Address address)
 {
-  mRemoteChild.SetAddress(std::move(address));
+  mRemoteChild.SetAddress(address);
   OnChildrenChanged();
 }
 
-#undef GET_ENUM_STRING
-#undef GET_ENUM_VALUE
-
 } // namespace Internal
 
 } // namespace Toolkit