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