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