Support mouse & wheel events in web view.
[platform/core/uifw/dali-toolkit.git] / automated-tests / src / dali-toolkit / dali-toolkit-test-utils / toolkit-web-engine.cpp
index 48676ea..0043f2c 100755 (executable)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2021 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 <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-settings.h>
+#include <dali/public-api/adaptor-framework/native-image-source.h>
 #include <dali/public-api/images/pixel-data.h>
 #include <dali/public-api/object/any.h>
 #include <dali/public-api/object/base-object.h>
-#include <dali/public-api/adaptor-framework/native-image-source.h>
 #include <toolkit-application.h>
 
 namespace Dali
@@ -42,27 +42,34 @@ class WebEngine;
 
 namespace
 {
-static WebEngine* gInstance = NULL;
+
+// Generally only one WebEngine instance exists.
+// If > 1, a new web engine has been created by CreateWindowSignal.
+static WebEngine* gInstance = 0;
 static int gInstanceCount = 0;
 
 bool OnGoBack();
 bool OnGoForward();
 bool OnLoadUrl();
 bool OnEvaluteJavaScript();
+bool OnJavaScriptAlert();
+bool OnJavaScriptConfirm();
+bool OnJavaScriptPrompt();
+bool OnScrollEdge();
 bool OnClearHistory();
 
-static void ConnectToGlobalSignal( bool (*func)() )
+static void ConnectToGlobalSignal( bool ( *func )() )
 {
   Dali::Timer timer = Dali::Timer::New( 0 );
   timer.TickSignal().Connect( func );
 }
 
-static void DisconnectFromGlobalSignal( bool (*func)() )
+static void DisconnectFromGlobalSignal( bool ( *func )() )
 {
   Dali::Timer timer = Dali::Timer::New( 0 );
   timer.TickSignal().Disconnect( func );
 }
-}
+} // namespace anonymous
 
 class MockWebEngineContext : public Dali::WebEngineContext
 {
@@ -214,6 +221,18 @@ public:
   MockWebEngineSettings()
     : mockDefaultFontSize( 16 ),
       mockJavaScriptEnabled( true ),
+      mockAutoFittingEnabled ( true ),
+      mockPluginsEnabled ( true ),
+      mockPrivateBrowsingEnabled( true ),
+      mockLinkMagnifierEnabled( true ),
+      mockKeypadWithoutUserActionUsed( true ),
+      mockAutofillPasswordFormEnabled( true ),
+      mockFormCandidateDataEnabled( true ),
+      mockTextSelectionEnabled( true ),
+      mockTextAutosizingEnable( true ),
+      mockArrowScrollEnable( true ),
+      mockClipboardEnabled( true ),
+      mockImePanelEnabled( true ),
       mockImageLoadedAutomatically( true ),
       mockDefaultTextEncodingName()
   {
@@ -239,6 +258,126 @@ public:
     mockJavaScriptEnabled = enabled;
   }
 
+  bool IsAutoFittingEnabled() const override
+  {
+    return mockAutoFittingEnabled;
+  }
+
+  void EnableAutoFitting( bool enabled ) override
+  {
+    mockAutoFittingEnabled = enabled;
+  }
+
+  bool ArePluginsEnabled() const override
+  {
+    return mockPluginsEnabled;
+  }
+
+  void EnablePlugins( bool enabled ) override
+  {
+    mockPluginsEnabled = enabled;
+  }
+
+  bool IsPrivateBrowsingEnabled() const override
+  {
+    return mockPrivateBrowsingEnabled;
+  }
+
+  void EnablePrivateBrowsing( bool enabled ) override
+  {
+    mockPrivateBrowsingEnabled = enabled;
+  }
+
+  bool IsLinkMagnifierEnabled() const override
+  {
+    return mockLinkMagnifierEnabled;
+  }
+
+  void EnableLinkMagnifier( bool enabled ) override
+  {
+    mockLinkMagnifierEnabled = enabled;
+  }
+
+  bool IsKeypadWithoutUserActionUsed() const override
+  {
+    return mockKeypadWithoutUserActionUsed;
+  }
+
+  void UseKeypadWithoutUserAction( bool used ) override
+  {
+    mockKeypadWithoutUserActionUsed = used;
+  }
+
+  bool IsAutofillPasswordFormEnabled() const override
+  {
+    return mockAutofillPasswordFormEnabled;
+  }
+
+  void EnableAutofillPasswordForm( bool enabled ) override
+  {
+    mockAutofillPasswordFormEnabled = enabled;
+  }
+
+  bool IsFormCandidateDataEnabled() const override
+  {
+    return mockFormCandidateDataEnabled;
+  }
+
+  void EnableFormCandidateData( bool enabled ) override
+  {
+    mockFormCandidateDataEnabled = enabled;
+  }
+
+  bool IsTextSelectionEnabled() const override
+  {
+    return mockTextSelectionEnabled;
+  }
+
+  void EnableTextSelection( bool enabled ) override
+  {
+    mockTextSelectionEnabled = enabled;
+  }
+
+  bool IsTextAutosizingEnabled() const override
+  {
+    return mockTextAutosizingEnable;
+  }
+
+  void EnableTextAutosizing( bool enabled ) override
+  {
+    mockTextAutosizingEnable = enabled;
+  }
+
+  bool IsArrowScrollEnabled() const override
+  {
+    return mockArrowScrollEnable;
+  }
+
+  void EnableArrowScroll( bool enabled ) override
+  {
+    mockArrowScrollEnable = enabled;
+  }
+
+  bool IsClipboardEnabled() const override
+  {
+    return mockClipboardEnabled;
+  }
+
+  void EnableClipboard( bool enabled ) override
+  {
+    mockClipboardEnabled = enabled;
+  }
+
+  bool IsImePanelEnabled() const override
+  {
+    return mockImePanelEnabled;
+  }
+
+  void EnableImePanel( bool enabled ) override
+  {
+    mockImePanelEnabled = enabled;
+  }
+
   bool AreImagesLoadedAutomatically() const override
   {
     return mockImageLoadedAutomatically;
@@ -271,6 +410,18 @@ public:
   {
   }
 
+  void EnableCacheBuilder( bool enabled ) override
+  {
+  }
+
+  void UseScrollbarThumbFocusNotifications( bool used ) override
+  {
+  }
+
+  void EnableDoNotTrack( bool enabled ) override
+  {
+  }
+
   void AllowFileAccessFromExternalUrl( bool allowed ) override
   {
   }
@@ -282,6 +433,18 @@ public:
 private:
   int mockDefaultFontSize;
   bool mockJavaScriptEnabled;
+  bool mockAutoFittingEnabled;
+  bool mockPluginsEnabled;
+  bool mockPrivateBrowsingEnabled;
+  bool mockLinkMagnifierEnabled;
+  bool mockKeypadWithoutUserActionUsed;
+  bool mockAutofillPasswordFormEnabled;
+  bool mockFormCandidateDataEnabled;
+  bool mockTextSelectionEnabled;
+  bool mockTextAutosizingEnable;
+  bool mockArrowScrollEnable;
+  bool mockClipboardEnabled;
+  bool mockImePanelEnabled;
   bool mockImageLoadedAutomatically;
   std::string mockDefaultTextEncodingName;
 };
@@ -290,6 +453,11 @@ class WebEngine: public Dali::BaseObject
 {
 public:
 
+  using JavaScriptEvaluatedResultCallback = std::function<void(const std::string&)>;
+  using JavaScriptAlertCallback = std::function<bool(const std::string&)>;
+  using JavaScriptConfirmCallback = std::function<bool(const std::string&)>;
+  using JavaScriptPromptCallback = std::function<bool(const std::string&, const std::string&)>;
+
   WebEngine()
     : mUrl()
     , mCurrentPlusOnePos( 0 )
@@ -300,7 +468,10 @@ public:
     , mContentSize( 500, 500 )
   {
     gInstanceCount++;
-    gInstance = this;
+    if ( gInstanceCount == 1 ) // only first web engine need be saved.
+    {
+      gInstance = this;
+    }
 
     mockWebEngineSettings = new MockWebEngineSettings();
     mockWebEngineContext = new MockWebEngineContext();
@@ -313,7 +484,7 @@ public:
     gInstanceCount--;
     if( !gInstanceCount )
     {
-      gInstance = NULL;
+      gInstance = 0;
     }
 
     delete mockWebEngineSettings;
@@ -416,6 +587,33 @@ public:
     }
   }
 
+  void RegisterJavaScriptAlertCallback( Dali::WebEnginePlugin::JavaScriptAlertCallback callback )
+  {
+    if ( callback )
+    {
+      ConnectToGlobalSignal( &OnJavaScriptAlert );
+      mJavaScriptAlertCallback = callback;
+    }
+  }
+
+  void RegisterJavaScriptConfirmCallback( Dali::WebEnginePlugin::JavaScriptConfirmCallback callback )
+  {
+    if ( callback )
+    {
+      ConnectToGlobalSignal( &OnJavaScriptConfirm );
+      mJavaScriptConfirmCallback = callback;
+    }
+  }
+
+  void RegisterJavaScriptPromptCallback( Dali::WebEnginePlugin::JavaScriptPromptCallback callback )
+  {
+    if ( callback )
+    {
+      ConnectToGlobalSignal( &OnJavaScriptPrompt );
+      mJavaScriptPromptCallback = callback;
+    }
+  }
+
   void ClearHistory()
   {
     ConnectToGlobalSignal( &OnClearHistory );
@@ -436,7 +634,7 @@ public:
     mScrollPosition += Dali::Vector2( dx, dy );
     if ( mScrollPosition.y + mScrollSize.height > mContentSize.height )
     {
-      gInstance->mScrollEdgeReachedSignal.Emit( Dali::WebEnginePlugin::ScrollEdge::BOTTOM );
+      ConnectToGlobalSignal( &OnScrollEdge );
     }
   }
 
@@ -446,22 +644,19 @@ public:
     mScrollPosition.y = y;
   }
 
