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