[Tizen] Fix crash issue when favicon is null.
[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/adaptor-framework/web-engine-back-forward-list.h>
24 #include <dali/devel-api/adaptor-framework/web-engine-context.h>
25 #include <dali/devel-api/adaptor-framework/web-engine-cookie-manager.h>
26 #include <dali/devel-api/adaptor-framework/web-engine-settings.h>
27 #include <dali/devel-api/scripting/enum-helper.h>
28 #include <dali/devel-api/scripting/scripting.h>
29 #include <dali/devel-api/common/stage.h>
30 #include <dali/public-api/adaptor-framework/native-image-source.h>
31 #include <dali/public-api/object/type-registry.h>
32 #include <dali/public-api/object/type-registry-helper.h>
33
34 // INTERNAL INCLUDES
35 #include <dali-toolkit/devel-api/controls/control-devel.h>
36 #include <dali-toolkit/devel-api/controls/web-view/web-back-forward-list.h>
37 #include <dali-toolkit/devel-api/controls/web-view/web-context.h>
38 #include <dali-toolkit/devel-api/controls/web-view/web-cookie-manager.h>
39 #include <dali-toolkit/devel-api/controls/web-view/web-settings.h>
40 #include <dali-toolkit/devel-api/image-loader/texture-manager.h>
41 #include <dali-toolkit/internal/visuals/visual-factory-impl.h>
42 #include <dali-toolkit/public-api/image-loader/image.h>
43 #include <dali-toolkit/public-api/visuals/image-visual-properties.h>
44
45 namespace Dali
46 {
47
48 namespace Toolkit
49 {
50
51 namespace Internal
52 {
53
54 namespace
55 {
56
57 BaseHandle Create()
58 {
59   return Toolkit::WebView::New();
60 }
61
62 DALI_TYPE_REGISTRATION_BEGIN( Toolkit::WebView, Toolkit::Control, Create )
63
64 DALI_PROPERTY_REGISTRATION( Toolkit, WebView, "url",                     STRING,  URL                        )
65 DALI_PROPERTY_REGISTRATION( Toolkit, WebView, "userAgent",               STRING,  USER_AGENT                 )
66 DALI_PROPERTY_REGISTRATION( Toolkit, WebView, "scrollPosition",          VECTOR2, SCROLL_POSITION            )
67 DALI_PROPERTY_REGISTRATION( Toolkit, WebView, "scrollSize",              VECTOR2, SCROLL_SIZE                )
68 DALI_PROPERTY_REGISTRATION( Toolkit, WebView, "contentSize",             VECTOR2, CONTENT_SIZE               )
69 DALI_PROPERTY_REGISTRATION( Toolkit, WebView, "title",                   STRING,  TITLE                      )
70 DALI_PROPERTY_REGISTRATION( Toolkit, WebView, "videoHoleEnabled",        BOOLEAN, VIDEO_HOLE_ENABLED         )
71
72 DALI_SIGNAL_REGISTRATION(   Toolkit, WebView, "pageLoadStarted",         PAGE_LOAD_STARTED_SIGNAL            )
73 DALI_SIGNAL_REGISTRATION(   Toolkit, WebView, "pageLoadFinished",        PAGE_LOAD_FINISHED_SIGNAL           )
74 DALI_SIGNAL_REGISTRATION(   Toolkit, WebView, "pageLoadError",           PAGE_LOAD_ERROR_SIGNAL              )
75 DALI_SIGNAL_REGISTRATION(   Toolkit, WebView, "scrollEdgeReached",       SCROLL_EDGE_REACHED_SIGNAL          )
76
77 DALI_TYPE_REGISTRATION_END()
78
79 const std::string kEmptyString;
80
81 const char* DEFAULT_SAMPLER_TYPENAME = "sampler2D";
82
83 const char* FRAGMENT_SHADER_TEXTURE = DALI_COMPOSE_SHADER(
84   varying mediump vec2 vTexCoord;\n
85   uniform sampler2D sTexture;\n
86   uniform lowp vec4 uColor;\n
87   uniform lowp vec3 mixColor;\n
88   uniform lowp float preMultipliedAlpha;\n
89   \n
90   void main()\n
91   {\n
92       gl_FragColor = texture2D( sTexture, vTexCoord ) * uColor * vec4( mixColor, 1.0 );\n
93   }\n
94 );
95
96 Dali::Toolkit::Visual::Base CreateNativeImageVisual( NativeImageInterfacePtr nativeImageInterface )
97 {
98   std::string fragmentShader;
99
100   const char* fragmentPrefix = nativeImageInterface->GetCustomFragmentPrefix();
101   if( fragmentPrefix )
102   {
103     fragmentShader = fragmentPrefix;
104     fragmentShader += FRAGMENT_SHADER_TEXTURE;
105   }
106   else
107   {
108     fragmentShader = FRAGMENT_SHADER_TEXTURE;
109   }
110
111   const char* customSamplerTypename = nativeImageInterface->GetCustomSamplerTypename();
112   if( customSamplerTypename )
113   {
114     fragmentShader.replace( fragmentShader.find( DEFAULT_SAMPLER_TYPENAME ), strlen( DEFAULT_SAMPLER_TYPENAME ), customSamplerTypename );
115   }
116
117   Texture texture = Dali::Texture::New( *nativeImageInterface );
118   const std::string nativeImageUrl = Dali::Toolkit::TextureManager::AddTexture( texture );
119
120   return Toolkit::VisualFactory::Get().CreateVisual(
121     { { Toolkit::Visual::Property::TYPE,  Toolkit::Visual::IMAGE } ,
122       { Toolkit::Visual::Property::SHADER, { { Toolkit::Visual::Shader::Property::FRAGMENT_SHADER, fragmentShader } } },
123       { Toolkit::ImageVisual::Property::URL, nativeImageUrl } } );
124 }
125
126 } // anonymous namepsace
127
128 #define GET_ENUM_STRING( structName, inputExp ) \
129   Scripting::GetLinearEnumerationName< Toolkit::WebView::structName::Type >( static_cast< Toolkit::WebView::structName::Type >( inputExp ), structName##_TABLE, structName##_TABLE_COUNT )
130
131 #define GET_ENUM_VALUE( structName, inputExp, outputExp ) \
132   Scripting::GetEnumerationProperty< Toolkit::WebView::structName::Type >( inputExp, structName##_TABLE, structName##_TABLE_COUNT, outputExp )
133
134 WebView::WebView( const std::string& locale, const std::string& timezoneId )
135 : Control( ControlBehaviour( ACTOR_BEHAVIOUR_DEFAULT | DISABLE_STYLE_CHANGE_SIGNALS ) ),
136   mUrl(),
137   mVisual(),
138   mWebViewSize( Stage::GetCurrent().GetSize() ),
139   mWebEngine(),
140   mPageLoadStartedSignal(),
141   mPageLoadFinishedSignal(),
142   mPageLoadErrorSignal(),
143   mVideoHoleEnabled( true ),
144   mWebViewArea ( 0, 0, mWebViewSize.width, mWebViewSize.height )
145 {
146   mWebEngine = Dali::WebEngine::New();
147
148   // WebEngine is empty when it is not properly initialized.
149   if( mWebEngine )
150   {
151     mWebEngine.Create( mWebViewSize.width, mWebViewSize.height, locale, timezoneId );
152   }
153 }
154
155 WebView::WebView( int argc, char** argv )
156 : Control( ControlBehaviour( ACTOR_BEHAVIOUR_DEFAULT | DISABLE_STYLE_CHANGE_SIGNALS ) ),
157   mUrl(),
158   mVisual(),
159   mWebViewSize( Stage::GetCurrent().GetSize() ),
160   mWebEngine(),
161   mPageLoadStartedSignal(),
162   mPageLoadFinishedSignal(),
163   mPageLoadErrorSignal(),
164   mVideoHoleEnabled( true ),
165   mWebViewArea ( 0, 0, mWebViewSize.width, mWebViewSize.height )
166 {
167   mWebEngine = Dali::WebEngine::New();
168
169   // WebEngine is empty when it is not properly initialized.
170   if ( mWebEngine )
171   {
172     mWebEngine.Create( mWebViewSize.width, mWebViewSize.height, argc, argv );
173   }
174 }
175
176 WebView::WebView()
177 : WebView( "", "" )
178 {
179 }
180
181 WebView::~WebView()
182 {
183   if( mWebEngine )
184   {
185     mWebEngine.Destroy();
186   }
187 }
188
189 Toolkit::WebView WebView::New()
190 {
191   WebView* impl = new WebView();
192   Toolkit::WebView handle = Toolkit::WebView( *impl );
193
194   impl->Initialize();
195   return handle;
196 }
197
198 Toolkit::WebView WebView::New( const std::string& locale, const std::string& timezoneId )
199 {
200   WebView* impl = new WebView( locale, timezoneId );
201   Toolkit::WebView handle = Toolkit::WebView( *impl );
202
203   impl->Initialize();
204   return handle;
205 }
206
207 Toolkit::WebView WebView::New( int argc, char** argv )
208 {
209   WebView* impl = new WebView( argc, argv );
210   Toolkit::WebView handle = Toolkit::WebView( *impl );
211
212   impl->Initialize();
213   return handle;
214 }
215
216 void WebView::OnInitialize()
217 {
218   Actor self = Self();
219
220   self.SetProperty( Actor::Property::KEYBOARD_FOCUSABLE, true );
221   self.TouchedSignal().Connect( this, &WebView::OnTouchEvent );
222
223   mPositionUpdateNotification = self.AddPropertyNotification( Actor::Property::WORLD_POSITION, StepCondition( 1.0f, 1.0f ) );
224   mSizeUpdateNotification = self.AddPropertyNotification( Actor::Property::SIZE, StepCondition( 1.0f, 1.0f ) );
225   mScaleUpdateNotification = self.AddPropertyNotification( Actor::Property::WORLD_SCALE, StepCondition( 0.1f, 1.0f ) );
226   mPositionUpdateNotification.NotifySignal().Connect( this, &WebView::UpdateDisplayArea );
227   mSizeUpdateNotification.NotifySignal().Connect( this, &WebView::UpdateDisplayArea );
228   mScaleUpdateNotification.NotifySignal().Connect( this, &WebView::UpdateDisplayArea );
229
230   if( mWebEngine )
231   {
232     mWebEngine.PageLoadStartedSignal().Connect( this, &WebView::OnPageLoadStarted );
233     mWebEngine.PageLoadFinishedSignal().Connect( this, &WebView::OnPageLoadFinished );
234     mWebEngine.PageLoadErrorSignal().Connect( this, &WebView::OnPageLoadError );
235     mWebEngine.ScrollEdgeReachedSignal().Connect( this, &WebView::OnScrollEdgeReached );
236
237     mWebContext = std::unique_ptr<Dali::Toolkit::WebContext>( new WebContext( mWebEngine.GetContext() ) );
238     mWebCookieManager = std::unique_ptr<Dali::Toolkit::WebCookieManager>( new WebCookieManager( mWebEngine.GetCookieManager() ) );
239     mWebSettings = std::unique_ptr<Dali::Toolkit::WebSettings>( new WebSettings( mWebEngine.GetSettings() ) );
240     mWebBackForwardList = std::unique_ptr<Dali::Toolkit::WebBackForwardList>( new WebBackForwardList( mWebEngine.GetBackForwardList() ) );
241   }
242 }
243
244 Dali::Toolkit::WebSettings* WebView::GetSettings() const
245 {
246   return mWebSettings.get();
247 }
248
249 Dali::Toolkit::WebContext* WebView::GetContext() const
250 {
251   return mWebContext.get();
252 }
253
254 Dali::Toolkit::WebCookieManager* WebView::GetCookieManager() const
255 {
256   return mWebCookieManager.get();
257 }
258
259 Dali::Toolkit::WebBackForwardList* WebView::GetBackForwardList() const
260 {
261   return mWebBackForwardList.get();
262 }
263
264 Dali::Toolkit::ImageView WebView::GetFavicon() const
265 {
266   Dali::Toolkit::ImageView faviconView;
267   if(mWebEngine)
268   {
269     Dali::PixelData pixelData = mWebEngine.GetFavicon();
270     if(pixelData)
271     {
272       std::string url = Dali::Toolkit::Image::GenerateUrl(pixelData);
273       faviconView     = Dali::Toolkit::ImageView::New(url);
274       faviconView.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS);
275     }
276   }
277   return faviconView;
278 }
279
280 void WebView::LoadUrl( const std::string& url )
281 {
282   mUrl = url;
283   if( mWebEngine )
284   {
285     mVisual = CreateNativeImageVisual( mWebEngine.GetNativeImageSource() );
286
287     if( mVisual )
288     {
289       // Clean up previously registered visual and add new one.
290       DevelControl::RegisterVisual( *this, Toolkit::WebView::Property::URL, mVisual );
291       mWebEngine.LoadUrl( url );
292     }
293
294     if ( mVideoHoleEnabled )
295     {
296       EnableBlendMode( false );
297     }
298   }
299 }
300
301 void WebView::LoadHtmlString( const std::string& htmlString )
302 {
303   if( mWebEngine )
304   {
305     mVisual = CreateNativeImageVisual( mWebEngine.GetNativeImageSource() );
306
307     if( mVisual )
308     {
309       DevelControl::RegisterVisual( *this, Toolkit::WebView::Property::URL, mVisual );
310       mWebEngine.LoadHtmlString( htmlString );
311     }
312
313     if ( mVideoHoleEnabled )
314     {
315       EnableBlendMode( false );
316     }
317   }
318 }
319
320 void WebView::Reload()
321 {
322   if( mWebEngine )
323   {
324     mWebEngine.Reload();
325   }
326 }
327
328 void WebView::StopLoading()
329 {
330   if( mWebEngine )
331   {
332     mWebEngine.StopLoading();
333   }
334 }
335
336 void WebView::Suspend()
337 {
338   if( mWebEngine )
339   {
340     mWebEngine.Suspend();
341   }
342 }
343
344 void WebView::Resume()
345 {
346   if( mWebEngine )
347   {
348     mWebEngine.Resume();
349   }
350 }
351
352 void WebView::ScrollBy( int deltaX, int deltaY )
353 {
354   if ( mWebEngine )
355   {
356     mWebEngine.ScrollBy( deltaX, deltaY );
357   }
358 }
359
360 bool WebView::CanGoForward()
361 {
362   return mWebEngine ? mWebEngine.CanGoForward() : false;
363 }
364
365 void WebView::GoForward()
366 {
367   if( mWebEngine )
368   {
369     mWebEngine.GoForward();
370   }
371 }
372
373 bool WebView::CanGoBack()
374 {
375   return mWebEngine ? mWebEngine.CanGoBack() : false;
376 }
377
378 void WebView::GoBack()
379 {
380   if( mWebEngine )
381   {
382     mWebEngine.GoBack();
383   }
384 }
385
386 void WebView::EvaluateJavaScript( const std::string& script, std::function< void( const std::string& ) > resultHandler )
387 {
388   if( mWebEngine )
389   {
390     mWebEngine.EvaluateJavaScript( script, resultHandler );
391   }
392 }
393
394 void WebView::AddJavaScriptMessageHandler( const std::string& exposedObjectName, std::function< void( const std::string& ) > handler )
395 {
396   if( mWebEngine )
397   {
398     mWebEngine.AddJavaScriptMessageHandler( exposedObjectName, handler );
399   }
400 }
401
402 void WebView::ClearAllTilesResources()
403 {
404   if( mWebEngine )
405   {
406     mWebEngine.ClearAllTilesResources();
407   }
408 }
409
410 void WebView::ClearHistory()
411 {
412   if( mWebEngine )
413   {
414     mWebEngine.ClearHistory();
415   }
416 }
417
418 void WebView::UpdateDisplayArea( Dali::PropertyNotification& /*source*/ )
419 {
420   if( !mWebEngine )
421     return;
422
423   Actor self( Self() );
424
425   bool positionUsesAnchorPoint = self.GetProperty< bool >( Actor::Property::POSITION_USES_ANCHOR_POINT );
426   Vector3 actorSize = self.GetCurrentProperty< Vector3 >( Actor::Property::SIZE ) * self.GetCurrentProperty< Vector3 >( Actor::Property::SCALE );
427   Vector3 anchorPointOffSet = actorSize * ( positionUsesAnchorPoint ? self.GetCurrentProperty< Vector3 >( Actor::Property::ANCHOR_POINT ) : AnchorPoint::TOP_LEFT );
428   Vector2 screenPosition = self.GetProperty< Vector2 >( Actor::Property::SCREEN_POSITION );
429
430   Dali::Rect< int > displayArea;
431   displayArea.x = screenPosition.x - anchorPointOffSet.x;
432   displayArea.y = screenPosition.y - anchorPointOffSet.y;
433   displayArea.width = actorSize.x;
434   displayArea.height = actorSize.y;
435
436   Size displaySize = Size( displayArea.width, displayArea.height );
437   if ( mWebViewSize != displaySize )
438   {
439     mWebViewSize = displaySize;
440   }
441
442   if (mWebViewArea != displayArea )
443   {
444     mWebViewArea = displayArea;
445     mWebEngine.UpdateDisplayArea( mWebViewArea );
446   }
447 }
448
449 void WebView::EnableVideoHole( bool enabled )
450 {
451   mVideoHoleEnabled = enabled;
452
453   EnableBlendMode( !mVideoHoleEnabled );
454
455   if( mWebEngine )
456   {
457     mWebEngine.EnableVideoHole( mVideoHoleEnabled );
458   }
459 }
460
461 void WebView::EnableBlendMode( bool blendEnabled )
462 {
463   Actor self = Self();
464   for (uint32_t i = 0; i < self.GetRendererCount(); i++)
465   {
466     Dali::Renderer render = self.GetRendererAt( i );
467     render.SetProperty( Renderer::Property::BLEND_MODE, blendEnabled ? BlendMode::ON : BlendMode::OFF );
468   }
469 }
470
471 Dali::Toolkit::WebView::WebViewPageLoadSignalType& WebView::PageLoadStartedSignal()
472 {
473   return mPageLoadStartedSignal;
474 }
475
476 Dali::Toolkit::WebView::WebViewPageLoadSignalType& WebView::PageLoadFinishedSignal()
477 {
478   return mPageLoadFinishedSignal;
479 }
480
481 Dali::Toolkit::WebView::WebViewPageLoadErrorSignalType& WebView::PageLoadErrorSignal()
482 {
483   return mPageLoadErrorSignal;
484 }
485
486 Dali::Toolkit::WebView::WebViewScrollEdgeReachedSignalType& WebView::ScrollEdgeReachedSignal()
487 {
488   return mScrollEdgeReachedSignal;
489 }
490
491 void WebView::OnPageLoadStarted( const std::string& url )
492 {
493   if( !mPageLoadStartedSignal.Empty() )
494   {
495     Dali::Toolkit::WebView handle( GetOwner() );
496     mPageLoadStartedSignal.Emit( handle, url );
497   }
498 }
499
500 void WebView::OnPageLoadFinished( const std::string& url )
501 {
502   if( !mPageLoadFinishedSignal.Empty() )
503   {
504     Dali::Toolkit::WebView handle( GetOwner() );
505     mPageLoadFinishedSignal.Emit( handle, url );
506   }
507 }
508
509 void WebView::OnPageLoadError( const std::string& url, int errorCode )
510 {
511   if( !mPageLoadErrorSignal.Empty() )
512   {
513     Dali::Toolkit::WebView handle( GetOwner() );
514     mPageLoadErrorSignal.Emit( handle, url, static_cast< Toolkit::WebView::LoadErrorCode >( errorCode ) );
515   }
516 }
517
518 void WebView::OnScrollEdgeReached( Dali::WebEnginePlugin::ScrollEdge edge )
519 {
520   if( !mScrollEdgeReachedSignal.Empty() )
521   {
522     Dali::Toolkit::WebView handle( GetOwner() );
523     mScrollEdgeReachedSignal.Emit( handle, edge );
524   }
525 }
526
527 bool WebView::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
528 {
529   Dali::BaseHandle handle( object );
530
531   bool connected = false;
532   Toolkit::WebView webView = Toolkit::WebView::DownCast( handle );
533
534   if( 0 == strcmp( signalName.c_str(), PAGE_LOAD_STARTED_SIGNAL ) )
535   {
536     webView.PageLoadStartedSignal().Connect( tracker, functor );
537     connected = true;
538   }
539   else if( 0 == strcmp( signalName.c_str(), PAGE_LOAD_FINISHED_SIGNAL ) )
540   {
541     webView.PageLoadFinishedSignal().Connect( tracker, functor );
542     connected = true;
543   }
544   else if( 0 == strcmp( signalName.c_str(), PAGE_LOAD_ERROR_SIGNAL ) )
545   {
546     webView.PageLoadErrorSignal().Connect( tracker, functor );
547     connected = true;
548   }
549   else if( 0 == strcmp( signalName.c_str(), SCROLL_EDGE_REACHED_SIGNAL ) )
550   {
551     webView.ScrollEdgeReachedSignal().Connect( tracker, functor );
552     connected = true;
553   }
554
555   return connected;
556 }
557
558 Vector3 WebView::GetNaturalSize()
559 {
560   if( mVisual )
561   {
562     Vector2 rendererNaturalSize;
563     mVisual.GetNaturalSize( rendererNaturalSize );
564     return Vector3( rendererNaturalSize );
565   }
566
567   return Vector3( mWebViewSize );
568 }
569
570 void WebView::OnSceneConnection( int depth )
571 {
572   Control::OnSceneConnection( depth );
573
574   EnableBlendMode( !mVideoHoleEnabled );
575 }
576
577 void WebView::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
578 {
579   Toolkit::WebView webView = Toolkit::WebView::DownCast( Dali::BaseHandle( object ) );
580
581   if( webView )
582   {
583     WebView& impl = GetImpl( webView );
584     switch( index )
585     {
586       case Toolkit::WebView::Property::URL:
587       {
588         std::string url;
589         if( value.Get( url ) )
590         {
591           impl.LoadUrl( url );
592         }
593         break;
594       }
595       case Toolkit::WebView::Property::USER_AGENT:
596       {
597         std::string input;
598         if( value.Get( input ) )
599         {
600           impl.SetUserAgent( input );
601         }
602         break;
603       }
604       case Toolkit::WebView::Property::SCROLL_POSITION:
605       {
606         Vector2 input;
607         if ( value.Get( input ) )
608         {
609           impl.SetScrollPosition( input.x, input.y );
610         }
611         break;
612       }
613       case Toolkit::WebView::Property::VIDEO_HOLE_ENABLED:
614       {
615         bool input;
616         if( value.Get( input ) )
617         {
618           impl.EnableVideoHole( input );
619         }
620         break;
621       }
622     }
623   }
624 }
625
626 Property::Value WebView::GetProperty( BaseObject* object, Property::Index propertyIndex )
627 {
628   Property::Value value;
629
630   Toolkit::WebView webView = Toolkit::WebView::DownCast( Dali::BaseHandle( object ) );
631
632   if( webView )
633   {
634     WebView& impl = GetImpl( webView );
635     switch( propertyIndex )
636     {
637       case Toolkit::WebView::Property::URL:
638       {
639         value = impl.mUrl;
640         break;
641       }
642       case Toolkit::WebView::Property::USER_AGENT:
643       {
644         value = impl.GetUserAgent();
645         break;
646       }
647       case Toolkit::WebView::Property::SCROLL_POSITION:
648       {
649         int x, y;
650         impl.GetScrollPosition( x, y );
651         value = Vector2( x, y );
652         break;
653       }
654       case Toolkit::WebView::Property::SCROLL_SIZE:
655       {
656         int width, height;
657         impl.GetScrollSize( width, height );
658         value = Vector2( width, height );
659         break;
660       }
661       case Toolkit::WebView::Property::CONTENT_SIZE:
662       {
663         int width, height;
664         impl.GetContentSize( width, height );
665         value = Vector2( width, height );
666         break;
667       }
668       case Toolkit::WebView::Property::TITLE:
669       {
670         value = impl.GetTitle();
671         break;
672       }
673       case Toolkit::WebView::Property::VIDEO_HOLE_ENABLED:
674       {
675         value = impl.mVideoHoleEnabled;
676         break;
677       }
678       default:
679          break;
680     }
681   }
682
683   return value;
684 }
685
686 bool WebView::OnTouchEvent( Actor actor, const Dali::TouchEvent& touch )
687 {
688   bool result = false;
689
690   if( mWebEngine )
691   {
692     result = mWebEngine.SendTouchEvent( touch );
693   }
694   return result;
695 }
696
697 bool WebView::OnKeyEvent( const Dali::KeyEvent& event )
698 {
699   bool result = false;
700
701   if( mWebEngine )
702   {
703     result = mWebEngine.SendKeyEvent( event );
704   }
705   return result;
706 }
707
708 void WebView::OnKeyInputFocusGained()
709 {
710   if( mWebEngine )
711   {
712     mWebEngine.SetFocus( true );
713   }
714
715   EmitKeyInputFocusSignal( true ); // Calls back into the Control hence done last.
716 }
717
718 void WebView::OnKeyInputFocusLost()
719 {
720   if( mWebEngine )
721   {
722     mWebEngine.SetFocus( false );
723   }
724
725   EmitKeyInputFocusSignal( false ); // Calls back into the Control hence done last.
726 }
727
728 void WebView::SetScrollPosition( int x, int y )
729 {
730   if( mWebEngine )
731   {
732     mWebEngine.SetScrollPosition( x, y );
733   }
734 }
735
736 void WebView::GetScrollPosition( int& x, int& y ) const
737 {
738   if( mWebEngine )
739   {
740     mWebEngine.GetScrollPosition( x, y );
741   }
742 }
743
744 void WebView::GetScrollSize( int& width, int& height ) const
745 {
746   if( mWebEngine )
747   {
748     mWebEngine.GetScrollSize( width, height );
749   }
750 }
751
752 void WebView::GetContentSize( int& width, int& height ) const
753 {
754   if( mWebEngine )
755   {
756     mWebEngine.GetContentSize( width, height );
757   }
758 }
759
760 std::string WebView::GetTitle() const
761 {
762   return mWebEngine ?  mWebEngine.GetTitle() : kEmptyString;
763 }
764
765 const std::string& WebView::GetUserAgent() const
766 {
767   return mWebEngine ? mWebEngine.GetUserAgent() : kEmptyString;
768 }
769
770 void WebView::SetUserAgent( const std::string& userAgent )
771 {
772   if( mWebEngine )
773   {
774     mWebEngine.SetUserAgent( userAgent );
775   }
776 }
777
778 #undef GET_ENUM_STRING
779 #undef GET_ENUM_VALUE
780
781 } // namespace Internal
782
783 } // namespace Toolkit
784
785 } // namespace Dali