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