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