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