2 * Copyright (c) 2021 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include "web-view-impl.h"
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-settings.h>
26 #include <dali/devel-api/common/stage.h>
27 #include <dali/devel-api/scripting/enum-helper.h>
28 #include <dali/devel-api/scripting/scripting.h>
29 #include <dali/public-api/adaptor-framework/native-image-source.h>
30 #include <dali/public-api/object/type-registry-helper.h>
31 #include <dali/public-api/object/type-registry.h>
35 #include <dali-toolkit/devel-api/controls/control-devel.h>
36 #include <dali-toolkit/devel-api/controls/web-view/web-back-forward-list.h>
37 #include <dali-toolkit/devel-api/controls/web-view/web-context.h>
38 #include <dali-toolkit/devel-api/controls/web-view/web-cookie-manager.h>
39 #include <dali-toolkit/devel-api/controls/web-view/web-settings.h>
40 #include <dali-toolkit/devel-api/image-loader/texture-manager.h>
41 #include <dali-toolkit/internal/visuals/visual-factory-impl.h>
42 #include <dali-toolkit/public-api/image-loader/image.h>
43 #include <dali-toolkit/public-api/visuals/image-visual-properties.h>
55 return Toolkit::WebView::New();
59 DALI_TYPE_REGISTRATION_BEGIN(Toolkit::WebView, Toolkit::Control, Create)
61 DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "url", STRING, URL )
62 DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "userAgent", STRING, USER_AGENT )
63 DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "scrollPosition", VECTOR2, SCROLL_POSITION )
64 DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "scrollSize", VECTOR2, SCROLL_SIZE )
65 DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "contentSize", VECTOR2, CONTENT_SIZE )
66 DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "title", STRING, TITLE )
67 DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "videoHoleEnabled", BOOLEAN, VIDEO_HOLE_ENABLED)
69 DALI_SIGNAL_REGISTRATION(Toolkit, WebView, "pageLoadStarted", PAGE_LOAD_STARTED_SIGNAL )
70 DALI_SIGNAL_REGISTRATION(Toolkit, WebView, "pageLoadFinished", PAGE_LOAD_FINISHED_SIGNAL )
71 DALI_SIGNAL_REGISTRATION(Toolkit, WebView, "pageLoadError", PAGE_LOAD_ERROR_SIGNAL )
72 DALI_SIGNAL_REGISTRATION(Toolkit, WebView, "scrollEdgeReached", SCROLL_EDGE_REACHED_SIGNAL)
74 DALI_TYPE_REGISTRATION_END()
77 const std::string kEmptyString;
81 #define GET_ENUM_STRING(structName, inputExp) \
82 Scripting::GetLinearEnumerationName<Toolkit::WebView::structName::Type>(static_cast<Toolkit::WebView::structName::Type>(inputExp), structName##_TABLE, structName##_TABLE_COUNT)
84 #define GET_ENUM_VALUE(structName, inputExp, outputExp) \
85 Scripting::GetEnumerationProperty<Toolkit::WebView::structName::Type>(inputExp, structName##_TABLE, structName##_TABLE_COUNT, outputExp)
87 WebView::WebView(const std::string& locale, const std::string& timezoneId)
88 : Control(ControlBehaviour(ACTOR_BEHAVIOUR_DEFAULT | DISABLE_STYLE_CHANGE_SIGNALS)),
91 mWebViewSize(Stage::GetCurrent().GetSize()),
93 mPageLoadStartedSignal(),
94 mPageLoadFinishedSignal(),
95 mPageLoadErrorSignal(),
96 mVideoHoleEnabled(true),
97 mWebViewArea(0, 0, mWebViewSize.width, mWebViewSize.height)
99 mWebEngine = Dali::WebEngine::New();
101 // WebEngine is empty when it is not properly initialized.
104 mWebEngine.Create(mWebViewSize.width, mWebViewSize.height, locale, timezoneId);
108 WebView::WebView(int argc, char** argv)
109 : Control(ControlBehaviour(ACTOR_BEHAVIOUR_DEFAULT | DISABLE_STYLE_CHANGE_SIGNALS)),
112 mWebViewSize(Stage::GetCurrent().GetSize()),
114 mPageLoadStartedSignal(),
115 mPageLoadFinishedSignal(),
116 mPageLoadErrorSignal(),
117 mVideoHoleEnabled(true),
118 mWebViewArea(0, 0, mWebViewSize.width, mWebViewSize.height)
120 mWebEngine = Dali::WebEngine::New();
122 // WebEngine is empty when it is not properly initialized.
125 mWebEngine.Create(mWebViewSize.width, mWebViewSize.height, argc, argv);
138 mWebEngine.Destroy();
142 Toolkit::WebView WebView::New()
144 WebView* impl = new WebView();
145 Toolkit::WebView handle = Toolkit::WebView(*impl);
151 Toolkit::WebView WebView::New(const std::string& locale, const std::string& timezoneId)
153 WebView* impl = new WebView(locale, timezoneId);
154 Toolkit::WebView handle = Toolkit::WebView(*impl);
160 Toolkit::WebView WebView::New(int argc, char** argv)
162 WebView* impl = new WebView(argc, argv);
163 Toolkit::WebView handle = Toolkit::WebView(*impl);
169 void WebView::OnInitialize()
173 self.SetProperty(Actor::Property::KEYBOARD_FOCUSABLE, true);
174 self.TouchedSignal().Connect(this, &WebView::OnTouchEvent);
176 mPositionUpdateNotification = self.AddPropertyNotification(Actor::Property::WORLD_POSITION, StepCondition(1.0f, 1.0f));
177 mSizeUpdateNotification = self.AddPropertyNotification(Actor::Property::SIZE, StepCondition(1.0f, 1.0f));
178 mScaleUpdateNotification = self.AddPropertyNotification(Actor::Property::WORLD_SCALE, StepCondition(0.1f, 1.0f));
179 mPositionUpdateNotification.NotifySignal().Connect(this, &WebView::UpdateDisplayArea);
180 mSizeUpdateNotification.NotifySignal().Connect(this, &WebView::UpdateDisplayArea);
181 mScaleUpdateNotification.NotifySignal().Connect(this, &WebView::UpdateDisplayArea);
185 mWebEngine.PageLoadStartedSignal().Connect(this, &WebView::OnPageLoadStarted);
186 mWebEngine.PageLoadFinishedSignal().Connect(this, &WebView::OnPageLoadFinished);
187 mWebEngine.PageLoadErrorSignal().Connect(this, &WebView::OnPageLoadError);
188 mWebEngine.ScrollEdgeReachedSignal().Connect(this, &WebView::OnScrollEdgeReached);
190 mWebContext = std::unique_ptr<Dali::Toolkit::WebContext>(new WebContext(mWebEngine.GetContext()));
191 mWebCookieManager = std::unique_ptr<Dali::Toolkit::WebCookieManager>(new WebCookieManager(mWebEngine.GetCookieManager()));
192 mWebSettings = std::unique_ptr<Dali::Toolkit::WebSettings>(new WebSettings(mWebEngine.GetSettings()));
193 mWebBackForwardList = std::unique_ptr<Dali::Toolkit::WebBackForwardList>(new WebBackForwardList(mWebEngine.GetBackForwardList()));
197 Dali::Toolkit::WebSettings* WebView::GetSettings() const
199 return mWebSettings.get();
202 Dali::Toolkit::WebContext* WebView::GetContext() const
204 return mWebContext.get();
207 Dali::Toolkit::WebCookieManager* WebView::GetCookieManager() const
209 return mWebCookieManager.get();
212 Dali::Toolkit::WebBackForwardList* WebView::GetBackForwardList() const
214 return mWebBackForwardList.get();
217 Dali::Toolkit::ImageView& WebView::GetFavicon()
221 Dali::PixelData pixelData = mWebEngine.GetFavicon();
222 std::string url = Dali::Toolkit::Image::GenerateUrl(pixelData);
223 mFaviconView = Dali::Toolkit::ImageView::New(url);
224 mFaviconView.SetResizePolicy(ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS);
225 mFaviconView.SetProperty(Dali::Actor::Property::SIZE, Vector2(pixelData.GetWidth(), pixelData.GetHeight()));
230 void WebView::LoadUrl(const std::string& url)
235 Texture texture = Dali::Texture::New(*mWebEngine.GetNativeImageSource());
236 const std::string nativeImageUrl = Dali::Toolkit::TextureManager::AddTexture(texture);
237 mVisual = Toolkit::VisualFactory::Get().CreateVisual(
238 {{Toolkit::Visual::Property::TYPE, Toolkit::Visual::IMAGE},
239 {Toolkit::ImageVisual::Property::URL, nativeImageUrl}});
243 // Clean up previously registered visual and add new one.
244 DevelControl::RegisterVisual(*this, Toolkit::WebView::Property::URL, mVisual);
245 mWebEngine.LoadUrl(url);
248 if(mVideoHoleEnabled)
250 EnableBlendMode(false);
255 void WebView::LoadHtmlString(const std::string& htmlString)
259 Texture texture = Dali::Texture::New(*mWebEngine.GetNativeImageSource());
260 const std::string nativeImageUrl = Dali::Toolkit::TextureManager::AddTexture(texture);
261 mVisual = Toolkit::VisualFactory::Get().CreateVisual(
262 {{Toolkit::Visual::Property::TYPE, Toolkit::Visual::IMAGE},
263 {Toolkit::ImageVisual::Property::URL, nativeImageUrl}});
267 DevelControl::RegisterVisual(*this, Toolkit::WebView::Property::URL, mVisual);
268 mWebEngine.LoadHtmlString(htmlString);
271 if(mVideoHoleEnabled)
273 EnableBlendMode(false);
278 void WebView::Reload()
286 void WebView::StopLoading()
290 mWebEngine.StopLoading();
294 void WebView::Suspend()
298 mWebEngine.Suspend();
302 void WebView::Resume()
310 void WebView::ScrollBy(int deltaX, int deltaY)
314 mWebEngine.ScrollBy(deltaX, deltaY);
318 bool WebView::CanGoForward()
320 return mWebEngine ? mWebEngine.CanGoForward() : false;
323 void WebView::GoForward()
327 mWebEngine.GoForward();
331 bool WebView::CanGoBack()
333 return mWebEngine ? mWebEngine.CanGoBack() : false;
336 void WebView::GoBack()
344 void WebView::EvaluateJavaScript(const std::string& script, std::function<void(const std::string&)> resultHandler)
348 mWebEngine.EvaluateJavaScript(script, resultHandler);
352 void WebView::AddJavaScriptMessageHandler(const std::string& exposedObjectName, std::function<void(const std::string&)> handler)
356 mWebEngine.AddJavaScriptMessageHandler(exposedObjectName, handler);
360 void WebView::ClearAllTilesResources()
364 mWebEngine.ClearAllTilesResources();
368 void WebView::ClearHistory()
372 mWebEngine.ClearHistory();
376 void WebView::UpdateDisplayArea(Dali::PropertyNotification& /*source*/)
383 bool positionUsesAnchorPoint = self.GetProperty<bool>(Actor::Property::POSITION_USES_ANCHOR_POINT);
384 Vector3 actorSize = self.GetCurrentProperty<Vector3>(Actor::Property::SIZE) * self.GetCurrentProperty<Vector3>(Actor::Property::SCALE);
385 Vector3 anchorPointOffSet = actorSize * (positionUsesAnchorPoint ? self.GetCurrentProperty<Vector3>(Actor::Property::ANCHOR_POINT) : AnchorPoint::TOP_LEFT);
386 Vector2 screenPosition = self.GetProperty<Vector2>(Actor::Property::SCREEN_POSITION);
388 Dali::Rect<int> displayArea;
389 displayArea.x = screenPosition.x - anchorPointOffSet.x;
390 displayArea.y = screenPosition.y - anchorPointOffSet.y;
391 displayArea.width = actorSize.x;
392 displayArea.height = actorSize.y;
394 Size displaySize = Size(displayArea.width, displayArea.height);
395 if(mWebViewSize != displaySize)
397 mWebViewSize = displaySize;
400 if(mWebViewArea != displayArea)
402 mWebViewArea = displayArea;
403 mWebEngine.UpdateDisplayArea(mWebViewArea);
407 void WebView::EnableVideoHole(bool enabled)
409 mVideoHoleEnabled = enabled;
411 EnableBlendMode(!mVideoHoleEnabled);
415 mWebEngine.EnableVideoHole(mVideoHoleEnabled);
419 void WebView::EnableBlendMode(bool blendEnabled)
422 for(uint32_t i = 0; i < self.GetRendererCount(); i++)
424 Dali::Renderer render = self.GetRendererAt(i);
425 render.SetProperty(Renderer::Property::BLEND_MODE, blendEnabled ? BlendMode::ON : BlendMode::OFF);
429 Dali::Toolkit::WebView::WebViewPageLoadSignalType& WebView::PageLoadStartedSignal()
431 return mPageLoadStartedSignal;
434 Dali::Toolkit::WebView::WebViewPageLoadSignalType& WebView::PageLoadFinishedSignal()
436 return mPageLoadFinishedSignal;
439 Dali::Toolkit::WebView::WebViewPageLoadErrorSignalType& WebView::PageLoadErrorSignal()
441 return mPageLoadErrorSignal;
444 Dali::Toolkit::WebView::WebViewScrollEdgeReachedSignalType& WebView::ScrollEdgeReachedSignal()
446 return mScrollEdgeReachedSignal;
449 void WebView::OnPageLoadStarted(const std::string& url)
451 if(!mPageLoadStartedSignal.Empty())
453 Dali::Toolkit::WebView handle(GetOwner());
454 mPageLoadStartedSignal.Emit(handle, url);
458 void WebView::OnPageLoadFinished(const std::string& url)
460 if(!mPageLoadFinishedSignal.Empty())
462 Dali::Toolkit::WebView handle(GetOwner());
463 mPageLoadFinishedSignal.Emit(handle, url);
467 void WebView::OnPageLoadError(const std::string& url, int errorCode)
469 if(!mPageLoadErrorSignal.Empty())
471 Dali::Toolkit::WebView handle(GetOwner());
472 mPageLoadErrorSignal.Emit(handle, url, static_cast<Toolkit::WebView::LoadErrorCode>(errorCode));
476 void WebView::OnScrollEdgeReached(Dali::WebEnginePlugin::ScrollEdge edge)
478 if(!mScrollEdgeReachedSignal.Empty())
480 Dali::Toolkit::WebView handle(GetOwner());
481 mScrollEdgeReachedSignal.Emit(handle, edge);
485 bool WebView::DoConnectSignal(BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor)
487 Dali::BaseHandle handle(object);
489 bool connected = false;
490 Toolkit::WebView webView = Toolkit::WebView::DownCast(handle);
492 if(0 == strcmp(signalName.c_str(), PAGE_LOAD_STARTED_SIGNAL))
494 webView.PageLoadStartedSignal().Connect(tracker, functor);
497 else if(0 == strcmp(signalName.c_str(), PAGE_LOAD_FINISHED_SIGNAL))
499 webView.PageLoadFinishedSignal().Connect(tracker, functor);
502 else if(0 == strcmp(signalName.c_str(), PAGE_LOAD_ERROR_SIGNAL))
504 webView.PageLoadErrorSignal().Connect(tracker, functor);
507 else if(0 == strcmp(signalName.c_str(), SCROLL_EDGE_REACHED_SIGNAL))
509 webView.ScrollEdgeReachedSignal().Connect(tracker, functor);
516 Vector3 WebView::GetNaturalSize()
520 Vector2 rendererNaturalSize;
521 mVisual.GetNaturalSize(rendererNaturalSize);
522 return Vector3(rendererNaturalSize);
525 return Vector3(mWebViewSize);
528 void WebView::OnSceneConnection(int depth)
530 Control::OnSceneConnection(depth);
532 EnableBlendMode(!mVideoHoleEnabled);
535 void WebView::SetProperty(BaseObject* object, Property::Index index, const Property::Value& value)
537 Toolkit::WebView webView = Toolkit::WebView::DownCast(Dali::BaseHandle(object));
541 WebView& impl = GetImpl(webView);
544 case Toolkit::WebView::Property::URL:
553 case Toolkit::WebView::Property::USER_AGENT:
558 impl.SetUserAgent(input);
562 case Toolkit::WebView::Property::SCROLL_POSITION:
567 impl.SetScrollPosition(input.x, input.y);
571 case Toolkit::WebView::Property::VIDEO_HOLE_ENABLED:
576 impl.EnableVideoHole(input);
584 Property::Value WebView::GetProperty(BaseObject* object, Property::Index propertyIndex)
586 Property::Value value;
588 Toolkit::WebView webView = Toolkit::WebView::DownCast(Dali::BaseHandle(object));
592 WebView& impl = GetImpl(webView);
593 switch(propertyIndex)
595 case Toolkit::WebView::Property::URL:
600 case Toolkit::WebView::Property::USER_AGENT:
602 value = impl.GetUserAgent();
605 case Toolkit::WebView::Property::SCROLL_POSITION:
607 value = impl.GetScrollPosition();
610 case Toolkit::WebView::Property::SCROLL_SIZE:
612 value = impl.GetScrollSize();
615 case Toolkit::WebView::Property::CONTENT_SIZE:
617 value = impl.GetContentSize();
620 case Toolkit::WebView::Property::TITLE:
622 value = impl.GetTitle();
625 case Toolkit::WebView::Property::VIDEO_HOLE_ENABLED:
627 value = impl.mVideoHoleEnabled;
638 bool WebView::OnTouchEvent(Actor actor, const Dali::TouchEvent& touch)
644 result = mWebEngine.SendTouchEvent(touch);
649 bool WebView::OnKeyEvent(const Dali::KeyEvent& event)
655 result = mWebEngine.SendKeyEvent(event);
660 void WebView::OnKeyInputFocusGained()
664 mWebEngine.SetFocus(true);
667 EmitKeyInputFocusSignal(true); // Calls back into the Control hence done last.
670 void WebView::OnKeyInputFocusLost()
674 mWebEngine.SetFocus(false);
677 EmitKeyInputFocusSignal(false); // Calls back into the Control hence done last.
680 void WebView::SetScrollPosition(int x, int y)
684 mWebEngine.SetScrollPosition(x, y);
688 Dali::Vector2 WebView::GetScrollPosition() const
690 return mWebEngine ? mWebEngine.GetScrollPosition() : Dali::Vector2::ZERO;
693 Dali::Vector2 WebView::GetScrollSize() const
695 return mWebEngine ? mWebEngine.GetScrollSize() : Dali::Vector2::ZERO;
698 Dali::Vector2 WebView::GetContentSize() const
700 return mWebEngine ? mWebEngine.GetContentSize() : Dali::Vector2::ZERO;
703 std::string WebView::GetTitle() const
705 return mWebEngine ? mWebEngine.GetTitle() : kEmptyString;
708 const std::string& WebView::GetUserAgent() const
710 return mWebEngine ? mWebEngine.GetUserAgent() : kEmptyString;
713 void WebView::SetUserAgent(const std::string& userAgent)
717 mWebEngine.SetUserAgent(userAgent);
721 #undef GET_ENUM_STRING
722 #undef GET_ENUM_VALUE
724 } // namespace Internal
726 } // namespace Toolkit