DALi Version 2.0.36
[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-certificate.h>
24 #include <dali/devel-api/adaptor-framework/web-engine-console-message.h>
25 #include <dali/devel-api/adaptor-framework/web-engine-context-menu-item.h>
26 #include <dali/devel-api/adaptor-framework/web-engine-context-menu.h>
27 #include <dali/devel-api/adaptor-framework/web-engine-context.h>
28 #include <dali/devel-api/adaptor-framework/web-engine-cookie-manager.h>
29 #include <dali/devel-api/adaptor-framework/web-engine-form-repost-decision.h>
30 #include <dali/devel-api/adaptor-framework/web-engine-hit-test.h>
31 #include <dali/devel-api/adaptor-framework/web-engine-http-auth-handler.h>
32 #include <dali/devel-api/adaptor-framework/web-engine-load-error.h>
33 #include <dali/devel-api/adaptor-framework/web-engine-policy-decision.h>
34 #include <dali/devel-api/adaptor-framework/web-engine-request-interceptor.h>
35 #include <dali/devel-api/adaptor-framework/web-engine-settings.h>
36 #include <dali/devel-api/common/stage.h>
37 #include <dali/devel-api/scripting/enum-helper.h>
38 #include <dali/devel-api/scripting/scripting.h>
39 #include <dali/public-api/adaptor-framework/native-image-source.h>
40 #include <dali/public-api/object/type-registry-helper.h>
41 #include <dali/public-api/object/type-registry.h>
42 #include <cstring>
43 #include <memory>
44
45 // INTERNAL INCLUDES
46 #include <dali-toolkit/devel-api/controls/control-devel.h>
47 #include <dali-toolkit/devel-api/controls/web-view/web-back-forward-list.h>
48 #include <dali-toolkit/devel-api/controls/web-view/web-context.h>
49 #include <dali-toolkit/devel-api/controls/web-view/web-cookie-manager.h>
50 #include <dali-toolkit/devel-api/controls/web-view/web-settings.h>
51 #include <dali-toolkit/devel-api/image-loader/texture-manager.h>
52 #include <dali-toolkit/internal/visuals/visual-factory-impl.h>
53 #include <dali-toolkit/public-api/image-loader/image.h>
54 #include <dali-toolkit/public-api/visuals/image-visual-properties.h>
55 #include <dali-toolkit/public-api/image-loader/image-url.h>
56
57 namespace Dali
58 {
59 namespace Toolkit
60 {
61 namespace Internal
62 {
63 namespace
64 {
65 BaseHandle Create()
66 {
67   return Toolkit::WebView::New();
68 }
69
70 // clang-format off
71 DALI_TYPE_REGISTRATION_BEGIN(Toolkit::WebView, Toolkit::Control, Create)
72
73 DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "url",                     STRING,  URL                       )
74 DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "userAgent",               STRING,  USER_AGENT                )
75 DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "scrollPosition",          VECTOR2, SCROLL_POSITION           )
76 DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "scrollSize",              VECTOR2, SCROLL_SIZE               )
77 DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "contentSize",             VECTOR2, CONTENT_SIZE              )
78 DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "title",                   STRING,  TITLE                     )
79 DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "videoHoleEnabled",        BOOLEAN, VIDEO_HOLE_ENABLED        )
80 DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "mouseEventsEnabled",      BOOLEAN, MOUSE_EVENTS_ENABLED      )
81 DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "keyEventsEnabled",        BOOLEAN, KEY_EVENTS_ENABLED        )
82 DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "documentBackgroundColor", VECTOR4, DOCUMENT_BACKGROUND_COLOR )
83 DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "tilesClearedWhenHidden",  BOOLEAN, TILES_CLEARED_WHEN_HIDDEN )
84 DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "tileCoverAreaMultiplier", FLOAT,   TILE_COVER_AREA_MULTIPLIER)
85 DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "cursorEnabledByClient",   BOOLEAN, CURSOR_ENABLED_BY_CLIENT  )
86 DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "selectedText",            STRING,  SELECTED_TEXT             )
87 DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "pageZoomFactor",          FLOAT,   PAGE_ZOOM_FACTOR          )
88 DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "textZoomFactor",          FLOAT,   TEXT_ZOOM_FACTOR          )
89 DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "loadProgressPercentage",  FLOAT,   LOAD_PROGRESS_PERCENTAGE  )
90
91 DALI_TYPE_REGISTRATION_END()
92 // clang-format on
93
94 } // namespace
95
96 #define GET_ENUM_STRING(structName, inputExp) \
97   Scripting::GetLinearEnumerationName<Toolkit::WebView::structName::Type>(static_cast<Toolkit::WebView::structName::Type>(inputExp), structName##_TABLE, structName##_TABLE_COUNT)
98
99 #define GET_ENUM_VALUE(structName, inputExp, outputExp) \
100   Scripting::GetEnumerationProperty<Toolkit::WebView::structName::Type>(inputExp, structName##_TABLE, structName##_TABLE_COUNT, outputExp)
101
102 WebView::WebView(const std::string& locale, const std::string& timezoneId)
103 : Control(ControlBehaviour(ACTOR_BEHAVIOUR_DEFAULT | DISABLE_STYLE_CHANGE_SIGNALS)),
104   mVisual(),
105   mWebViewSize(Stage::GetCurrent().GetSize()),
106   mWebEngine(),
107   mWebViewArea(0, 0, mWebViewSize.width, mWebViewSize.height),
108   mVideoHoleEnabled(false),
109   mMouseEventsEnabled(true),
110   mKeyEventsEnabled(true),
111   mScreenshotCapturedCallback(nullptr)
112 {
113   mWebEngine = Dali::WebEngine::New();
114
115   // WebEngine is empty when it is not properly initialized.
116   if(mWebEngine)
117   {
118     mWebEngine.Create(mWebViewSize.width, mWebViewSize.height, locale, timezoneId);
119   }
120 }
121
122 WebView::WebView(uint32_t argc, char** argv)
123 : Control(ControlBehaviour(ACTOR_BEHAVIOUR_DEFAULT | DISABLE_STYLE_CHANGE_SIGNALS)),
124   mVisual(),
125   mWebViewSize(Stage::GetCurrent().GetSize()),
126   mWebEngine(),
127   mWebViewArea(0, 0, mWebViewSize.width, mWebViewSize.height),
128   mVideoHoleEnabled(false),
129   mMouseEventsEnabled(true),
130   mKeyEventsEnabled(true),
131   mScreenshotCapturedCallback(nullptr)
132 {
133   mWebEngine = Dali::WebEngine::New();
134
135   // WebEngine is empty when it is not properly initialized.
136   if(mWebEngine)
137   {
138     mWebEngine.Create(mWebViewSize.width, mWebViewSize.height, argc, argv);
139   }
140 }
141
142 WebView::WebView()
143 : WebView("", "")
144 {
145 }
146
147 WebView::~WebView()
148 {
149   if(mWebEngine)
150   {
151     mWebEngine.FrameRenderedSignal().Disconnect(this, &WebView::OnFrameRendered);
152     mWebEngine.Destroy();
153   }
154 }
155
156 Toolkit::WebView WebView::New()
157 {
158   WebView*         impl   = new WebView();
159   Toolkit::WebView handle = Toolkit::WebView(*impl);
160
161   impl->Initialize();
162   return handle;
163 }
164
165 Toolkit::WebView WebView::New(const std::string& locale, const std::string& timezoneId)
166 {
167   WebView*         impl   = new WebView(locale, timezoneId);
168   Toolkit::WebView handle = Toolkit::WebView(*impl);
169
170   impl->Initialize();
171   return handle;
172 }
173
174 Toolkit::WebView WebView::New(uint32_t argc, char** argv)
175 {
176   WebView*         impl   = new WebView(argc, argv);
177   Toolkit::WebView handle = Toolkit::WebView(*impl);
178
179   impl->Initialize();
180   return handle;
181 }
182
183 void WebView::OnInitialize()
184 {
185   Actor self = Self();
186
187   self.SetProperty(Actor::Property::KEYBOARD_FOCUSABLE, true);
188   self.TouchedSignal().Connect(this, &WebView::OnTouchEvent);
189   self.HoveredSignal().Connect(this, &WebView::OnHoverEvent);
190   self.WheelEventSignal().Connect(this, &WebView::OnWheelEvent);
191   Dali::DevelActor::VisibilityChangedSignal(self).Connect(this, &WebView::OnVisibilityChanged);
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.FrameRenderedSignal().Connect(this, &WebView::OnFrameRendered);
203     mWebContext         = std::unique_ptr<Dali::Toolkit::WebContext>(new WebContext(mWebEngine.GetContext()));
204     mWebCookieManager   = std::unique_ptr<Dali::Toolkit::WebCookieManager>(new WebCookieManager(mWebEngine.GetCookieManager()));
205     mWebSettings        = std::unique_ptr<Dali::Toolkit::WebSettings>(new WebSettings(mWebEngine.GetSettings()));
206     mWebBackForwardList = std::unique_ptr<Dali::Toolkit::WebBackForwardList>(new WebBackForwardList(mWebEngine.GetBackForwardList()));
207   }
208 }
209
210 Dali::Toolkit::WebSettings* WebView::GetSettings() const
211 {
212   return mWebSettings.get();
213 }
214
215 Dali::Toolkit::WebContext* WebView::GetContext() const
216 {
217   return mWebContext.get();
218 }
219
220 Dali::Toolkit::WebCookieManager* WebView::GetCookieManager() const
221 {
222   return mWebCookieManager.get();
223 }
224
225 Dali::Toolkit::WebBackForwardList* WebView::GetBackForwardList() const
226 {
227   return mWebBackForwardList.get();
228 }
229
230 Dali::Toolkit::ImageView WebView::GetFavicon() const
231 {
232   Dali::Toolkit::ImageView faviconView;
233   if(mWebEngine)
234   {
235     Dali::PixelData pixelData = mWebEngine.GetFavicon();
236     faviconView               = CreateImageView(pixelData);
237   }
238   return faviconView;
239 }
240
241 void WebView::LoadUrl(const std::string& url)
242 {
243   if(mWebEngine)
244   {
245     if(!mVisual)
246     {
247       mWebEngine.FrameRenderedSignal().Connect(this, &WebView::OnInitialFrameRendered);
248     }
249
250     mWebEngine.LoadUrl(url);
251   }
252 }
253
254 void WebView::LoadHtmlString(const std::string& htmlString)
255 {
256   if(mWebEngine)
257   {
258     if(!mVisual)
259     {
260       mWebEngine.FrameRenderedSignal().Connect(this, &WebView::OnInitialFrameRendered);
261     }
262
263     mWebEngine.LoadHtmlString(htmlString);
264   }
265 }
266
267 bool WebView::LoadHtmlStringOverrideCurrentEntry(const std::string& html, const std::string& basicUri, const std::string& unreachableUrl)
268 {
269   if(!mWebEngine)
270     return false;
271
272   if(!mVisual)
273   {
274     mWebEngine.FrameRenderedSignal().Connect(this, &WebView::OnInitialFrameRendered);
275   }
276
277   return mWebEngine.LoadHtmlStringOverrideCurrentEntry(html, basicUri, unreachableUrl);
278 }
279
280 bool WebView::LoadContents(const std::string& contents, uint32_t contentSize, const std::string& mimeType, const std::string& encoding, const std::string& baseUri)
281 {
282   if(!mWebEngine)
283     return false;
284
285   if(!mVisual)
286   {
287     mWebEngine.FrameRenderedSignal().Connect(this, &WebView::OnInitialFrameRendered);
288   }
289
290   return mWebEngine.LoadContents(contents, contentSize, mimeType, encoding, baseUri);
291 }
292
293 void WebView::Reload()
294 {
295   if(mWebEngine)
296   {
297     mWebEngine.Reload();
298   }
299 }
300
301 bool WebView::ReloadWithoutCache()
302 {
303   return mWebEngine ? mWebEngine.ReloadWithoutCache() : false;
304 }
305
306 void WebView::StopLoading()
307 {
308   if(mWebEngine)
309   {
310     mWebEngine.StopLoading();
311   }
312 }
313
314 void WebView::Suspend()
315 {
316   if(mWebEngine)
317   {
318     mWebEngine.Suspend();
319   }
320 }
321
322 void WebView::Resume()
323 {
324   if(mWebEngine)
325   {
326     mWebEngine.Resume();
327   }
328 }
329
330 void WebView::SuspendNetworkLoading()
331 {
332   if(mWebEngine)
333   {
334     mWebEngine.SuspendNetworkLoading();
335   }
336 }
337
338 void WebView::ResumeNetworkLoading()
339 {
340   if(mWebEngine)
341   {
342     mWebEngine.ResumeNetworkLoading();
343   }
344 }
345
346 bool WebView::AddCustomHeader(const std::string& name, const std::string& value)
347 {
348   return mWebEngine ? mWebEngine.AddCustomHeader(name, value) : false;
349 }
350
351 bool WebView::RemoveCustomHeader(const std::string& name)
352 {
353   return mWebEngine ? mWebEngine.RemoveCustomHeader(name) : false;
354 }
355
356 uint32_t WebView::StartInspectorServer(uint32_t port)
357 {
358   return mWebEngine ? mWebEngine.StartInspectorServer(port) : false;
359 }
360
361 bool WebView::StopInspectorServer()
362 {
363   return mWebEngine ? mWebEngine.StopInspectorServer() : false;
364 }
365
366 void WebView::ScrollBy(int32_t deltaX, int32_t deltaY)
367 {
368   if(mWebEngine)
369   {
370     mWebEngine.ScrollBy(deltaX, deltaY);
371   }
372 }
373
374 bool WebView::ScrollEdgeBy(int32_t deltaX, int32_t deltaY)
375 {
376   return mWebEngine ? mWebEngine.ScrollEdgeBy(deltaX, deltaY) : false;
377 }
378
379 bool WebView::CanGoForward()
380 {
381   return mWebEngine ? mWebEngine.CanGoForward() : false;
382 }
383
384 void WebView::GoForward()
385 {
386   if(mWebEngine)
387   {
388     mWebEngine.GoForward();
389   }
390 }
391
392 bool WebView::CanGoBack()
393 {
394   return mWebEngine ? mWebEngine.CanGoBack() : false;
395 }
396
397 void WebView::GoBack()
398 {
399   if(mWebEngine)
400   {
401     mWebEngine.GoBack();
402   }
403 }
404
405 void WebView::EvaluateJavaScript(const std::string& script, std::function<void(const std::string&)> resultHandler)
406 {
407   if(mWebEngine)
408   {
409     mWebEngine.EvaluateJavaScript(script, resultHandler);
410   }
411 }
412
413 void WebView::AddJavaScriptMessageHandler(const std::string& exposedObjectName, std::function<void(const std::string&)> handler)
414 {
415   if(mWebEngine)
416   {
417     mWebEngine.AddJavaScriptMessageHandler(exposedObjectName, handler);
418   }
419 }
420
421 void WebView::RegisterJavaScriptAlertCallback(Dali::WebEnginePlugin::JavaScriptAlertCallback callback)
422 {
423   if(mWebEngine)
424   {
425     mWebEngine.RegisterJavaScriptAlertCallback(callback);
426   }
427 }
428
429 void WebView::JavaScriptAlertReply()
430 {
431   if(mWebEngine)
432   {
433     mWebEngine.JavaScriptAlertReply();
434   }
435 }
436
437 void WebView::RegisterJavaScriptConfirmCallback(Dali::WebEnginePlugin::JavaScriptConfirmCallback callback)
438 {
439   if(mWebEngine)
440   {
441     mWebEngine.RegisterJavaScriptConfirmCallback(callback);
442   }
443 }
444
445 void WebView::JavaScriptConfirmReply(bool confirmed)
446 {
447   if(mWebEngine)
448   {
449     mWebEngine.JavaScriptConfirmReply(confirmed);
450   }
451 }
452
453 void WebView::RegisterJavaScriptPromptCallback(Dali::WebEnginePlugin::JavaScriptPromptCallback callback)
454 {
455   if(mWebEngine)
456   {
457     mWebEngine.RegisterJavaScriptPromptCallback(callback);
458   }
459 }
460
461 void WebView::JavaScriptPromptReply(const std::string& result)
462 {
463   if(mWebEngine)
464   {
465     mWebEngine.JavaScriptPromptReply(result);
466   }
467 }
468
469 std::unique_ptr<Dali::WebEngineHitTest> WebView::CreateHitTest(int32_t x, int32_t y, Dali::WebEngineHitTest::HitTestMode mode)
470 {
471   std::unique_ptr<Dali::WebEngineHitTest> webHitTest;
472   if(!mWebEngine)
473   {
474     return webHitTest;
475   }
476
477   return mWebEngine.CreateHitTest(x, y, mode);
478 }
479
480 bool WebView::CreateHitTestAsynchronously(int32_t x, int32_t y, Dali::WebEngineHitTest::HitTestMode mode, Dali::WebEnginePlugin::WebEngineHitTestCreatedCallback callback)
481 {
482   bool result = false;
483   if(mWebEngine)
484   {
485     result = mWebEngine.CreateHitTestAsynchronously(x, y, mode, callback);
486   }
487   return result;
488 }
489
490 void WebView::ClearHistory()
491 {
492   if(mWebEngine)
493   {
494     mWebEngine.ClearHistory();
495   }
496 }
497
498 void WebView::ClearAllTilesResources()
499 {
500   if(mWebEngine)
501   {
502     mWebEngine.ClearAllTilesResources();
503   }
504 }
505
506 void WebView::SetScaleFactor(float scaleFactor, Dali::Vector2 point)
507 {
508   if(mWebEngine)
509   {
510     mWebEngine.SetScaleFactor(scaleFactor, point);
511   }
512 }
513
514 float WebView::GetScaleFactor() const
515 {
516   return mWebEngine ? mWebEngine.GetScaleFactor() : 0.0f;
517 }
518
519 void WebView::ActivateAccessibility(bool activated)
520 {
521   if(mWebEngine)
522   {
523     mWebEngine.ActivateAccessibility(activated);
524   }
525 }
526
527 bool WebView::HighlightText(const std::string& text, Dali::WebEnginePlugin::FindOption options, uint32_t maxMatchCount)
528 {
529   return mWebEngine ? mWebEngine.HighlightText(text, options, maxMatchCount) : false;
530 }
531
532 void WebView::AddDynamicCertificatePath(const std::string& host, const std::string& certPath)
533 {
534   if(mWebEngine)
535   {
536     mWebEngine.AddDynamicCertificatePath(host, certPath);
537   }
538 }
539
540 Dali::Toolkit::ImageView WebView::GetScreenshot(Dali::Rect<int32_t> viewArea, float scaleFactor)
541 {
542   Dali::Toolkit::ImageView imageView;
543   if(mWebEngine)
544   {
545     Dali::PixelData pixelData = mWebEngine.GetScreenshot(viewArea, scaleFactor);
546     imageView                 = CreateImageView(pixelData);
547   }
548   return imageView;
549 }
550
551 bool WebView::GetScreenshotAsynchronously(Dali::Rect<int32_t> viewArea, float scaleFactor, Dali::Toolkit::WebView::WebViewScreenshotCapturedCallback callback)
552 {
553   mScreenshotCapturedCallback = callback;
554   return mWebEngine ? mWebEngine.GetScreenshotAsynchronously(viewArea, scaleFactor, std::bind(&WebView::OnScreenshotCaptured, this, std::placeholders::_1)) : false;
555 }
556
557 bool WebView::CheckVideoPlayingAsynchronously(Dali::WebEnginePlugin::VideoPlayingCallback callback)
558 {
559   return mWebEngine ? mWebEngine.CheckVideoPlayingAsynchronously(callback) : false;
560 }
561
562 void WebView::RegisterGeolocationPermissionCallback(Dali::WebEnginePlugin::GeolocationPermissionCallback callback)
563 {
564   if(mWebEngine)
565   {
566     mWebEngine.RegisterGeolocationPermissionCallback(callback);
567   }
568 }
569
570 void WebView::SetTtsFocus(bool focused)
571 {
572   if(mWebEngine && !HasKeyInputFocus())
573   {
574     mWebEngine.SetFocus(focused);
575   }
576 }
577
578 void WebView::UpdateDisplayArea(Dali::PropertyNotification& /*source*/)
579 {
580   if(!mWebEngine)
581     return;
582
583   Actor self(Self());
584
585   bool    positionUsesAnchorPoint = self.GetProperty<bool>(Actor::Property::POSITION_USES_ANCHOR_POINT);
586   Vector3 actorSize               = self.GetCurrentProperty<Vector3>(Actor::Property::SIZE) * self.GetCurrentProperty<Vector3>(Actor::Property::SCALE);
587   Vector3 anchorPointOffSet       = actorSize * (positionUsesAnchorPoint ? self.GetCurrentProperty<Vector3>(Actor::Property::ANCHOR_POINT) : AnchorPoint::TOP_LEFT);
588   Vector2 screenPosition          = self.GetProperty<Vector2>(Actor::Property::SCREEN_POSITION);
589
590   Dali::Rect<int32_t> displayArea;
591   displayArea.x      = screenPosition.x - anchorPointOffSet.x;
592   displayArea.y      = screenPosition.y - anchorPointOffSet.y;
593   displayArea.width  = actorSize.x;
594   displayArea.height = actorSize.y;
595
596   Size displaySize = Size(displayArea.width, displayArea.height);
597   if(mWebViewSize != displaySize)
598   {
599     mWebViewSize = displaySize;
600   }
601
602   if(mWebViewArea != displayArea)
603   {
604     mWebViewArea = displayArea;
605     mWebEngine.UpdateDisplayArea(mWebViewArea);
606   }
607 }
608
609 void WebView::EnableVideoHole(bool enabled)
610 {
611   mVideoHoleEnabled = enabled;
612
613   EnableBlendMode(!mVideoHoleEnabled);
614
615   if(mWebEngine)
616   {
617     mWebEngine.EnableVideoHole(mVideoHoleEnabled);
618   }
619 }
620
621 void WebView::EnableBlendMode(bool blendEnabled)
622 {
623   Actor self = Self();
624   for(uint32_t i = 0; i < self.GetRendererCount(); i++)
625   {
626     Dali::Renderer render = self.GetRendererAt(i);
627     render.SetProperty(Renderer::Property::BLEND_MODE, blendEnabled ? BlendMode::ON : BlendMode::OFF);
628   }
629 }
630
631 Dali::Toolkit::ImageView WebView::CreateImageView(Dali::PixelData pixel) const
632 {
633   if(!pixel)
634   {
635     return Dali::Toolkit::ImageView();
636   }
637
638   Dali::Toolkit::ImageUrl url       = Dali::Toolkit::Image::GenerateUrl(pixel);
639   Dali::Toolkit::ImageView imageView = Dali::Toolkit::ImageView::New(url.GetUrl());
640   imageView.SetProperty(Dali::Actor::Property::SIZE, Vector2(pixel.GetWidth(), pixel.GetHeight()));
641   return imageView;
642 }
643
644 void WebView::RegisterPageLoadStartedCallback(Dali::WebEnginePlugin::WebEnginePageLoadCallback callback)
645 {
646   if(mWebEngine)
647   {
648     mWebEngine.RegisterPageLoadStartedCallback(callback);
649   }
650 }
651
652 void WebView::RegisterPageLoadInProgressCallback(Dali::WebEnginePlugin::WebEnginePageLoadCallback callback)
653 {
654   if(mWebEngine)
655   {
656     mWebEngine.RegisterPageLoadInProgressCallback(callback);
657   }
658 }
659
660 void WebView::RegisterPageLoadFinishedCallback(Dali::WebEnginePlugin::WebEnginePageLoadCallback callback)
661 {
662   if(mWebEngine)
663   {
664     mWebEngine.RegisterPageLoadFinishedCallback(callback);
665   }
666 }
667
668 void WebView::RegisterPageLoadErrorCallback(Dali::WebEnginePlugin::WebEnginePageLoadErrorCallback callback)
669 {
670   if(mWebEngine)
671   {
672     mWebEngine.RegisterPageLoadErrorCallback(callback);
673   }
674 }
675
676 void WebView::RegisterScrollEdgeReachedCallback(Dali::WebEnginePlugin::WebEngineScrollEdgeReachedCallback callback)
677 {
678   if(mWebEngine)
679   {
680     mWebEngine.RegisterScrollEdgeReachedCallback(callback);
681   }
682 }
683
684 void WebView::RegisterUrlChangedCallback(Dali::WebEnginePlugin::WebEngineUrlChangedCallback callback)
685 {
686   if(mWebEngine)
687   {
688     mWebEngine.RegisterUrlChangedCallback(callback);
689   }
690 }
691
692 void WebView::RegisterFormRepostDecidedCallback(Dali::WebEnginePlugin::WebEngineFormRepostDecidedCallback callback)
693 {
694   if(mWebEngine)
695   {
696     mWebEngine.RegisterFormRepostDecidedCallback(callback);
697   }
698 }
699
700 void WebView::RegisterFrameRenderedCallback(Dali::WebEnginePlugin::WebEngineFrameRenderedCallback callback)
701 {
702   mFrameRenderedCallback = callback;
703 }
704
705 void WebView::RegisterRequestInterceptorCallback(Dali::WebEnginePlugin::WebEngineRequestInterceptorCallback callback)
706 {
707   if(mWebEngine)
708   {
709     mWebEngine.RegisterRequestInterceptorCallback(callback);
710   }
711 }
712
713 void WebView::RegisterConsoleMessageReceivedCallback(Dali::WebEnginePlugin::WebEngineConsoleMessageReceivedCallback callback)
714 {
715   if(mWebEngine)
716   {
717     mWebEngine.RegisterConsoleMessageReceivedCallback(callback);
718   }
719 }
720
721 void WebView::RegisterResponsePolicyDecidedCallback(Dali::WebEnginePlugin::WebEngineResponsePolicyDecidedCallback callback)
722 {
723   if(mWebEngine)
724   {
725     mWebEngine.RegisterResponsePolicyDecidedCallback(callback);
726   }
727 }
728
729 void WebView::RegisterCertificateConfirmedCallback(Dali::WebEnginePlugin::WebEngineCertificateCallback callback)
730 {
731   if(mWebEngine)
732   {
733     mWebEngine.RegisterCertificateConfirmedCallback(callback);
734   }
735 }
736
737 void WebView::RegisterSslCertificateChangedCallback(Dali::WebEnginePlugin::WebEngineCertificateCallback callback)
738 {
739   if(mWebEngine)
740   {
741     mWebEngine.RegisterSslCertificateChangedCallback(callback);
742   }
743 }
744
745 void WebView::RegisterHttpAuthHandlerCallback(Dali::WebEnginePlugin::WebEngineHttpAuthHandlerCallback callback)
746 {
747   if(mWebEngine)
748   {
749     mWebEngine.RegisterHttpAuthHandlerCallback(callback);
750   }
751 }
752
753 void WebView::RegisterContextMenuShownCallback(Dali::WebEnginePlugin::WebEngineContextMenuShownCallback callback)
754 {
755   if(mWebEngine)
756   {
757     mWebEngine.RegisterContextMenuShownCallback(callback);
758   }
759 }
760
761 void WebView::RegisterContextMenuHiddenCallback(Dali::WebEnginePlugin::WebEngineContextMenuHiddenCallback callback)
762 {
763   if(mWebEngine)
764   {
765     mWebEngine.RegisterContextMenuHiddenCallback(callback);
766   }
767 }
768
769 void WebView::OnFrameRendered()
770 {
771   if(mFrameRenderedCallback)
772   {
773     mFrameRenderedCallback();
774   }
775 }
776
777 void WebView::OnInitialFrameRendered()
778 {
779   mWebEngine.FrameRenderedSignal().Disconnect(this, &WebView::OnInitialFrameRendered);
780
781   Texture           texture        = Dali::Texture::New(*mWebEngine.GetNativeImageSource());
782   const std::string nativeImageUrl = Dali::Toolkit::TextureManager::AddTexture(texture);
783   mVisual                          = Toolkit::VisualFactory::Get().CreateVisual({{Toolkit::Visual::Property::TYPE, Toolkit::Visual::IMAGE}, {Toolkit::ImageVisual::Property::URL, nativeImageUrl}});
784
785   if(mVisual)
786   {
787     DevelControl::RegisterVisual(*this, Toolkit::WebView::Property::URL, mVisual);
788     EnableBlendMode(!mVideoHoleEnabled);
789   }
790 }
791
792 void WebView::OnVisibilityChanged(Actor actor, bool isVisible, Dali::DevelActor::VisibilityChange::Type type)
793 {
794   if(type == Dali::DevelActor::VisibilityChange::Type::SELF)
795   {
796     SetVisibility(isVisible);
797   }
798 }
799
800 void WebView::OnScreenshotCaptured(Dali::PixelData pixel)
801 {
802   if(mScreenshotCapturedCallback)
803   {
804     Dali::Toolkit::ImageView imageView = CreateImageView(pixel);
805     mScreenshotCapturedCallback(imageView);
806   }
807 }
808
809 void WebView::OnSceneConnection(int depth)
810 {
811   Control::OnSceneConnection(depth);
812   EnableBlendMode(!mVideoHoleEnabled);
813 }
814
815 bool WebView::OnTouchEvent(Actor actor, const Dali::TouchEvent& touch)
816 {
817   bool result = false;
818
819   if(mWebEngine)
820   {
821     result = mWebEngine.SendTouchEvent(touch);
822   }
823   return result;
824 }
825
826 bool WebView::OnKeyEvent(const Dali::KeyEvent& event)
827 {
828   bool result = false;
829
830   if(mWebEngine)
831   {
832     result = mWebEngine.SendKeyEvent(event);
833   }
834   return result;
835 }
836
837 bool WebView::OnHoverEvent(Actor actor, const Dali::HoverEvent& hover)
838 {
839   bool result = false;
840   if(mWebEngine && mMouseEventsEnabled)
841   {
842     result = mWebEngine.SendHoverEvent(hover);
843   }
844   return result;
845 }
846
847 bool WebView::OnWheelEvent(Actor actor, const Dali::WheelEvent& wheel)
848 {
849   bool result = false;
850   if(mWebEngine && mMouseEventsEnabled)
851   {
852     result = mWebEngine.SendWheelEvent(wheel);
853   }
854   return result;
855 }
856
857 void WebView::OnKeyInputFocusGained()
858 {
859   if(mWebEngine)
860   {
861     mWebEngine.SetFocus(true);
862   }
863
864   EmitKeyInputFocusSignal(true); // Calls back into the Control hence done last.
865 }
866
867 void WebView::OnKeyInputFocusLost()
868 {
869   if(mWebEngine)
870   {
871     mWebEngine.SetFocus(false);
872   }
873
874   EmitKeyInputFocusSignal(false); // Calls back into the Control hence done last.
875 }
876
877 Vector3 WebView::GetNaturalSize()
878 {
879   if(mVisual)
880   {
881     Vector2 rendererNaturalSize;
882     mVisual.GetNaturalSize(rendererNaturalSize);
883     return Vector3(rendererNaturalSize);
884   }
885
886   return Vector3(mWebViewSize);
887 }
888
889 void WebView::SetProperty(BaseObject* object, Property::Index index, const Property::Value& value)
890 {
891   Toolkit::WebView webView = Toolkit::WebView::DownCast(Dali::BaseHandle(object));
892
893   if(webView)
894   {
895     WebView& impl = GetImpl(webView);
896     switch(index)
897     {
898       case Toolkit::WebView::Property::URL:
899       {
900         std::string url;
901         if(value.Get(url))
902         {
903           impl.LoadUrl(url);
904         }
905         break;
906       }
907       case Toolkit::WebView::Property::USER_AGENT:
908       {
909         std::string input;
910         if(value.Get(input))
911         {
912           impl.SetUserAgent(input);
913         }
914         break;
915       }
916       case Toolkit::WebView::Property::SCROLL_POSITION:
917       {
918         Vector2 input;
919         if(value.Get(input))
920         {
921           impl.SetScrollPosition(input.x, input.y);
922         }
923         break;
924       }
925       case Toolkit::WebView::Property::VIDEO_HOLE_ENABLED:
926       {
927         bool input;
928         if(value.Get(input))
929         {
930           impl.EnableVideoHole(input);
931         }
932         break;
933       }
934       case Toolkit::WebView::Property::MOUSE_EVENTS_ENABLED:
935       {
936         bool input;
937         if(value.Get(input))
938         {
939           impl.EnableMouseEvents(input);
940         }
941         break;
942       }
943       case Toolkit::WebView::Property::KEY_EVENTS_ENABLED:
944       {
945         bool input;
946         if(value.Get(input))
947         {
948           impl.EnableKeyEvents(input);
949         }
950         break;
951       }
952       case Toolkit::WebView::Property::DOCUMENT_BACKGROUND_COLOR:
953       {
954         Vector4 input;
955         if(value.Get(input))
956         {
957           impl.SetDocumentBackgroundColor(input);
958         }
959         break;
960       }
961       case Toolkit::WebView::Property::TILES_CLEARED_WHEN_HIDDEN:
962       {
963         bool input;
964         if(value.Get(input))
965         {
966           impl.ClearTilesWhenHidden(input);
967         }
968         break;
969       }
970       case Toolkit::WebView::Property::TILE_COVER_AREA_MULTIPLIER:
971       {
972         float input;
973         if(value.Get(input))
974         {
975           impl.SetTileCoverAreaMultiplier(input);
976         }
977         break;
978       }
979       case Toolkit::WebView::Property::CURSOR_ENABLED_BY_CLIENT:
980       {
981         bool input;
982         if(value.Get(input))
983         {
984           impl.EnableCursorByClient(input);
985         }
986         break;
987       }
988       case Toolkit::WebView::Property::PAGE_ZOOM_FACTOR:
989       {
990         float input;
991         if(value.Get(input))
992         {
993           impl.SetPageZoomFactor(input);
994         }
995         break;
996       }
997       case Toolkit::WebView::Property::TEXT_ZOOM_FACTOR:
998       {
999         float input;
1000         if(value.Get(input))
1001         {
1002           impl.SetTextZoomFactor(input);
1003         }
1004         break;
1005       }
1006       default:
1007         break;
1008     }
1009   }
1010 }
1011
1012 Property::Value WebView::GetProperty(BaseObject* object, Property::Index propertyIndex)
1013 {
1014   Property::Value value;
1015
1016   Toolkit::WebView webView = Toolkit::WebView::DownCast(Dali::BaseHandle(object));
1017
1018   if(webView)
1019   {
1020     WebView& impl = GetImpl(webView);
1021     switch(propertyIndex)
1022     {
1023       case Toolkit::WebView::Property::URL:
1024       {
1025         value = impl.GetUrl();
1026         break;
1027       }
1028       case Toolkit::WebView::Property::USER_AGENT:
1029       {
1030         value = impl.GetUserAgent();
1031         break;
1032       }
1033       case Toolkit::WebView::Property::SCROLL_POSITION:
1034       {
1035         value = impl.GetScrollPosition();
1036         break;
1037       }
1038       case Toolkit::WebView::Property::SCROLL_SIZE:
1039       {
1040         value = impl.GetScrollSize();
1041         break;
1042       }
1043       case Toolkit::WebView::Property::CONTENT_SIZE:
1044       {
1045         value = impl.GetContentSize();
1046         break;
1047       }
1048       case Toolkit::WebView::Property::TITLE:
1049       {
1050         value = impl.GetTitle();
1051         break;
1052       }
1053       case Toolkit::WebView::Property::VIDEO_HOLE_ENABLED:
1054       {
1055         value = impl.mVideoHoleEnabled;
1056         break;
1057       }
1058       case Toolkit::WebView::Property::MOUSE_EVENTS_ENABLED:
1059       {
1060         value = impl.mMouseEventsEnabled;
1061         break;
1062       }
1063       case Toolkit::WebView::Property::KEY_EVENTS_ENABLED:
1064       {
1065         value = impl.mKeyEventsEnabled;
1066         break;
1067       }
1068       case Toolkit::WebView::Property::SELECTED_TEXT:
1069       {
1070         value = impl.GetSelectedText();
1071         break;
1072       }
1073       case Toolkit::WebView::Property::PAGE_ZOOM_FACTOR:
1074       {
1075         value = impl.GetPageZoomFactor();
1076         break;
1077       }
1078       case Toolkit::WebView::Property::TEXT_ZOOM_FACTOR:
1079       {
1080         value = impl.GetTextZoomFactor();
1081         break;
1082       }
1083       case Toolkit::WebView::Property::LOAD_PROGRESS_PERCENTAGE:
1084       {
1085         value = impl.GetLoadProgressPercentage();
1086         break;
1087       }
1088       default:
1089         break;
1090     }
1091   }
1092
1093   return value;
1094 }
1095
1096 void WebView::SetScrollPosition(int32_t x, int32_t y)
1097 {
1098   if(mWebEngine)
1099   {
1100     mWebEngine.SetScrollPosition(x, y);
1101   }
1102 }
1103
1104 Dali::Vector2 WebView::GetScrollPosition() const
1105 {
1106   return mWebEngine ? mWebEngine.GetScrollPosition() : Dali::Vector2::ZERO;
1107 }
1108
1109 Dali::Vector2 WebView::GetScrollSize() const
1110 {
1111   return mWebEngine ? mWebEngine.GetScrollSize() : Dali::Vector2::ZERO;
1112 }
1113
1114 Dali::Vector2 WebView::GetContentSize() const
1115 {
1116   return mWebEngine ? mWebEngine.GetContentSize() : Dali::Vector2::ZERO;
1117 }
1118
1119 std::string WebView::GetTitle() const
1120 {
1121   return mWebEngine ? mWebEngine.GetTitle() : std::string();
1122 }
1123
1124 void WebView::SetDocumentBackgroundColor(Dali::Vector4 color)
1125 {
1126   if(mWebEngine)
1127   {
1128     mWebEngine.SetDocumentBackgroundColor(color);
1129   }
1130 }
1131
1132 void WebView::ClearTilesWhenHidden(bool cleared)
1133 {
1134   if(mWebEngine)
1135   {
1136     mWebEngine.ClearTilesWhenHidden(cleared);
1137   }
1138 }
1139
1140 void WebView::SetTileCoverAreaMultiplier(float multiplier)
1141 {
1142   if(mWebEngine)
1143   {
1144     mWebEngine.SetTileCoverAreaMultiplier(multiplier);
1145   }
1146 }
1147
1148 void WebView::EnableCursorByClient(bool enabled)
1149 {
1150   if(mWebEngine)
1151   {
1152     mWebEngine.EnableCursorByClient(enabled);
1153   }
1154 }
1155
1156 std::string WebView::GetSelectedText() const
1157 {
1158   return mWebEngine ? mWebEngine.GetSelectedText() : std::string();
1159 }
1160
1161 std::string WebView::GetUrl() const
1162 {
1163   return mWebEngine ? mWebEngine.GetUrl() : std::string();
1164 }
1165
1166 std::string WebView::GetUserAgent() const
1167 {
1168   return mWebEngine ? mWebEngine.GetUserAgent() : std::string();
1169 }
1170
1171 void WebView::SetUserAgent(const std::string& userAgent)
1172 {
1173   if(mWebEngine)
1174   {
1175     mWebEngine.SetUserAgent(userAgent);
1176   }
1177 }
1178
1179 void WebView::EnableMouseEvents(bool enabled)
1180 {
1181   if(mWebEngine)
1182   {
1183     mMouseEventsEnabled = enabled;
1184     mWebEngine.EnableMouseEvents(enabled);
1185   }
1186 }
1187
1188 void WebView::EnableKeyEvents(bool enabled)
1189 {
1190   if(mWebEngine)
1191   {
1192     mKeyEventsEnabled = enabled;
1193     mWebEngine.EnableKeyEvents(enabled);
1194   }
1195 }
1196
1197 void WebView::SetPageZoomFactor(float zoomFactor)
1198 {
1199   if(mWebEngine)
1200   {
1201     mWebEngine.SetPageZoomFactor(zoomFactor);
1202   }
1203 }
1204
1205 float WebView::GetPageZoomFactor() const
1206 {
1207   return mWebEngine ? mWebEngine.GetPageZoomFactor() : 0.0f;
1208 }
1209
1210 void WebView::SetTextZoomFactor(float zoomFactor)
1211 {
1212   if(mWebEngine)
1213   {
1214     mWebEngine.SetTextZoomFactor(zoomFactor);
1215   }
1216 }
1217
1218 float WebView::GetTextZoomFactor() const
1219 {
1220   return mWebEngine ? mWebEngine.GetTextZoomFactor() : 0.0f;
1221 }
1222
1223 float WebView::GetLoadProgressPercentage() const
1224 {
1225   return mWebEngine ? mWebEngine.GetLoadProgressPercentage() : 0.0f;
1226 }
1227
1228 bool WebView::SetVisibility(bool visible)
1229 {
1230   return mWebEngine ? mWebEngine.SetVisibility(visible) : false;
1231 }
1232
1233 #undef GET_ENUM_STRING
1234 #undef GET_ENUM_VALUE
1235
1236 } // namespace Internal
1237
1238 } // namespace Toolkit
1239
1240 } // namespace Dali