[Tizen] Update position & size of web view.
[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()
265 {
266   if ( mWebEngine )
267   {
268     Dali::PixelData pixelData = mWebEngine.GetFavicon();
269     std::string url = Dali::Toolkit::Image::GenerateUrl( pixelData );
270     mFaviconView = Dali::Toolkit::ImageView::New( url );
271     mFaviconView.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
272     mFaviconView.SetProperty( Dali::Actor::Property::SIZE, Vector2( pixelData.GetWidth(), pixelData.GetHeight() ) );
273   }
274   return mFaviconView;
275 }
276
277 void WebView::LoadUrl( const std::string& url )
278 {
279   mUrl = url;
280   if( mWebEngine )
281   {
282     mVisual = CreateNativeImageVisual( mWebEngine.GetNativeImageSource() );
283
284     if( mVisual )
285     {
286       // Clean up previously registered visual and add new one.
287       DevelControl::RegisterVisual( *this, Toolkit::WebView::Property::URL, mVisual );
288       mWebEngine.LoadUrl( url );
289     }
290
291     if ( mVideoHoleEnabled )
292     {
293       EnableBlendMode( false );
294     }
295   }
296 }
297
298 void WebView::LoadHtmlString( const std::string& htmlString )
299 {
300   if( mWebEngine )
301   {
302     mVisual = CreateNativeImageVisual( mWebEngine.GetNativeImageSource() );
303
304     if( mVisual )
305     {
306       DevelControl::RegisterVisual( *this, Toolkit::WebView::Property::URL, mVisual );
307       mWebEngine.LoadHtmlString( htmlString );
308     }
309
310     if ( mVideoHoleEnabled )
311     {
312       EnableBlendMode( false );
313     }
314   }
315 }
316
317 void WebView::Reload()
318 {
319   if( mWebEngine )
320   {
321     mWebEngine.Reload();
322   }
323 }
324
325 void WebView::StopLoading()
326 {
327   if( mWebEngine )
328   {
329     mWebEngine.StopLoading();
330   }
331 }
332
333 void WebView::Suspend()
334 {
335   if( mWebEngine )
336   {
337     mWebEngine.Suspend();
338   }
339 }
340
341 void WebView::Resume()
342 {
343   if( mWebEngine )
344   {
345     mWebEngine.Resume();
346   }
347 }
348
349 void WebView::ScrollBy( int deltaX, int deltaY )
350 {
351   if ( mWebEngine )
352   {
353     mWebEngine.ScrollBy( deltaX, deltaY );
354   }
355 }
356
357 bool WebView::CanGoForward()
358 {
359   return mWebEngine ? mWebEngine.CanGoForward() : false;
360 }
361
362 void WebView::GoForward()
363 {
364   if( mWebEngine )
365   {
366     mWebEngine.GoForward();
367   }
368 }
369
370 bool WebView::CanGoBack()
371 {
372   return mWebEngine ? mWebEngine.CanGoBack() : false;
373 }
374
375 void WebView::GoBack()
376 {
377   if( mWebEngine )
378   {
379     mWebEngine.GoBack();
380   }
381 }
382
383 void WebView::EvaluateJavaScript( const std::string& script, std::function< void( const std::string& ) > resultHandler )
384 {
385   if( mWebEngine )
386   {
387     mWebEngine.EvaluateJavaScript( script, resultHandler );
388   }
389 }
390
391 void WebView::AddJavaScriptMessageHandler( const std::string& exposedObjectName, std::function< void( const std::string& ) > handler )
392 {
393   if( mWebEngine )
394   {
395     mWebEngine.AddJavaScriptMessageHandler( exposedObjectName, handler );
396   }
397 }
398
399 void WebView::ClearAllTilesResources()
400 {
401   if( mWebEngine )
402   {
403     mWebEngine.ClearAllTilesResources();
404   }
405 }
406
407 void WebView::ClearHistory()
408 {
409   if( mWebEngine )
410   {
411     mWebEngine.ClearHistory();
412   }
413 }
414
415 void WebView::UpdateDisplayArea( Dali::PropertyNotification& /*source*/ )
416 {
417   if( !mWebEngine )
418     return;
419
420   Actor self( Self() );
421
422   bool positionUsesAnchorPoint = self.GetProperty< bool >( Actor::Property::POSITION_USES_ANCHOR_POINT );
423   Vector3 actorSize = self.GetCurrentProperty< Vector3 >( Actor::Property::SIZE ) * self.GetCurrentProperty< Vector3 >( Actor::Property::SCALE );
424   Vector3 anchorPointOffSet = actorSize * ( positionUsesAnchorPoint ? self.GetCurrentProperty< Vector3 >( Actor::Property::ANCHOR_POINT ) : AnchorPoint::TOP_LEFT );
425   Vector2 screenPosition = self.GetProperty< Vector2 >( Actor::Property::SCREEN_POSITION );
426
427   Dali::Rect< int > displayArea;
428   displayArea.x = screenPosition.x - anchorPointOffSet.x;
429   displayArea.y = screenPosition.y - anchorPointOffSet.y;
430   displayArea.width = actorSize.x;
431   displayArea.height = actorSize.y;
432
433   Size displaySize = Size( displayArea.width, displayArea.height );
434   if ( mWebViewSize != displaySize )
435   {
436     mWebViewSize = displaySize;
437   }
438
439   if (mWebViewArea != displayArea )
440   {
441     mWebViewArea = displayArea;
442     mWebEngine.UpdateDisplayArea( mWebViewArea );
443   }
444 }
445
446 void WebView::EnableVideoHole( bool enabled )
447 {
448   mVideoHoleEnabled = enabled;
449
450   EnableBlendMode( !mVideoHoleEnabled );
451
452   if( mWebEngine )
453   {
454     mWebEngine.EnableVideoHole( mVideoHoleEnabled );
455   }
456 }
457
458 void WebView::EnableBlendMode( bool blendEnabled )
459 {
460   Actor self = Self();
461   for (uint32_t i = 0; i < self.GetRendererCount(); i++)
462   {
463     Dali::Renderer render = self.GetRendererAt( i );
464     render.SetProperty( Renderer::Property::BLEND_MODE, blendEnabled ? BlendMode::ON : BlendMode::OFF );
465   }
466 }
467
468 Dali::Toolkit::WebView::WebViewPageLoadSignalType& WebView::PageLoadStartedSignal()
469 {
470   return mPageLoadStartedSignal;
471 }
472
473 Dali::Toolkit::WebView::WebViewPageLoadSignalType& WebView::PageLoadFinishedSignal()
474 {
475   return mPageLoadFinishedSignal;
476 }
477
478 Dali::Toolkit::WebView::WebViewPageLoadErrorSignalType& WebView::PageLoadErrorSignal()
479 {
480   return mPageLoadErrorSignal;
481 }
482
483 Dali::Toolkit::WebView::WebViewScrollEdgeReachedSignalType& WebView::ScrollEdgeReachedSignal()
484 {
485   return mScrollEdgeReachedSignal;
486 }
487
488 void WebView::OnPageLoadStarted( const std::string& url )
489 {
490   if( !mPageLoadStartedSignal.Empty() )
491   {
492     Dali::Toolkit::WebView handle( GetOwner() );
493     mPageLoadStartedSignal.Emit( handle, url );
494   }
495 }
496
497 void WebView::OnPageLoadFinished( const std::string& url )
498 {
499   if( !mPageLoadFinishedSignal.Empty() )
500   {
501     Dali::Toolkit::WebView handle( GetOwner() );
502     mPageLoadFinishedSignal.Emit( handle, url );
503   }
504 }
505
506 void WebView::OnPageLoadError( const std::string& url, int errorCode )
507 {
508   if( !mPageLoadErrorSignal.Empty() )
509   {
510     Dali::Toolkit::WebView handle( GetOwner() );
511     mPageLoadErrorSignal.Emit( handle, url, static_cast< Toolkit::WebView::LoadErrorCode >( errorCode ) );
512   }
513 }
514
515 void WebView::OnScrollEdgeReached( Dali::WebEnginePlugin::ScrollEdge edge )
516 {
517   if( !mScrollEdgeReachedSignal.Empty() )
518   {
519     Dali::Toolkit::WebView handle( GetOwner() );
520     mScrollEdgeReachedSignal.Emit( handle, edge );
521   }
522 }
523
524 bool WebView::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
525 {
526   Dali::BaseHandle handle( object );
527
528   bool connected = false;
529   Toolkit::WebView webView = Toolkit::WebView::DownCast( handle );
530
531   if( 0 == strcmp( signalName.c_str(), PAGE_LOAD_STARTED_SIGNAL ) )
532   {
533     webView.PageLoadStartedSignal().Connect( tracker, functor );
534     connected = true;
535   }
536   else if( 0 == strcmp( signalName.c_str(), PAGE_LOAD_FINISHED_SIGNAL ) )
537   {
538     webView.PageLoadFinishedSignal().Connect( tracker, functor );
539     connected = true;
540   }
541   else if( 0 == strcmp( signalName.c_str(), PAGE_LOAD_ERROR_SIGNAL ) )
542   {
543     webView.PageLoadErrorSignal().Connect( tracker, functor );
544     connected = true;
545   }
546   else if( 0 == strcmp( signalName.c_str(), SCROLL_EDGE_REACHED_SIGNAL ) )
547   {
548     webView.ScrollEdgeReachedSignal().Connect( tracker, functor );
549     connected = true;
550   }
551
552   return connected;
553 }
554
555 Vector3 WebView::GetNaturalSize()
556 {
557   if( mVisual )
558   {
559     Vector2 rendererNaturalSize;
560     mVisual.GetNaturalSize( rendererNaturalSize );
561     return Vector3( rendererNaturalSize );
562   }
563
564   return Vector3( mWebViewSize );
565 }
566
567 void WebView::OnSceneConnection( int depth )
568 {
569   Control::OnSceneConnection( depth );
570
571   EnableBlendMode( !mVideoHoleEnabled );
572 }
573
574 void WebView::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
575 {
576   Toolkit::WebView webView = Toolkit::WebView::DownCast( Dali::BaseHandle( object ) );
577
578   if( webView )
579   {
580     WebView& impl = GetImpl( webView );
581     switch( index )
582     {
583       case Toolkit::WebView::Property::URL:
584       {
585         std::string url;
586         if( value.Get( url ) )
587         {
588           impl.LoadUrl( url );
589         }
590         break;
591       }
592       case Toolkit::WebView::Property::USER_AGENT:
593       {
594         std::string input;
595         if( value.Get( input ) )
596         {
597           impl.SetUserAgent( input );
598         }
599         break;
600       }
601       case Toolkit::WebView::Property::SCROLL_POSITION:
602       {
603         Vector2 input;
604         if ( value.Get( input ) )
605         {
606           impl.SetScrollPosition( input.x, input.y );
607         }
608         break;
609       }
610       case Toolkit::WebView::Property::VIDEO_HOLE_ENABLED:
611       {
612         bool input;
613         if( value.Get( input ) )
614         {
615           impl.EnableVideoHole( input );
616         }
617         break;
618       }
619     }
620   }
621 }
622
623 Property::Value WebView::GetProperty( BaseObject* object, Property::Index propertyIndex )
624 {
625   Property::Value value;
626
627   Toolkit::WebView webView = Toolkit::WebView::DownCast( Dali::BaseHandle( object ) );
628
629   if( webView )
630   {
631     WebView& impl = GetImpl( webView );
632     switch( propertyIndex )
633     {
634       case Toolkit::WebView::Property::URL:
635       {
636         value = impl.mUrl;
637         break;
638       }
639       case Toolkit::WebView::Property::USER_AGENT:
640       {
641         value = impl.GetUserAgent();
642         break;
643       }
644       case Toolkit::WebView::Property::SCROLL_POSITION:
645       {
646         int x, y;
647         impl.GetScrollPosition( x, y );
648         value = Vector2( x, y );
649         break;
650       }
651       case Toolkit::WebView::Property::SCROLL_SIZE:
652       {
653         int width, height;
654         impl.GetScrollSize( width, height );
655         value = Vector2( width, height );
656         break;
657       }
658       case Toolkit::WebView::Property::CONTENT_SIZE:
659       {
660         int width, height;
661         impl.GetContentSize( width, height );
662         value = Vector2( width, height );
663         break;
664       }
665       case Toolkit::WebView::Property::TITLE:
666       {
667         value = impl.GetTitle();
668         break;
669       }
670       case Toolkit::WebView::Property::VIDEO_HOLE_ENABLED:
671       {
672         value = impl.mVideoHoleEnabled;
673         break;
674       }
675       default:
676          break;
677     }
678   }
679
680   return value;
681 }
682
683 bool WebView::OnTouchEvent( Actor actor, const Dali::TouchEvent& touch )
684 {
685   bool result = false;
686
687   if( mWebEngine )
688   {
689     result = mWebEngine.SendTouchEvent( touch );
690   }
691   return result;
692 }
693
694 bool WebView::OnKeyEvent( const Dali::KeyEvent& event )
695 {
696   bool result = false;
697
698   if( mWebEngine )
699   {
700     result = mWebEngine.SendKeyEvent( event );
701   }
702   return result;
703 }
704
705 void WebView::OnKeyInputFocusGained()
706 {
707   if( mWebEngine )
708   {
709     mWebEngine.SetFocus( true );
710   }
711
712   EmitKeyInputFocusSignal( true ); // Calls back into the Control hence done last.
713 }
714
715 void WebView::OnKeyInputFocusLost()
716 {
717   if( mWebEngine )
718   {
719     mWebEngine.SetFocus( false );
720   }
721
722   EmitKeyInputFocusSignal( false ); // Calls back into the Control hence done last.
723 }
724
725 void WebView::SetScrollPosition( int x, int y )
726 {
727   if( mWebEngine )
728   {
729     mWebEngine.SetScrollPosition( x, y );
730   }
731 }
732
733 void WebView::GetScrollPosition( int& x, int& y ) const
734 {
735   if( mWebEngine )
736   {
737     mWebEngine.GetScrollPosition( x, y );
738   }
739 }
740
741 void WebView::GetScrollSize( int& width, int& height ) const
742 {
743   if( mWebEngine )
744   {
745     mWebEngine.GetScrollSize( width, height );
746   }
747 }
748
749 void WebView::GetContentSize( int& width, int& height ) const
750 {
751   if( mWebEngine )
752   {
753     mWebEngine.GetContentSize( width, height );
754   }
755 }
756
757 std::string WebView::GetTitle() const
758 {
759   return mWebEngine ?  mWebEngine.GetTitle() : kEmptyString;
760 }
761
762 const std::string& WebView::GetUserAgent() const
763 {
764   return mWebEngine ? mWebEngine.GetUserAgent() : kEmptyString;
765 }
766
767 void WebView::SetUserAgent( const std::string& userAgent )
768 {
769   if( mWebEngine )
770   {
771     mWebEngine.SetUserAgent( userAgent );
772   }
773 }
774
775 #undef GET_ENUM_STRING
776 #undef GET_ENUM_VALUE
777
778 } // namespace Internal
779
780 } // namespace Toolkit
781
782 } // namespace Dali