-  void GetScrollPosition( int& x, int& y ) const
+  Dali::Vector2 GetScrollPosition() const
   {
-    x = mScrollPosition.x;
-    y = mScrollPosition.y;
+    return mScrollPosition;
   }
 
-  void GetScrollSize( int& w, int& h ) const
+  Dali::Vector2 GetScrollSize() const
   {
-    w = mScrollSize.width;
-    h = mScrollSize.height;
+    return mScrollSize;
   }
 
-  void GetContentSize( int& w, int& h ) const
+  Dali::Vector2 GetContentSize() const
   {
-    w = mContentSize.width;
-    h = mContentSize.height;
+    return  mContentSize;
   }
 
   Dali::WebEnginePlugin::WebEnginePageLoadSignalType& PageLoadStartedSignal()
@@ -469,6 +664,11 @@ public:
     return mPageLoadStartedSignal;
   }
 
+  Dali::WebEnginePlugin::WebEnginePageLoadSignalType& PageLoadInProgressSignal()
+  {
+    return mPageLoadInProgressSignal;
+  }
+
   Dali::WebEnginePlugin::WebEnginePageLoadSignalType& PageLoadFinishedSignal()
   {
     return mPageLoadFinishedSignal;
@@ -484,14 +684,20 @@ public:
     return mScrollEdgeReachedSignal;
   }
 
