c4bf4e9da4186280399ac9a5c65f803ff268cc8f
[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 DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "mouseEventsEnabled",      BOOLEAN, MOUSE_EVENTS_ENABLED      )
69 DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "keyEventsEnabled",        BOOLEAN, KEY_EVENTS_ENABLED        )
70 DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "documentBackgroundColor", VECTOR4, DOCUMENT_BACKGROUND_COLOR )
71 DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "tilesClearedWhenHidden",  BOOLEAN, TILES_CLEARED_WHEN_HIDDEN )
72 DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "tileCoverAreaMultiplier", FLOAT,   TILE_COVER_AREA_MULTIPLIER)
73 DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "cursorEnabledByClient",   BOOLEAN, CURSOR_ENABLED_BY_CLIENT  )
74 DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "selectedText",            STRING,  SELECTED_TEXT             )
75
76 DALI_SIGNAL_REGISTRATION(Toolkit, WebView, "pageLoadStarted",    PAGE_LOAD_STARTED_SIGNAL    )
77 DALI_SIGNAL_REGISTRATION(Toolkit, WebView, "pageLoadInProgress", PAGE_LOAD_IN_PROGRESS_SIGNAL)
78 DALI_SIGNAL_REGISTRATION(Toolkit, WebView, "pageLoadFinished",   PAGE_LOAD_FINISHED_SIGNAL   )
79 DALI_SIGNAL_REGISTRATION(Toolkit, WebView, "pageLoadError",      PAGE_LOAD_ERROR_SIGNAL      )
80 DALI_SIGNAL_REGISTRATION(Toolkit, WebView, "scrollEdgeReached",  SCROLL_EDGE_REACHED_SIGNAL  )
81 DALI_SIGNAL_REGISTRATION(Toolkit, WebView, "urlChanged",         URL_CHANGED_SIGNAL          )
82
83 DALI_TYPE_REGISTRATION_END()
84 // clang-format on
85
86 const std::string kEmptyString;
87
88 } // namespace
89
90 #define GET_ENUM_STRING(structName, inputExp) \
91   Scripting::GetLinearEnumerationName<Toolkit::WebView::structName::Type>(static_cast<Toolkit::WebView::structName::Type>(inputExp), structName##_TABLE, structName##_TABLE_COUNT)
92
93 #define GET_ENUM_VALUE(structName, inputExp, outputExp) \
94   Scripting::GetEnumerationProperty<Toolkit::WebView::structName::Type>(inputExp, structName##_TABLE, structName##_TABLE_COUNT, outputExp)
95
96 WebView::WebView(const std::string& locale, const std::string& timezoneId)
97 : Control(ControlBehaviour(ACTOR_BEHAVIOUR_DEFAULT | DISABLE_STYLE_CHANGE_SIGNALS)),
98   mUrl(),
99   mVisual(),
100   mWebViewSize(Stage::GetCurrent().GetSize()),
101   mWebEngine(),
102   mPageLoadStartedSignal(),
103   mPageLoadFinishedSignal(),
104   mPageLoadErrorSignal(),
105   mUrlChangedSignal(),
106   mVideoHoleEnabled(true),
107   mWebViewArea(0, 0, mWebViewSize.width, mWebViewSize.height),
108   mMouseEventsEnabled(true),
109   mKeyEventsEnabled(true)
110 {
111   mWebEngine = Dali::WebEngine::New();
112
113   // WebEngine is empty when it is not properly initialized.
114   if(mWebEngine)
115   {
116     mWebEngine.Create(mWebViewSize.width, mWebViewSize.height, locale, timezoneId);
117   }
118 }
119
120 WebView::WebView(int argc, char** argv)
121 : Control(ControlBehaviour(ACTOR_BEHAVIOUR_DEFAULT | DISABLE_STYLE_CHANGE_SIGNALS)),
122   mUrl(),
123   mVisual(),
124   mWebViewSize(Stage::GetCurrent().GetSize()),
125   mWebEngine(),
126   mPageLoadStartedSignal(),
127   mPageLoadFinishedSignal(),
128   mPageLoadErrorSignal(),
129   mUrlChangedSignal(),
130   mVideoHoleEnabled(true),
131   mWebViewArea(0, 0, mWebViewSize.width, mWebViewSize.height),
132   mMouseEventsEnabled(true),
133   mKeyEventsEnabled(true)
134 {
135   mWebEngine = Dali::WebEngine::New();
136
137   // WebEngine is empty when it is not properly initialized.
138   if(mWebEngine)
139   {
140     mWebEngine.Create(mWebViewSize.width, mWebViewSize.height, argc, argv);
141   }
142 }
143
144 WebView::WebView()
145 : WebView("", "")
146 {
147 }
148
149 WebView::~WebView()
150 {
151   if(mWebEngine)
152   {
153     mWebEngine.Destroy();
154   }
155 }
156
157 Toolkit::WebView WebView::New()
158 {
159   WebView*         impl   = new WebView();
160   Toolkit::WebView handle = Toolkit::WebView(*impl);
161
162   impl->Initialize();
163   return handle;
164 }
165
166 Toolkit::WebView WebView::New(const std::string& locale, const std::string& timezoneId)
167 {
168   WebView*         impl   = new WebView(locale, timezoneId);
169   Toolkit::WebView handle = Toolkit::WebView(*impl);
170
171   impl->Initialize();
172   return handle;
173 }
174
175 Toolkit::WebView WebView::New(int argc, char** argv)
176 {
177   WebView*         impl   = new WebView(argc, argv);
178   Toolkit::WebView handle = Toolkit::WebView(*impl);
179
180   impl->Initialize();
181   return handle;
182 }
183
184 void WebView::OnInitialize()
185 {
186   Actor self = Self();
187
188   self.SetProperty(Actor::Property::KEYBOARD_FOCUSABLE, true);
189   self.TouchedSignal().Connect(this, &WebView::OnTouchEvent);
190   self.HoveredSignal().Connect(this, &WebView::OnHoverEvent);
191   self.WheelEventSignal().Connect(this, &WebView::OnWheelEvent);
192
193   mPositionUpdateNotification = self.AddPropertyNotification(Actor::Property::WORLD_POSITION, StepCondition(1.0f, 1.0f));
194   mSizeUpdateNotification     = self.AddPropertyNotification(Actor::Property::SIZE, StepCondition(1.0f, 1.0f));
195   mScaleUpdateNotification    = self.AddPropertyNotification(Actor::Property::WORLD_SCALE, StepCondition(0.1f, 1.0f));
196   mPositionUpdateNotification.NotifySignal().Connect(this, &WebView::UpdateDisplayArea);
197   mSizeUpdateNotification.NotifySignal().Connect(this, &WebView::UpdateDisplayArea);
198   mScaleUpdateNotification.NotifySignal().Connect(this, &WebView::UpdateDisplayArea);
199
200   if(mWebEngine)
201   {
202     mWebEngine.PageLoadStartedSignal().Connect(this, &WebView::OnPageLoadStarted);
203     mWebEngine.PageLoadInProgressSignal().Connect(this, &WebView::OnPageLoadInProgress);
204     mWebEngine.PageLoadFinishedSignal().Connect(this, &WebView::OnPageLoadFinished);
205     mWebEngine.PageLoadErrorSignal().Connect(this, &WebView::OnPageLoadError);
206     mWebEngine.ScrollEdgeReachedSignal().Connect(this, &WebView::OnScrollEdgeReached);
207     mWebEngine.UrlChangedSignal().Connect(this, &WebView::OnUrlChanged);
208
209     mWebContext         = std::unique_ptr<Dali::Toolkit::WebContext>(new WebContext(mWebEngine.GetContext()));
210     mWebCookieManager   = std::unique_ptr<Dali::Toolkit::WebCookieManager>(new WebCookieManager(mWebEngine.GetCookieManager()));
211     mWebSettings        = std::unique_ptr<Dali::Toolkit::WebSettings>(new WebSettings(mWebEngine.GetSettings()));
212     mWebBackForwardList = std::unique_ptr<Dali::Toolkit::WebBackForwardList>(new WebBackForwardList(mWebEngine.GetBackForwardList()));
213   }
214 }
215
216 Dali::Toolkit::WebSettings* WebView::GetSettings() const
217 {
218   return mWebSettings.get();
219 }
220
221 Dali::Toolkit::WebContext* WebView::GetContext() const
222 {
223   return mWebContext.get();
224 }
225
226 Dali::Toolkit::WebCookieManager* WebView::GetCookieManager() const
227 {
228   return mWebCookieManager.get();
229 }
230
231 Dali::Toolkit::WebBackForwardList* WebView::GetBackForwardList() const
232 {
233   return mWebBackForwardList.get();
234 }
235
236 Dali::Toolkit::ImageView& WebView::GetFavicon()
237 {
238   if(mWebEngine)
239   {
240     Dali::PixelData pixelData = mWebEngine.GetFavicon();
241     std::string     url       = Dali::Toolkit::Image::GenerateUrl(pixelData);
242     mFaviconView              = Dali::Toolkit::ImageView::New(url);
243     mFaviconView.SetResizePolicy(ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS);
244     mFaviconView.SetProperty(Dali::Actor::Property::SIZE, Vector2(pixelData.GetWidth(), pixelData.GetHeight()));
245   }
246   return mFaviconView;
247 }
248
249 void WebView::LoadUrl(const std::string& url)
250 {
251   mUrl = url;
252   if(mWebEngine)
253   {
254     Texture           texture        = Dali::Texture::New(*mWebEngine.GetNativeImageSource());
255     const std::string nativeImageUrl = Dali::Toolkit::TextureManager::AddTexture(texture);
256     mVisual                          = Toolkit::VisualFactory::Get().CreateVisual(
257       {{Toolkit::Visual::Property::TYPE, Toolkit::Visual::IMAGE},
258        {Toolkit::ImageVisual::Property::URL, nativeImageUrl}});
259
260     if(mVisual)
261     {
262       // Clean up previously registered visual and add new one.
263       DevelControl::RegisterVisual(*this, Toolkit::WebView::Property::URL, mVisual);
264       mWebEngine.LoadUrl(url);
265     }
266
267     if(mVideoHoleEnabled)
268     {
269       EnableBlendMode(false);
270     }
271   }
272 }
273
274 void WebView::LoadHtmlString(const std::string& htmlString)
275 {
276   if(mWebEngine)
277   {
278     Texture           texture        = Dali::Texture::New(*mWebEngine.GetNativeImageSource());
279     const std::string nativeImageUrl = Dali::Toolkit::TextureManager::AddTexture(texture);
280     mVisual                          = Toolkit::VisualFactory::Get().CreateVisual(
281       {{Toolkit::Visual::Property::TYPE, Toolkit::Visual::IMAGE},
282        {Toolkit::ImageVisual::Property::URL, nativeImageUrl}});
283
284     if(mVisual)
285     {
286       DevelControl::RegisterVisual(*this, Toolkit::WebView::Property::URL, mVisual);
287       mWebEngine.LoadHtmlString(htmlString);
288     }
289
290     if(mVideoHoleEnabled)
291     {
292       EnableBlendMode(false);
293     }
294   }
295 }
296
297 void WebView::Reload()
298 {
299   if(mWebEngine)
300   {
301     mWebEngine.Reload();
302   }
303 }
304
305 void WebView::StopLoading()
306 {
307   if(mWebEngine)
308   {
309     mWebEngine.StopLoading();
310   }
311 }
312
313 void WebView::Suspend()
314 {
315   if(mWebEngine)
316   {
317     mWebEngine.Suspend();
318   }
319 }
320
321 void WebView::Resume()
322 {
323   if(mWebEngine)
324   {
325     mWebEngine.Resume();
326   }
327 }
328
329 void WebView::ScrollBy(int deltaX, int deltaY)
330 {
331   if(mWebEngine)
332   {
333     mWebEngine.ScrollBy(deltaX, deltaY);
334   }
335 }
336
337 bool WebView::CanGoForward()
338 {
339   return mWebEngine ? mWebEngine.CanGoForward() : false;
340 }
341
342 void WebView::GoForward()
343 {
344   if(mWebEngine)
345   {
346     mWebEngine.GoForward();
347   }
348 }
349
350 bool WebView::CanGoBack()
351 {
352   return mWebEngine ? mWebEngine.CanGoBack() : false;
353 }
354
355 void WebView::GoBack()
356 {
357   if(mWebEngine)
358   {
359     mWebEngine.GoBack();
360   }
361 }
362
363 void WebView::EvaluateJavaScript(const std::string& script, std::function<void(const std::string&)> resultHandler)
364 {
365   if(mWebEngine)
366   {
367     mWebEngine.EvaluateJavaScript(script, resultHandler);
368   }
369 }
370
371 void WebView::AddJavaScriptMessageHandler(const std::string& exposedObjectName, std::function<void(const std::string&)> handler)
372 {
373   if(mWebEngine)
374   {
375     mWebEngine.AddJavaScriptMessageHandler(exposedObjectName, handler);
376   }
377 }
378
379 void WebView::RegisterJavaScriptAlertCallback(Dali::WebEnginePlugin::JavaScriptAlertCallback callback)
380 {
381   if(mWebEngine)
382   {
383     mWebEngine.RegisterJavaScriptAlertCallback(callback);
384   }
385 }
386
387 void WebView::JavaScriptAlertReply()
388 {
389   if(mWebEngine)
390   {
391     mWebEngine.JavaScriptAlertReply();
392   }
393 }
394
395 void WebView::RegisterJavaScriptConfirmCallback(Dali::WebEnginePlugin::JavaScriptConfirmCallback callback)
396 {
397   if(mWebEngine)
398   {
399     mWebEngine.RegisterJavaScriptConfirmCallback(callback);
400   }
401 }
402
403 void WebView::JavaScriptConfirmReply(bool confirmed)
404 {
405   if(mWebEngine)
406   {
407     mWebEngine.JavaScriptConfirmReply(confirmed);
408   }
409 }
410
411 void WebView::RegisterJavaScriptPromptCallback(Dali::WebEnginePlugin::JavaScriptPromptCallback callback)
412 {
413   if(mWebEngine)
414   {
415     mWebEngine.RegisterJavaScriptPromptCallback(callback);
416   }
417 }
418
419 void WebView::JavaScriptPromptReply(const std::string& result)
420 {
421   if(mWebEngine)
422   {
423     mWebEngine.JavaScriptPromptReply(result);
424   }
425 }
426
427 void WebView::ClearHistory()
428 {
429   if(mWebEngine)
430   {
431     mWebEngine.ClearHistory();
432   }
433 }
434
435 void WebView::UpdateDisplayArea(Dali::PropertyNotification& /*source*/)
436 {
437   if(!mWebEngine)
438     return;
439
440   Actor self(Self());
441
442   bool    positionUsesAnchorPoint = self.GetProperty<bool>(Actor::Property::POSITION_USES_ANCHOR_POINT);
443   Vector3 actorSize               = self.GetCurrentProperty<Vector3>(Actor::Property::SIZE) * self.GetCurrentProperty<Vector3>(Actor::Property::SCALE);
444   Vector3 anchorPointOffSet       = actorSize * (positionUsesAnchorPoint ? self.GetCurrentProperty<Vector3>(Actor::Property::ANCHOR_POINT) : AnchorPoint::TOP_LEFT);
445   Vector2 screenPosition          = self.GetProperty<Vector2>(Actor::Property::SCREEN_POSITION);
446
447   Dali::Rect<int> displayArea;
448   displayArea.x      = screenPosition.x - anchorPointOffSet.x;
449   displayArea.y      = screenPosition.y - anchorPointOffSet.y;
450   displayArea.width  = actorSize.x;
451   displayArea.height = actorSize.y;
452
453   Size displaySize = Size(displayArea.width, displayArea.height);
454   if(mWebViewSize != displaySize)
455   {
456     mWebViewSize = displaySize;
457   }
458
459   if(mWebViewArea != displayArea)
460   {
461     mWebViewArea = displayArea;
462     mWebEngine.UpdateDisplayArea(mWebViewArea);
463   }
464 }
465
466 void WebView::EnableVideoHole(bool enabled)
467 {
468   mVideoHoleEnabled = enabled;
469
470   EnableBlendMode(!mVideoHoleEnabled);
471
472   if(mWebEngine)
473   {
474     mWebEngine.EnableVideoHole(mVideoHoleEnabled);
475   }
476 }
477
478 void WebView::EnableBlendMode(bool blendEnabled)
479 {
480   Actor self = Self();
481   for(uint32_t i = 0; i < self.GetRendererCount(); i++)
482   {
483     Dali::Renderer render = self.GetRendererAt(i);
484     render.SetProperty(Renderer::Property::BLEND_MODE, blendEnabled ? BlendMode::ON : BlendMode::OFF);
485   }
486 }
487
488 void WebView::ClearAllTilesResources()
489 {
490   if(mWebEngine)
491   {
492     mWebEngine.ClearAllTilesResources();
493   }
494 }
495
496 Dali::Toolkit::WebView::WebViewPageLoadSignalType& WebView::PageLoadStartedSignal()
497 {
498   return mPageLoadStartedSignal;
499 }
500
501 Dali::Toolkit::WebView::WebViewPageLoadSignalType& WebView::PageLoadInProgressSignal()
502 {
503   return mPageLoadInProgressSignal;
504 }
505
506 Dali::Toolkit::WebView::WebViewPageLoadSignalType& WebView::PageLoadFinishedSignal()
507 {
508   return mPageLoadFinishedSignal;
509 }
510
511 Dali::Toolkit::WebView::WebViewPageLoadErrorSignalType& WebView::PageLoadErrorSignal()
512 {
513   return mPageLoadErrorSignal;
514 }
515
516 Dali::Toolkit::WebView::WebViewScrollEdgeReachedSignalType& WebView::ScrollEdgeReachedSignal()
517 {
518   return mScrollEdgeReachedSignal;
519 }
520
521 Dali::Toolkit::WebView::WebViewUrlChangedSignalType& WebView::UrlChangedSignal()
522 {
523   return mUrlChangedSignal;
524 }
525
526 void WebView::OnPageLoadStarted(const std::string& url)
527 {
528   if(!mPageLoadStartedSignal.Empty())
529   {
530     Dali::Toolkit::WebView handle(GetOwner());
531     mPageLoadStartedSignal.Emit(handle, url);
532   }
533 }
534
535 void WebView::OnPageLoadInProgress(const std::string& url)
536 {
537   if(!mPageLoadInProgressSignal.Empty())
538   {
539     Dali::Toolkit::WebView handle(GetOwner());
540     mPageLoadInProgressSignal.Emit(handle, url);
541   }
542 }
543
544 void WebView::OnPageLoadFinished(const std::string& url)
545 {
546   if(!mPageLoadFinishedSignal.Empty())
547   {
548     Dali::Toolkit::WebView handle(GetOwner());
549     mPageLoadFinishedSignal.Emit(handle, url);
550   }
551 }
552
553 void WebView::OnPageLoadError(const std::string& url, int errorCode)
554 {
555   if(!mPageLoadErrorSignal.Empty())
556   {
557     Dali::Toolkit::WebView handle(GetOwner());
558     mPageLoadErrorSignal.Emit(handle, url, static_cast<Toolkit::WebView::LoadErrorCode>(errorCode));
559   }
560 }
561
562 void WebView::OnScrollEdgeReached(Dali::WebEnginePlugin::ScrollEdge edge)
563 {
564   if(!mScrollEdgeReachedSignal.Empty())
565   {
566     Dali::Toolkit::WebView handle(GetOwner());
567     mScrollEdgeReachedSignal.Emit(handle, edge);
568   }
569 }
570
571 void WebView::OnUrlChanged(const std::string& url)
572 {
573   if(!mUrlChangedSignal.Empty())
574   {
575     Dali::Toolkit::WebView handle(GetOwner());
576     mUrlChangedSignal.Emit(handle, url);
577   }
578 }
579
580 bool WebView::DoConnectSignal(BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor)
581 {
582   Dali::BaseHandle handle(object);
583
584   bool             connected = false;
585   Toolkit::WebView webView   = Toolkit::WebView::DownCast(handle);
586
587   if(0 == strcmp(signalName.c_str(), PAGE_LOAD_STARTED_SIGNAL))
588   {
589     webView.PageLoadStartedSignal().Connect(tracker, functor);
590     connected = true;
591   }
592   else if(0 == strcmp(signalName.c_str(), PAGE_LOAD_IN_PROGRESS_SIGNAL))
593   {
594     webView.PageLoadInProgressSignal().Connect(tracker, functor);
595     connected = true;
596   }
597   else if(0 == strcmp(signalName.c_str(), PAGE_LOAD_FINISHED_SIGNAL))
598   {
599     webView.PageLoadFinishedSignal().Connect(tracker, functor);
600     connected = true;
601   }
602   else if(0 == strcmp(signalName.c_str(), PAGE_LOAD_ERROR_SIGNAL))
603   {
604     webView.PageLoadErrorSignal().Connect(tracker, functor);
605     connected = true;
606   }
607   else if(0 == strcmp(signalName.c_str(), SCROLL_EDGE_REACHED_SIGNAL))
608   {
609     webView.ScrollEdgeReachedSignal().Connect(tracker, functor);
610     connected = true;
611   }
612   else if(0 == strcmp(signalName.c_str(), URL_CHANGED_SIGNAL))
613   {
614     webView.UrlChangedSignal().Connect(tracker, functor);
615     connected = true;
616   }
617
618   return connected;
619 }
620
621 Vector3 WebView::GetNaturalSize()
622 {
623   if(mVisual)
624   {
625     Vector2 rendererNaturalSize;
626     mVisual.GetNaturalSize(rendererNaturalSize);
627     return Vector3(rendererNaturalSize);
628   }
629
630   return Vector3(mWebViewSize);
631 }
632
633 void WebView::OnSceneConnection(int depth)
634 {
635   Control::OnSceneConnection(depth);
636
637   EnableBlendMode(!mVideoHoleEnabled);
638 }
639
640 void WebView::SetProperty(BaseObject* object, Property::Index index, const Property::Value& value)
641 {
642   Toolkit::WebView webView = Toolkit::WebView::DownCast(Dali::BaseHandle(object));
643
644   if(webView)
645   {
646     WebView& impl = GetImpl(webView);
647     switch(index)
648     {
649       case Toolkit::WebView::Property::URL:
650       {
651         std::string url;
652         if(value.Get(url))
653         {
654           impl.LoadUrl(url);
655         }
656         break;
657       }
658       case Toolkit::WebView::Property::USER_AGENT:
659       {
660         std::string input;
661         if(value.Get(input))
662         {
663           impl.SetUserAgent(input);
664         }
665         break;
666       }
667       case Toolkit::WebView::Property::SCROLL_POSITION:
668       {
669         Vector2 input;
670         if(value.Get(input))
671         {
672           impl.SetScrollPosition(input.x, input.y);
673         }
674         break;
675       }
676       case Toolkit::WebView::Property::VIDEO_HOLE_ENABLED:
677       {
678         bool input;
679         if(value.Get(input))
680         {
681           impl.EnableVideoHole(input);
682         }
683         break;
684       }
685       case Toolkit::WebView::Property::MOUSE_EVENTS_ENABLED:
686       {
687         bool input;
688         if(value.Get(input))
689         {
690           impl.EnableMouseEvents(input);
691         }
692         break;
693       }
694       case Toolkit::WebView::Property::KEY_EVENTS_ENABLED:
695       {
696         bool input;
697         if(value.Get(input))
698         {
699           impl.EnableKeyEvents(input);
700         }
701         break;
702       }
703       case Toolkit::WebView::Property::DOCUMENT_BACKGROUND_COLOR:
704       {
705         Vector4 input;
706         if(value.Get(input))
707         {
708           impl.SetDocumentBackgroundColor(input);
709         }
710         break;
711       }
712       case Toolkit::WebView::Property::TILES_CLEARED_WHEN_HIDDEN:
713       {
714         bool input;
715         if(value.Get(input))
716         {
717           impl.ClearTilesWhenHidden(input);
718         }
719         break;
720       }
721       case Toolkit::WebView::Property::TILE_COVER_AREA_MULTIPLIER:
722       {
723         float input;
724         if(value.Get(input))
725         {
726           impl.SetTileCoverAreaMultiplier(input);
727         }
728         break;
729       }
730       case Toolkit::WebView::Property::CURSOR_ENABLED_BY_CLIENT:
731       {
732         bool input;
733         if(value.Get(input))
734         {
735           impl.EnableCursorByClient(input);
736         }
737         break;
738       }
739     }
740   }
741 }
742
743 Property::Value WebView::GetProperty(BaseObject* object, Property::Index propertyIndex)
744 {
745   Property::Value value;
746
747   Toolkit::WebView webView = Toolkit::WebView::DownCast(Dali::BaseHandle(object));
748
749   if(webView)
750   {
751     WebView& impl = GetImpl(webView);
752     switch(propertyIndex)
753     {
754       case Toolkit::WebView::Property::URL:
755       {
756         value = impl.mUrl;
757         break;
758       }
759       case Toolkit::WebView::Property::USER_AGENT:
760       {
761         value = impl.GetUserAgent();
762         break;
763       }
764       case Toolkit::WebView::Property::SCROLL_POSITION:
765       {
766         value = impl.GetScrollPosition();
767         break;
768       }
769       case Toolkit::WebView::Property::SCROLL_SIZE:
770       {
771         value = impl.GetScrollSize();
772         break;
773       }
774       case Toolkit::WebView::Property::CONTENT_SIZE:
775       {
776         value = impl.GetContentSize();
777         break;
778       }
779       case Toolkit::WebView::Property::TITLE:
780       {
781         value = impl.GetTitle();
782         break;
783       }
784       case Toolkit::WebView::Property::VIDEO_HOLE_ENABLED:
785       {
786         value = impl.mVideoHoleEnabled;
787         break;
788       }
789       case Toolkit::WebView::Property::MOUSE_EVENTS_ENABLED:
790       {
791         value = impl.mMouseEventsEnabled;
792         break;
793       }
794       case Toolkit::WebView::Property::KEY_EVENTS_ENABLED:
795       {
796         value = impl.mKeyEventsEnabled;
797         break;
798       }
799       case Toolkit::WebView::Property::SELECTED_TEXT:
800       {
801         value = impl.GetSelectedText();
802         break;
803       }
804       default:
805         break;
806     }
807   }
808
809   return value;
810 }
811
812 bool WebView::OnTouchEvent(Actor actor, const Dali::TouchEvent& touch)
813 {
814   bool result = false;
815
816   if(mWebEngine)
817   {
818     result = mWebEngine.SendTouchEvent(touch);
819   }
820   return result;
821 }
822
823 bool WebView::OnKeyEvent(const Dali::KeyEvent& event)
824 {
825   bool result = false;
826
827   if(mWebEngine)
828   {
829     result = mWebEngine.SendKeyEvent(event);
830   }
831   return result;
832 }
833
834 bool WebView::OnHoverEvent(Actor actor, const Dali::HoverEvent& hover)
835 {
836   bool result = false;
837   if(mWebEngine)
838   {
839     result = mWebEngine.SendHoverEvent(hover);
840   }
841   return result;
842 }
843
844 bool WebView::OnWheelEvent(Actor actor, const Dali::WheelEvent& wheel)
845 {
846   bool result = false;
847   if(mWebEngine)
848   {
849     result = mWebEngine.SendWheelEvent(wheel);
850   }
851   return result;
852 }
853
854 void WebView::OnKeyInputFocusGained()
855 {
856   if(mWebEngine)
857   {
858     mWebEngine.SetFocus(true);
859   }
860
861   EmitKeyInputFocusSignal(true); // Calls back into the Control hence done last.
862 }
863
864 void WebView::OnKeyInputFocusLost()
865 {
866   if(mWebEngine)
867   {
868     mWebEngine.SetFocus(false);
869   }
870
871   EmitKeyInputFocusSignal(false); // Calls back into the Control hence done last.
872 }
873
874 void WebView::SetScrollPosition(int x, int y)
875 {
876   if(mWebEngine)
877   {
878     mWebEngine.SetScrollPosition(x, y);
879   }
880 }
881
882 Dali::Vector2 WebView::GetScrollPosition() const
883 {
884   return mWebEngine ? mWebEngine.GetScrollPosition() : Dali::Vector2::ZERO;
885 }
886
887 Dali::Vector2 WebView::GetScrollSize() const
888 {
889   return mWebEngine ? mWebEngine.GetScrollSize() : Dali::Vector2::ZERO;
890 }
891
892 Dali::Vector2 WebView::GetContentSize() const
893 {
894   return mWebEngine ? mWebEngine.GetContentSize() : Dali::Vector2::ZERO;
895 }
896
897 std::string WebView::GetTitle() const
898 {
899   return mWebEngine ? mWebEngine.GetTitle() : kEmptyString;
900 }
901
902 void WebView::SetDocumentBackgroundColor(Dali::Vector4 color)
903 {
904   if(mWebEngine)
905   {
906     mWebEngine.SetDocumentBackgroundColor(color);
907   }
908 }
909
910 void WebView::ClearTilesWhenHidden(bool cleared)
911 {
912   if(mWebEngine)
913   {
914     mWebEngine.ClearTilesWhenHidden(cleared);
915   }
916 }
917
918 void WebView::SetTileCoverAreaMultiplier(float multiplier)
919 {
920   if(mWebEngine)
921   {
922     mWebEngine.SetTileCoverAreaMultiplier(multiplier);
923   }
924 }
925
926 void WebView::EnableCursorByClient(bool enabled)
927 {
928   if(mWebEngine)
929   {
930     mWebEngine.EnableCursorByClient(enabled);
931   }
932 }
933
934 std::string WebView::GetSelectedText() const
935 {
936   return mWebEngine ? mWebEngine.GetSelectedText() : kEmptyString;
937 }
938
939 const std::string& WebView::GetUserAgent() const
940 {
941   return mWebEngine ? mWebEngine.GetUserAgent() : kEmptyString;
942 }
943
944 void WebView::SetUserAgent(const std::string& userAgent)
945 {
946   if(mWebEngine)
947   {
948     mWebEngine.SetUserAgent(userAgent);
949   }
950 }
951
952 void WebView::EnableMouseEvents(bool enabled)
953 {
954   if(mWebEngine)
955   {
956     mMouseEventsEnabled = enabled;
957     mWebEngine.EnableMouseEvents(enabled);
958   }
959 }
960
961 void WebView::EnableKeyEvents(bool enabled)
962 {
963   if(mWebEngine)
964   {
965     mKeyEventsEnabled = enabled;
966     mWebEngine.EnableKeyEvents(enabled);
967   }
968 }
969
970 #undef GET_ENUM_STRING
971 #undef GET_ENUM_VALUE
972
973 } // namespace Internal
974
975 } // namespace Toolkit
976
977 } // namespace Dali