From a3892a845d42560b034a6eb734e4e5ea360e136a Mon Sep 17 00:00:00 2001 From: "huayong.xu" Date: Wed, 30 Dec 2020 17:47:04 +0800 Subject: [PATCH] Add APIs to show javascript popup in web view. Add callbacks for 'url,changed', 'load,progress', and javascript alert/confirm/prompt. Change-Id: Ib59b6d3046c1ae370b736d7f099661a42bc2605f --- .../dali-toolkit-test-utils/toolkit-web-engine.cpp | 189 ++++++++++++++++++--- .../src/dali-toolkit/utc-Dali-WebView.cpp | 83 ++++++++- .../devel-api/controls/web-view/web-view.cpp | 44 ++++- .../devel-api/controls/web-view/web-view.h | 61 ++++++- .../internal/controls/web-view/web-view-impl.cpp | 122 +++++++++++-- .../internal/controls/web-view/web-view-impl.h | 96 ++++++++--- 6 files changed, 526 insertions(+), 69 deletions(-) diff --git a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-web-engine.cpp b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-web-engine.cpp index 9aa5155..863a3b0 100755 --- a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-web-engine.cpp +++ b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-web-engine.cpp @@ -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. @@ -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 { @@ -290,6 +297,11 @@ class WebEngine: public Dali::BaseObject { public: + using JavaScriptEvaluatedResultCallback = std::function; + using JavaScriptAlertCallback = std::function; + using JavaScriptConfirmCallback = std::function; + using JavaScriptPromptCallback = std::function; + WebEngine() : mUrl() , mCurrentPlusOnePos( 0 ) @@ -300,7 +312,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 +328,7 @@ public: gInstanceCount--; if( !gInstanceCount ) { - gInstance = NULL; + gInstance = 0; } delete mockWebEngineSettings; @@ -416,6 +431,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 +478,7 @@ public: mScrollPosition += Dali::Vector2( dx, dy ); if ( mScrollPosition.y + mScrollSize.height > mContentSize.height ) { - gInstance->mScrollEdgeReachedSignal.Emit( Dali::WebEnginePlugin::ScrollEdge::BOTTOM ); + ConnectToGlobalSignal( &OnScrollEdge ); } } @@ -466,6 +508,11 @@ public: return mPageLoadStartedSignal; } + Dali::WebEnginePlugin::WebEnginePageLoadSignalType& PageLoadInProgressSignal() + { + return mPageLoadInProgressSignal; + } + Dali::WebEnginePlugin::WebEnginePageLoadSignalType& PageLoadFinishedSignal() { return mPageLoadFinishedSignal; @@ -481,14 +528,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 mResultCallbacks; bool mEvaluating; Dali::WebEnginePlugin::WebEngineScrollEdgeReachedSignalType mScrollEdgeReachedSignal; @@ -499,21 +552,13 @@ public: WebEngineContext* mockWebEngineContext; WebEngineCookieManager* mockWebEngineCookieManager; WebEngineSettings* mockWebEngineSettings; -}; + Dali::WebEnginePlugin::WebEngineUrlChangedSignalType mUrlChangedSignal; -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 ); -} + JavaScriptAlertCallback mJavaScriptAlertCallback; + JavaScriptConfirmCallback mJavaScriptConfirmCallback; + JavaScriptPromptCallback mJavaScriptPromptCallback; +}; -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 { @@ -553,11 +598,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 ); @@ -573,11 +632,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 ); @@ -585,13 +675,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() { @@ -737,6 +841,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() { } @@ -812,6 +943,11 @@ Dali::WebEnginePlugin::WebEnginePageLoadSignalType& WebEngine::PageLoadStartedSi 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(); @@ -827,5 +963,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; diff --git a/automated-tests/src/dali-toolkit/utc-Dali-WebView.cpp b/automated-tests/src/dali-toolkit/utc-Dali-WebView.cpp index 28863cf..b92cea6 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-WebView.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-WebView.cpp @@ -44,9 +44,14 @@ const char* const TEST_URL1( "http://www.somewhere.valid1.com" ); const char* const TEST_URL2( "http://www.somewhere.valid2.com" ); static int gPageLoadStartedCallbackCalled = 0; +static int gPageLoadInProgressCallbackCalled = 0; static int gPageLoadFinishedCallbackCalled = 0; static int gScrollEdgeReachedCallbackCalled = 0; +static int gUrlChangedCallbackCalled = 0; static int gEvaluateJavaScriptCallbackCalled = 0; +static int gJavaScriptAlertCallbackCalled = 0; +static int gJavaScriptConfirmCallbackCalled = 0; +static int gJavaScriptPromptCallbackCalled = 0; static bool gTouched = false; struct CallbackFunctor @@ -68,6 +73,11 @@ static void OnPageLoadStarted( WebView view, const std::string& url ) gPageLoadStartedCallbackCalled++; } +static void OnPageLoadInProgress( WebView view, const std::string& url ) +{ + gPageLoadInProgressCallbackCalled++; +} + static void OnPageLoadFinished( WebView view, const std::string& url ) { gPageLoadFinishedCallbackCalled++; @@ -78,6 +88,11 @@ static void OnScrollEdgeReached( WebView view, Dali::WebEnginePlugin::ScrollEdge gScrollEdgeReachedCallbackCalled++; } +static void OnUrlChanged( WebView view, const std::string& url ) +{ + gUrlChangedCallbackCalled++; +} + static void OnPageLoadError( WebView view, const std::string& url, WebView::LoadErrorCode errorCode ) { } @@ -87,6 +102,24 @@ static void OnEvaluateJavaScript( const std::string& result ) gEvaluateJavaScriptCallbackCalled++; } +static bool OnJavaScriptAlert( const std::string& result ) +{ + gJavaScriptAlertCallbackCalled++; + return true; +} + +static bool OnJavaScriptConfirm( const std::string& result ) +{ + gJavaScriptConfirmCallbackCalled++; + return true; +} + +static bool OnJavaScriptPrompt( const std::string& meesage1, const std::string& message2 ) +{ + gJavaScriptPromptCallbackCalled++; + return true; +} + static bool OnTouched( Actor actor, const Dali::TouchEvent& touch ) { gTouched = true; @@ -167,26 +200,35 @@ int UtcDaliWebViewPageNavigation(void) ConnectionTracker* testTracker = new ConnectionTracker(); view.PageLoadStartedSignal().Connect( &OnPageLoadStarted ); + view.PageLoadInProgressSignal().Connect( &OnPageLoadInProgress ); view.PageLoadFinishedSignal().Connect( &OnPageLoadFinished ); view.PageLoadErrorSignal().Connect( &OnPageLoadError ); + view.UrlChangedSignal().Connect( &OnUrlChanged ); bool signal1 = false; bool signal2 = false; bool signal3 = false; + bool signal4 = false; + bool signal5 = false; view.ConnectSignal( testTracker, "pageLoadStarted", CallbackFunctor(&signal1) ); - view.ConnectSignal( testTracker, "pageLoadFinished", CallbackFunctor(&signal2) ); - view.ConnectSignal( testTracker, "invalidname", CallbackFunctor(&signal3) ); + view.ConnectSignal( testTracker, "pageLoadInProgress", CallbackFunctor(&signal2) ); + view.ConnectSignal( testTracker, "pageLoadFinished", CallbackFunctor(&signal3) ); + view.ConnectSignal( testTracker, "urlChanged", CallbackFunctor(&signal4) ); + view.ConnectSignal( testTracker, "invalidname", CallbackFunctor(&signal5) ); DALI_TEST_EQUALS( gPageLoadStartedCallbackCalled, 0, TEST_LOCATION ); + DALI_TEST_EQUALS( gPageLoadInProgressCallbackCalled, 0, TEST_LOCATION ); DALI_TEST_EQUALS( gPageLoadFinishedCallbackCalled, 0, TEST_LOCATION ); - + DALI_TEST_EQUALS( gUrlChangedCallbackCalled, 0, TEST_LOCATION ); view.LoadUrl( TEST_URL1 ); view.GetNaturalSize(); Test::EmitGlobalTimerSignal(); DALI_TEST_EQUALS( view.CanGoBack(), false, TEST_LOCATION ); DALI_TEST_EQUALS( gPageLoadStartedCallbackCalled, 1, TEST_LOCATION ); + DALI_TEST_EQUALS( gPageLoadInProgressCallbackCalled, 1, TEST_LOCATION ); DALI_TEST_EQUALS( gPageLoadFinishedCallbackCalled, 1, TEST_LOCATION ); - DALI_TEST_CHECK( signal1 & signal2 ); - DALI_TEST_CHECK( !signal3 ); + DALI_TEST_EQUALS( gUrlChangedCallbackCalled, 1, TEST_LOCATION ); + DALI_TEST_CHECK( signal1 & signal2 & signal3 & signal4 ); + DALI_TEST_CHECK( !signal5 ); view.LoadUrl( TEST_URL2 ); view.Suspend(); @@ -198,7 +240,9 @@ int UtcDaliWebViewPageNavigation(void) DALI_TEST_EQUALS( view.CanGoBack(), true, TEST_LOCATION ); DALI_TEST_EQUALS( view.CanGoForward(), false, TEST_LOCATION ); DALI_TEST_EQUALS( gPageLoadStartedCallbackCalled, 2, TEST_LOCATION ); + DALI_TEST_EQUALS( gPageLoadInProgressCallbackCalled, 2, TEST_LOCATION ); DALI_TEST_EQUALS( gPageLoadFinishedCallbackCalled, 2, TEST_LOCATION ); + DALI_TEST_EQUALS( gUrlChangedCallbackCalled, 2, TEST_LOCATION ); view.GoBack(); Test::EmitGlobalTimerSignal(); @@ -518,6 +562,8 @@ int UtcDaliWebViewScrollBy(void) // scroll by and trigger scrollEdgeReached event. view.ScrollBy( 50, 50 ); + Test::EmitGlobalTimerSignal(); + view.GetProperty( WebView::Property::SCROLL_POSITION ).Get( output ); DALI_TEST_CHECK( output.x == 150 && output.y == 150 ); DALI_TEST_EQUALS( gScrollEdgeReachedCallbackCalled, 1, TEST_LOCATION ); @@ -542,6 +588,33 @@ int UtcDaliWebViewEvaluteJavaScript(void) END_TEST; } +int UtcDaliWebViewJavaScriptAlertConfirmPrompt(void) +{ + ToolkitTestApplication application; + + WebView view = WebView::New( "ko-KR", "Asia/Seoul" ); + + view.RegisterJavaScriptAlertCallback( &OnJavaScriptAlert ); + view.LoadHtmlString( "Hello World!" ); + view.JavaScriptAlertReply(); + Test::EmitGlobalTimerSignal(); + DALI_TEST_EQUALS( gJavaScriptAlertCallbackCalled, 1, TEST_LOCATION ); + + view.RegisterJavaScriptConfirmCallback( &OnJavaScriptConfirm ); + view.LoadHtmlString( "Hello World!" ); + view.JavaScriptConfirmReply( true ); + Test::EmitGlobalTimerSignal(); + DALI_TEST_EQUALS( gJavaScriptConfirmCallbackCalled, 1, TEST_LOCATION ); + + view.RegisterJavaScriptPromptCallback( &OnJavaScriptPrompt ); + view.LoadHtmlString( "Hello World!" ); + view.JavaScriptPromptReply( "it is a prompt." ); + Test::EmitGlobalTimerSignal(); + DALI_TEST_EQUALS( gJavaScriptPromptCallbackCalled, 1, TEST_LOCATION ); + + END_TEST; +} + int UtcDaliWebViewMethodsForCoverage(void) { ToolkitTestApplication application; diff --git a/dali-toolkit/devel-api/controls/web-view/web-view.cpp b/dali-toolkit/devel-api/controls/web-view/web-view.cpp index c3a9d40..201f280 100644 --- a/dali-toolkit/devel-api/controls/web-view/web-view.cpp +++ b/dali-toolkit/devel-api/controls/web-view/web-view.cpp @@ -164,9 +164,34 @@ void WebView::AddJavaScriptMessageHandler(const std::string& exposedObjectName, Dali::Toolkit::GetImpl(*this).AddJavaScriptMessageHandler(exposedObjectName, handler); } -void WebView::ClearAllTilesResources() +void WebView::RegisterJavaScriptAlertCallback( Dali::WebEnginePlugin::JavaScriptAlertCallback callback ) +{ + Dali::Toolkit::GetImpl( *this ).RegisterJavaScriptAlertCallback( callback ); +} + +void WebView::JavaScriptAlertReply() +{ + Dali::Toolkit::GetImpl( *this ).JavaScriptAlertReply(); +} + +void WebView::RegisterJavaScriptConfirmCallback( Dali::WebEnginePlugin::JavaScriptConfirmCallback callback ) +{ + Dali::Toolkit::GetImpl( *this ).RegisterJavaScriptConfirmCallback( callback ); +} + +void WebView::JavaScriptConfirmReply( bool confirmed ) +{ + Dali::Toolkit::GetImpl( *this ).JavaScriptConfirmReply( confirmed ); +} + +void WebView::RegisterJavaScriptPromptCallback( Dali::WebEnginePlugin::JavaScriptPromptCallback callback ) { - Dali::Toolkit::GetImpl(*this).ClearAllTilesResources(); + Dali::Toolkit::GetImpl( *this ).RegisterJavaScriptPromptCallback( callback ); +} + +void WebView::JavaScriptPromptReply( const std::string& result ) +{ + Dali::Toolkit::GetImpl( *this ).JavaScriptPromptReply( result ); } void WebView::ClearHistory() @@ -174,11 +199,21 @@ void WebView::ClearHistory() Dali::Toolkit::GetImpl(*this).ClearHistory(); } +void WebView::ClearAllTilesResources() +{ + Dali::Toolkit::GetImpl( *this ).ClearAllTilesResources(); +} + WebView::WebViewPageLoadSignalType& WebView::PageLoadStartedSignal() { return Dali::Toolkit::GetImpl(*this).PageLoadStartedSignal(); } +WebView::WebViewPageLoadSignalType& WebView::PageLoadInProgressSignal() +{ + return Dali::Toolkit::GetImpl( *this ).PageLoadInProgressSignal(); +} + WebView::WebViewPageLoadSignalType& WebView::PageLoadFinishedSignal() { return Dali::Toolkit::GetImpl(*this).PageLoadFinishedSignal(); @@ -194,6 +229,11 @@ WebView::WebViewScrollEdgeReachedSignalType& WebView::ScrollEdgeReachedSignal() return Dali::Toolkit::GetImpl(*this).ScrollEdgeReachedSignal(); } +WebView::WebViewUrlChangedSignalType& WebView::UrlChangedSignal() +{ + return Dali::Toolkit::GetImpl( *this ).UrlChangedSignal(); +} + WebView::WebView(Internal::WebView& implementation) : Control(implementation) { diff --git a/dali-toolkit/devel-api/controls/web-view/web-view.h b/dali-toolkit/devel-api/controls/web-view/web-view.h index 8c842b7..13ce3c0 100644 --- a/dali-toolkit/devel-api/controls/web-view/web-view.h +++ b/dali-toolkit/devel-api/controls/web-view/web-view.h @@ -157,6 +157,11 @@ public: */ using WebViewScrollEdgeReachedSignalType = Signal; + /** + * @brief WebView signal type related with url changed. + */ + using WebViewUrlChangedSignalType = Signal; + public: /** * @brief Creates an initialized WebView. @@ -354,9 +359,42 @@ public: void AddJavaScriptMessageHandler(const std::string& exposedObjectName, std::function handler); /** - * @brief Clears all tiles resources of Web. + * @brief Register alert callback for javascript. + * + * @param[in] callback The callback function to be called by the JavaScript runtime. */ - void ClearAllTilesResources(); + void RegisterJavaScriptAlertCallback(Dali::WebEnginePlugin::JavaScriptAlertCallback callback); + + /** + * @brief Reply for JavaScript alert. + */ + void JavaScriptAlertReply(); + + /** + * @brief Register confirm callback for javascript. + * + * @param[in] callback The callback function to be called by the JavaScript runtime. + */ + void RegisterJavaScriptConfirmCallback(Dali::WebEnginePlugin::JavaScriptConfirmCallback callback); + + /** + * @brief Reply for JavaScript confirm. + * @param[in] confirmed True if confirmed, false otherwise + */ + void JavaScriptConfirmReply(bool confirmed); + + /** + * @brief Register prompt callback for javascript. + * + * @param[in] callback The callback function to be called by the JavaScript runtime. + */ + void RegisterJavaScriptPromptCallback(Dali::WebEnginePlugin::JavaScriptPromptCallback callback); + + /** + * @brief Reply for JavaScript prompt. + * @param[in] result The result from input-field of prompt popup. + */ + void JavaScriptPromptReply(const std::string& result); /** * @brief Clears the history of Web. @@ -364,6 +402,11 @@ public: void ClearHistory(); /** + * @brief Clears all tiles resources of Web. + */ + void ClearAllTilesResources(); + + /** * @brief Connects to this signal to be notified when page loading is started. * * @return A signal object to connect with @@ -371,6 +414,13 @@ public: WebViewPageLoadSignalType& PageLoadStartedSignal(); /** + * @brief Connects to this signal to be notified when page loading is in progress. + * + * @return A signal object to connect with. + */ + WebViewPageLoadSignalType& PageLoadInProgressSignal(); + + /** * @brief Connects to this signal to be notified when page loading is finished. * * @return A signal object to connect with @@ -391,6 +441,13 @@ public: */ WebViewScrollEdgeReachedSignalType& ScrollEdgeReachedSignal(); + /** + * @brief Connects to this signal to be notified when url is changed. + * + * @return A signal object to connect with. + */ + WebViewUrlChangedSignalType& UrlChangedSignal(); + public: // Not intended for application developers /// @cond internal /** diff --git a/dali-toolkit/internal/controls/web-view/web-view-impl.cpp b/dali-toolkit/internal/controls/web-view/web-view-impl.cpp index f7f1663..3595b12 100644 --- a/dali-toolkit/internal/controls/web-view/web-view-impl.cpp +++ b/dali-toolkit/internal/controls/web-view/web-view-impl.cpp @@ -66,10 +66,12 @@ DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "contentSize", VECTOR2, CONTEN DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "title", STRING, TITLE ) DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "videoHoleEnabled", BOOLEAN, VIDEO_HOLE_ENABLED) -DALI_SIGNAL_REGISTRATION(Toolkit, WebView, "pageLoadStarted", PAGE_LOAD_STARTED_SIGNAL ) -DALI_SIGNAL_REGISTRATION(Toolkit, WebView, "pageLoadFinished", PAGE_LOAD_FINISHED_SIGNAL ) -DALI_SIGNAL_REGISTRATION(Toolkit, WebView, "pageLoadError", PAGE_LOAD_ERROR_SIGNAL ) -DALI_SIGNAL_REGISTRATION(Toolkit, WebView, "scrollEdgeReached", SCROLL_EDGE_REACHED_SIGNAL) +DALI_SIGNAL_REGISTRATION(Toolkit, WebView, "pageLoadStarted", PAGE_LOAD_STARTED_SIGNAL ) +DALI_SIGNAL_REGISTRATION(Toolkit, WebView, "pageLoadInProgress", PAGE_LOAD_IN_PROGRESS_SIGNAL) +DALI_SIGNAL_REGISTRATION(Toolkit, WebView, "pageLoadFinished", PAGE_LOAD_FINISHED_SIGNAL ) +DALI_SIGNAL_REGISTRATION(Toolkit, WebView, "pageLoadError", PAGE_LOAD_ERROR_SIGNAL ) +DALI_SIGNAL_REGISTRATION(Toolkit, WebView, "scrollEdgeReached", SCROLL_EDGE_REACHED_SIGNAL ) +DALI_SIGNAL_REGISTRATION(Toolkit, WebView, "urlChanged", URL_CHANGED_SIGNAL ) DALI_TYPE_REGISTRATION_END() // clang-format on @@ -94,7 +96,8 @@ WebView::WebView(const std::string& locale, const std::string& timezoneId) mPageLoadFinishedSignal(), mPageLoadErrorSignal(), mVideoHoleEnabled(true), - mWebViewArea(0, 0, mWebViewSize.width, mWebViewSize.height) + mWebViewArea(0, 0, mWebViewSize.width, mWebViewSize.height), + mUrlChangedSignal() { mWebEngine = Dali::WebEngine::New(); @@ -115,7 +118,8 @@ WebView::WebView(int argc, char** argv) mPageLoadFinishedSignal(), mPageLoadErrorSignal(), mVideoHoleEnabled(true), - mWebViewArea(0, 0, mWebViewSize.width, mWebViewSize.height) + mWebViewArea(0, 0, mWebViewSize.width, mWebViewSize.height), + mUrlChangedSignal() { mWebEngine = Dali::WebEngine::New(); @@ -182,10 +186,12 @@ void WebView::OnInitialize() if(mWebEngine) { - mWebEngine.PageLoadStartedSignal().Connect(this, &WebView::OnPageLoadStarted); - mWebEngine.PageLoadFinishedSignal().Connect(this, &WebView::OnPageLoadFinished); - mWebEngine.PageLoadErrorSignal().Connect(this, &WebView::OnPageLoadError); - mWebEngine.ScrollEdgeReachedSignal().Connect(this, &WebView::OnScrollEdgeReached); + mWebEngine.PageLoadStartedSignal().Connect( this, &WebView::OnPageLoadStarted ); + mWebEngine.PageLoadInProgressSignal().Connect(this, &WebView::OnPageLoadInProgress); + mWebEngine.PageLoadFinishedSignal().Connect( this, &WebView::OnPageLoadFinished ); + mWebEngine.PageLoadErrorSignal().Connect( this, &WebView::OnPageLoadError ); + mWebEngine.ScrollEdgeReachedSignal().Connect( this, &WebView::OnScrollEdgeReached ); + mWebEngine.UrlChangedSignal().Connect(this, &WebView::OnUrlChanged); mWebContext = std::unique_ptr(new WebContext(mWebEngine.GetContext())); mWebCookieManager = std::unique_ptr(new WebCookieManager(mWebEngine.GetCookieManager())); @@ -357,11 +363,51 @@ void WebView::AddJavaScriptMessageHandler(const std::string& exposedObjectName, } } -void WebView::ClearAllTilesResources() +void WebView::RegisterJavaScriptAlertCallback( Dali::WebEnginePlugin::JavaScriptAlertCallback callback ) { if(mWebEngine) { - mWebEngine.ClearAllTilesResources(); + mWebEngine.RegisterJavaScriptAlertCallback( callback ); + } +} + +void WebView::JavaScriptAlertReply() +{ + if ( mWebEngine ) + { + mWebEngine.JavaScriptAlertReply(); + } +} + +void WebView::RegisterJavaScriptConfirmCallback( Dali::WebEnginePlugin::JavaScriptConfirmCallback callback ) +{ + if ( mWebEngine ) + { + mWebEngine.RegisterJavaScriptConfirmCallback( callback ); + } +} + +void WebView::JavaScriptConfirmReply( bool confirmed ) +{ + if ( mWebEngine ) + { + mWebEngine.JavaScriptConfirmReply( confirmed ); + } +} + +void WebView::RegisterJavaScriptPromptCallback( Dali::WebEnginePlugin::JavaScriptPromptCallback callback ) +{ + if ( mWebEngine ) + { + mWebEngine.RegisterJavaScriptPromptCallback( callback ); + } +} + +void WebView::JavaScriptPromptReply( const std::string& result ) +{ + if ( mWebEngine ) + { + mWebEngine.JavaScriptPromptReply( result ); } } @@ -426,11 +472,24 @@ void WebView::EnableBlendMode(bool blendEnabled) } } +void WebView::ClearAllTilesResources() +{ + if( mWebEngine ) + { + mWebEngine.ClearAllTilesResources(); + } +} + Dali::Toolkit::WebView::WebViewPageLoadSignalType& WebView::PageLoadStartedSignal() { return mPageLoadStartedSignal; } +Dali::Toolkit::WebView::WebViewPageLoadSignalType& WebView::PageLoadInProgressSignal() +{ + return mPageLoadInProgressSignal; +} + Dali::Toolkit::WebView::WebViewPageLoadSignalType& WebView::PageLoadFinishedSignal() { return mPageLoadFinishedSignal; @@ -446,7 +505,12 @@ Dali::Toolkit::WebView::WebViewScrollEdgeReachedSignalType& WebView::ScrollEdgeR return mScrollEdgeReachedSignal; } -void WebView::OnPageLoadStarted(const std::string& url) +Dali::Toolkit::WebView::WebViewUrlChangedSignalType& WebView::UrlChangedSignal() +{ + return mUrlChangedSignal; +} + +void WebView::OnPageLoadStarted( const std::string& url ) { if(!mPageLoadStartedSignal.Empty()) { @@ -455,7 +519,16 @@ void WebView::OnPageLoadStarted(const std::string& url) } } -void WebView::OnPageLoadFinished(const std::string& url) +void WebView::OnPageLoadInProgress( const std::string& url ) +{ + if ( !mPageLoadInProgressSignal.Empty() ) + { + Dali::Toolkit::WebView handle( GetOwner() ); + mPageLoadInProgressSignal.Emit( handle, url ); + } +} + +void WebView::OnPageLoadFinished( const std::string& url ) { if(!mPageLoadFinishedSignal.Empty()) { @@ -482,7 +555,16 @@ void WebView::OnScrollEdgeReached(Dali::WebEnginePlugin::ScrollEdge edge) } } -bool WebView::DoConnectSignal(BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor) +void WebView::OnUrlChanged(const std::string& url) +{ + if (!mUrlChangedSignal.Empty()) + { + Dali::Toolkit::WebView handle(GetOwner()); + mUrlChangedSignal.Emit(handle, url); + } +} + +bool WebView::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor ) { Dali::BaseHandle handle(object); @@ -494,6 +576,11 @@ bool WebView::DoConnectSignal(BaseObject* object, ConnectionTrackerInterface* tr webView.PageLoadStartedSignal().Connect(tracker, functor); connected = true; } + else if (0 == strcmp(signalName.c_str(), PAGE_LOAD_IN_PROGRESS_SIGNAL)) + { + webView.PageLoadInProgressSignal().Connect(tracker, functor); + connected = true; + } else if(0 == strcmp(signalName.c_str(), PAGE_LOAD_FINISHED_SIGNAL)) { webView.PageLoadFinishedSignal().Connect(tracker, functor); @@ -509,6 +596,11 @@ bool WebView::DoConnectSignal(BaseObject* object, ConnectionTrackerInterface* tr webView.ScrollEdgeReachedSignal().Connect(tracker, functor); connected = true; } + else if (0 == strcmp(signalName.c_str(), URL_CHANGED_SIGNAL)) + { + webView.UrlChangedSignal().Connect( tracker, functor ); + connected = true; + } return connected; } diff --git a/dali-toolkit/internal/controls/web-view/web-view-impl.h b/dali-toolkit/internal/controls/web-view/web-view-impl.h index 5a76ab5..065dc45 100644 --- a/dali-toolkit/internal/controls/web-view/web-view-impl.h +++ b/dali-toolkit/internal/controls/web-view/web-view-impl.h @@ -164,9 +164,34 @@ public: void AddJavaScriptMessageHandler(const std::string& exposedObjectName, std::function handler); /** - * @brief Clears all tiles resources of Web. + * @copydoc Dali::Toolkit::WebView::RegisterJavaScriptAlertCallback() */ - void ClearAllTilesResources(); + void RegisterJavaScriptAlertCallback( Dali::WebEnginePlugin::JavaScriptAlertCallback callback ); + + /** + * @copydoc Dali::Toolkit::WebView::JavaScriptAlertReply() + */ + void JavaScriptAlertReply(); + + /** + * @copydoc Dali::Toolkit::WebView::RegisterJavaScriptConfirmCallback() + */ + void RegisterJavaScriptConfirmCallback( Dali::WebEnginePlugin::JavaScriptConfirmCallback callback ); + + /** + * @copydoc Dali::Toolkit::WebView::JavaScriptConfirmReply() + */ + void JavaScriptConfirmReply( bool confirmed ); + + /** + * @copydoc Dali::Toolkit::WebView::RegisterJavaScriptPromptCallback() + */ + void RegisterJavaScriptPromptCallback( Dali::WebEnginePlugin::JavaScriptPromptCallback callback); + + /** + * @copydoc Dali::Toolkit::WebView::JavaScriptPromptReply() + */ + void JavaScriptPromptReply( const std::string& result ); /** * @copydoc Dali::Toolkit::WebView::ClearHistory() @@ -174,11 +199,21 @@ public: void ClearHistory(); /** + * @brief Clears all tiles resources of Web. + */ + void ClearAllTilesResources(); + + /** * @copydoc Dali::Toolkit::WebView::PageLoadStartedSignal() */ Dali::Toolkit::WebView::WebViewPageLoadSignalType& PageLoadStartedSignal(); /** + * @copydoc Dali::Toolkit::WebView::PageLoadInProgressSignal() + */ + Dali::Toolkit::WebView::WebViewPageLoadSignalType& PageLoadInProgressSignal(); + + /** * @copydoc Dali::Toolkit::WebView::PageLoadFinishedSignal() */ Dali::Toolkit::WebView::WebViewPageLoadSignalType& PageLoadFinishedSignal(); @@ -193,6 +228,11 @@ public: */ Dali::Toolkit::WebView::WebViewScrollEdgeReachedSignalType& ScrollEdgeReachedSignal(); + /** + * @copydoc Dali::Toolkit::WebView::UrlChangedSignal() + */ + Dali::Toolkit::WebView::WebViewUrlChangedSignalType& UrlChangedSignal(); + public: // Properties /** * @brief Called when a property of an object of this type is set. @@ -340,6 +380,12 @@ private: void OnPageLoadStarted(const std::string& url); /** + * @brief Callback function to be called when page is loading in progress. + * @param[in] url The url currently being loaded + */ + void OnPageLoadInProgress( const std::string& url ); + + /** * @brief Callback function to be called when page load finished. * @param[in] url The url currently being loaded */ @@ -358,28 +404,36 @@ private: */ void OnScrollEdgeReached(Dali::WebEnginePlugin::ScrollEdge edge); + /** + * @brief Callback function to be called when url is changed. + * @param[in] url The url currently being loaded + */ + void OnUrlChanged( const std::string& url ); + private: - std::string mUrl; - Dali::Toolkit::Visual::Base mVisual; - Dali::Size mWebViewSize; - Dali::WebEngine mWebEngine; - - Dali::Toolkit::WebView::WebViewPageLoadSignalType mPageLoadStartedSignal; - Dali::Toolkit::WebView::WebViewPageLoadSignalType mPageLoadFinishedSignal; - Dali::Toolkit::WebView::WebViewPageLoadErrorSignalType mPageLoadErrorSignal; + std::string mUrl; + Dali::Toolkit::Visual::Base mVisual; + Dali::Size mWebViewSize; + Dali::WebEngine mWebEngine; + + Dali::Toolkit::WebView::WebViewPageLoadSignalType mPageLoadStartedSignal; + Dali::Toolkit::WebView::WebViewPageLoadSignalType mPageLoadInProgressSignal; + Dali::Toolkit::WebView::WebViewPageLoadSignalType mPageLoadFinishedSignal; + Dali::Toolkit::WebView::WebViewPageLoadErrorSignalType mPageLoadErrorSignal; Dali::Toolkit::WebView::WebViewScrollEdgeReachedSignalType mScrollEdgeReachedSignal; - std::unique_ptr mWebContext; - std::unique_ptr mWebCookieManager; - std::unique_ptr mWebSettings; - std::unique_ptr mWebBackForwardList; - Dali::Toolkit::ImageView mFaviconView; - - Dali::PropertyNotification mPositionUpdateNotification; - Dali::PropertyNotification mSizeUpdateNotification; - Dali::PropertyNotification mScaleUpdateNotification; - bool mVideoHoleEnabled; - Dali::Rect mWebViewArea; + std::unique_ptr mWebContext; + std::unique_ptr mWebCookieManager; + std::unique_ptr mWebSettings; + std::unique_ptr mWebBackForwardList; + Dali::Toolkit::ImageView mFaviconView; + + Dali::PropertyNotification mPositionUpdateNotification; + Dali::PropertyNotification mSizeUpdateNotification; + Dali::PropertyNotification mScaleUpdateNotification; + bool mVideoHoleEnabled; + Dali::Rect< int > mWebViewArea; + Dali::Toolkit::WebView::WebViewUrlChangedSignalType mUrlChangedSignal; }; } // namespace Internal -- 2.7.4