c121cc712fbca19808e188fe4a969b81b1e14d27
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / web-view / web-view-impl.cpp
1 /*
2  * Copyright (c) 2024 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 <dali-toolkit/internal/controls/web-view/web-view-impl.h>
20
21 // EXTERNAL INCLUDES
22 #include <dali/devel-api/adaptor-framework/web-engine/web-engine-back-forward-list.h>
23 #include <dali/devel-api/adaptor-framework/web-engine/web-engine-certificate.h>
24 #include <dali/devel-api/adaptor-framework/web-engine/web-engine-console-message.h>
25 #include <dali/devel-api/adaptor-framework/web-engine/web-engine-context-menu-item.h>
26 #include <dali/devel-api/adaptor-framework/web-engine/web-engine-context-menu.h>
27 #include <dali/devel-api/adaptor-framework/web-engine/web-engine-context.h>
28 #include <dali/devel-api/adaptor-framework/web-engine/web-engine-cookie-manager.h>
29 #include <dali/devel-api/adaptor-framework/web-engine/web-engine-form-repost-decision.h>
30 #include <dali/devel-api/adaptor-framework/web-engine/web-engine-hit-test.h>
31 #include <dali/devel-api/adaptor-framework/web-engine/web-engine-http-auth-handler.h>
32 #include <dali/devel-api/adaptor-framework/web-engine/web-engine-load-error.h>
33 #include <dali/devel-api/adaptor-framework/web-engine/web-engine-policy-decision.h>
34 #include <dali/devel-api/adaptor-framework/web-engine/web-engine-settings.h>
35 #include <dali/devel-api/adaptor-framework/window-devel.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
43 // INTERNAL INCLUDES
44 #include <dali-toolkit/devel-api/controls/control-devel.h>
45 #include <dali-toolkit/devel-api/controls/web-view/web-back-forward-list.h>
46 #include <dali-toolkit/devel-api/controls/web-view/web-settings.h>
47 #include <dali-toolkit/devel-api/visuals/visual-actions-devel.h>
48 #include <dali-toolkit/internal/visuals/visual-base-impl.h>
49 #include <dali-toolkit/internal/visuals/visual-factory-impl.h>
50 #include <dali-toolkit/public-api/image-loader/image-url.h>
51 #include <dali-toolkit/public-api/image-loader/image.h>
52 #include <dali-toolkit/public-api/visuals/image-visual-properties.h>
53
54 #include <functional>
55 #include <memory>
56 #include <unordered_map>
57
58 namespace Dali
59 {
60 namespace Toolkit
61 {
62 namespace Internal
63 {
64 namespace
65 {
66 BaseHandle Create()
67 {
68   return Toolkit::WebView::New();
69 }
70
71 // clang-format off
72 DALI_TYPE_REGISTRATION_BEGIN(Toolkit::WebView, Toolkit::Control, Create)
73
74 DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "url",                     STRING,  URL                       )
75 DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "userAgent",               STRING,  USER_AGENT                )
76 DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "scrollPosition",          VECTOR2, SCROLL_POSITION           )
77 DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "scrollSize",              VECTOR2, SCROLL_SIZE               )
78 DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "contentSize",             VECTOR2, CONTENT_SIZE              )
79 DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "title",                   STRING,  TITLE                     )
80 DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "videoHoleEnabled",        BOOLEAN, VIDEO_HOLE_ENABLED        )
81 DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "mouseEventsEnabled",      BOOLEAN, MOUSE_EVENTS_ENABLED      )
82 DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "keyEventsEnabled",        BOOLEAN, KEY_EVENTS_ENABLED        )
83 DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "documentBackgroundColor", VECTOR4, DOCUMENT_BACKGROUND_COLOR )
84 DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "tilesClearedWhenHidden",  BOOLEAN, TILES_CLEARED_WHEN_HIDDEN )
85 DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "tileCoverAreaMultiplier", FLOAT,   TILE_COVER_AREA_MULTIPLIER)
86 DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "cursorEnabledByClient",   BOOLEAN, CURSOR_ENABLED_BY_CLIENT  )
87 DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "selectedText",            STRING,  SELECTED_TEXT             )
88 DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "pageZoomFactor",          FLOAT,   PAGE_ZOOM_FACTOR          )
89 DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "textZoomFactor",          FLOAT,   TEXT_ZOOM_FACTOR          )
90 DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "loadProgressPercentage",  FLOAT,   LOAD_PROGRESS_PERCENTAGE  )
91
92 DALI_TYPE_REGISTRATION_END()
93 // clang-format on
94
95 std::unordered_map<Dali::WebEnginePlugin*, Dali::WeakHandle<Toolkit::WebView>>& GetPluginWebViewTable()
96 {
97   static std::unordered_map<Dali::WebEnginePlugin*, Dali::WeakHandle<Toolkit::WebView>> pluginWebViewMap;
98   return pluginWebViewMap;
99 }
100
101 enum class DisplayAreaCalculateOption
102 {
103   PROPERTY         = 0, ///< Calculate display update area by property
104   CURRENT_PROPERTY = 1, ///< Calculate display update area by current property
105 };
106
107 /**
108  * @brief Helper function to calculate exact display area, offset and size.
109  * It will be useful when view size is not integer value, or view size is not matched with texture size.
110  *
111  * @param[in] self The view itself.
112  * @param[in] option Option of this calculation. Let we decide what kind of property will be used.
113  * @return DisplayArea for this view.
114  */
115 Rect<int32_t> CalculateDisplayArea(Dali::Actor self, DisplayAreaCalculateOption option)
116 {
117   bool    positionUsesAnchorPoint = self.GetProperty<bool>(Actor::Property::POSITION_USES_ANCHOR_POINT);
118   Vector3 actorSize               = (option == DisplayAreaCalculateOption::CURRENT_PROPERTY) ? self.GetCurrentProperty<Vector3>(Actor::Property::SIZE) * self.GetCurrentProperty<Vector3>(Actor::Property::SCALE)
119                                                                                              : self.GetProperty<Vector3>(Actor::Property::SIZE) * self.GetProperty<Vector3>(Actor::Property::SCALE);
120   Vector3 anchorPointOffSet       = actorSize * (positionUsesAnchorPoint ? self.GetCurrentProperty<Vector3>(Actor::Property::ANCHOR_POINT) : AnchorPoint::TOP_LEFT);
121   Vector2 screenPosition          = (option == DisplayAreaCalculateOption::CURRENT_PROPERTY) ? self.GetProperty<Vector2>(Actor::Property::SCREEN_POSITION)
122                                                                                              : Dali::DevelActor::CalculateScreenPosition(self);
123
124   Dali::Rect<int32_t> displayArea;
125   displayArea.x      = screenPosition.x - anchorPointOffSet.x;
126   displayArea.y      = screenPosition.y - anchorPointOffSet.y;
127   displayArea.width  = actorSize.x;
128   displayArea.height = actorSize.y;
129
130   return displayArea;
131 }
132
133 constexpr Vector4 FULL_TEXTURE_RECT(0.f, 0.f, 1.f, 1.f);
134
135 /**
136  * @brief Helper function to calculate exact pixel area value by view and texture size.
137  * It will be useful when view size is not integer value, or view size is not matched with texture size.
138  *
139  * @param[in] viewSize The size of view.
140  * @param[in] textureWidth The width of texture, that must be integer type.
141  * @param[in] textureHeight The height of texture, that must be integer type.
142  * @return PixelArea value that image visual can use.
143  */
144 Vector4 CalculatePixelArea(const Size& viewSize, const uint32_t textureWidth, const uint32_t textureHeight)
145 {
146   float widthRatio  = textureWidth == 0u ? 1.0f : viewSize.width / static_cast<float>(textureWidth);
147   float heightRatio = textureHeight == 0u ? 1.0f : viewSize.height / static_cast<float>(textureHeight);
148   return Vector4(0.0f, 0.0f, widthRatio, heightRatio);
149 }
150
151 } // namespace
152
153 WebView::WebView(const std::string& locale, const std::string& timezoneId)
154 : Control(ControlBehaviour(ACTOR_BEHAVIOUR_DEFAULT | DISABLE_STYLE_CHANGE_SIGNALS)),
155   mVisual(),
156   mWebViewSize(Stage::GetCurrent().GetSize()),
157   mWebEngine(),
158   mLastRenderedNativeImageWidth(0u),
159   mLastRenderedNativeImageHeight(0u),
160   mWebViewArea(0, 0, mWebViewSize.width, mWebViewSize.height),
161   mVideoHoleEnabled(false),
162   mMouseEventsEnabled(true),
163   mKeyEventsEnabled(true),
164   mVisualChangeRequired(false),
165   mScreenshotCapturedCallback{nullptr},
166   mFrameRenderedCallback{nullptr}
167 {
168   mWebEngine = Dali::WebEngine::New();
169
170   // WebEngine is empty when it is not properly initialized.
171   if(mWebEngine)
172   {
173     mWebEngine.Create(mWebViewSize.width, mWebViewSize.height, locale, timezoneId);
174   }
175 }
176
177 WebView::WebView(uint32_t argc, char** argv)
178 : Control(ControlBehaviour(ACTOR_BEHAVIOUR_DEFAULT | DISABLE_STYLE_CHANGE_SIGNALS)),
179   mVisual(),
180   mWebViewSize(Stage::GetCurrent().GetSize()),
181   mWebEngine(),
182   mLastRenderedNativeImageWidth(0u),
183   mLastRenderedNativeImageHeight(0u),
184   mWebViewArea(0, 0, mWebViewSize.width, mWebViewSize.height),
185   mVideoHoleEnabled(false),
186   mMouseEventsEnabled(true),
187   mKeyEventsEnabled(true),
188   mVisualChangeRequired(false),
189   mScreenshotCapturedCallback{nullptr},
190   mFrameRenderedCallback{nullptr}
191 {
192   mWebEngine = Dali::WebEngine::New();
193
194   // WebEngine is empty when it is not properly initialized.
195   if(mWebEngine)
196   {
197     mWebEngine.Create(mWebViewSize.width, mWebViewSize.height, argc, argv);
198   }
199 }
200
201 WebView::WebView()
202 : WebView("", "")
203 {
204 }
205
206 WebView::~WebView()
207 {
208   if(mWebEngine)
209   {
210     auto iter = GetPluginWebViewTable().find(mWebEngine.GetPlugin());
211     if(iter != GetPluginWebViewTable().end())
212     {
213       GetPluginWebViewTable().erase(iter);
214     }
215     mWebEngine.Destroy();
216   }
217 }
218
219 Toolkit::WebView WebView::New()
220 {
221   WebView*         impl   = new WebView();
222   Toolkit::WebView handle = Toolkit::WebView(*impl);
223   if(impl->GetPlugin())
224   {
225     GetPluginWebViewTable()[impl->GetPlugin()] = handle;
226   }
227   impl->Initialize();
228   return handle;
229 }
230
231 Toolkit::WebView WebView::New(const std::string& locale, const std::string& timezoneId)
232 {
233   WebView*         impl   = new WebView(locale, timezoneId);
234   Toolkit::WebView handle = Toolkit::WebView(*impl);
235   if(impl->GetPlugin())
236   {
237     GetPluginWebViewTable()[impl->GetPlugin()] = handle;
238   }
239   impl->Initialize();
240   return handle;
241 }
242
243 Toolkit::WebView WebView::New(uint32_t argc, char** argv)
244 {
245   WebView*         impl   = new WebView(argc, argv);
246   Toolkit::WebView handle = Toolkit::WebView(*impl);
247   if(impl->GetPlugin())
248   {
249     GetPluginWebViewTable()[impl->GetPlugin()] = handle;
250   }
251   impl->Initialize();
252   return handle;
253 }
254
255 Toolkit::WebView WebView::FindWebView(Dali::WebEnginePlugin* plugin)
256 {
257   auto iter = GetPluginWebViewTable().find(plugin);
258   if(iter != GetPluginWebViewTable().end())
259   {
260     return iter->second.GetHandle();
261   }
262   return Toolkit::WebView();
263 }
264
265 Dali::WebEngineContext* WebView::GetContext()
266 {
267   return Dali::WebEngine::GetContext();
268 }
269
270 Dali::WebEngineCookieManager* WebView::GetCookieManager()
271 {
272   return Dali::WebEngine::GetCookieManager();
273 }
274
275 void WebView::OnInitialize()
276 {
277   Actor self = Self();
278
279   self.SetProperty(Actor::Property::KEYBOARD_FOCUSABLE, true);
280   self.SetProperty(DevelActor::Property::TOUCH_FOCUSABLE, true);
281   self.TouchedSignal().Connect(this, &WebView::OnTouchEvent);
282   self.HoveredSignal().Connect(this, &WebView::OnHoverEvent);
283   self.WheelEventSignal().Connect(this, &WebView::OnWheelEvent);
284   Dali::DevelActor::VisibilityChangedSignal(self).Connect(this, &WebView::OnVisibilityChanged);
285
286   mWebViewVisibleState |= WebViewVisibleStateFlag::SELF_SHOW;
287
288   mPositionUpdateNotification = self.AddPropertyNotification(Actor::Property::WORLD_POSITION, StepCondition(1.0f, 1.0f));
289   mSizeUpdateNotification     = self.AddPropertyNotification(Actor::Property::SIZE, StepCondition(1.0f, 1.0f));
290   mScaleUpdateNotification    = self.AddPropertyNotification(Actor::Property::WORLD_SCALE, StepCondition(0.1f, 1.0f));
291   mPositionUpdateNotification.NotifySignal().Connect(this, &WebView::OnDisplayAreaUpdated);
292   mSizeUpdateNotification.NotifySignal().Connect(this, &WebView::OnDisplayAreaUpdated);
293   mScaleUpdateNotification.NotifySignal().Connect(this, &WebView::OnDisplayAreaUpdated);
294
295   if(mWebEngine)
296   {
297     mWebEngine.RegisterFrameRenderedCallback(std::bind(&WebView::OnFrameRendered, this));
298     mWebSettings        = std::unique_ptr<Dali::Toolkit::WebSettings>(new WebSettings(mWebEngine.GetSettings()));
299     mWebBackForwardList = std::unique_ptr<Dali::Toolkit::WebBackForwardList>(new WebBackForwardList(mWebEngine.GetBackForwardList()));
300   }
301
302   self.SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::FILLER);
303 }
304
305 DevelControl::ControlAccessible* WebView::CreateAccessibleObject()
306 {
307   return new WebViewAccessible(Self(), mWebEngine);
308 }
309
310 void WebView::OnRelayout(const Vector2& size, RelayoutContainer& container)
311 {
312   if(!mWebEngine)
313   {
314     return;
315   }
316
317   auto displayArea = CalculateDisplayArea(Self(), DisplayAreaCalculateOption::PROPERTY);
318
319   SetDisplayArea(displayArea);
320 }
321
322 Dali::Toolkit::WebSettings* WebView::GetSettings() const
323 {
324   return mWebSettings.get();
325 }
326
327 Dali::Toolkit::WebBackForwardList* WebView::GetBackForwardList() const
328 {
329   return mWebBackForwardList.get();
330 }
331
332 Dali::WebEnginePlugin* WebView::GetPlugin() const
333 {
334   return mWebEngine ? mWebEngine.GetPlugin() : nullptr;
335 }
336
337 Dali::Toolkit::ImageView WebView::GetFavicon() const
338 {
339   Dali::Toolkit::ImageView faviconView;
340   if(mWebEngine)
341   {
342     Dali::PixelData pixelData = mWebEngine.GetFavicon();
343     faviconView               = CreateImageView(pixelData);
344   }
345   return faviconView;
346 }
347
348 void WebView::LoadUrl(const std::string& url)
349 {
350   if(mWebEngine)
351   {
352     mWebEngine.LoadUrl(url);
353   }
354 }
355
356 void WebView::LoadHtmlString(const std::string& htmlString)
357 {
358   if(mWebEngine)
359   {
360     mWebEngine.LoadHtmlString(htmlString);
361   }
362 }
363
364 bool WebView::LoadHtmlStringOverrideCurrentEntry(const std::string& html, const std::string& basicUri, const std::string& unreachableUrl)
365 {
366   if(!mWebEngine)
367     return false;
368
369   return mWebEngine.LoadHtmlStringOverrideCurrentEntry(html, basicUri, unreachableUrl);
370 }
371
372 bool WebView::LoadContents(const int8_t* contents, uint32_t contentSize, const std::string& mimeType, const std::string& encoding, const std::string& baseUri)
373 {
374   if(!mWebEngine)
375     return false;
376
377   return mWebEngine.LoadContents(contents, contentSize, mimeType, encoding, baseUri);
378 }
379
380 void WebView::Reload()
381 {
382   if(mWebEngine)
383   {
384     mWebEngine.Reload();
385   }
386 }
387
388 bool WebView::ReloadWithoutCache()
389 {
390   return mWebEngine ? mWebEngine.ReloadWithoutCache() : false;
391 }
392
393 void WebView::StopLoading()
394 {
395   if(mWebEngine)
396   {
397     mWebEngine.StopLoading();
398   }
399 }
400
401 void WebView::Suspend()
402 {
403   if(mWebEngine)
404   {
405     mWebEngine.Suspend();
406   }
407 }
408
409 void WebView::Resume()
410 {
411   if(mWebEngine)
412   {
413     mWebEngine.Resume();
414   }
415 }
416
417 void WebView::SuspendNetworkLoading()
418 {
419   if(mWebEngine)
420   {
421     mWebEngine.SuspendNetworkLoading();
422   }
423 }
424
425 void WebView::ResumeNetworkLoading()
426 {
427   if(mWebEngine)
428   {
429     mWebEngine.ResumeNetworkLoading();
430   }
431 }
432
433 bool WebView::AddCustomHeader(const std::string& name, const std::string& value)
434 {
435   return mWebEngine ? mWebEngine.AddCustomHeader(name, value) : false;
436 }
437
438 bool WebView::RemoveCustomHeader(const std::string& name)
439 {
440   return mWebEngine ? mWebEngine.RemoveCustomHeader(name) : false;
441 }
442
443 uint32_t WebView::StartInspectorServer(uint32_t port)
444 {
445   return mWebEngine ? mWebEngine.StartInspectorServer(port) : false;
446 }
447
448 bool WebView::StopInspectorServer()
449 {
450   return mWebEngine ? mWebEngine.StopInspectorServer() : false;
451 }
452
453 void WebView::ScrollBy(int32_t deltaX, int32_t deltaY)
454 {
455   if(mWebEngine)
456   {
457     mWebEngine.ScrollBy(deltaX, deltaY);
458   }
459 }
460
461 bool WebView::ScrollEdgeBy(int32_t deltaX, int32_t deltaY)
462 {
463   return mWebEngine ? mWebEngine.ScrollEdgeBy(deltaX, deltaY) : false;
464 }
465
466 bool WebView::CanGoForward()
467 {
468   return mWebEngine ? mWebEngine.CanGoForward() : false;
469 }
470
471 void WebView::GoForward()
472 {
473   if(mWebEngine)
474   {
475     mWebEngine.GoForward();
476   }
477 }
478
479 bool WebView::CanGoBack()
480 {
481   return mWebEngine ? mWebEngine.CanGoBack() : false;
482 }
483
484 void WebView::GoBack()
485 {
486   if(mWebEngine)
487   {
488     mWebEngine.GoBack();
489   }
490 }
491
492 void WebView::EvaluateJavaScript(const std::string& script, std::function<void(const std::string&)> resultHandler)
493 {
494   if(mWebEngine)
495   {
496     mWebEngine.EvaluateJavaScript(script, std::move(resultHandler));
497   }
498 }
499
500 void WebView::AddJavaScriptMessageHandler(const std::string& exposedObjectName, std::function<void(const std::string&)> handler)
501 {
502   if(mWebEngine)
503   {
504     mWebEngine.AddJavaScriptMessageHandler(exposedObjectName, std::move(handler));
505   }
506 }
507
508 void WebView::RegisterJavaScriptAlertCallback(Dali::WebEnginePlugin::JavaScriptAlertCallback callback)
509 {
510   if(mWebEngine)
511   {
512     mWebEngine.RegisterJavaScriptAlertCallback(std::move(callback));
513   }
514 }
515
516 void WebView::JavaScriptAlertReply()
517 {
518   if(mWebEngine)
519   {
520     mWebEngine.JavaScriptAlertReply();
521   }
522 }
523
524 void WebView::RegisterJavaScriptConfirmCallback(Dali::WebEnginePlugin::JavaScriptConfirmCallback callback)
525 {
526   if(mWebEngine)
527   {
528     mWebEngine.RegisterJavaScriptConfirmCallback(std::move(callback));
529   }
530 }
531
532 void WebView::JavaScriptConfirmReply(bool confirmed)
533 {
534   if(mWebEngine)
535   {
536     mWebEngine.JavaScriptConfirmReply(confirmed);
537   }
538 }
539
540 void WebView::RegisterJavaScriptPromptCallback(Dali::WebEnginePlugin::JavaScriptPromptCallback callback)
541 {
542   if(mWebEngine)
543   {
544     mWebEngine.RegisterJavaScriptPromptCallback(std::move(callback));
545   }
546 }
547
548 void WebView::JavaScriptPromptReply(const std::string& result)
549 {
550   if(mWebEngine)
551   {
552     mWebEngine.JavaScriptPromptReply(result);
553   }
554 }
555
556 std::unique_ptr<Dali::WebEngineHitTest> WebView::CreateHitTest(int32_t x, int32_t y, Dali::WebEngineHitTest::HitTestMode mode)
557 {
558   std::unique_ptr<Dali::WebEngineHitTest> webHitTest;
559   if(!mWebEngine)
560   {
561     return webHitTest;
562   }
563
564   return mWebEngine.CreateHitTest(x, y, mode);
565 }
566
567 bool WebView::CreateHitTestAsynchronously(int32_t x, int32_t y, Dali::WebEngineHitTest::HitTestMode mode, Dali::WebEnginePlugin::WebEngineHitTestCreatedCallback callback)
568 {
569   bool result = false;
570   if(mWebEngine)
571   {
572     result = mWebEngine.CreateHitTestAsynchronously(x, y, mode, std::move(callback));
573   }
574   return result;
575 }
576
577 void WebView::ClearHistory()
578 {
579   if(mWebEngine)
580   {
581     mWebEngine.ClearHistory();
582   }
583 }
584
585 void WebView::ClearAllTilesResources()
586 {
587   if(mWebEngine)
588   {
589     mWebEngine.ClearAllTilesResources();
590   }
591 }
592
593 void WebView::SetScaleFactor(float scaleFactor, Dali::Vector2 point)
594 {
595   if(mWebEngine)
596   {
597     mWebEngine.SetScaleFactor(scaleFactor, point);
598   }
599 }
600
601 float WebView::GetScaleFactor() const
602 {
603   return mWebEngine ? mWebEngine.GetScaleFactor() : 0.0f;
604 }
605
606 void WebView::ActivateAccessibility(bool activated)
607 {
608   if(mWebEngine)
609   {
610     mWebEngine.ActivateAccessibility(activated);
611   }
612 }
613
614 bool WebView::HighlightText(const std::string& text, Dali::WebEnginePlugin::FindOption options, uint32_t maxMatchCount)
615 {
616   return mWebEngine ? mWebEngine.HighlightText(text, options, maxMatchCount) : false;
617 }
618
619 void WebView::AddDynamicCertificatePath(const std::string& host, const std::string& certPath)
620 {
621   if(mWebEngine)
622   {
623     mWebEngine.AddDynamicCertificatePath(host, certPath);
624   }
625 }
626
627 Dali::Toolkit::ImageView WebView::GetScreenshot(Dali::Rect<int32_t> viewArea, float scaleFactor)
628 {
629   Dali::Toolkit::ImageView imageView;
630   if(mWebEngine)
631   {
632     Dali::PixelData pixelData = mWebEngine.GetScreenshot(viewArea, scaleFactor);
633     imageView                 = CreateImageView(pixelData);
634   }
635   return imageView;
636 }
637
638 bool WebView::GetScreenshotAsynchronously(Dali::Rect<int32_t> viewArea, float scaleFactor, Dali::Toolkit::WebView::WebViewScreenshotCapturedCallback callback)
639 {
640   mScreenshotCapturedCallback = std::move(callback);
641   return mWebEngine ? mWebEngine.GetScreenshotAsynchronously(viewArea, scaleFactor, std::bind(&WebView::OnScreenshotCaptured, this, std::placeholders::_1)) : false;
642 }
643
644 bool WebView::CheckVideoPlayingAsynchronously(Dali::WebEnginePlugin::VideoPlayingCallback callback)
645 {
646   return mWebEngine ? mWebEngine.CheckVideoPlayingAsynchronously(std::move(callback)) : false;
647 }
648
649 void WebView::RegisterGeolocationPermissionCallback(Dali::WebEnginePlugin::GeolocationPermissionCallback callback)
650 {
651   if(mWebEngine)
652   {
653     mWebEngine.RegisterGeolocationPermissionCallback(std::move(callback));
654   }
655 }
656
657 void WebView::SetTtsFocus(bool focused)
658 {
659   if(mWebEngine && !HasKeyInputFocus())
660   {
661     mWebEngine.SetFocus(focused);
662   }
663 }
664
665 void WebView::EnableVideoHole(bool enabled)
666 {
667   mVideoHoleEnabled = enabled;
668
669   EnableBlendMode(!mVideoHoleEnabled);
670
671   if(mWebEngine)
672   {
673     mWebEngine.EnableVideoHole(mVideoHoleEnabled);
674   }
675 }
676
677 void WebView::EnableBlendMode(bool blendEnabled)
678 {
679   Actor self = Self();
680   for(uint32_t i = 0; i < self.GetRendererCount(); i++)
681   {
682     Dali::Renderer render = self.GetRendererAt(i);
683     render.SetProperty(Renderer::Property::BLEND_MODE, blendEnabled ? BlendMode::ON : BlendMode::OFF);
684   }
685 }
686
687 Dali::Toolkit::ImageView WebView::CreateImageView(Dali::PixelData pixel) const
688 {
689   if(!pixel)
690   {
691     return Dali::Toolkit::ImageView();
692   }
693
694   Dali::Toolkit::ImageUrl  url       = Dali::Toolkit::Image::GenerateUrl(pixel);
695   Dali::Toolkit::ImageView imageView = Dali::Toolkit::ImageView::New(url.GetUrl());
696   imageView.SetProperty(Dali::Actor::Property::SIZE, Vector2(pixel.GetWidth(), pixel.GetHeight()));
697   return imageView;
698 }
699
700 void WebView::RegisterPageLoadStartedCallback(Dali::WebEnginePlugin::WebEnginePageLoadCallback callback)
701 {
702   if(mWebEngine)
703   {
704     mWebEngine.RegisterPageLoadStartedCallback(std::move(callback));
705   }
706 }
707
708 void WebView::RegisterPageLoadInProgressCallback(Dali::WebEnginePlugin::WebEnginePageLoadCallback callback)
709 {
710   if(mWebEngine)
711   {
712     mWebEngine.RegisterPageLoadInProgressCallback(std::move(callback));
713   }
714 }
715
716 void WebView::RegisterPageLoadFinishedCallback(Dali::WebEnginePlugin::WebEnginePageLoadCallback callback)
717 {
718   if(mWebEngine)
719   {
720     mWebEngine.RegisterPageLoadFinishedCallback(std::move(callback));
721   }
722 }
723
724 void WebView::RegisterPageLoadErrorCallback(Dali::WebEnginePlugin::WebEnginePageLoadErrorCallback callback)
725 {
726   if(mWebEngine)
727   {
728     mWebEngine.RegisterPageLoadErrorCallback(std::move(callback));
729   }
730 }
731
732 void WebView::RegisterScrollEdgeReachedCallback(Dali::WebEnginePlugin::WebEngineScrollEdgeReachedCallback callback)
733 {
734   if(mWebEngine)
735   {
736     mWebEngine.RegisterScrollEdgeReachedCallback(std::move(callback));
737   }
738 }
739
740 void WebView::RegisterUrlChangedCallback(Dali::WebEnginePlugin::WebEngineUrlChangedCallback callback)
741 {
742   if(mWebEngine)
743   {
744     mWebEngine.RegisterUrlChangedCallback(std::move(callback));
745   }
746 }
747
748 void WebView::RegisterFormRepostDecidedCallback(Dali::WebEnginePlugin::WebEngineFormRepostDecidedCallback callback)
749 {
750   if(mWebEngine)
751   {
752     mWebEngine.RegisterFormRepostDecidedCallback(std::move(callback));
753   }
754 }
755
756 void WebView::RegisterFrameRenderedCallback(Dali::WebEnginePlugin::WebEngineFrameRenderedCallback callback)
757 {
758   mFrameRenderedCallback = std::move(callback);
759 }
760
761 void WebView::RegisterConsoleMessageReceivedCallback(Dali::WebEnginePlugin::WebEngineConsoleMessageReceivedCallback callback)
762 {
763   if(mWebEngine)
764   {
765     mWebEngine.RegisterConsoleMessageReceivedCallback(std::move(callback));
766   }
767 }
768
769 void WebView::RegisterResponsePolicyDecidedCallback(Dali::WebEnginePlugin::WebEngineResponsePolicyDecidedCallback callback)
770 {
771   if(mWebEngine)
772   {
773     mWebEngine.RegisterResponsePolicyDecidedCallback(std::move(callback));
774   }
775 }
776
777 void WebView::RegisterNavigationPolicyDecidedCallback(Dali::WebEnginePlugin::WebEngineNavigationPolicyDecidedCallback callback)
778 {
779   if(mWebEngine)
780   {
781     mWebEngine.RegisterNavigationPolicyDecidedCallback(std::move(callback));
782   }
783 }
784
785 void WebView::RegisterNewWindowCreatedCallback(Dali::WebEnginePlugin::WebEngineNewWindowCreatedCallback callback)
786 {
787   if(mWebEngine)
788   {
789     mWebEngine.RegisterNewWindowCreatedCallback(std::move(callback));
790   }
791 }
792
793 void WebView::RegisterCertificateConfirmedCallback(Dali::WebEnginePlugin::WebEngineCertificateCallback callback)
794 {
795   if(mWebEngine)
796   {
797     mWebEngine.RegisterCertificateConfirmedCallback(std::move(callback));
798   }
799 }
800
801 void WebView::RegisterSslCertificateChangedCallback(Dali::WebEnginePlugin::WebEngineCertificateCallback callback)
802 {
803   if(mWebEngine)
804   {
805     mWebEngine.RegisterSslCertificateChangedCallback(std::move(callback));
806   }
807 }
808
809 void WebView::RegisterHttpAuthHandlerCallback(Dali::WebEnginePlugin::WebEngineHttpAuthHandlerCallback callback)
810 {
811   if(mWebEngine)
812   {
813     mWebEngine.RegisterHttpAuthHandlerCallback(std::move(callback));
814   }
815 }
816
817 void WebView::RegisterContextMenuShownCallback(Dali::WebEnginePlugin::WebEngineContextMenuShownCallback callback)
818 {
819   if(mWebEngine)
820   {
821     mWebEngine.RegisterContextMenuShownCallback(std::move(callback));
822   }
823 }
824
825 void WebView::RegisterContextMenuHiddenCallback(Dali::WebEnginePlugin::WebEngineContextMenuHiddenCallback callback)
826 {
827   if(mWebEngine)
828   {
829     mWebEngine.RegisterContextMenuHiddenCallback(std::move(callback));
830   }
831 }
832
833 void WebView::GetPlainTextAsynchronously(Dali::WebEnginePlugin::PlainTextReceivedCallback callback)
834 {
835   if(mWebEngine)
836   {
837     mWebEngine.GetPlainTextAsynchronously(std::move(callback));
838   }
839 }
840
841 void WebView::OnFrameRendered()
842 {
843   if(mFrameRenderedCallback)
844   {
845     mFrameRenderedCallback();
846   }
847
848   // Make sure that mVisual is created only if required.
849   if(mVisualChangeRequired || !mVisual)
850   {
851     // Reset flag
852     mVisualChangeRequired = false;
853
854     auto nativeImageSourcePtr = mWebEngine.GetNativeImageSource();
855
856     mLastRenderedNativeImageWidth  = nativeImageSourcePtr->GetWidth();
857     mLastRenderedNativeImageHeight = nativeImageSourcePtr->GetHeight();
858
859     Dali::Toolkit::ImageUrl nativeImageUrl = Dali::Toolkit::Image::GenerateUrl(nativeImageSourcePtr);
860
861     mVisual = Toolkit::VisualFactory::Get().CreateVisual(
862       {{Toolkit::Visual::Property::TYPE, Toolkit::Visual::IMAGE},
863        {Toolkit::ImageVisual::Property::URL, nativeImageUrl.GetUrl()},
864        {Toolkit::ImageVisual::Property::PIXEL_AREA, FULL_TEXTURE_RECT},
865        {Toolkit::ImageVisual::Property::WRAP_MODE_U, Dali::WrapMode::CLAMP_TO_EDGE},
866        {Toolkit::ImageVisual::Property::WRAP_MODE_V, Dali::WrapMode::CLAMP_TO_EDGE}});
867
868     if(mVisual)
869     {
870       DevelControl::RegisterVisual(*this, Toolkit::WebView::Property::URL, mVisual);
871       EnableBlendMode(!mVideoHoleEnabled);
872     }
873   }
874 }
875
876 void WebView::OnDisplayAreaUpdated(Dali::PropertyNotification& /*source*/)
877 {
878   if(!mWebEngine)
879   {
880     return;
881   }
882
883   auto displayArea = CalculateDisplayArea(Self(), DisplayAreaCalculateOption::CURRENT_PROPERTY);
884
885   SetDisplayArea(displayArea);
886 }
887
888 void WebView::OnVisibilityChanged(Actor actor, bool isVisible, Dali::DevelActor::VisibilityChange::Type type)
889 {
890   if(type == Dali::DevelActor::VisibilityChange::Type::SELF)
891   {
892     if(isVisible)
893     {
894       mWebViewVisibleState |= WebViewVisibleStateFlag::SELF_SHOW;
895     }
896     else
897     {
898       mWebViewVisibleState &= ~WebViewVisibleStateFlag::SELF_SHOW;
899     }
900   }
901   else if(type == Dali::DevelActor::VisibilityChange::Type::PARENT)
902   {
903     if(isVisible)
904     {
905       mWebViewVisibleState |= WebViewVisibleStateFlag::PARENT_SHOW;
906       // TODO : We should consider double-hide called from parent
907     }
908     else
909     {
910       mWebViewVisibleState &= ~WebViewVisibleStateFlag::PARENT_SHOW;
911     }
912   }
913   ApplyVisibilityCheck();
914 }
915
916 void WebView::OnWindowVisibilityChanged(Window window, bool visible)
917 {
918   if(visible)
919   {
920     mWebViewVisibleState |= WebViewVisibleStateFlag::WINDOW_SHOW;
921   }
922   else
923   {
924     mWebViewVisibleState &= ~WebViewVisibleStateFlag::WINDOW_SHOW;
925   }
926   ApplyVisibilityCheck();
927 }
928
929 void WebView::OnScreenshotCaptured(Dali::PixelData pixel)
930 {
931   if(mScreenshotCapturedCallback)
932   {
933     Dali::Toolkit::ImageView imageView = CreateImageView(pixel);
934     mScreenshotCapturedCallback(imageView);
935   }
936 }
937
938 void WebView::SetDisplayArea(const Dali::Rect<int32_t>& displayArea)
939 {
940   Size displaySize = Size(displayArea.width, displayArea.height);
941   if(mWebViewSize != displaySize)
942   {
943     mWebViewSize = displaySize;
944   }
945
946   if(mWebViewArea != displayArea)
947   {
948     // WebEngine visual size changed. we have to re-create visual.
949     mVisualChangeRequired = true;
950
951     // Change old visual's pixel area matched as changed web view size
952     if(mVisual)
953     {
954       auto pixelArea = CalculatePixelArea(mWebViewSize, mLastRenderedNativeImageWidth, mLastRenderedNativeImageHeight);
955       Toolkit::GetImplementation(mVisual).DoAction(Toolkit::DevelVisual::Action::UPDATE_PROPERTY, {{Toolkit::ImageVisual::Property::PIXEL_AREA, pixelArea}});
956     }
957
958     mWebViewArea = displayArea;
959     mWebEngine.UpdateDisplayArea(mWebViewArea);
960   }
961 }
962
963 void WebView::OnSceneConnection(int depth)
964 {
965   mWebViewVisibleState |= WebViewVisibleStateFlag::SCENE_ON;
966   mWebViewVisibleState |= WebViewVisibleStateFlag::PARENT_SHOW;
967   // TODO : We should consider already hided parent
968   Window window = DevelWindow::Get(Self());
969   if(window)
970   {
971     // Hold the weak handle of the placement window.
972     mPlacementWindow = window;
973     if(window.IsVisible())
974     {
975       mWebViewVisibleState |= WebViewVisibleStateFlag::WINDOW_SHOW;
976     }
977     else
978     {
979       mWebViewVisibleState &= ~WebViewVisibleStateFlag::WINDOW_SHOW;
980     }
981     DevelWindow::VisibilityChangedSignal(window).Connect(this, &WebView::OnWindowVisibilityChanged);
982   }
983   ApplyVisibilityCheck();
984   Control::OnSceneConnection(depth);
985   EnableBlendMode(!mVideoHoleEnabled);
986 }
987
988 void WebView::OnSceneDisconnection()
989 {
990   mWebViewVisibleState &= ~WebViewVisibleStateFlag::SCENE_ON;
991   mWebViewVisibleState &= ~WebViewVisibleStateFlag::WINDOW_SHOW;
992   mWebViewVisibleState &= ~WebViewVisibleStateFlag::PARENT_SHOW;
993   Window window = mPlacementWindow.GetHandle();
994   if(window)
995   {
996     DevelWindow::VisibilityChangedSignal(window).Disconnect(this, &WebView::OnWindowVisibilityChanged);
997     mPlacementWindow.Reset();
998   }
999   ApplyVisibilityCheck();
1000   Control::OnSceneDisconnection();
1001 }
1002
1003 bool WebView::OnTouchEvent(Actor actor, const Dali::TouchEvent& touch)
1004 {
1005   bool result = false;
1006
1007   if(mWebEngine)
1008   {
1009     result = mWebEngine.SendTouchEvent(touch);
1010   }
1011   return result;
1012 }
1013
1014 bool WebView::OnKeyEvent(const Dali::KeyEvent& event)
1015 {
1016   bool result = false;
1017
1018   if(mWebEngine)
1019   {
1020     result = mWebEngine.SendKeyEvent(event);
1021   }
1022   return result;
1023 }
1024
1025 bool WebView::OnHoverEvent(Actor actor, const Dali::HoverEvent& hover)
1026 {
1027   bool result = false;
1028   if(mWebEngine && mMouseEventsEnabled)
1029   {
1030     result = mWebEngine.SendHoverEvent(hover);
1031   }
1032   return result;
1033 }
1034
1035 bool WebView::OnWheelEvent(Actor actor, const Dali::WheelEvent& wheel)
1036 {
1037   bool result = false;
1038   if(mWebEngine && mMouseEventsEnabled)
1039   {
1040     result = mWebEngine.SendWheelEvent(wheel);
1041   }
1042   return result;
1043 }
1044
1045 void WebView::OnKeyInputFocusGained()
1046 {
1047   if(mWebEngine)
1048   {
1049     mWebEngine.SetFocus(true);
1050   }
1051
1052   EmitKeyInputFocusSignal(true); // Calls back into the Control hence done last.
1053 }
1054
1055 void WebView::OnKeyInputFocusLost()
1056 {
1057   if(mWebEngine)
1058   {
1059     mWebEngine.SetFocus(false);
1060   }
1061
1062   EmitKeyInputFocusSignal(false); // Calls back into the Control hence done last.
1063 }
1064
1065 Vector3 WebView::GetNaturalSize()
1066 {
1067   if(mVisual)
1068   {
1069     Vector2 rendererNaturalSize;
1070     mVisual.GetNaturalSize(rendererNaturalSize);
1071     return Vector3(rendererNaturalSize);
1072   }
1073
1074   return Vector3(mWebViewSize);
1075 }
1076
1077 void WebView::SetProperty(BaseObject* object, Property::Index index, const Property::Value& value)
1078 {
1079   Toolkit::WebView webView = Toolkit::WebView::DownCast(Dali::BaseHandle(object));
1080
1081   if(webView)
1082   {
1083     WebView& impl = GetImpl(webView);
1084     switch(index)
1085     {
1086       case Toolkit::WebView::Property::URL:
1087       {
1088         std::string url;
1089         if(value.Get(url))
1090         {
1091           impl.LoadUrl(url);
1092         }
1093         break;
1094       }
1095       case Toolkit::WebView::Property::USER_AGENT:
1096       {
1097         std::string input;
1098         if(value.Get(input))
1099         {
1100           impl.SetUserAgent(input);
1101         }
1102         break;
1103       }
1104       case Toolkit::WebView::Property::SCROLL_POSITION:
1105       {
1106         Vector2 input;
1107         if(value.Get(input))
1108         {
1109           impl.SetScrollPosition(input.x, input.y);
1110         }
1111         break;
1112       }
1113       case Toolkit::WebView::Property::VIDEO_HOLE_ENABLED:
1114       {
1115         bool input;
1116         if(value.Get(input))
1117         {
1118           impl.EnableVideoHole(input);
1119         }
1120         break;
1121       }
1122       case Toolkit::WebView::Property::MOUSE_EVENTS_ENABLED:
1123       {
1124         bool input;
1125         if(value.Get(input))
1126         {
1127           impl.EnableMouseEvents(input);
1128         }
1129         break;
1130       }
1131       case Toolkit::WebView::Property::KEY_EVENTS_ENABLED:
1132       {
1133         bool input;
1134         if(value.Get(input))
1135         {
1136           impl.EnableKeyEvents(input);
1137         }
1138         break;
1139       }
1140       case Toolkit::WebView::Property::DOCUMENT_BACKGROUND_COLOR:
1141       {
1142         Vector4 input;
1143         if(value.Get(input))
1144         {
1145           impl.SetDocumentBackgroundColor(input);
1146         }
1147         break;
1148       }
1149       case Toolkit::WebView::Property::TILES_CLEARED_WHEN_HIDDEN:
1150       {
1151         bool input;
1152         if(value.Get(input))
1153         {
1154           impl.ClearTilesWhenHidden(input);
1155         }
1156         break;
1157       }
1158       case Toolkit::WebView::Property::TILE_COVER_AREA_MULTIPLIER:
1159       {
1160         float input;
1161         if(value.Get(input))
1162         {
1163           impl.SetTileCoverAreaMultiplier(input);
1164         }
1165         break;
1166       }
1167       case Toolkit::WebView::Property::CURSOR_ENABLED_BY_CLIENT:
1168       {
1169         bool input;
1170         if(value.Get(input))
1171         {
1172           impl.EnableCursorByClient(input);
1173         }
1174         break;
1175       }
1176       case Toolkit::WebView::Property::PAGE_ZOOM_FACTOR:
1177       {
1178         float input;
1179         if(value.Get(input))
1180         {
1181           impl.SetPageZoomFactor(input);
1182         }
1183         break;
1184       }
1185       case Toolkit::WebView::Property::TEXT_ZOOM_FACTOR:
1186       {
1187         float input;
1188         if(value.Get(input))
1189         {
1190           impl.SetTextZoomFactor(input);
1191         }
1192         break;
1193       }
1194       default:
1195         break;
1196     }
1197   }
1198 }
1199
1200 Property::Value WebView::GetProperty(BaseObject* object, Property::Index propertyIndex)
1201 {
1202   Property::Value value;
1203
1204   Toolkit::WebView webView = Toolkit::WebView::DownCast(Dali::BaseHandle(object));
1205
1206   if(webView)
1207   {
1208     WebView& impl = GetImpl(webView);
1209     switch(propertyIndex)
1210     {
1211       case Toolkit::WebView::Property::URL:
1212       {
1213         value = impl.GetUrl();
1214         break;
1215       }
1216       case Toolkit::WebView::Property::USER_AGENT:
1217       {
1218         value = impl.GetUserAgent();
1219         break;
1220       }
1221       case Toolkit::WebView::Property::SCROLL_POSITION:
1222       {
1223         value = impl.GetScrollPosition();
1224         break;
1225       }
1226       case Toolkit::WebView::Property::SCROLL_SIZE:
1227       {
1228         value = impl.GetScrollSize();
1229         break;
1230       }
1231       case Toolkit::WebView::Property::CONTENT_SIZE:
1232       {
1233         value = impl.GetContentSize();
1234         break;
1235       }
1236       case Toolkit::WebView::Property::TITLE:
1237       {
1238         value = impl.GetTitle();
1239         break;
1240       }
1241       case Toolkit::WebView::Property::VIDEO_HOLE_ENABLED:
1242       {
1243         value = impl.mVideoHoleEnabled;
1244         break;
1245       }
1246       case Toolkit::WebView::Property::MOUSE_EVENTS_ENABLED:
1247       {
1248         value = impl.mMouseEventsEnabled;
1249         break;
1250       }
1251       case Toolkit::WebView::Property::KEY_EVENTS_ENABLED:
1252       {
1253         value = impl.mKeyEventsEnabled;
1254         break;
1255       }
1256       case Toolkit::WebView::Property::SELECTED_TEXT:
1257       {
1258         value = impl.GetSelectedText();
1259         break;
1260       }
1261       case Toolkit::WebView::Property::PAGE_ZOOM_FACTOR:
1262       {
1263         value = impl.GetPageZoomFactor();
1264         break;
1265       }
1266       case Toolkit::WebView::Property::TEXT_ZOOM_FACTOR:
1267       {
1268         value = impl.GetTextZoomFactor();
1269         break;
1270       }
1271       case Toolkit::WebView::Property::LOAD_PROGRESS_PERCENTAGE:
1272       {
1273         value = impl.GetLoadProgressPercentage();
1274         break;
1275       }
1276       default:
1277         break;
1278     }
1279   }
1280
1281   return value;
1282 }
1283
1284 void WebView::SetScrollPosition(int32_t x, int32_t y)
1285 {
1286   if(mWebEngine)
1287   {
1288     mWebEngine.SetScrollPosition(x, y);
1289   }
1290 }
1291
1292 Dali::Vector2 WebView::GetScrollPosition() const
1293 {
1294   return mWebEngine ? mWebEngine.GetScrollPosition() : Dali::Vector2::ZERO;
1295 }
1296
1297 Dali::Vector2 WebView::GetScrollSize() const
1298 {
1299   return mWebEngine ? mWebEngine.GetScrollSize() : Dali::Vector2::ZERO;
1300 }
1301
1302 Dali::Vector2 WebView::GetContentSize() const
1303 {
1304   return mWebEngine ? mWebEngine.GetContentSize() : Dali::Vector2::ZERO;
1305 }
1306
1307 std::string WebView::GetTitle() const
1308 {
1309   return mWebEngine ? mWebEngine.GetTitle() : std::string();
1310 }
1311
1312 void WebView::SetDocumentBackgroundColor(Dali::Vector4 color)
1313 {
1314   if(mWebEngine)
1315   {
1316     mWebEngine.SetDocumentBackgroundColor(color);
1317   }
1318 }
1319
1320 void WebView::ClearTilesWhenHidden(bool cleared)
1321 {
1322   if(mWebEngine)
1323   {
1324     mWebEngine.ClearTilesWhenHidden(cleared);
1325   }
1326 }
1327
1328 void WebView::SetTileCoverAreaMultiplier(float multiplier)
1329 {
1330   if(mWebEngine)
1331   {
1332     mWebEngine.SetTileCoverAreaMultiplier(multiplier);
1333   }
1334 }
1335
1336 void WebView::EnableCursorByClient(bool enabled)
1337 {
1338   if(mWebEngine)
1339   {
1340     mWebEngine.EnableCursorByClient(enabled);
1341   }
1342 }
1343
1344 std::string WebView::GetSelectedText() const
1345 {
1346   return mWebEngine ? mWebEngine.GetSelectedText() : std::string();
1347 }
1348
1349 std::string WebView::GetUrl() const
1350 {
1351   return mWebEngine ? mWebEngine.GetUrl() : std::string();
1352 }
1353
1354 std::string WebView::GetUserAgent() const
1355 {
1356   return mWebEngine ? mWebEngine.GetUserAgent() : std::string();
1357 }
1358
1359 void WebView::SetUserAgent(const std::string& userAgent)
1360 {
1361   if(mWebEngine)
1362   {
1363     mWebEngine.SetUserAgent(userAgent);
1364   }
1365 }
1366
1367 void WebView::EnableMouseEvents(bool enabled)
1368 {
1369   if(mWebEngine)
1370   {
1371     mMouseEventsEnabled = enabled;
1372     mWebEngine.EnableMouseEvents(enabled);
1373   }
1374 }
1375
1376 void WebView::EnableKeyEvents(bool enabled)
1377 {
1378   if(mWebEngine)
1379   {
1380     mKeyEventsEnabled = enabled;
1381     mWebEngine.EnableKeyEvents(enabled);
1382   }
1383 }
1384
1385 void WebView::SetPageZoomFactor(float zoomFactor)
1386 {
1387   if(mWebEngine)
1388   {
1389     mWebEngine.SetPageZoomFactor(zoomFactor);
1390   }
1391 }
1392
1393 float WebView::GetPageZoomFactor() const
1394 {
1395   return mWebEngine ? mWebEngine.GetPageZoomFactor() : 0.0f;
1396 }
1397
1398 void WebView::SetTextZoomFactor(float zoomFactor)
1399 {
1400   if(mWebEngine)
1401   {
1402     mWebEngine.SetTextZoomFactor(zoomFactor);
1403   }
1404 }
1405
1406 float WebView::GetTextZoomFactor() const
1407 {
1408   return mWebEngine ? mWebEngine.GetTextZoomFactor() : 0.0f;
1409 }
1410
1411 float WebView::GetLoadProgressPercentage() const
1412 {
1413   return mWebEngine ? mWebEngine.GetLoadProgressPercentage() : 0.0f;
1414 }
1415
1416 bool WebView::SetVisibility(bool visible)
1417 {
1418   return mWebEngine ? mWebEngine.SetVisibility(visible) : false;
1419 }
1420
1421 void WebView::ApplyVisibilityCheck()
1422 {
1423   SetVisibility(mWebViewVisibleState == WebViewVisibleStateFlag::VISIBLE);
1424 }
1425
1426 WebView::WebViewAccessible::WebViewAccessible(Dali::Actor self, Dali::WebEngine& webEngine)
1427 : ControlAccessible(self),
1428   mRemoteChild{},
1429   mWebEngine{webEngine}
1430 {
1431   mRemoteChild.SetParent(this);
1432
1433   Dali::Accessibility::Bridge::EnabledSignal().Connect(this, &WebViewAccessible::OnAccessibilityEnabled);
1434   Dali::Accessibility::Bridge::DisabledSignal().Connect(this, &WebViewAccessible::OnAccessibilityDisabled);
1435
1436   if(Dali::Accessibility::IsUp())
1437   {
1438     OnAccessibilityEnabled();
1439   }
1440   else
1441   {
1442     OnAccessibilityDisabled();
1443   }
1444 }
1445
1446 Dali::Accessibility::Attributes WebView::WebViewAccessible::GetAttributes() const
1447 {
1448   auto attributes = DevelControl::ControlAccessible::GetAttributes();
1449
1450   if(mRemoteChild.GetAddress())
1451   {
1452     attributes.insert_or_assign("child_bus", mRemoteChild.GetAddress().GetBus());
1453   }
1454
1455   return attributes;
1456 }
1457
1458 void WebView::WebViewAccessible::DoGetChildren(std::vector<Dali::Accessibility::Accessible*>& children)
1459 {
1460   if(mRemoteChild.GetAddress())
1461   {
1462     // DoGetChildren is called at most once per every OnChildrenChanged.
1463     // We have only one OnChildrenChanged in this case, so EmbedAtkSocket will be called only once.
1464     Accessibility::Bridge::GetCurrentBridge()->EmbedAtkSocket(GetAddress(), mRemoteChild.GetAddress());
1465     children.push_back(&mRemoteChild);
1466   }
1467 }
1468
1469 void WebView::WebViewAccessible::OnAccessibilityEnabled()
1470 {
1471   if(!mWebEngine)
1472   {
1473     return;
1474   }
1475
1476   mWebEngine.ActivateAccessibility(true);
1477   SetRemoteChildAddress(mWebEngine.GetAccessibilityAddress());
1478 }
1479
1480 void WebView::WebViewAccessible::OnAccessibilityDisabled()
1481 {
1482   if(!mWebEngine)
1483   {
1484     return;
1485   }
1486
1487   SetRemoteChildAddress({});
1488   mWebEngine.ActivateAccessibility(false);
1489 }
1490
1491 void WebView::WebViewAccessible::SetRemoteChildAddress(Dali::Accessibility::Address address)
1492 {
1493   mRemoteChild.SetAddress(address);
1494   OnChildrenChanged();
1495 }
1496
1497 } // namespace Internal
1498
1499 } // namespace Toolkit
1500
1501 } // namespace Dali