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