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