+  Dali::WebEnginePlugin::WebEngineUrlChangedSignalType& UrlChangedSignal()
+  {
+    return mUrlChangedSignal;
+  }
+
   std::string                                                mUrl;
   std::vector< std::string >                                 mHistory;
   size_t                                                     mCurrentPlusOnePos;
   std::string                                                mUserAgent;
   Dali::WebEnginePlugin::WebEnginePageLoadSignalType         mPageLoadStartedSignal;
+  Dali::WebEnginePlugin::WebEnginePageLoadSignalType         mPageLoadInProgressSignal;
   Dali::WebEnginePlugin::WebEnginePageLoadSignalType         mPageLoadFinishedSignal;
   Dali::WebEnginePlugin::WebEnginePageLoadErrorSignalType    mPageLoadErrorSignal;
-  std::vector< std::function< void( const std::string& ) > > mResultCallbacks;
+  std::vector<JavaScriptEvaluatedResultCallback>             mResultCallbacks;
   bool                                                       mEvaluating;
 
   Dali::WebEnginePlugin::WebEngineScrollEdgeReachedSignalType mScrollEdgeReachedSignal;
@@ -502,21 +708,13 @@ public:
   WebEngineContext*                                           mockWebEngineContext;
   WebEngineCookieManager*                                     mockWebEngineCookieManager;
   WebEngineSettings*                                          mockWebEngineSettings;
+  Dali::WebEnginePlugin::WebEngineUrlChangedSignalType        mUrlChangedSignal;
+
+  JavaScriptAlertCallback                                     mJavaScriptAlertCallback;
+  JavaScriptConfirmCallback                                   mJavaScriptConfirmCallback;
+  JavaScriptPromptCallback                                    mJavaScriptPromptCallback;
 };
 
