2 * Copyright (c) 2020 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 #include "toolkit-timer.h"
20 #include <dali/devel-api/adaptor-framework/web-engine.h>
21 #include <dali/devel-api/adaptor-framework/web-engine-back-forward-list.h>
22 #include <dali/devel-api/adaptor-framework/web-engine-back-forward-list-item.h>
23 #include <dali/devel-api/adaptor-framework/web-engine-context.h>
24 #include <dali/devel-api/adaptor-framework/web-engine-cookie-manager.h>
25 #include <dali/devel-api/adaptor-framework/web-engine-settings.h>
26 #include <dali/public-api/object/any.h>
27 #include <dali/public-api/object/base-object.h>
28 #include <dali/public-api/adaptor-framework/native-image-source.h>
29 #include <toolkit-application.h>
44 static WebEngine* gInstance = NULL;
45 static int gInstanceCount = 0;
50 bool OnEvaluteJavaScript();
51 bool OnClearHistory();
53 static void ConnectToGlobalSignal( bool (*func)() )
55 Dali::Timer timer = Dali::Timer::New( 0 );
56 timer.TickSignal().Connect( func );
59 static void DisconnectFromGlobalSignal( bool (*func)() )
61 Dali::Timer timer = Dali::Timer::New( 0 );
62 timer.TickSignal().Disconnect( func );
66 class MockWebEngineContext : public Dali::WebEngineContext
69 MockWebEngineContext()
70 : mockModel( Dali::WebEngineContext::CacheModel::DOCUMENT_VIEWER )
74 Dali::WebEngineContext::CacheModel GetCacheModel() const override
79 void SetCacheModel( Dali::WebEngineContext::CacheModel cacheModel ) override
81 mockModel = cacheModel;
84 void SetProxyUri( const std::string& uri ) override
88 void SetDefaultProxyAuth( const std::string& username, const std::string& password ) override
92 void SetCertificateFilePath( const std::string& certificatePath ) override
96 void DeleteWebDatabase() override
100 void DeleteWebStorage() override
104 void DeleteLocalFileSystem() override
108 void DisableCache( bool cacheDisabled ) override
112 void ClearCache() override
117 Dali::WebEngineContext::CacheModel mockModel;
120 class MockWebEngineCookieManager : public Dali::WebEngineCookieManager
123 MockWebEngineCookieManager()
124 : mockCookieAcceptPolicy( Dali::WebEngineCookieManager::CookieAcceptPolicy::NO_THIRD_PARTY )
128 void SetCookieAcceptPolicy( Dali::WebEngineCookieManager::CookieAcceptPolicy policy ) override
130 mockCookieAcceptPolicy = policy;
133 Dali::WebEngineCookieManager::CookieAcceptPolicy GetCookieAcceptPolicy() const override
135 return mockCookieAcceptPolicy;
138 void ClearCookies() override
142 void SetPersistentStorage( const std::string& path, Dali::WebEngineCookieManager::CookiePersistentStorage storage ) override
147 Dali::WebEngineCookieManager::CookieAcceptPolicy mockCookieAcceptPolicy;
150 class MockWebEngineBackForwardListItem : public Dali::WebEngineBackForwardListItem
153 MockWebEngineBackForwardListItem()
154 : mockUrl( "http://url" ),
155 mockTitle( "title" ),
156 mockOriginalUrl( "http://originalurl" )
160 std::string GetUrl() const override
165 std::string GetTitle() const override
170 std::string GetOriginalUrl() const override
172 return mockOriginalUrl;
177 std::string mockTitle;
178 std::string mockOriginalUrl;
181 class MockWebEngineBackForwardList : public Dali::WebEngineBackForwardList
184 MockWebEngineBackForwardList( )
186 pMockItem( &mockItem )
190 Dali::WebEngineBackForwardListItem& GetCurrentItem() const override
195 Dali::WebEngineBackForwardListItem& GetItemAtIndex( uint32_t index ) const override
200 uint32_t GetItemCount() const override
206 MockWebEngineBackForwardListItem mockItem;
207 WebEngineBackForwardListItem* pMockItem;
210 class MockWebEngineSettings : public WebEngineSettings
213 MockWebEngineSettings()
214 : mockDefaultFontSize( 16 ),
215 mockJavaScriptEnabled( true ),
216 mockImageLoadedAutomatically( true ),
217 mockDefaultTextEncodingName()
221 uint32_t GetDefaultFontSize() const override
223 return mockDefaultFontSize;
226 void SetDefaultFontSize( uint32_t size ) override
228 mockDefaultFontSize = size;
231 bool IsJavaScriptEnabled() const override
233 return mockJavaScriptEnabled;
236 void EnableJavaScript( bool enabled ) override
238 mockJavaScriptEnabled = enabled;
241 bool AreImagesLoadedAutomatically() const override
243 return mockImageLoadedAutomatically;
246 void AllowImagesLoadAutomatically( bool automatic ) override
248 mockImageLoadedAutomatically = automatic;
251 std::string GetDefaultTextEncodingName() const override
253 return mockDefaultTextEncodingName;
256 void SetDefaultTextEncodingName( const std::string& defaultTextEncodingName ) override
258 mockDefaultTextEncodingName = defaultTextEncodingName;
261 void AllowMixedContents( bool allowed ) override
265 void EnableSpatialNavigation( bool enabled ) override
269 void EnableWebSecurity( bool enabled ) override
273 void AllowFileAccessFromExternalUrl( bool allowed ) override
277 void AllowScriptsOpenWindows( bool allowed ) override
282 int mockDefaultFontSize;
283 bool mockJavaScriptEnabled;
284 bool mockImageLoadedAutomatically;
285 std::string mockDefaultTextEncodingName;
288 class WebEngine: public Dali::BaseObject
294 , mCurrentPlusOnePos( 0 )
296 , mEvaluating( false )
297 , mScrollPosition( 0, 0 )
298 , mScrollSize( 500, 500 )
299 , mContentSize( 500, 500 )
304 mockWebEngineSettings = new MockWebEngineSettings();
305 mockWebEngineContext = new MockWebEngineContext();
306 mockWebEngineCookieManager = new MockWebEngineCookieManager();
307 mockWebEngineBackForwardList = new MockWebEngineBackForwardList();
313 if( !gInstanceCount )
318 delete mockWebEngineSettings;
319 delete mockWebEngineContext;
320 delete mockWebEngineCookieManager;
321 delete mockWebEngineBackForwardList;
324 Dali::WebEngineSettings& GetSettings() const
326 return *mockWebEngineSettings;
329 Dali::WebEngineContext& GetContext() const
331 return *mockWebEngineContext;
334 Dali::WebEngineCookieManager& GetCookieManager() const
336 return *mockWebEngineCookieManager;
339 Dali::WebEngineBackForwardList& GetBackForwardList() const
341 return *mockWebEngineBackForwardList;
344 void LoadUrl( const std::string& url )
347 ConnectToGlobalSignal( &OnLoadUrl );
350 const std::string& GetUrl() const
355 bool CanGoForward() const
357 return mHistory.size() > mCurrentPlusOnePos;
362 ConnectToGlobalSignal( &OnGoForward );
365 bool CanGoBack() const
367 return mCurrentPlusOnePos > 1;
372 ConnectToGlobalSignal( &OnGoBack );
375 void EvaluateJavaScript( const std::string& script, std::function< void( const std::string& ) > resultHandler )
381 ConnectToGlobalSignal( &OnEvaluteJavaScript );
383 mResultCallbacks.push_back( resultHandler );
389 ConnectToGlobalSignal( &OnClearHistory );
392 const std::string& GetUserAgent() const
397 void SetUserAgent( const std::string& userAgent )
399 mUserAgent = userAgent;
402 void ScrollBy( int dx, int dy )
404 mScrollPosition += Dali::Vector2( dx, dy );
405 if ( mScrollPosition.y + mScrollSize.height > mContentSize.height )
407 gInstance->mScrollEdgeReachedSignal.Emit( Dali::WebEnginePlugin::ScrollEdge::BOTTOM );
411 void SetScrollPosition( int x, int y )
413 mScrollPosition.x = x;
414 mScrollPosition.y = y;
417 void GetScrollPosition( int& x, int& y ) const
419 x = mScrollPosition.x;
420 y = mScrollPosition.y;
423 void GetScrollSize( int& w, int& h ) const
425 w = mScrollSize.width;
426 h = mScrollSize.height;
429 void GetContentSize( int& w, int& h ) const
431 w = mContentSize.width;
432 h = mContentSize.height;
435 Dali::WebEnginePlugin::WebEnginePageLoadSignalType& PageLoadStartedSignal()
437 return mPageLoadStartedSignal;
440 Dali::WebEnginePlugin::WebEnginePageLoadSignalType& PageLoadFinishedSignal()
442 return mPageLoadFinishedSignal;
445 Dali::WebEnginePlugin::WebEnginePageLoadErrorSignalType& PageLoadErrorSignal()
447 return mPageLoadErrorSignal;
450 Dali::WebEnginePlugin::WebEngineScrollEdgeReachedSignalType& ScrollEdgeReachedSignal()
452 return mScrollEdgeReachedSignal;
456 std::vector< std::string > mHistory;
457 size_t mCurrentPlusOnePos;
458 std::string mUserAgent;
459 Dali::WebEnginePlugin::WebEnginePageLoadSignalType mPageLoadStartedSignal;
460 Dali::WebEnginePlugin::WebEnginePageLoadSignalType mPageLoadFinishedSignal;
461 Dali::WebEnginePlugin::WebEnginePageLoadErrorSignalType mPageLoadErrorSignal;
462 std::vector< std::function< void( const std::string& ) > > mResultCallbacks;
465 Dali::WebEnginePlugin::WebEngineScrollEdgeReachedSignalType mScrollEdgeReachedSignal;
466 Dali::Vector2 mScrollPosition;
467 Dali::Vector2 mScrollSize;
468 Dali::Vector2 mContentSize;
469 WebEngineBackForwardList* mockWebEngineBackForwardList;
470 WebEngineContext* mockWebEngineContext;
471 WebEngineCookieManager* mockWebEngineCookieManager;
472 WebEngineSettings* mockWebEngineSettings;
475 inline WebEngine& GetImplementation( Dali::WebEngine& webEngine )
477 DALI_ASSERT_ALWAYS( webEngine && "WebEngine handle is empty." );
478 BaseObject& handle = webEngine.GetBaseObject();
479 return static_cast< Internal::Adaptor::WebEngine& >( handle );
482 inline const WebEngine& GetImplementation( const Dali::WebEngine& webEngine )
484 DALI_ASSERT_ALWAYS( webEngine && "WebEngine handle is empty." );
485 const BaseObject& handle = webEngine.GetBaseObject();
486 return static_cast< const Internal::Adaptor::WebEngine& >( handle );
494 DisconnectFromGlobalSignal( &OnGoBack );
496 if( gInstance && gInstance->CanGoBack() )
498 gInstance->mCurrentPlusOnePos--;
505 DisconnectFromGlobalSignal( &OnGoForward );
507 if( gInstance && gInstance->CanGoForward() )
509 gInstance->mCurrentPlusOnePos++;
516 DisconnectFromGlobalSignal( &OnLoadUrl );
520 if( gInstance->mHistory.size() > gInstance->mCurrentPlusOnePos )
522 gInstance->mHistory.erase( gInstance->mHistory.begin() + gInstance->mCurrentPlusOnePos, gInstance->mHistory.end() );
524 gInstance->mHistory.push_back( gInstance->mUrl );
525 gInstance->mCurrentPlusOnePos++;
526 gInstance->mPageLoadStartedSignal.Emit( gInstance->mUrl );
527 gInstance->mPageLoadFinishedSignal.Emit( gInstance->mUrl );
532 bool OnEvaluteJavaScript()
534 DisconnectFromGlobalSignal( &OnEvaluteJavaScript );
538 for( auto& func : gInstance->mResultCallbacks )
542 gInstance->mResultCallbacks.clear();
547 bool OnClearHistory()
549 DisconnectFromGlobalSignal( &OnClearHistory );
551 if( gInstance && gInstance->mCurrentPlusOnePos ) {
552 std::string url = gInstance->mHistory[ gInstance->mCurrentPlusOnePos - 1 ];
553 std::vector< std::string >().swap( gInstance->mHistory );
554 gInstance->mHistory.push_back( url );
555 gInstance->mCurrentPlusOnePos = 1;
561 } // namespace Adaptor
563 } // namespace Internal
566 // Dali::WebEngine Implementation
567 WebEngine::WebEngine()
571 WebEngine::WebEngine( Internal::Adaptor::WebEngine* internal )
572 : BaseHandle( internal )
576 WebEngine::~WebEngine()
580 WebEngine WebEngine::New()
582 Internal::Adaptor::WebEngine* baseObject = new Internal::Adaptor::WebEngine();
584 return WebEngine( baseObject );
587 WebEngine::WebEngine( const WebEngine& WebEngine )
588 : BaseHandle( WebEngine )
592 WebEngine& WebEngine::operator=( const WebEngine& webEngine )
594 BaseHandle::operator=( webEngine );
598 WebEngine WebEngine::DownCast( BaseHandle handle )
600 return WebEngine( dynamic_cast< Internal::Adaptor::WebEngine* >( handle.GetObjectPtr() ) );
603 void WebEngine::Create( int width, int height, const std::string& locale, const std::string& timezoneId )
607 void WebEngine::Destroy()
611 WebEngineSettings& WebEngine::GetSettings() const
613 return Internal::Adaptor::GetImplementation( *this ).GetSettings();
616 WebEngineContext& WebEngine::GetContext() const
618 return Internal::Adaptor::GetImplementation( *this ).GetContext();
621 WebEngineCookieManager& WebEngine::GetCookieManager() const
623 return Internal::Adaptor::GetImplementation( *this ).GetCookieManager();
626 WebEngineBackForwardList& WebEngine::GetBackForwardList() const
628 return Internal::Adaptor::GetImplementation( *this ).GetBackForwardList();
631 void WebEngine::LoadUrl( const std::string& url )
633 return Internal::Adaptor::GetImplementation( *this ).LoadUrl( url );
636 const std::string& WebEngine::GetUrl()
638 return Internal::Adaptor::GetImplementation( *this ).GetUrl();
641 NativeImageInterfacePtr WebEngine::GetNativeImageSource()
644 Dali::NativeImageSourcePtr sourcePtr = Dali::NativeImageSource::New( source );
648 void WebEngine::LoadHtmlString( const std::string& htmlString )
652 void WebEngine::Reload()
656 void WebEngine::StopLoading()
660 void WebEngine::Suspend()
664 void WebEngine::Resume()
668 bool WebEngine::CanGoForward()
670 return Internal::Adaptor::GetImplementation( *this ).CanGoForward();
673 void WebEngine::GoForward()
675 Internal::Adaptor::GetImplementation( *this ).GoForward();
678 bool WebEngine::CanGoBack()
680 return Internal::Adaptor::GetImplementation( *this ).CanGoBack();
683 void WebEngine::GoBack()
685 Internal::Adaptor::GetImplementation( *this ).GoBack();
688 void WebEngine::EvaluateJavaScript( const std::string& script, std::function< void( const std::string& ) > resultHandler )
690 Internal::Adaptor::GetImplementation( *this ).EvaluateJavaScript( script, resultHandler );
693 void WebEngine::AddJavaScriptMessageHandler( const std::string& exposedObjectName, std::function< void(const std::string&) > handler )
697 void WebEngine::ClearHistory()
699 Internal::Adaptor::GetImplementation( *this ).ClearHistory();
702 const std::string& WebEngine::GetUserAgent() const
704 return Internal::Adaptor::GetImplementation( *this ).GetUserAgent();
707 void WebEngine::SetUserAgent( const std::string& userAgent )
709 Internal::Adaptor::GetImplementation( *this ).SetUserAgent( userAgent );
712 void WebEngine::ScrollBy( int dx, int dy )
714 Internal::Adaptor::GetImplementation( *this ).ScrollBy( dx, dy );
717 void WebEngine::SetScrollPosition( int x, int y )
719 Internal::Adaptor::GetImplementation( *this ).SetScrollPosition( x, y );
722 void WebEngine::GetScrollPosition( int& x, int& y ) const
724 Internal::Adaptor::GetImplementation( *this ).GetScrollPosition( x, y );
727 void WebEngine::GetScrollSize( int& w, int& h ) const
729 Internal::Adaptor::GetImplementation( *this ).GetScrollSize( w, h );
732 void WebEngine::GetContentSize( int& w, int& h ) const
734 Internal::Adaptor::GetImplementation( *this ).GetContentSize( w, h );
737 void WebEngine::SetSize( int width, int height )
741 bool WebEngine::SendTouchEvent( const TouchEvent& touch )
746 bool WebEngine::SendKeyEvent( const KeyEvent& event )
751 void WebEngine::SetFocus( bool focused )
755 Dali::WebEnginePlugin::WebEnginePageLoadSignalType& WebEngine::PageLoadStartedSignal()
757 return Internal::Adaptor::GetImplementation( *this ).PageLoadStartedSignal();
760 Dali::WebEnginePlugin::WebEnginePageLoadSignalType& WebEngine::PageLoadFinishedSignal()
762 return Internal::Adaptor::GetImplementation( *this ).PageLoadFinishedSignal();
765 Dali::WebEnginePlugin::WebEnginePageLoadErrorSignalType& WebEngine::PageLoadErrorSignal()
767 return Internal::Adaptor::GetImplementation( *this ).PageLoadErrorSignal();
770 Dali::WebEnginePlugin::WebEngineScrollEdgeReachedSignalType& WebEngine::ScrollEdgeReachedSignal()
772 return Internal::Adaptor::GetImplementation( *this ).ScrollEdgeReachedSignal();