42139f8bdee312fb69a410986b53d54708f38c95
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / web-view / web-view-impl.cpp
1 /*
2  * Copyright (c) 2020 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  *
16  */
17
18 // CLASS HEADER
19 #include "web-view-impl.h"
20
21 // EXTERNAL INCLUDES
22 #include <cstring>
23 #include <dali/devel-api/scripting/enum-helper.h>
24 #include <dali/devel-api/scripting/scripting.h>
25 #include <dali/public-api/common/stage.h>
26 #include <dali/public-api/images/native-image.h>
27 #include <dali/public-api/adaptor-framework/native-image-source.h>
28 #include <dali/public-api/object/type-registry.h>
29 #include <dali/public-api/object/type-registry-helper.h>
30
31 // INTERNAL INCLUDES
32 #include <dali-toolkit/devel-api/controls/control-devel.h>
33 #include <dali-toolkit/devel-api/image-loader/texture-manager.h>
34 #include <dali-toolkit/internal/visuals/visual-factory-impl.h>
35
36 namespace Dali
37 {
38
39 namespace Toolkit
40 {
41
42 namespace Internal
43 {
44
45 namespace
46 {
47
48 BaseHandle Create()
49 {
50   return Toolkit::WebView::New();
51 }
52
53 DALI_ENUM_TO_STRING_TABLE_BEGIN( CacheModel )
54 DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::WebView::CacheModel, DOCUMENT_VIEWER )
55 DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::WebView::CacheModel, DOCUMENT_BROWSER )
56 DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::WebView::CacheModel, PRIMARY_WEB_BROWSER )
57 DALI_ENUM_TO_STRING_TABLE_END( CacheModel )
58
59 DALI_ENUM_TO_STRING_TABLE_BEGIN( CookieAcceptPolicy )
60 DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::WebView::CookieAcceptPolicy, ALWAYS )
61 DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::WebView::CookieAcceptPolicy, NEVER )
62 DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::WebView::CookieAcceptPolicy, NO_THIRD_PARTY )
63 DALI_ENUM_TO_STRING_TABLE_END( CookieAcceptPolicy )
64
65 DALI_TYPE_REGISTRATION_BEGIN( Toolkit::WebView, Toolkit::Control, Create )
66
67 DALI_PROPERTY_REGISTRATION( Toolkit, WebView, "url",                     STRING,  URL                        )
68 DALI_PROPERTY_REGISTRATION( Toolkit, WebView, "cacheModel",              STRING,  CACHE_MODEL                )
69 DALI_PROPERTY_REGISTRATION( Toolkit, WebView, "cookieAcceptPolicy",      STRING,  COOKIE_ACCEPT_POLICY       )
70 DALI_PROPERTY_REGISTRATION( Toolkit, WebView, "userAgent",               STRING,  USER_AGENT                 )
71 DALI_PROPERTY_REGISTRATION( Toolkit, WebView, "enableJavaScript",        BOOLEAN, ENABLE_JAVASCRIPT          )
72 DALI_PROPERTY_REGISTRATION( Toolkit, WebView, "loadImagesAutomatically", BOOLEAN, LOAD_IMAGES_AUTOMATICALLY  )
73 DALI_PROPERTY_REGISTRATION( Toolkit, WebView, "defaultTextEncodingName", STRING,  DEFAULT_TEXT_ENCODING_NAME )
74 DALI_PROPERTY_REGISTRATION( Toolkit, WebView, "defaultFontSize",         INTEGER, DEFAULT_FONT_SIZE          )
75
76 DALI_SIGNAL_REGISTRATION(   Toolkit, WebView, "pageLoadStarted",         PAGE_LOAD_STARTED_SIGNAL            )
77 DALI_SIGNAL_REGISTRATION(   Toolkit, WebView, "pageLoadFinished",        PAGE_LOAD_FINISHED_SIGNAL           )
78 DALI_SIGNAL_REGISTRATION(   Toolkit, WebView, "pageLoadError",           PAGE_LOAD_ERROR_SIGNAL              )
79
80 DALI_TYPE_REGISTRATION_END()
81
82 const std::string kEmptyString;
83
84 } // anonymous namepsace
85
86 #define GET_ENUM_STRING( structName, inputExp ) \
87   Scripting::GetLinearEnumerationName< Toolkit::WebView::structName::Type >( static_cast< Toolkit::WebView::structName::Type >( inputExp ), structName##_TABLE, structName##_TABLE_COUNT )
88
89 #define GET_ENUM_VALUE( structName, inputExp, outputExp ) \
90   Scripting::GetEnumerationProperty< Toolkit::WebView::structName::Type >( inputExp, structName##_TABLE, structName##_TABLE_COUNT, outputExp )
91
92 WebView::WebView( const std::string& locale, const std::string& timezoneId )
93 : Control( ControlBehaviour( ACTOR_BEHAVIOUR_DEFAULT | DISABLE_STYLE_CHANGE_SIGNALS ) ),
94   mUrl(),
95   mVisual(),
96   mWebViewSize( Stage::GetCurrent().GetSize() ),
97   mWebEngine(),
98   mPageLoadStartedSignal(),
99   mPageLoadFinishedSignal(),
100   mPageLoadErrorSignal()
101 {
102   mWebEngine = Dali::WebEngine::New();
103
104   // WebEngine is empty when it is not properly initialized.
105   if( mWebEngine )
106   {
107     mWebEngine.Create( mWebViewSize.width, mWebViewSize.height, locale, timezoneId );
108   }
109 }
110
111 WebView::WebView()
112 : WebView( "", "" )
113 {
114 }
115
116 WebView::~WebView()
117 {
118 }
119
120 Toolkit::WebView WebView::New()
121 {
122   WebView* impl = new WebView();
123   Toolkit::WebView handle = Toolkit::WebView( *impl );
124
125   impl->Initialize();
126   return handle;
127 }
128
129 Toolkit::WebView WebView::New( const std::string& locale, const std::string& timezoneId )
130 {
131   WebView* impl = new WebView( locale, timezoneId );
132   Toolkit::WebView handle = Toolkit::WebView( *impl );
133
134   impl->Initialize();
135   return handle;
136 }
137
138 void WebView::OnInitialize()
139 {
140   Self().SetKeyboardFocusable( true );
141   Self().TouchSignal().Connect( this, &WebView::OnTouchEvent );
142
143   if( mWebEngine )
144   {
145     mWebEngine.PageLoadStartedSignal().Connect( this, &WebView::OnPageLoadStarted );
146     mWebEngine.PageLoadFinishedSignal().Connect( this, &WebView::OnPageLoadFinished );
147     mWebEngine.PageLoadErrorSignal().Connect( this, &WebView::OnPageLoadError );
148   }
149 }
150
151 void WebView::LoadUrl( const std::string& url )
152 {
153   mUrl = url;
154   if( mWebEngine )
155   {
156     Texture texture = Dali::Texture::New( *mWebEngine.GetNativeImageSource() );
157         const std::string nativeImageUrl = Dali::Toolkit::TextureManager::AddTexture( texture );
158     mVisual = Toolkit::VisualFactory::Get().CreateVisual(
159       { { Toolkit::Visual::Property::TYPE,  Toolkit::Visual::IMAGE } ,
160         { Toolkit::ImageVisual::Property::URL, nativeImageUrl } } );
161
162     if( mVisual )
163     {
164       // Clean up previously registered visual and add new one.
165       DevelControl::RegisterVisual( *this, Toolkit::WebView::Property::URL, mVisual );
166       mWebEngine.LoadUrl( url );
167     }
168   }
169 }
170
171 void WebView::LoadHTMLString( const std::string& htmlString )
172 {
173   if( mWebEngine )
174   {
175     Texture texture = Dali::Texture::New( *mWebEngine.GetNativeImageSource() );
176     const std::string nativeImageUrl = Dali::Toolkit::TextureManager::AddTexture( texture );
177
178     mVisual = Toolkit::VisualFactory::Get().CreateVisual(
179       { { Toolkit::Visual::Property::TYPE,  Toolkit::Visual::IMAGE } ,
180         { Toolkit::ImageVisual::Property::URL, nativeImageUrl } } );
181
182     if( mVisual )
183     {
184       DevelControl::RegisterVisual( *this, Toolkit::WebView::Property::URL, mVisual );
185       mWebEngine.LoadHTMLString( htmlString );
186     }
187   }
188 }
189
190 void WebView::Reload()
191 {
192   if( mWebEngine )
193   {
194     mWebEngine.Reload();
195   }
196 }
197
198 void WebView::StopLoading()
199 {
200   if( mWebEngine )
201   {
202     mWebEngine.StopLoading();
203   }
204 }
205
206 void WebView::Suspend()
207 {
208   if( mWebEngine )
209   {
210     mWebEngine.Suspend();
211   }
212 }
213
214 void WebView::Resume()
215 {
216   if( mWebEngine )
217   {
218     mWebEngine.Resume();
219   }
220 }
221
222 bool WebView::CanGoForward()
223 {
224   return mWebEngine ? mWebEngine.CanGoForward() : false;
225 }
226
227 void WebView::GoForward()
228 {
229   if( mWebEngine )
230   {
231     mWebEngine.GoForward();
232   }
233 }
234
235 bool WebView::CanGoBack()
236 {
237   return mWebEngine ? mWebEngine.CanGoBack() : false;
238 }
239
240 void WebView::GoBack()
241 {
242   if( mWebEngine )
243   {
244     mWebEngine.GoBack();
245   }
246 }
247
248 void WebView::EvaluateJavaScript( const std::string& script, std::function< void( const std::string& ) > resultHandler )
249 {
250   if( mWebEngine )
251   {
252     mWebEngine.EvaluateJavaScript( script, resultHandler );
253   }
254 }
255
256 void WebView::AddJavaScriptMessageHandler( const std::string& exposedObjectName, std::function< void( const std::string& ) > handler )
257 {
258   if( mWebEngine )
259   {
260     mWebEngine.AddJavaScriptMessageHandler( exposedObjectName, handler );
261   }
262 }
263
264 void WebView::ClearHistory()
265 {
266   if( mWebEngine )
267   {
268     mWebEngine.ClearHistory();
269   }
270 }
271
272 void WebView::ClearCache()
273 {
274   if( mWebEngine )
275   {
276     mWebEngine.ClearCache();
277   }
278 }
279
280 void WebView::ClearCookies()
281 {
282   if( mWebEngine )
283   {
284     mWebEngine.ClearCookies();
285   }
286 }
287
288 Dali::Toolkit::WebView::WebViewPageLoadSignalType& WebView::PageLoadStartedSignal()
289 {
290   return mPageLoadStartedSignal;
291 }
292
293 Dali::Toolkit::WebView::WebViewPageLoadSignalType& WebView::PageLoadFinishedSignal()
294 {
295   return mPageLoadFinishedSignal;
296 }
297
298 Dali::Toolkit::WebView::WebViewPageLoadErrorSignalType& WebView::PageLoadErrorSignal()
299 {
300   return mPageLoadErrorSignal;
301 }
302
303 void WebView::OnPageLoadStarted( const std::string& url )
304 {
305   if( !mPageLoadStartedSignal.Empty() )
306   {
307     Dali::Toolkit::WebView handle( GetOwner() );
308     mPageLoadStartedSignal.Emit( handle, url );
309   }
310 }
311
312 void WebView::OnPageLoadFinished( const std::string& url )
313 {
314   if( !mPageLoadFinishedSignal.Empty() )
315   {
316     Dali::Toolkit::WebView handle( GetOwner() );
317     mPageLoadFinishedSignal.Emit( handle, url );
318   }
319 }
320
321 void WebView::OnPageLoadError( const std::string& url, int errorCode )
322 {
323   if( !mPageLoadErrorSignal.Empty() )
324   {
325     Dali::Toolkit::WebView handle( GetOwner() );
326     mPageLoadErrorSignal.Emit( handle, url, static_cast< Toolkit::WebView::LoadErrorCode >( errorCode ) );
327   }
328 }
329
330 bool WebView::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
331 {
332   Dali::BaseHandle handle( object );
333
334   bool connected = false;
335   Toolkit::WebView webView = Toolkit::WebView::DownCast( handle );
336
337   if( 0 == strcmp( signalName.c_str(), PAGE_LOAD_STARTED_SIGNAL ) )
338   {
339     webView.PageLoadStartedSignal().Connect( tracker, functor );
340     connected = true;
341   }
342   else if( 0 == strcmp( signalName.c_str(), PAGE_LOAD_FINISHED_SIGNAL ) )
343   {
344     webView.PageLoadFinishedSignal().Connect( tracker, functor );
345     connected = true;
346   }
347   else if( 0 == strcmp( signalName.c_str(), PAGE_LOAD_ERROR_SIGNAL ) )
348   {
349     webView.PageLoadErrorSignal().Connect( tracker, functor );
350     connected = true;
351   }
352
353   return connected;
354 }
355
356 Vector3 WebView::GetNaturalSize()
357 {
358   if( mVisual )
359   {
360     Vector2 rendererNaturalSize;
361     mVisual.GetNaturalSize( rendererNaturalSize );
362     return Vector3( rendererNaturalSize );
363   }
364
365   return Vector3( mWebViewSize );
366 }
367
368 void WebView::OnRelayout( const Vector2& size, RelayoutContainer& container )
369 {
370   Control::OnRelayout( size, container );
371
372   if( size.width > 0 && size.height > 0 && mWebViewSize != size )
373   {
374     mWebViewSize = size;
375
376     if( mWebEngine )
377     {
378       mWebEngine.SetSize( size.width, size.height );
379     }
380   }
381 }
382
383 void WebView::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
384 {
385   Toolkit::WebView webView = Toolkit::WebView::DownCast( Dali::BaseHandle( object ) );
386
387   if( webView )
388   {
389     WebView& impl = GetImpl( webView );
390     switch( index )
391     {
392       case Toolkit::WebView::Property::URL:
393       {
394         std::string url;
395         if( value.Get( url ) )
396         {
397           impl.LoadUrl( url );
398         }
399         break;
400       }
401       case Toolkit::WebView::Property::CACHE_MODEL:
402       {
403         Toolkit::WebView::CacheModel::Type output = impl.GetCacheModel();
404         GET_ENUM_VALUE( CacheModel, value, output );
405         impl.SetCacheModel( output );
406         break;
407       }
408       case Toolkit::WebView::Property::COOKIE_ACCEPT_POLICY:
409       {
410         Toolkit::WebView::CookieAcceptPolicy::Type output = impl.GetCookieAcceptPolicy();
411         GET_ENUM_VALUE( CookieAcceptPolicy, value, output );
412         impl.SetCookieAcceptPolicy( output );
413         break;
414       }
415       case Toolkit::WebView::Property::USER_AGENT:
416       {
417         std::string input;
418         if( value.Get( input ) )
419         {
420           impl.SetUserAgent( input );
421         }
422         break;
423       }
424       case Toolkit::WebView::Property::ENABLE_JAVASCRIPT:
425       {
426         bool input;
427         if( value.Get( input ) )
428         {
429           impl.EnableJavaScript( input );
430         }
431         break;
432       }
433       case Toolkit::WebView::Property::LOAD_IMAGES_AUTOMATICALLY:
434       {
435         bool input;
436         if( value.Get( input ) )
437         {
438           impl.LoadImagesAutomatically( input );
439         }
440         break;
441       }
442       case Toolkit::WebView::Property::DEFAULT_TEXT_ENCODING_NAME:
443       {
444         std::string input;
445         if( value.Get( input ) )
446         {
447           impl.SetDefaultTextEncodingName( input );
448         }
449         break;
450       }
451       case Toolkit::WebView::Property::DEFAULT_FONT_SIZE:
452       {
453         int input;
454         if( value.Get( input ) )
455         {
456           impl.SetDefaultFontSize( input );
457         }
458         break;
459       }
460     }
461   }
462 }
463
464 Property::Value WebView::GetProperty( BaseObject* object, Property::Index propertyIndex )
465 {
466   Property::Value value;
467
468   Toolkit::WebView webView = Toolkit::WebView::DownCast( Dali::BaseHandle( object ) );
469
470   if( webView )
471   {
472     WebView& impl = GetImpl( webView );
473     switch( propertyIndex )
474     {
475       case Toolkit::WebView::Property::URL:
476       {
477         value = impl.mUrl;
478         break;
479       }
480       case Toolkit::WebView::Property::CACHE_MODEL:
481       {
482         value = GET_ENUM_STRING( CacheModel, impl.GetCacheModel() );
483         break;
484       }
485       case Toolkit::WebView::Property::COOKIE_ACCEPT_POLICY:
486       {
487         value = GET_ENUM_STRING( CookieAcceptPolicy, impl.GetCookieAcceptPolicy() );
488         break;
489       }
490       case Toolkit::WebView::Property::USER_AGENT:
491       {
492         value = impl.GetUserAgent();
493         break;
494       }
495       case Toolkit::WebView::Property::ENABLE_JAVASCRIPT:
496       {
497         value = impl.IsJavaScriptEnabled();
498         break;
499       }
500       case Toolkit::WebView::Property::LOAD_IMAGES_AUTOMATICALLY:
501       {
502         value = impl.AreImagesAutomaticallyLoaded();
503         break;
504       }
505       case Toolkit::WebView::Property::DEFAULT_TEXT_ENCODING_NAME:
506       {
507         value = impl.GetDefaultTextEncodingName();
508         break;
509       }
510       case Toolkit::WebView::Property::DEFAULT_FONT_SIZE:
511       {
512         value = impl.GetDefaultFontSize();
513         break;
514       }
515       default:
516          break;
517     }
518   }
519
520   return value;
521 }
522
523 bool WebView::OnTouchEvent( Actor actor, const Dali::TouchData& touch )
524 {
525   bool result = false;
526
527   if( mWebEngine )
528   {
529     result = mWebEngine.SendTouchEvent( touch );
530   }
531   return result;
532 }
533
534 bool WebView::OnKeyEvent( const Dali::KeyEvent& event )
535 {
536   bool result = false;
537
538   if( mWebEngine )
539   {
540     result = mWebEngine.SendKeyEvent( event );
541   }
542   return result;
543 }
544
545 Toolkit::WebView::CacheModel::Type WebView::GetCacheModel() const
546 {
547   return mWebEngine ? static_cast< Toolkit::WebView::CacheModel::Type >( mWebEngine.GetCacheModel() ) : Toolkit::WebView::CacheModel::DOCUMENT_VIEWER;
548 }
549
550 void WebView::SetCacheModel( Toolkit::WebView::CacheModel::Type cacheModel )
551 {
552   if( mWebEngine )
553   {
554     mWebEngine.SetCacheModel( static_cast< WebEnginePlugin::CacheModel >( cacheModel ) );
555   }
556 }
557
558 Toolkit::WebView::CookieAcceptPolicy::Type WebView::GetCookieAcceptPolicy() const
559 {
560   return mWebEngine ? static_cast< Toolkit::WebView::CookieAcceptPolicy::Type >( mWebEngine.GetCookieAcceptPolicy() ) : Toolkit::WebView::CookieAcceptPolicy::NO_THIRD_PARTY;
561 }
562
563 void WebView::SetCookieAcceptPolicy( Toolkit::WebView::CookieAcceptPolicy::Type policy )
564 {
565   if( mWebEngine )
566   {
567     mWebEngine.SetCookieAcceptPolicy( static_cast< WebEnginePlugin::CookieAcceptPolicy >( policy ) );
568   }
569 }
570
571 const std::string& WebView::GetUserAgent() const
572 {
573   return mWebEngine ? mWebEngine.GetUserAgent() : kEmptyString;
574 }
575
576 void WebView::SetUserAgent( const std::string& userAgent )
577 {
578   if( mWebEngine )
579   {
580     mWebEngine.SetUserAgent( userAgent );
581   }
582 }
583
584 bool WebView::IsJavaScriptEnabled() const
585 {
586   return mWebEngine ? mWebEngine.IsJavaScriptEnabled() : true;
587 }
588
589 void WebView::EnableJavaScript( bool enabled )
590 {
591   if( mWebEngine )
592   {
593     mWebEngine.EnableJavaScript( enabled );
594   }
595 }
596
597 bool WebView::AreImagesAutomaticallyLoaded() const
598 {
599   return mWebEngine ? mWebEngine.AreImagesAutomaticallyLoaded() : true;
600 }
601
602 void WebView::LoadImagesAutomatically( bool automatic )
603 {
604   if( mWebEngine )
605   {
606     mWebEngine.LoadImagesAutomatically( automatic );
607   }
608 }
609
610 const std::string& WebView::GetDefaultTextEncodingName() const
611 {
612   return mWebEngine ? mWebEngine.GetDefaultTextEncodingName() : kEmptyString;
613 }
614
615 void WebView::SetDefaultTextEncodingName( const std::string& defaultTextEncodingName )
616 {
617   if( mWebEngine )
618   {
619     mWebEngine.SetDefaultTextEncodingName( defaultTextEncodingName );
620   }
621 }
622
623 int WebView::GetDefaultFontSize() const
624 {
625   return mWebEngine ? mWebEngine.GetDefaultFontSize() : 0;
626 }
627
628 void WebView::SetDefaultFontSize( int defaultFontSize )
629 {
630   if( mWebEngine )
631   {
632     mWebEngine.SetDefaultFontSize( defaultFontSize );
633   }
634 }
635
636 #undef GET_ENUM_STRING
637 #undef GET_ENUM_VALUE
638
639 } // namespace Internal
640
641 } // namespace Toolkit
642
643 } // namespace Dali