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