-inline WebEngine& GetImplementation( Dali::WebEngine& webEngine )
-{
-  DALI_ASSERT_ALWAYS( webEngine && "WebEngine handle is empty." );
-  BaseObject& handle = webEngine.GetBaseObject();
-  return static_cast< Internal::Adaptor::WebEngine& >( handle );
-}
-
-inline const WebEngine& GetImplementation( const Dali::WebEngine& webEngine )
-{
-  DALI_ASSERT_ALWAYS( webEngine && "WebEngine handle is empty." );
-  const BaseObject& handle = webEngine.GetBaseObject();
-  return static_cast< const Internal::Adaptor::WebEngine& >( handle );
-}
 
 namespace
 {
@@ -556,11 +754,25 @@ bool OnLoadUrl()
     gInstance->mHistory.push_back( gInstance->mUrl );
     gInstance->mCurrentPlusOnePos++;
     gInstance->mPageLoadStartedSignal.Emit( gInstance->mUrl );
+    gInstance->mPageLoadInProgressSignal.Emit( gInstance->mUrl );
     gInstance->mPageLoadFinishedSignal.Emit( gInstance->mUrl );
+    gInstance->mUrlChangedSignal.Emit( "http://new-test" );
   }
   return false;
 }
 
+bool OnScrollEdge()
+{
+  DisconnectFromGlobalSignal( &OnScrollEdge );
+
+  if( gInstance )
+  {
+    gInstance->mScrollEdgeReachedSignal.Emit( Dali::WebEnginePlugin::ScrollEdge::BOTTOM );
+  }
+
+  return false;
+}
+
 bool OnEvaluteJavaScript()
 {
   DisconnectFromGlobalSignal( &OnEvaluteJavaScript );
@@ -576,11 +788,42 @@ bool OnEvaluteJavaScript()
   return false;
 }
 
+bool OnJavaScriptAlert()
+{
+  DisconnectFromGlobalSignal( &OnJavaScriptAlert );
+  if ( gInstance )
+  {
+    gInstance->mJavaScriptAlertCallback( "this is an alert popup." );
+  }
+  return false;
+}
+
+bool OnJavaScriptConfirm()
+{
+  DisconnectFromGlobalSignal( &OnJavaScriptConfirm );
+  if ( gInstance )
+  {
+    gInstance->mJavaScriptConfirmCallback( "this is a confirm popup." );
+  }
+  return false;
+}
+
+bool OnJavaScriptPrompt()
+{
+  DisconnectFromGlobalSignal( &OnJavaScriptPrompt );
+  if ( gInstance )
+  {
+    gInstance->mJavaScriptPromptCallback( "this is a prompt pompt.", "" );
+  }
+  return false;
+}
+
 bool OnClearHistory()
 {
   DisconnectFromGlobalSignal( &OnClearHistory );
 
-  if( gInstance && gInstance->mCurrentPlusOnePos ) {
+  if( gInstance && gInstance->mCurrentPlusOnePos )
+  {
     std::string url = gInstance->mHistory[ gInstance->mCurrentPlusOnePos - 1 ];
     std::vector< std::string >().swap( gInstance->mHistory );
     gInstance->mHistory.push_back( url );
@@ -588,13 +831,27 @@ bool OnClearHistory()
   }
   return false;
 }
+
 } // namespace
 
+inline WebEngine& GetImplementation( Dali::WebEngine& webEngine )
+{
+  DALI_ASSERT_ALWAYS( webEngine && "WebEngine handle is empty." );
+  BaseObject& handle = webEngine.GetBaseObject();
+  return static_cast< Internal::Adaptor::WebEngine& >( handle );
+}
+
+inline const WebEngine& GetImplementation( const Dali::WebEngine& webEngine )
+{
+  DALI_ASSERT_ALWAYS( webEngine && "WebEngine handle is empty." );
+  const BaseObject& handle = webEngine.GetBaseObject();
+  return static_cast< const Internal::Adaptor::WebEngine& >( handle );
+}
+
 } // namespace Adaptor
 
 } // namespace Internal
 
-
 // Dali::WebEngine Implementation
 WebEngine::WebEngine()
 {
@@ -740,6 +997,33 @@ void WebEngine::AddJavaScriptMessageHandler( const std::string& exposedObjectNam
 {
 }
 
+void WebEngine::RegisterJavaScriptAlertCallback( Dali::WebEnginePlugin::JavaScriptAlertCallback callback )
+{
+  Internal::Adaptor::GetImplementation( *this ).RegisterJavaScriptAlertCallback( callback );
+}
+
+void WebEngine::JavaScriptAlertReply()
+{
+}
+
+void WebEngine::RegisterJavaScriptConfirmCallback( Dali::WebEnginePlugin::JavaScriptConfirmCallback callback )
+{
+  Internal::Adaptor::GetImplementation( *this ).RegisterJavaScriptConfirmCallback( callback );
+}
+
+void WebEngine::JavaScriptConfirmReply( bool confirmed )
+{
+}
+
+void WebEngine::RegisterJavaScriptPromptCallback( Dali::WebEnginePlugin::JavaScriptPromptCallback callback )
+{
+  Internal::Adaptor::GetImplementation( *this ).RegisterJavaScriptPromptCallback( callback );
+}
+
+void WebEngine::JavaScriptPromptReply( const std::string& result )
+{
+}
+
 void WebEngine::ClearAllTilesResources()
 {
 }
@@ -769,19 +1053,19 @@ void WebEngine::SetScrollPosition( int x, int y )
   Internal::Adaptor::GetImplementation( *this ).SetScrollPosition( x, y );
 }
 
-void WebEngine::GetScrollPosition( int& x, int& y ) const
+Dali::Vector2 WebEngine::GetScrollPosition() const
 {
-  Internal::Adaptor::GetImplementation( *this ).GetScrollPosition( x, y );
+  return Internal::Adaptor::GetImplementation( *this ).GetScrollPosition();
 }
 
-void WebEngine::GetScrollSize( int& w, int& h ) const
+Dali::Vector2 WebEngine::GetScrollSize() const
 {
-  Internal::Adaptor::GetImplementation( *this ).GetScrollSize( w, h );
+  return Internal::Adaptor::GetImplementation( *this ).GetScrollSize();
 }
 
-void WebEngine::GetContentSize( int& w, int& h ) const
+Dali::Vector2 WebEngine::GetContentSize() const
 {
-  Internal::Adaptor::GetImplementation( *this ).GetContentSize( w, h );
+  return Internal::Adaptor::GetImplementation( *this ).GetContentSize();
 }
 
 void WebEngine::SetSize( int width, int height )
@@ -798,15 +1082,46 @@ bool WebEngine::SendKeyEvent( const KeyEvent& event )
   return true;
 }
 
+bool WebEngine::SendHoverEvent( const HoverEvent& event )
+{
+  return true;
+}
+
+bool WebEngine::SendWheelEvent( const WheelEvent& event )
+{
+  return true;
+}
+
 void WebEngine::SetFocus( bool focused )
 {
 }
 
+void WebEngine::UpdateDisplayArea( Dali::Rect< int > displayArea )
+{
+}
+
+void WebEngine::EnableVideoHole( bool enabled )
+{
+}
+
+void WebEngine::EnableMouseEvents( bool enabled )
+{
+}
+
+void WebEngine::EnableKeyEvents( bool enabled )
+{
+}
+
 Dali::WebEnginePlugin::WebEnginePageLoadSignalType& WebEngine::PageLoadStartedSignal()
 {
   return Internal::Adaptor::GetImplementation( *this ).PageLoadStartedSignal();
 }
 
+Dali::WebEnginePlugin::WebEnginePageLoadSignalType& WebEngine::PageLoadInProgressSignal()
+{
+  return Internal::Adaptor::GetImplementation( *this ).PageLoadInProgressSignal();
+}
+
 Dali::WebEnginePlugin::WebEnginePageLoadSignalType& WebEngine::PageLoadFinishedSignal()
 {
   return Internal::Adaptor::GetImplementation( *this ).PageLoadFinishedSignal();
@@ -822,5 +1137,10 @@ Dali::WebEnginePlugin::WebEngineScrollEdgeReachedSignalType& WebEngine::ScrollEd
   return Internal::Adaptor::GetImplementation( *this ).ScrollEdgeReachedSignal();
 }
 
+Dali::WebEnginePlugin::WebEngineUrlChangedSignalType& WebEngine::UrlChangedSignal()
+{
+  return Internal::Adaptor::GetImplementation( *this ).UrlChangedSignal();
+}
+
 } // namespace Dali;