Merge branch 'devel/master' into devel/graphics 46/256646/1
authorAdeel Kazmi <adeel.kazmi@samsung.com>
Thu, 8 Apr 2021 09:55:22 +0000 (10:55 +0100)
committerAdeel Kazmi <adeel.kazmi@samsung.com>
Thu, 8 Apr 2021 09:55:22 +0000 (10:55 +0100)
Change-Id: I8ba1b31b2b1b0af4c5ad38fdfada31d63fcec8a8

90 files changed:
automated-tests/coverage.sh
automated-tests/src/dali-toolkit-internal/dali-toolkit-test-utils/toolkit-text-utils.cpp
automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Markup.cpp
automated-tests/src/dali-toolkit/CMakeLists.txt
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-graphics-controller.cpp
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-graphics-program.cpp
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-graphics-program.h
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-canvas-renderer.cpp [new file with mode: 0644]
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-web-engine.cpp
automated-tests/src/dali-toolkit/utc-Dali-CanvasView.cpp [new file with mode: 0644]
automated-tests/src/dali-toolkit/utc-Dali-TextEditor.cpp
automated-tests/src/dali-toolkit/utc-Dali-TextField.cpp
automated-tests/src/dali-toolkit/utc-Dali-TextLabel.cpp
automated-tests/src/dali-toolkit/utc-Dali-TextSelectionPopup.cpp
automated-tests/src/dali-toolkit/utc-Dali-WebView.cpp
build/tizen/CMakeLists.txt
build/tizen/dali-scene-loader/CMakeLists.txt
dali-scene-loader/public-api/mesh-definition.cpp
dali-scene-loader/public-api/mesh-definition.h
dali-scene-loader/public-api/mesh-geometry.h
dali-toolkit/devel-api/controls/accessible-impl.cpp
dali-toolkit/devel-api/controls/accessible-impl.h
dali-toolkit/devel-api/controls/canvas-view/canvas-view.cpp [new file with mode: 0644]
dali-toolkit/devel-api/controls/canvas-view/canvas-view.h [new file with mode: 0644]
dali-toolkit/devel-api/controls/text-controls/text-editor-devel.cpp
dali-toolkit/devel-api/controls/text-controls/text-editor-devel.h
dali-toolkit/devel-api/controls/text-controls/text-field-devel.cpp
dali-toolkit/devel-api/controls/text-controls/text-field-devel.h
dali-toolkit/devel-api/controls/text-controls/text-label-devel.cpp [new file with mode: 0644]
dali-toolkit/devel-api/controls/text-controls/text-label-devel.h
dali-toolkit/devel-api/controls/text-controls/text-selection-popup.h
dali-toolkit/devel-api/controls/web-view/web-context.cpp
dali-toolkit/devel-api/controls/web-view/web-context.h [changed mode: 0644->0755]
dali-toolkit/devel-api/controls/web-view/web-cookie-manager.h [changed mode: 0644->0755]
dali-toolkit/devel-api/controls/web-view/web-form-repost-decision.cpp [new file with mode: 0644]
dali-toolkit/devel-api/controls/web-view/web-form-repost-decision.h [new file with mode: 0755]
dali-toolkit/devel-api/controls/web-view/web-view.cpp [changed mode: 0644->0755]
dali-toolkit/devel-api/controls/web-view/web-view.h [changed mode: 0644->0755]
dali-toolkit/devel-api/file.list
dali-toolkit/devel-api/text/text-utils-devel.cpp
dali-toolkit/internal/controls/buttons/button-impl.cpp
dali-toolkit/internal/controls/buttons/check-box-button-impl.cpp
dali-toolkit/internal/controls/buttons/push-button-impl.cpp
dali-toolkit/internal/controls/buttons/radio-button-impl.cpp
dali-toolkit/internal/controls/buttons/toggle-button-impl.cpp
dali-toolkit/internal/controls/canvas-view/canvas-view-impl.cpp [new file with mode: 0644]
dali-toolkit/internal/controls/canvas-view/canvas-view-impl.h [new file with mode: 0644]
dali-toolkit/internal/controls/popup/popup-impl.cpp
dali-toolkit/internal/controls/progress-bar/progress-bar-impl.cpp
dali-toolkit/internal/controls/scroll-bar/scroll-bar-impl.cpp
dali-toolkit/internal/controls/scrollable/item-view/item-view-impl.cpp
dali-toolkit/internal/controls/scrollable/scroll-view/scroll-view-impl.cpp
dali-toolkit/internal/controls/slider/slider-impl.cpp
dali-toolkit/internal/controls/text-controls/text-editor-impl.cpp
dali-toolkit/internal/controls/text-controls/text-editor-impl.h
dali-toolkit/internal/controls/text-controls/text-field-impl.cpp
dali-toolkit/internal/controls/text-controls/text-field-impl.h
dali-toolkit/internal/controls/text-controls/text-label-impl.cpp
dali-toolkit/internal/controls/text-controls/text-label-impl.h
dali-toolkit/internal/controls/text-controls/text-selection-popup-impl.cpp
dali-toolkit/internal/controls/text-controls/text-selection-popup-impl.h
dali-toolkit/internal/controls/web-view/web-view-impl.cpp
dali-toolkit/internal/controls/web-view/web-view-impl.h [changed mode: 0644->0755]
dali-toolkit/internal/file.list
dali-toolkit/internal/graphics/shaders/canvas-view.frag [new file with mode: 0644]
dali-toolkit/internal/graphics/shaders/canvas-view.vert [new file with mode: 0644]
dali-toolkit/internal/graphics/shaders/color-visual-blur-edge-shader.frag
dali-toolkit/internal/graphics/shaders/color-visual-blur-edge-shader.vert
dali-toolkit/internal/text/anchor.h [new file with mode: 0644]
dali-toolkit/internal/text/logical-model-impl.cpp
dali-toolkit/internal/text/logical-model-impl.h
dali-toolkit/internal/text/markup-processor-anchor.cpp [new file with mode: 0644]
dali-toolkit/internal/text/markup-processor-anchor.h [new file with mode: 0644]
dali-toolkit/internal/text/markup-processor.cpp
dali-toolkit/internal/text/markup-processor.h
dali-toolkit/internal/text/text-anchor-control-interface.h [new file with mode: 0644]
dali-toolkit/internal/text/text-controller-event-handler.cpp
dali-toolkit/internal/text/text-controller-event-handler.h
dali-toolkit/internal/text/text-controller-impl.h
dali-toolkit/internal/text/text-controller-relayouter.cpp
dali-toolkit/internal/text/text-controller-text-updater.cpp
dali-toolkit/internal/text/text-controller-text-updater.h
dali-toolkit/internal/text/text-controller.cpp
dali-toolkit/internal/text/text-controller.h
dali-toolkit/internal/text/text-editable-control-interface.h
dali-toolkit/public-api/dali-toolkit-version.cpp
dali-toolkit/styles/720x1280/dali-toolkit-default-theme.json
dali-toolkit/styles/images-common/IoT-selection-popup-background.9.png [new file with mode: 0644]
doc/dali-toolkit-doc.h
packaging/dali-toolkit.spec

index 96c3740..11c534d 100755 (executable)
@@ -29,7 +29,7 @@ for i in `find . -name "*.dir"` ; do
         if [[ $? -eq 0 ]]
         then
             lcov $LCOV_OPTS --directory . -c -o dali.info
-            lcov $LCOV_OPTS --remove dali.info "/usr/include/*" "*/automated-tests/*" "*/dali-env/*" -o dali.info
+            lcov $LCOV_OPTS --remove dali.info "/usr/include/*" "/usr/local/include/*" "*/automated-tests/*" "*/dali-env/*" "*/third-party/*" -o dali.info
             if [ ! -s dali.info ]
             then
               rm -f dali.info
@@ -41,7 +41,7 @@ done
 (
     if [ $opt_genhtml == true ] ; then
         cd .. ;
-        genhtml $LCOV_OPTS -o build/$BUILD_DIR_NAME/doc/coverage `find . -name dali.info`
+        genhtml -p `pwd` $LCOV_OPTS -o build/$BUILD_DIR_NAME/doc/coverage `find . -name dali.info`
         echo "Coverage output: ../build/$BUILD_DIR_NAME/doc/coverage/index.html"
     fi
 )
index b7a1122..d98f397 100755 (executable)
@@ -108,7 +108,8 @@ void CreateTextModel( const std::string& text,
 
   MarkupProcessData markupProcessData( logicalModel->mColorRuns,
                                        logicalModel->mFontDescriptionRuns,
-                                       logicalModel->mEmbeddedItems );
+                                       logicalModel->mEmbeddedItems,
+                                       logicalModel->mAnchors );
 
   Length textSize = 0u;
   const uint8_t* utf8 = NULL;
index 779eb56..6e2d632 100755 (executable)
@@ -184,7 +184,8 @@ namespace
     Vector<ColorRun> colorRuns;
     Vector<FontDescriptionRun> fontRuns;
     Vector<EmbeddedItem> items;
-    MarkupProcessData markupProcessData( colorRuns, fontRuns, items );
+    Vector<Anchor> anchors;
+    MarkupProcessData markupProcessData( colorRuns, fontRuns, items, anchors );
     ProcessMarkupString( data.xHTMLEntityString, markupProcessData );
 
     for( Vector<EmbeddedItem>::Iterator it = items.Begin(),
index 7649466..c3ab255 100755 (executable)
@@ -14,6 +14,7 @@ SET(TC_SOURCES
   utc-Dali-BloomView.cpp
   utc-Dali-BubbleEmitter.cpp
   utc-Dali-Builder.cpp
+  utc-Dali-CanvasView.cpp
   utc-Dali-CheckBoxButton.cpp
   utc-Dali-ConfirmationPopup.cpp
   utc-Dali-CubeTransitionEffect.cpp
@@ -78,6 +79,7 @@ SET(TC_SOURCES
 SET(TEST_HARNESS_SOURCES
   dali-toolkit-test-utils/toolkit-adaptor.cpp
   dali-toolkit-test-utils/toolkit-application.cpp
+  dali-toolkit-test-utils/toolkit-canvas-renderer.cpp
   dali-toolkit-test-utils/toolkit-clipboard.cpp
   dali-toolkit-test-utils/toolkit-clipboard-event-notifier.cpp
   dali-toolkit-test-utils/toolkit-event-thread-callback.cpp
index 48d6912..54e8f77 100644 (file)
@@ -180,7 +180,9 @@ public:
   : mCallStack(callStack),
     mBuffer(buffer),
     mMappedOffset(mappedOffset),
-    mMappedSize(mappedSize)
+    mMappedSize(mappedSize),
+    mLockedOffset(0u),
+    mLockedSize(0u)
   {
   }
 
index 0bf698a..a994157 100644 (file)
@@ -36,11 +36,6 @@ bool TestGraphicsProgramImpl::GetParameter(uint32_t parameterId, void* outData)
   return true;
 }
 
-TestGraphicsProgram::TestGraphicsProgram(TestGlAbstraction& gl, const Graphics::ProgramCreateInfo& createInfo, Property::Array& vertexFormats, std::vector<UniformData>& customUniforms)
-{
-  mImpl = new TestGraphicsProgramImpl(gl, createInfo, vertexFormats, customUniforms);
-}
-
 TestGraphicsProgram::TestGraphicsProgram(TestGraphicsProgramImpl* impl)
 {
   mImpl = impl;
index 3aae276..3899bec 100644 (file)
@@ -54,7 +54,6 @@ public:
 class TestGraphicsProgram : public Graphics::Program
 {
 public:
-  TestGraphicsProgram(TestGlAbstraction& gl, const Graphics::ProgramCreateInfo& createInfo, Property::Array& vertexFormats, std::vector<UniformData>& customUniforms);
   TestGraphicsProgram(TestGraphicsProgramImpl* impl);
 
   const TestGraphicsReflection& GetReflection() const
diff --git a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-canvas-renderer.cpp b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-canvas-renderer.cpp
new file mode 100644 (file)
index 0000000..0d6b87e
--- /dev/null
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <dali/devel-api/adaptor-framework/canvas-renderer.h>
+#include <dali/devel-api/adaptor-framework/canvas-renderer-drawable.h>
+#include <dali/public-api/object/base-object.h>
+#include <dali/public-api/rendering/renderer.h>
+#include <toolkit-application.h>
+#include <toolkit-event-thread-callback.h>
+#include <memory>
+#include <cstring>
+#include <sys/stat.h>
+
+namespace Dali
+{
+
+namespace Internal
+{
+
+namespace Adaptor
+{
+
+class CanvasRenderer: public Dali::BaseObject
+{
+public:
+  CanvasRenderer( const Vector2& size )
+  : mPixelBuffer( Devel::PixelBuffer::New(size.width, size.height, Dali::Pixel::RGBA8888) ),
+    mSize(size)
+  {
+  }
+
+  ~CanvasRenderer()
+  {
+  }
+
+  bool Commit()
+  {
+     return true;
+  }
+
+  bool AddDrawable(Dali::CanvasRenderer::Drawable& drawable)
+  {
+    if (!drawable)
+    {
+      return false;
+    }
+    return true;
+  }
+
+  Devel::PixelBuffer GetPixelBuffer()
+  {
+    return mPixelBuffer;
+  }
+
+
+  bool SetSize(const Vector2& size)
+  {
+    mSize = size;
+    // For negative test
+    if ( size.width == -999 && size.height == -999 )
+    {
+      return false;
+    }
+    return true;
+  }
+
+  const Vector2& GetSize()
+  {
+    mSize = Vector2(200, 200);
+    return mSize;
+  }
+
+
+public:
+   Devel::PixelBuffer mPixelBuffer;
+   Vector2 mSize;
+};
+
+inline CanvasRenderer& GetImplementation( Dali::CanvasRenderer& renderer )
+{
+  DALI_ASSERT_ALWAYS( renderer && "CanvasRenderer handle is empty." );
+  BaseObject& handle = renderer.GetBaseObject();
+  return static_cast< Internal::Adaptor::CanvasRenderer& >( handle );
+}
+
+inline const CanvasRenderer& GetImplementation( const Dali::CanvasRenderer& renderer )
+{
+  DALI_ASSERT_ALWAYS( renderer && "CanvasRenderer handle is empty." );
+  const BaseObject& handle = renderer.GetBaseObject();
+  return static_cast< const Internal::Adaptor::CanvasRenderer& >( handle );
+}
+
+} // namespace Adaptor
+
+} // namespace Internal
+
+
+/********************************************************************************/
+/*********************************  PUBLIC CLASS  *******************************/
+/********************************************************************************/
+
+CanvasRenderer CanvasRenderer::New( const Vector2& size )
+{
+  Internal::Adaptor::CanvasRenderer* imageRenderer = new Internal::Adaptor::CanvasRenderer(size);
+
+  return CanvasRenderer( imageRenderer );
+}
+
+CanvasRenderer::CanvasRenderer()
+{
+}
+
+CanvasRenderer::~CanvasRenderer()
+{
+}
+
+CanvasRenderer::CanvasRenderer( Internal::Adaptor::CanvasRenderer* internal )
+: BaseHandle( internal )
+{
+}
+
+bool CanvasRenderer::Commit()
+{
+  return Internal::Adaptor::GetImplementation(*this).Commit();
+}
+
+Devel::PixelBuffer CanvasRenderer::GetPixelBuffer()
+{
+  return Internal::Adaptor::GetImplementation(*this).GetPixelBuffer();
+}
+
+bool CanvasRenderer::AddDrawable(Dali::CanvasRenderer::Drawable& drawable)
+{
+  return Internal::Adaptor::GetImplementation(*this).AddDrawable(drawable);
+}
+
+bool CanvasRenderer::SetSize(const Vector2& size)
+{
+  return Internal::Adaptor::GetImplementation(*this).SetSize(size);
+}
+
+const Vector2& CanvasRenderer::GetSize()
+{
+  return Internal::Adaptor::GetImplementation(*this).GetSize();
+}
+
+
+} // namespace Dali
index 0043f2c..d760930 100755 (executable)
 #include <dali/devel-api/adaptor-framework/web-engine.h>
 #include <dali/devel-api/adaptor-framework/web-engine-back-forward-list.h>
 #include <dali/devel-api/adaptor-framework/web-engine-back-forward-list-item.h>
+#include <dali/devel-api/adaptor-framework/web-engine-certificate.h>
+#include <dali/devel-api/adaptor-framework/web-engine-console-message.h>
 #include <dali/devel-api/adaptor-framework/web-engine-context.h>
+#include <dali/devel-api/adaptor-framework/web-engine-context-menu.h>
+#include <dali/devel-api/adaptor-framework/web-engine-context-menu-item.h>
 #include <dali/devel-api/adaptor-framework/web-engine-cookie-manager.h>
+#include <dali/devel-api/adaptor-framework/web-engine-form-repost-decision.h>
+#include <dali/devel-api/adaptor-framework/web-engine-frame.h>
+#include <dali/devel-api/adaptor-framework/web-engine-http-auth-handler.h>
+#include <dali/devel-api/adaptor-framework/web-engine-load-error.h>
+#include <dali/devel-api/adaptor-framework/web-engine-policy-decision.h>
+#include <dali/devel-api/adaptor-framework/web-engine-request-interceptor.h>
+#include <dali/devel-api/adaptor-framework/web-engine-security-origin.h>
 #include <dali/devel-api/adaptor-framework/web-engine-settings.h>
 #include <dali/public-api/adaptor-framework/native-image-source.h>
 #include <dali/public-api/images/pixel-data.h>
 #include <dali/public-api/object/any.h>
 #include <dali/public-api/object/base-object.h>
+#include <memory>
+#include <string.h>
 #include <toolkit-application.h>
 
 namespace Dali
@@ -39,14 +52,16 @@ namespace Adaptor
 {
 
 class WebEngine;
+class MockWebEngineContext;
 
 namespace
 {
 
 // Generally only one WebEngine instance exists.
 // If > 1, a new web engine has been created by CreateWindowSignal.
-static WebEngine* gInstance = 0;
+static WebEngine* gInstance = nullptr;
 static int gInstanceCount = 0;
+static MockWebEngineContext* gWebEngineContextInstance = nullptr;
 
 bool OnGoBack();
 bool OnGoForward();
@@ -56,7 +71,15 @@ bool OnJavaScriptAlert();
 bool OnJavaScriptConfirm();
 bool OnJavaScriptPrompt();
 bool OnScrollEdge();
+bool OnScreenshotCaptured();
+bool OnVideoPlaying();
+bool OnGeolocationPermission();
 bool OnClearHistory();
+bool OnSecurityOriginAcquired();
+bool OnStorageUsageAcquired();
+bool OnFormPasswordAcquired();
+bool OnDownloadStarted();
+bool OnMimeOverridden();
 
 static void ConnectToGlobalSignal( bool ( *func )() )
 {
@@ -101,12 +124,52 @@ public:
   {
   }
 
-  void DeleteWebDatabase() override
+  void DeleteAllWebDatabase() override
   {
   }
 
-  void DeleteWebStorage() override
+  bool GetWebDatabaseOrigins(Dali::WebEngineContext::WebEngineSecurityOriginAcquiredCallback callback)
   {
+    if (callback)
+    {
+      ConnectToGlobalSignal(&OnSecurityOriginAcquired);
+      mSecurityOriginAcquiredCallback = callback;
+    }
+    return true;
+  }
+
+  bool DeleteWebDatabase(Dali::WebEngineSecurityOrigin& origin)
+  {
+    return true;
+  }
+
+  bool GetWebStorageOrigins(Dali::WebEngineContext::WebEngineSecurityOriginAcquiredCallback callback)
+  {
+    if (callback)
+    {
+      ConnectToGlobalSignal(&OnSecurityOriginAcquired);
+      mSecurityOriginAcquiredCallback = callback;
+    }
+    return true;
+  }
+
+  bool GetWebStorageUsageForOrigin(Dali::WebEngineSecurityOrigin& origin, Dali::WebEngineContext::WebEngineStorageUsageAcquiredCallback callback) 
+  {
+    if (callback)
+    {
+      ConnectToGlobalSignal(&OnStorageUsageAcquired);
+      mStorageUsageAcquiredCallback = callback;
+    }
+    return true;
+  }
+
+  void DeleteAllWebStorage() override
+  {
+  }
+
+  bool DeleteWebStorageOrigin(Dali::WebEngineSecurityOrigin& origin)
+  {
+    return true;
   }
 
   void DeleteLocalFileSystem() override
@@ -121,10 +184,73 @@ public:
   {
   }
 
+  bool DeleteApplicationCache(Dali::WebEngineSecurityOrigin& origin)
+  {
+    return true;
+  }
+
+  void GetFormPasswordList(Dali::WebEngineContext::WebEngineFormPasswordAcquiredCallback callback)
+  {
+    if (callback)
+    {
+      ConnectToGlobalSignal(&OnFormPasswordAcquired);
+      mFormPasswordAcquiredCallback = callback;
+    }
+  }
+
+  void RegisterDownloadStartedCallback(Dali::WebEngineContext::WebEngineDownloadStartedCallback callback)
+  {
+    if (callback)
+    {
+      ConnectToGlobalSignal(&OnDownloadStarted);
+      mDownloadStartedCallback = callback;
+    }
+  }
+
+  void RegisterMimeOverriddenCallback(Dali::WebEngineContext::WebEngineMimeOverriddenCallback callback)
+  {
+    if (callback)
+    {
+      ConnectToGlobalSignal(&OnMimeOverridden);
+      mMimeOverriddenCallback = callback;
+    }
+  }
+
+public:
+  Dali::WebEngineContext::WebEngineSecurityOriginAcquiredCallback mSecurityOriginAcquiredCallback;
+  Dali::WebEngineContext::WebEngineStorageUsageAcquiredCallback mStorageUsageAcquiredCallback;
+  Dali::WebEngineContext::WebEngineFormPasswordAcquiredCallback mFormPasswordAcquiredCallback;
+  Dali::WebEngineContext::WebEngineDownloadStartedCallback mDownloadStartedCallback;
+  Dali::WebEngineContext::WebEngineMimeOverriddenCallback mMimeOverriddenCallback;
+
 private:
   Dali::WebEngineContext::CacheModel mockModel;
 };
 
+class MockWebEngineSecurityOrigin : public Dali::WebEngineSecurityOrigin
+{
+public:
+  MockWebEngineSecurityOrigin()
+    : mockUrl("https://test.html")
+    , mockPotocol("https")
+  {
+  }
+
+  std::string GetHost() const
+  {
+    return mockUrl;
+  }
+
+  std::string GetProtocol() const
+  {
+    return mockPotocol;
+  }
+
+private:
+  std::string mockUrl;
+  std::string mockPotocol;
+};
+
 class MockWebEngineCookieManager : public Dali::WebEngineCookieManager
 {
 public:
@@ -189,7 +315,7 @@ private:
 class MockWebEngineBackForwardList : public Dali::WebEngineBackForwardList
 {
 public:
-  MockWebEngineBackForwardList( )
+  MockWebEngineBackForwardList()
     : mockItem(),
       pMockItem( &mockItem )
   {
@@ -212,7 +338,342 @@ public:
 
 private:
   MockWebEngineBackForwardListItem mockItem;
-  WebEngineBackForwardListItem* pMockItem;
+  WebEngineBackForwardListItem*    pMockItem;
+};
+
+class MockWebEngineCertificate : public Dali::WebEngineCertificate
+{
+public:
+  MockWebEngineCertificate()
+  {
+  }
+
+  void Allow(bool allowed) override
+  {
+  }
+
+  bool IsFromMainFrame() const override
+  {
+    return true;
+  }
+
+  std::string GetPem() const override
+  {
+    return "abc";
+  }
+
+  bool IsContextSecure() const override
+  {
+    return true;
+  }
+};
+
+class MockWebEngineHttpAuthHandler : public Dali::WebEngineHttpAuthHandler
+{
+public:
+  MockWebEngineHttpAuthHandler()
+  {
+  }
+
+  std::string GetRealm() const override
+  {
+    return "test";
+  }
+
+  void Suspend() override
+  {
+  }
+
+  void UseCredential(const std::string& user, const std::string& password) override
+  {
+  }
+
+  void CancelCredential() override
+  {
+  }
+};
+
+class MockWebEngineFormRepostDecision : public WebEngineFormRepostDecision
+{
+public:
+  MockWebEngineFormRepostDecision()
+  {
+  }
+
+  void Reply(bool allowed) override {}
+};
+
+class MockWebEngineFrame : public Dali::WebEngineFrame
+{
+public:
+  MockWebEngineFrame()
+  {
+  }
+
+  bool IsMainFrame() const override
+  {
+    return true;
+  }
+};
+
+class MockWebEnginePolicyDecision : public Dali::WebEnginePolicyDecision
+{
+public:
+  MockWebEnginePolicyDecision()
+  {
+  }
+
+  std::string GetUrl() const override
+  {
+    return "http://test.html";
+  }
+
+  std::string GetCookie() const override
+  {
+    return "test:abc";
+  }
+
+  Dali::WebEnginePolicyDecision::DecisionType GetDecisionType() const
+  {
+    return Dali::WebEnginePolicyDecision::DecisionType::USE;
+  }
+
+  std::string GetResponseMime() const
+  {
+    return "txt/xml";
+  }
+
+  int32_t GetResponseStatusCode() const
+  {
+    return 500;
+  }
+
+  Dali::WebEnginePolicyDecision::NavigationType GetNavigationType() const
+  {
+    return Dali::WebEnginePolicyDecision::NavigationType::LINK_CLICKED;
+  }
+
+  Dali::WebEngineFrame& GetFrame() const
+  {
+    return *(Dali::WebEngineFrame*)(&mockWebFrame);
+  }
+
+  std::string GetScheme() const
+  {
+    return "test";
+  }
+
+  bool Use()
+  {
+    return true;
+  }
+
+  bool Ignore()
+  {
+    return true;
+  }
+
+  bool Suspend()
+  {
+    return true;
+  }
+
+private:
+  MockWebEngineFrame mockWebFrame;
+};
+
+class MockWebEngineRequestInterceptor : public WebEngineRequestInterceptor
+{
+public:
+  MockWebEngineRequestInterceptor()
+  {
+  }
+
+  std::string GetUrl() const override
+  {
+    return "http://test.html";
+  }
+
+  bool Ignore() override
+  {
+    return true;
+  }
+
+  bool SetResponseStatus(int statusCode, const std::string &customedStatusText) override
+  {
+    return true;
+  }
+
+  bool AddResponseHeader(const std::string &fieldName, const std::string &fieldValue) override
+  {
+    return true;
+  }
+
+  bool AddResponseBody(const std::string &body, uint32_t length) override
+  {
+    return true;
+  }
+};
+
+class MockWebEngineConsoleMessage : public Dali::WebEngineConsoleMessage
+{
+public:
+  MockWebEngineConsoleMessage()
+  {
+  }
+
+  std::string GetSource() const override
+  {
+    return "source";
+  }
+
+  uint32_t GetLine() const override
+  {
+    return 10;
+  }
+
+  SeverityLevel GetSeverityLevel() const override
+  {
+    return SeverityLevel::EMPTY;
+  }
+
+  std::string GetText() const override
+  {
+    return "This is a text.";
+  }
+};
+
+class MockWebEngineLoadError : public Dali::WebEngineLoadError
+{
+public:
+  MockWebEngineLoadError(const std::string& url)
+    : mockUrl(url)
+  {
+  }
+
+  std::string GetUrl() const override
+  {
+    return mockUrl;
+  }
+
+  ErrorCode GetCode() const override
+  {
+    return ErrorCode::UNKNOWN;
+  }
+
+  std::string GetDescription() const override
+  {
+    return "This is an error.";
+  }
+
+  ErrorType GetType() const override
+  {
+    return ErrorType::NONE;
+  }
+
+private:
+  std::string mockUrl;
+};
+
+class MockWebEngineContextMenuItem : public Dali::WebEngineContextMenuItem
+{
+public:
+  MockWebEngineContextMenuItem()
+  {
+  }
+
+  ItemTag GetTag() const override
+  {
+    return ItemTag::NO_ACTION;
+  }
+
+  ItemType GetType() const override
+  {
+    return ItemType::ACTION;
+  }
+
+  bool IsEnabled() const override
+  {
+    return true;
+  }
+
+  std::string GetLinkUrl() const override
+  {
+    return "http://test.html";
+  }
+
+  std::string GetImageUrl() const override
+  {
+    return "http://test.jpg";
+  }
+
+  std::string GetTitle() const override
+  {
+    return "title";
+  }
+
+  std::unique_ptr<Dali::WebEngineContextMenu> GetParentMenu() const override
+  {
+    std::unique_ptr<Dali::WebEngineContextMenu> result;
+    return result;
+  }
+};
+
+class MockWebEngineContextMenu : public Dali::WebEngineContextMenu
+{
+public:
+  MockWebEngineContextMenu()
+  {
+  }
+
+  uint32_t GetItemCount() const override
+  {
+    return 1;
+  }
+
+  std::unique_ptr<Dali::WebEngineContextMenuItem> GetItemAt(uint32_t index) const override
+  {
+    std::unique_ptr<Dali::WebEngineContextMenuItem> webitem(new MockWebEngineContextMenuItem());
+    return webitem;
+  }
+
+  std::vector<std::unique_ptr<WebEngineContextMenuItem>> GetItemList() const override
+  {
+    std::vector<std::unique_ptr<WebEngineContextMenuItem>> result;
+    std::unique_ptr<Dali::WebEngineContextMenuItem> webitem(new MockWebEngineContextMenuItem());
+    result.push_back(std::move(webitem));
+    return result;
+  }
+
+  Dali::Vector2 GetPosition() const override
+  {
+    return Dali::Vector2(100, 100);
+  }
+
+  bool RemoveItem(WebEngineContextMenuItem& item) override
+  {
+    return true;
+  }
+
+  bool AppendItemAsAction(WebEngineContextMenuItem::ItemTag tag, const std::string& title, bool enabled) override
+  {
+    return true;
+  }
+
+  bool AppendItem(WebEngineContextMenuItem::ItemTag tag, const std::string& title, const std::string& iconFile, bool enabled) override
+  {
+    return true;
+  }
+
+  bool SelectItem(WebEngineContextMenuItem& item) override
+  {
+    return true;
+  }
+
+  bool Hide() override
+  {
+    return true;
+  }
 };
 
 class MockWebEngineSettings : public WebEngineSettings
@@ -454,9 +915,6 @@ class WebEngine: public Dali::BaseObject
 public:
 
   using JavaScriptEvaluatedResultCallback = std::function<void(const std::string&)>;
-  using JavaScriptAlertCallback = std::function<bool(const std::string&)>;
-  using JavaScriptConfirmCallback = std::function<bool(const std::string&)>;
-  using JavaScriptPromptCallback = std::function<bool(const std::string&, const std::string&)>;
 
   WebEngine()
     : mUrl()
@@ -474,7 +932,12 @@ public:
     }
 
     mockWebEngineSettings = new MockWebEngineSettings();
-    mockWebEngineContext = new MockWebEngineContext();
+    MockWebEngineContext* engineContext = new MockWebEngineContext();
+    mockWebEngineContext = engineContext;
+    if ( gInstanceCount == 1 )
+    {
+      gWebEngineContextInstance = engineContext;
+    }
     mockWebEngineCookieManager = new MockWebEngineCookieManager();
     mockWebEngineBackForwardList = new MockWebEngineBackForwardList();
   }
@@ -485,6 +948,7 @@ public:
     if( !gInstanceCount )
     {
       gInstance = 0;
+      gWebEngineContextInstance = 0;
     }
 
     delete mockWebEngineSettings;
@@ -565,154 +1029,306 @@ public:
     ConnectToGlobalSignal( &OnGoForward );
   }
 
-  bool CanGoBack() const
+  bool CanGoBack() const
+  {
+    return mCurrentPlusOnePos > 1;
+  }
+
+  void GoBack()
+  {
+    ConnectToGlobalSignal( &OnGoBack );
+  }
+
+  void EvaluateJavaScript( const std::string& script, std::function< void( const std::string& ) > resultHandler )
+  {
+    if( resultHandler )
+    {
+      if( !mEvaluating )
+      {
+        ConnectToGlobalSignal( &OnEvaluteJavaScript );
+      }
+      mResultCallbacks.push_back( resultHandler );
+    }
+  }
+
+  void RegisterJavaScriptAlertCallback( Dali::WebEnginePlugin::JavaScriptAlertCallback callback )
+  {
+    if ( callback )
+    {
+      ConnectToGlobalSignal( &OnJavaScriptAlert );
+      mJavaScriptAlertCallback = callback;
+    }
+  }
+
+  void RegisterJavaScriptConfirmCallback( Dali::WebEnginePlugin::JavaScriptConfirmCallback callback )
+  {
+    if ( callback )
+    {
+      ConnectToGlobalSignal( &OnJavaScriptConfirm );
+      mJavaScriptConfirmCallback = callback;
+    }
+  }
+
+  void RegisterJavaScriptPromptCallback( Dali::WebEnginePlugin::JavaScriptPromptCallback callback )
+  {
+    if ( callback )
+    {
+      ConnectToGlobalSignal( &OnJavaScriptPrompt );
+      mJavaScriptPromptCallback = callback;
+    }
+  }
+
+  void ClearHistory()
+  {
+    ConnectToGlobalSignal( &OnClearHistory );
+  }
+
+  const std::string& GetUserAgent() const
+  {
+    return mUserAgent;
+  }
+
+  void SetUserAgent( const std::string& userAgent )
+  {
+    mUserAgent = userAgent;
+  }
+
+  void ScrollBy( int dx, int dy )
+  {
+    mScrollPosition += Dali::Vector2( dx, dy );
+    if ( mScrollPosition.y + mScrollSize.height > mContentSize.height )
+    {
+      ConnectToGlobalSignal( &OnScrollEdge );
+    }
+  }
+
+  bool ScrollEdgeBy( int dx, int dy )
+  {
+    mScrollPosition += Dali::Vector2( dx, dy );
+    if ( mScrollPosition.y + mScrollSize.height > mContentSize.height )
+    {
+      ConnectToGlobalSignal( &OnScrollEdge );
+    }
+    return true;
+  }
+
+  void SetScrollPosition( int x, int y )
+  {
+    mScrollPosition.x = x;
+    mScrollPosition.y = y;
+  }
+
+  Dali::Vector2 GetScrollPosition() const
+  {
+    return mScrollPosition;
+  }
+
+  Dali::Vector2 GetScrollSize() const
+  {
+    return mScrollSize;
+  }
+
+  Dali::Vector2 GetContentSize() const
+  {
+    return mContentSize;
+  }
+
+  void SetPageZoomFactor(float zoomFactor)
+  {
+    mPageZoomFactor = zoomFactor;
+  }
+
+  float GetPageZoomFactor() const
+  {
+    return mPageZoomFactor;
+  }
+
+  void SetTextZoomFactor(float zoomFactor)
+  {
+    mTextZoomFactor = zoomFactor;
+  }
+
+  float GetTextZoomFactor() const
+  {
+    return mTextZoomFactor;
+  }
+
+  float GetLoadProgressPercentage() const
+  {
+    return 0.5f;
+  }
+
+  void SetScaleFactor(float scaleFactor, Dali::Vector2 point)
   {
-    return mCurrentPlusOnePos > 1;
+    mScaleFactor = scaleFactor;
   }
 
-  void GoBack()
+  float GetScaleFactor() const
   {
-    ConnectToGlobalSignal( &OnGoBack );
+    return mScaleFactor;
   }
 
-  void EvaluateJavaScript( const std::string& script, std::function< void( const std::string& ) > resultHandler )
+  Dali::PixelData GetScreenshot(Dali::Rect<int> viewArea, float scaleFactor)
   {
-    if( resultHandler )
-    {
-      if( !mEvaluating )
-      {
-        ConnectToGlobalSignal( &OnEvaluteJavaScript );
-      }
-      mResultCallbacks.push_back( resultHandler );
-    }
+    uint32_t bufferSize = viewArea.width * viewArea.height * 4 ;
+    uint8_t* pixel = new uint8_t[ bufferSize ];
+    memset(pixel, 0xff, bufferSize);
+    return Dali::PixelData::New( pixel, bufferSize, viewArea.width, viewArea.height,
+                                 Dali::Pixel::Format::RGBA8888,
+                                 Dali::PixelData::ReleaseFunction::DELETE_ARRAY );
   }
 
-  void RegisterJavaScriptAlertCallback( Dali::WebEnginePlugin::JavaScriptAlertCallback callback )
+  bool GetScreenshotAsynchronously(Dali::Rect<int> viewArea, float scaleFactor, Dali::WebEnginePlugin::ScreenshotCapturedCallback callback)
   {
     if ( callback )
     {
-      ConnectToGlobalSignal( &OnJavaScriptAlert );
-      mJavaScriptAlertCallback = callback;
+      ConnectToGlobalSignal( &OnScreenshotCaptured );
+      mScreenshotCapturedCallback = callback;
     }
+    return true;
   }
 
-  void RegisterJavaScriptConfirmCallback( Dali::WebEnginePlugin::JavaScriptConfirmCallback callback )
+  bool CheckVideoPlayingAsynchronously(Dali::WebEnginePlugin::VideoPlayingCallback callback)
   {
     if ( callback )
     {
-      ConnectToGlobalSignal( &OnJavaScriptConfirm );
-      mJavaScriptConfirmCallback = callback;
+      ConnectToGlobalSignal( &OnVideoPlaying );
+      mVideoPlayingCallback = callback;
     }
+    return true;
   }
 
-  void RegisterJavaScriptPromptCallback( Dali::WebEnginePlugin::JavaScriptPromptCallback callback )
+  void RegisterGeolocationPermissionCallback(Dali::WebEnginePlugin::GeolocationPermissionCallback callback)
   {
     if ( callback )
     {
-      ConnectToGlobalSignal( &OnJavaScriptPrompt );
-      mJavaScriptPromptCallback = callback;
+      ConnectToGlobalSignal( &OnGeolocationPermission );
+      mGeolocationPermissionCallback = callback;
     }
   }
 
-  void ClearHistory()
+  Dali::WebEnginePlugin::WebEnginePageLoadSignalType& PageLoadStartedSignal()
   {
-    ConnectToGlobalSignal( &OnClearHistory );
+    return mPageLoadStartedSignal;
   }
 
-  const std::string& GetUserAgent() const
+  Dali::WebEnginePlugin::WebEnginePageLoadSignalType& PageLoadInProgressSignal()
   {
-    return mUserAgent;
+    return mPageLoadInProgressSignal;
   }
 
-  void SetUserAgent( const std::string& userAgent )
+  Dali::WebEnginePlugin::WebEnginePageLoadSignalType& PageLoadFinishedSignal()
   {
-    mUserAgent = userAgent;
+    return mPageLoadFinishedSignal;
   }
 
-  void ScrollBy( int dx, int dy )
+  Dali::WebEnginePlugin::WebEnginePageLoadErrorSignalType& PageLoadErrorSignal()
   {
-    mScrollPosition += Dali::Vector2( dx, dy );
-    if ( mScrollPosition.y + mScrollSize.height > mContentSize.height )
-    {
-      ConnectToGlobalSignal( &OnScrollEdge );
-    }
+    return mPageLoadErrorSignal;
   }
 
-  void SetScrollPosition( int x, int y )
+  Dali::WebEnginePlugin::WebEngineScrollEdgeReachedSignalType& ScrollEdgeReachedSignal()
   {
-    mScrollPosition.x = x;
-    mScrollPosition.y = y;
+    return mScrollEdgeReachedSignal;
   }
 
-  Dali::Vector2 GetScrollPosition() const
+  Dali::WebEnginePlugin::WebEngineUrlChangedSignalType& UrlChangedSignal()
   {
-    return mScrollPosition;
+    return mUrlChangedSignal;
   }
 
-  Dali::Vector2 GetScrollSize() const
+  Dali::WebEnginePlugin::WebEngineFormRepostDecisionSignalType& FormRepostDecisionSignal()
   {
-    return mScrollSize;
+    return mFormRepostDecisionSignal;
   }
 
-  Dali::Vector2 GetContentSize() const
+  Dali::WebEnginePlugin::WebEngineFrameRenderedSignalType& FrameRenderedSignal()
   {
-    return  mContentSize;
+    return mFrameRenderedSignal;
   }
 
-  Dali::WebEnginePlugin::WebEnginePageLoadSignalType& PageLoadStartedSignal()
+  Dali::WebEnginePlugin::WebEngineRequestInterceptorSignalType& RequestInterceptorSignal()
   {
-    return mPageLoadStartedSignal;
+    return mRequestInterceptorSignal;
   }
 
-  Dali::WebEnginePlugin::WebEnginePageLoadSignalType& PageLoadInProgressSignal()
+  Dali::WebEnginePlugin::WebEngineConsoleMessageSignalType& ConsoleMessageSignal()
   {
-    return mPageLoadInProgressSignal;
+    return mConsoleMessageSignal;
   }
 
-  Dali::WebEnginePlugin::WebEnginePageLoadSignalType& PageLoadFinishedSignal()
+  Dali::WebEnginePlugin::WebEnginePolicyDecisionSignalType& PolicyDecisionSignal()
   {
-    return mPageLoadFinishedSignal;
+    return mPolicyDecisionSignal;
   }
 
-  Dali::WebEnginePlugin::WebEnginePageLoadErrorSignalType& PageLoadErrorSignal()
+  Dali::WebEnginePlugin::WebEngineCertificateSignalType& CertificateConfirmSignal()
   {
-    return mPageLoadErrorSignal;
+    return mCertificateConfirmSignal;
   }
 
-  Dali::WebEnginePlugin::WebEngineScrollEdgeReachedSignalType& ScrollEdgeReachedSignal()
+  Dali::WebEnginePlugin::WebEngineCertificateSignalType& SslCertificateChangedSignal()
   {
-    return mScrollEdgeReachedSignal;
+    return mSslCertificateChangedSignal;
   }
 
-  Dali::WebEnginePlugin::WebEngineUrlChangedSignalType& UrlChangedSignal()
+  Dali::WebEnginePlugin::WebEngineHttpAuthHandlerSignalType& HttpAuthHandlerSignal()
   {
-    return mUrlChangedSignal;
+    return mHttpAuthHandlerSignal;
+  }
+
+  Dali::WebEnginePlugin::WebEngineContextMenuCustomizedSignalType& ContextMenuCustomizedSignal()
+  {
+    return mContextMenuCustomizedSignal;
+  }
+
+  Dali::WebEnginePlugin::WebEngineContextMenuItemSelectedSignalType& ContextMenuItemSelectedSignal()
+  {
+    return mContextMenuItemSelectedSignal;
   }
 
-  std::string                                                mUrl;
-  std::vector< std::string >                                 mHistory;
-  size_t                                                     mCurrentPlusOnePos;
-  std::string                                                mUserAgent;
-  Dali::WebEnginePlugin::WebEnginePageLoadSignalType         mPageLoadStartedSignal;
-  Dali::WebEnginePlugin::WebEnginePageLoadSignalType         mPageLoadInProgressSignal;
-  Dali::WebEnginePlugin::WebEnginePageLoadSignalType         mPageLoadFinishedSignal;
-  Dali::WebEnginePlugin::WebEnginePageLoadErrorSignalType    mPageLoadErrorSignal;
-  std::vector<JavaScriptEvaluatedResultCallback>             mResultCallbacks;
-  bool                                                       mEvaluating;
-
-  Dali::WebEnginePlugin::WebEngineScrollEdgeReachedSignalType mScrollEdgeReachedSignal;
-  Dali::Vector2                                               mScrollPosition;
-  Dali::Vector2                                               mScrollSize;
-  Dali::Vector2                                               mContentSize;
-  WebEngineBackForwardList*                                   mockWebEngineBackForwardList;
-  WebEngineContext*                                           mockWebEngineContext;
-  WebEngineCookieManager*                                     mockWebEngineCookieManager;
-  WebEngineSettings*                                          mockWebEngineSettings;
-  Dali::WebEnginePlugin::WebEngineUrlChangedSignalType        mUrlChangedSignal;
-
-  JavaScriptAlertCallback                                     mJavaScriptAlertCallback;
-  JavaScriptConfirmCallback                                   mJavaScriptConfirmCallback;
-  JavaScriptPromptCallback                                    mJavaScriptPromptCallback;
+  std::string              mUrl;
+  std::vector<std::string> mHistory;
+  size_t                   mCurrentPlusOnePos;
+  std::string              mUserAgent;
+
+  Dali::WebEnginePlugin::WebEnginePageLoadSignalType                mPageLoadStartedSignal;
+  Dali::WebEnginePlugin::WebEnginePageLoadSignalType                mPageLoadInProgressSignal;
+  Dali::WebEnginePlugin::WebEnginePageLoadSignalType                mPageLoadFinishedSignal;
+  Dali::WebEnginePlugin::WebEnginePageLoadErrorSignalType           mPageLoadErrorSignal;
+  Dali::WebEnginePlugin::WebEngineScrollEdgeReachedSignalType       mScrollEdgeReachedSignal;
+  Dali::WebEnginePlugin::WebEngineUrlChangedSignalType              mUrlChangedSignal;
+  Dali::WebEnginePlugin::WebEngineFormRepostDecisionSignalType      mFormRepostDecisionSignal;
+  Dali::WebEnginePlugin::WebEngineFrameRenderedSignalType           mFrameRenderedSignal;
+  Dali::WebEnginePlugin::WebEngineRequestInterceptorSignalType      mRequestInterceptorSignal;
+  Dali::WebEnginePlugin::WebEngineConsoleMessageSignalType          mConsoleMessageSignal;
+  Dali::WebEnginePlugin::WebEnginePolicyDecisionSignalType          mPolicyDecisionSignal;
+  Dali::WebEnginePlugin::WebEngineCertificateSignalType             mCertificateConfirmSignal;
+  Dali::WebEnginePlugin::WebEngineCertificateSignalType             mSslCertificateChangedSignal;
+  Dali::WebEnginePlugin::WebEngineHttpAuthHandlerSignalType         mHttpAuthHandlerSignal;
+  Dali::WebEnginePlugin::WebEngineContextMenuCustomizedSignalType   mContextMenuCustomizedSignal;
+  Dali::WebEnginePlugin::WebEngineContextMenuItemSelectedSignalType mContextMenuItemSelectedSignal;
+
+  bool  mEvaluating;
+  float mPageZoomFactor;
+  float mTextZoomFactor;
+  float mScaleFactor;
+
+  Dali::Vector2             mScrollPosition;
+  Dali::Vector2             mScrollSize;
+  Dali::Vector2             mContentSize;
+  WebEngineBackForwardList* mockWebEngineBackForwardList;
+  WebEngineContext*         mockWebEngineContext;
+  WebEngineCookieManager*   mockWebEngineCookieManager;
+  WebEngineSettings*        mockWebEngineSettings;
+
+  std::vector<JavaScriptEvaluatedResultCallback>       mResultCallbacks;
+  Dali::WebEnginePlugin::JavaScriptAlertCallback       mJavaScriptAlertCallback;
+  Dali::WebEnginePlugin::JavaScriptConfirmCallback     mJavaScriptConfirmCallback;
+  Dali::WebEnginePlugin::JavaScriptPromptCallback      mJavaScriptPromptCallback;
+  Dali::WebEnginePlugin::ScreenshotCapturedCallback    mScreenshotCapturedCallback;
+  Dali::WebEnginePlugin::VideoPlayingCallback          mVideoPlayingCallback;
+  Dali::WebEnginePlugin::GeolocationPermissionCallback mGeolocationPermissionCallback;
 };
 
 
@@ -757,6 +1373,31 @@ bool OnLoadUrl()
     gInstance->mPageLoadInProgressSignal.Emit( gInstance->mUrl );
     gInstance->mPageLoadFinishedSignal.Emit( gInstance->mUrl );
     gInstance->mUrlChangedSignal.Emit( "http://new-test" );
+
+    std::shared_ptr<Dali::WebEngineFormRepostDecision> repostDecision(new MockWebEngineFormRepostDecision());
+    gInstance->mFormRepostDecisionSignal.Emit(std::move(repostDecision));
+    gInstance->mFrameRenderedSignal.Emit();
+    std::shared_ptr<Dali::WebEngineRequestInterceptor> interceptor(new MockWebEngineRequestInterceptor());
+    gInstance->mRequestInterceptorSignal.Emit(std::move(interceptor));
+
+    std::shared_ptr<Dali::WebEngineLoadError> error(new MockWebEngineLoadError(gInstance->mUrl));
+    gInstance->mPageLoadErrorSignal.Emit(std::move(error));
+    std::shared_ptr<Dali::WebEngineConsoleMessage> message(new MockWebEngineConsoleMessage());
+    gInstance->mConsoleMessageSignal.Emit(std::move(message));
+    std::shared_ptr<Dali::WebEnginePolicyDecision> policyDecision(new MockWebEnginePolicyDecision());
+    gInstance->mPolicyDecisionSignal.Emit(std::move(policyDecision));
+
+    std::shared_ptr<Dali::WebEngineCertificate> certificate(new MockWebEngineCertificate());
+    gInstance->mCertificateConfirmSignal.Emit(std::move(certificate));
+    std::shared_ptr<Dali::WebEngineCertificate> sslCertificate(new MockWebEngineCertificate());
+    gInstance->mSslCertificateChangedSignal.Emit(std::move(sslCertificate));
+    std::shared_ptr<Dali::WebEngineHttpAuthHandler> handler(new MockWebEngineHttpAuthHandler());
+    gInstance->mHttpAuthHandlerSignal.Emit(std::move(handler));
+
+    std::shared_ptr<Dali::WebEngineContextMenu> menu(new MockWebEngineContextMenu());
+    gInstance->mContextMenuCustomizedSignal.Emit(std::move(menu));
+    std::shared_ptr<Dali::WebEngineContextMenuItem> item(new MockWebEngineContextMenuItem());
+    gInstance->mContextMenuItemSelectedSignal.Emit(std::move(item));
   }
   return false;
 }
@@ -818,6 +1459,41 @@ bool OnJavaScriptPrompt()
   return false;
 }
 
+bool OnScreenshotCaptured()
+{
+  DisconnectFromGlobalSignal( &OnScreenshotCaptured );
+  if ( gInstance )
+  {
+    uint8_t* pixel = new uint8_t[ 2 * 2 * 4 ];
+    memset(pixel, 0xff, 2 * 2 * 4);
+    Dali::PixelData data = Dali::PixelData::New( pixel, 2 * 2 * 4, 2, 2,
+                                 Dali::Pixel::Format::RGBA8888,
+                                 Dali::PixelData::ReleaseFunction::DELETE_ARRAY );
+    gInstance->mScreenshotCapturedCallback( data );
+  }
+  return false;
+}
+
+bool OnVideoPlaying()
+{
+  DisconnectFromGlobalSignal( &OnVideoPlaying );
+  if ( gInstance )
+  {
+    gInstance->mVideoPlayingCallback( true );
+  }
+  return false;
+}
+
+bool OnGeolocationPermission()
+{
+  DisconnectFromGlobalSignal( &OnGeolocationPermission );
+  if ( gInstance )
+  {
+    gInstance->mGeolocationPermissionCallback( "", "" );
+  }
+  return false;
+}
+
 bool OnClearHistory()
 {
   DisconnectFromGlobalSignal( &OnClearHistory );
@@ -832,6 +1508,65 @@ bool OnClearHistory()
   return false;
 }
 
+bool OnSecurityOriginAcquired()
+{
+  DisconnectFromGlobalSignal(&OnSecurityOriginAcquired);
+  if (gWebEngineContextInstance)
+  {
+    std::vector<std::unique_ptr<Dali::WebEngineSecurityOrigin>> securityOriginList;
+    std::unique_ptr<Dali::WebEngineSecurityOrigin> origin(new MockWebEngineSecurityOrigin());
+    securityOriginList.push_back(std::move(origin));
+    gWebEngineContextInstance->mSecurityOriginAcquiredCallback(securityOriginList);
+  }
+  return false;
+}
+
+bool OnStorageUsageAcquired()
+{
+  DisconnectFromGlobalSignal(&OnStorageUsageAcquired);
+  if (gWebEngineContextInstance)
+  {
+    gWebEngineContextInstance->mStorageUsageAcquiredCallback(0);
+  }
+  return false;
+}
+
+bool OnFormPasswordAcquired()
+{
+  DisconnectFromGlobalSignal(&OnFormPasswordAcquired);
+  if (gWebEngineContextInstance)
+  {
+    std::vector<std::unique_ptr<Dali::WebEngineContext::PasswordData>> formPasswordList;
+    std::unique_ptr<Dali::WebEngineContext::PasswordData> data(new Dali::WebEngineContext::PasswordData());
+    data->url = "http://test.html";
+    data->useFingerprint = false;
+    formPasswordList.push_back(std::move(data));
+    gWebEngineContextInstance->mFormPasswordAcquiredCallback(formPasswordList);
+  }
+  return false;
+}
+
+bool OnDownloadStarted()
+{
+  DisconnectFromGlobalSignal(&OnDownloadStarted);
+  if (gWebEngineContextInstance)
+  {
+    gWebEngineContextInstance->mDownloadStartedCallback("http://test.html");
+  }
+  return false;
+}
+
+bool OnMimeOverridden()
+{
+  DisconnectFromGlobalSignal(&OnMimeOverridden);
+  if (gWebEngineContextInstance)
+  {
+    std::string newMime;
+    gWebEngineContextInstance->mMimeOverriddenCallback("http://test.html", "txt/xml", newMime);
+  }
+  return false;
+}
+
 } // namespace
 
 inline WebEngine& GetImplementation( Dali::WebEngine& webEngine )
@@ -952,10 +1687,25 @@ void WebEngine::LoadHtmlString( const std::string& htmlString )
 {
 }
 
+bool WebEngine::LoadHtmlStringOverrideCurrentEntry(const std::string& html, const std::string& basicUri, const std::string& unreachableUrl)
+{
+  return true;
+}
+
+bool WebEngine::LoadContents(const std::string& contents, uint32_t contentSize, const std::string& mimeType, const std::string& encoding, const std::string& baseUri)
+{
+  return true;
+}
+
 void WebEngine::Reload()
 {
 }
 
+bool WebEngine::ReloadWithoutCache()
+{
+  return true;
+}
+
 void WebEngine::StopLoading()
 {
 }
@@ -968,6 +1718,34 @@ void WebEngine::Resume()
 {
 }
 
+void WebEngine::SuspendNetworkLoading()
+{
+}
+
+void WebEngine::ResumeNetworkLoading()
+{
+}
+
+bool WebEngine::AddCustomHeader(const std::string& name, const std::string& value)
+{
+  return true;
+}
+
+bool WebEngine::RemoveCustomHeader(const std::string& name)
+{
+  return true;
+}
+
+uint32_t WebEngine::StartInspectorServer(uint32_t port)
+{
+  return port;
+}
+
+bool WebEngine::StopInspectorServer()
+{
+  return true;
+}
+
 bool WebEngine::CanGoForward()
 {
   return Internal::Adaptor::GetImplementation( *this ).CanGoForward();
@@ -1033,6 +1811,49 @@ void WebEngine::ClearHistory()
   Internal::Adaptor::GetImplementation( *this ).ClearHistory();
 }
 
+void WebEngine::SetScaleFactor(float scaleFactor, Dali::Vector2 point)
+{
+  Internal::Adaptor::GetImplementation( *this ).SetScaleFactor(scaleFactor, point);
+}
+
+float WebEngine::GetScaleFactor() const
+{
+  return Internal::Adaptor::GetImplementation( *this ).GetScaleFactor();
+}
+
+void WebEngine::ActivateAccessibility(bool activated)
+{
+}
+
+bool WebEngine::HighlightText(const std::string& text, Dali::WebEnginePlugin::FindOption options, uint32_t maxMatchCount)
+{
+  return true;
+}
+
+void WebEngine::AddDynamicCertificatePath(const std::string& host, const std::string& certPath)
+{
+}
+
+Dali::PixelData WebEngine::GetScreenshot(Dali::Rect<int> viewArea, float scaleFactor)
+{
+  return Internal::Adaptor::GetImplementation( *this ).GetScreenshot(viewArea, scaleFactor);
+}
+
+bool WebEngine::GetScreenshotAsynchronously(Dali::Rect<int> viewArea, float scaleFactor, Dali::WebEnginePlugin::ScreenshotCapturedCallback callback)
+{
+  return Internal::Adaptor::GetImplementation( *this ).GetScreenshotAsynchronously(viewArea, scaleFactor, callback);
+}
+
+bool WebEngine::CheckVideoPlayingAsynchronously(Dali::WebEnginePlugin::VideoPlayingCallback callback)
+{
+  return Internal::Adaptor::GetImplementation( *this ).CheckVideoPlayingAsynchronously(callback);
+}
+
+void WebEngine::RegisterGeolocationPermissionCallback(Dali::WebEnginePlugin::GeolocationPermissionCallback callback)
+{
+  Internal::Adaptor::GetImplementation( *this ).RegisterGeolocationPermissionCallback(callback);
+}
+
 const std::string& WebEngine::GetUserAgent() const
 {
   return Internal::Adaptor::GetImplementation( *this ).GetUserAgent();
@@ -1048,6 +1869,11 @@ void WebEngine::ScrollBy( int dx, int dy )
   Internal::Adaptor::GetImplementation( *this ).ScrollBy( dx, dy );
 }
 
+bool WebEngine::ScrollEdgeBy( int dx, int dy )
+{
+  return Internal::Adaptor::GetImplementation( *this ).ScrollEdgeBy( dx, dy );
+}
+
 void WebEngine::SetScrollPosition( int x, int y )
 {
   Internal::Adaptor::GetImplementation( *this ).SetScrollPosition( x, y );
@@ -1072,6 +1898,27 @@ void WebEngine::SetSize( int width, int height )
 {
 }
 
+void WebEngine::SetDocumentBackgroundColor(Dali::Vector4 color)
+{
+}
+
+void WebEngine::ClearTilesWhenHidden(bool cleared)
+{
+}
+
+void WebEngine::SetTileCoverAreaMultiplier(float multiplier)
+{
+}
+
+void WebEngine::EnableCursorByClient(bool enabled)
+{
+}
+
+std::string WebEngine::GetSelectedText() const
+{
+  return "test";
+}
+
 bool WebEngine::SendTouchEvent( const TouchEvent& touch )
 {
   return true;
@@ -1096,6 +1943,31 @@ void WebEngine::SetFocus( bool focused )
 {
 }
 
+void WebEngine::SetPageZoomFactor(float zoomFactor)
+{
+  Internal::Adaptor::GetImplementation( *this ).SetPageZoomFactor(zoomFactor);
+}
+
+float WebEngine::GetPageZoomFactor() const
+{
+  return Internal::Adaptor::GetImplementation( *this ).GetPageZoomFactor();
+}
+
+void WebEngine::SetTextZoomFactor(float zoomFactor)
+{
+  Internal::Adaptor::GetImplementation( *this ).SetTextZoomFactor(zoomFactor);
+}
+
+float WebEngine::GetTextZoomFactor() const
+{
+  return Internal::Adaptor::GetImplementation( *this ).GetTextZoomFactor();
+}
+
+float WebEngine::GetLoadProgressPercentage() const
+{
+  return Internal::Adaptor::GetImplementation( *this ).GetLoadProgressPercentage();
+}
+
 void WebEngine::UpdateDisplayArea( Dali::Rect< int > displayArea )
 {
 }
@@ -1142,5 +2014,55 @@ Dali::WebEnginePlugin::WebEngineUrlChangedSignalType& WebEngine::UrlChangedSigna
   return Internal::Adaptor::GetImplementation( *this ).UrlChangedSignal();
 }
 
+Dali::WebEnginePlugin::WebEngineFormRepostDecisionSignalType& WebEngine::FormRepostDecisionSignal()
+{
+  return Internal::Adaptor::GetImplementation(*this).FormRepostDecisionSignal();
+}
+
+Dali::WebEnginePlugin::WebEngineFrameRenderedSignalType& WebEngine::FrameRenderedSignal()
+{
+  return Internal::Adaptor::GetImplementation(*this).FrameRenderedSignal();
+}
+
+Dali::WebEnginePlugin::WebEngineRequestInterceptorSignalType& WebEngine::RequestInterceptorSignal()
+{
+  return Internal::Adaptor::GetImplementation(*this).RequestInterceptorSignal();
+}
+
+Dali::WebEnginePlugin::WebEngineConsoleMessageSignalType& WebEngine::ConsoleMessageSignal()
+{
+  return Internal::Adaptor::GetImplementation(*this).ConsoleMessageSignal();
+}
+
+Dali::WebEnginePlugin::WebEnginePolicyDecisionSignalType& WebEngine::PolicyDecisionSignal()
+{
+  return Internal::Adaptor::GetImplementation(*this).PolicyDecisionSignal();
+}
+
+Dali::WebEnginePlugin::WebEngineCertificateSignalType& WebEngine::CertificateConfirmSignal()
+{
+  return Internal::Adaptor::GetImplementation(*this).CertificateConfirmSignal();
+}
+
+Dali::WebEnginePlugin::WebEngineCertificateSignalType& WebEngine::SslCertificateChangedSignal()
+{
+  return Internal::Adaptor::GetImplementation(*this).SslCertificateChangedSignal();
+}
+
+Dali::WebEnginePlugin::WebEngineHttpAuthHandlerSignalType& WebEngine::HttpAuthHandlerSignal()
+{
+  return Internal::Adaptor::GetImplementation(*this).HttpAuthHandlerSignal();
+}
+
+Dali::WebEnginePlugin::WebEngineContextMenuCustomizedSignalType& WebEngine::ContextMenuCustomizedSignal()
+{
+  return Internal::Adaptor::GetImplementation( *this ).ContextMenuCustomizedSignal();
+}
+
+Dali::WebEnginePlugin::WebEngineContextMenuItemSelectedSignalType& WebEngine::ContextMenuItemSelectedSignal()
+{
+  return Internal::Adaptor::GetImplementation( *this ).ContextMenuItemSelectedSignal();
+}
+
 } // namespace Dali;
 
diff --git a/automated-tests/src/dali-toolkit/utc-Dali-CanvasView.cpp b/automated-tests/src/dali-toolkit/utc-Dali-CanvasView.cpp
new file mode 100644 (file)
index 0000000..1c5128e
--- /dev/null
@@ -0,0 +1,204 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <iostream>
+#include <stdlib.h>
+#include <dali-toolkit-test-suite-utils.h>
+#include <dali-toolkit/dali-toolkit.h>
+#include <test-application.h>
+#include <dali-toolkit/devel-api/controls/canvas-view/canvas-view.h>
+#include <dali/devel-api/adaptor-framework/canvas-renderer-shape.h>
+
+
+using namespace Dali;
+using namespace Toolkit;
+
+namespace
+{
+
+
+} // namespace
+
+void utc_dali_toolkit_canvasview_startup(void)
+{
+  test_return_value = TET_UNDEF;
+}
+
+void utc_dali_toolkit_canvasview_cleanup(void)
+{
+  test_return_value = TET_PASS;
+}
+
+int UtcDaliCanvasViewConstructorP(void)
+{
+  ToolkitTestApplication application;
+  CanvasView canvasView;
+
+  DALI_TEST_CHECK( !canvasView );
+  END_TEST;
+}
+
+int UtcDaliCanvasViewMoveAssignment(void)
+{
+  ToolkitTestApplication application;
+  CanvasView canvasView = CanvasView::New(Vector2(100, 100));
+
+  CanvasView moved = std::move( canvasView );
+  DALI_TEST_CHECK( moved );
+  DALI_TEST_EQUALS( 1, moved.GetBaseObject().ReferenceCount(), TEST_LOCATION );
+  DALI_TEST_CHECK( !canvasView );
+
+  END_TEST;
+}
+
+int UtcDaliCanvasViewAssignmentConstructorP(void)
+{
+  ToolkitTestApplication application;
+  CanvasView canvasView = CanvasView::New(Vector2(100, 100));
+
+  CanvasView copy( canvasView );
+  DALI_TEST_CHECK( copy );
+
+  DALI_TEST_CHECK( canvasView == copy );
+  END_TEST;
+}
+
+int UtcDaliCanvasViewAssignmentOperatorP(void)
+{
+  ToolkitTestApplication application;
+  const CanvasView canvasView = CanvasView::New(Vector2(100, 100));
+
+  CanvasView assign;
+  DALI_TEST_CHECK( !assign );
+
+  assign = canvasView ;
+  DALI_TEST_CHECK( assign == canvasView);
+  END_TEST;
+}
+
+int UtcDaliCanvasViewNewP(void)
+{
+  ToolkitTestApplication application;
+  CanvasView canvasView = CanvasView::New(Vector2(100, 100));
+
+  DALI_TEST_CHECK( canvasView );
+  END_TEST;
+}
+
+int UtcDaliCanvasViewDownCastP(void)
+{
+  ToolkitTestApplication application;
+  CanvasView canvasView = CanvasView::New(Vector2(100,100));
+
+  BaseHandle object(canvasView);
+
+  CanvasView canvasView2 = CanvasView::DownCast( object );
+  DALI_TEST_CHECK(canvasView2);
+
+  CanvasView canvasView3 = DownCast< CanvasView >(object);
+  DALI_TEST_CHECK(canvasView3);
+  END_TEST;
+}
+
+int UtcDaliCanvasViewDownCastN(void)
+{
+  ToolkitTestApplication application;
+  BaseHandle unInitializedObject;
+
+  CanvasView canvasView1 = CanvasView::DownCast( unInitializedObject );
+  DALI_TEST_CHECK( !canvasView1 );
+
+  CanvasView canvasView2 = DownCast< CanvasView >( unInitializedObject );
+  DALI_TEST_CHECK( !canvasView2 );
+  END_TEST;
+}
+
+int UtcDaliCanvasViewAddP(void)
+{
+  ToolkitTestApplication application;
+  CanvasView canvasView = CanvasView::New(Vector2(100,100));
+  DALI_TEST_CHECK( canvasView );
+
+  Dali::CanvasRenderer::Shape shape = Dali::CanvasRenderer::Shape::New();
+
+  shape.AddRect(Rect<float>(10, 10, 10, 10), Vector2(0, 0));
+
+  canvasView.AddDrawable(shape);
+
+  END_TEST;
+}
+
+int UtcDaliCanvasViewAddN(void)
+{
+  ToolkitTestApplication application;
+  CanvasView canvasView = CanvasView::New(Vector2(100,100));
+  DALI_TEST_CHECK( canvasView );
+
+  Dali::CanvasRenderer::Shape shape;
+
+  canvasView.AddDrawable(shape);
+
+  END_TEST;
+}
+
+int UtcDaliCanvasViewChangeSizeP(void)
+{
+  ToolkitTestApplication application;
+
+  CanvasView canvasView = CanvasView::New(Vector2(100,100));
+  DALI_TEST_CHECK( canvasView );
+
+  application.GetScene().Add(canvasView);
+  application.SendNotification();
+  application.Render();
+
+  canvasView.SetProperty(Actor::Property::SIZE, Vector2(300, 300));
+
+  application.SendNotification();
+  application.Render();
+
+  Property::Value pv = canvasView.GetProperty(Actor::Property::SIZE);
+  Vector3 v3;
+  pv.Get(v3);
+  DALI_TEST_EQUALS( v3, Vector3(300, 300, 0), TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliCanvasViewSizeN(void)
+{
+  ToolkitTestApplication application;
+
+  CanvasView canvasView = CanvasView::New(Vector2(100,100));
+  DALI_TEST_CHECK( canvasView );
+
+  application.GetScene().Add(canvasView);
+  application.SendNotification();
+  application.Render();
+
+  canvasView.SetProperty(Actor::Property::SIZE, Vector2(-999, -999));
+
+  application.SendNotification();
+  application.Render();
+
+  Property::Value pv = canvasView.GetProperty(Actor::Property::SIZE);
+  Vector3 v3;
+  pv.Get(v3);
+  DALI_TEST_EQUALS( v3, Vector3(-999, -999, 0), TEST_LOCATION );
+
+  END_TEST;
+}
index b76a850..12d8805 100644 (file)
@@ -130,6 +130,8 @@ const char* HANDLE_RIGHT_SELECTION_FILE_NAME = TEST_RESOURCE_DIR "/selection_han
 
 const std::string DEFAULT_DEVICE_NAME("hwKeyboard");
 
+static bool gAnchorClickedCallBackCalled;
+static bool gAnchorClickedCallBackNotCalled;
 static bool gTextChangedCallBackCalled;
 static bool gInputStyleChangedCallbackCalled;
 static bool gMaxCharactersCallBackCalled;
@@ -149,6 +151,18 @@ struct CallbackFunctor
   bool* mCallbackFlag;
 };
 
+static void TestAnchorClickedCallback(TextEditor control, const char* href, unsigned int hrefLength)
+{
+  tet_infoline(" TestAnchorClickedCallback");
+
+  gAnchorClickedCallBackNotCalled = false;
+
+  if (!strcmp(href, "https://www.tizen.org") && hrefLength == strlen(href))
+  {
+    gAnchorClickedCallBackCalled = true;
+  }
+}
+
 static void TestTextChangedCallback( TextEditor control )
 {
   tet_infoline(" TestTextChangedCallback");
@@ -952,6 +966,52 @@ int utcDaliTextEditorAtlasRenderP(void)
   END_TEST;
 }
 
+// Positive test for the anchorClicked signal.
+int utcDaliTextEditorAnchorClickedP(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" utcDaliTextEditorAnchorClickedP");
+  TextEditor editor = TextEditor::New();
+  DALI_TEST_CHECK(editor);
+
+  application.GetScene().Add(editor);
+
+  // connect to the anchor clicked signal.
+  ConnectionTracker* testTracker = new ConnectionTracker();
+  DevelTextEditor::AnchorClickedSignal(editor).Connect(&TestAnchorClickedCallback);
+  bool anchorClickedSignal = false;
+  editor.ConnectSignal(testTracker, "anchorClicked", CallbackFunctor(&anchorClickedSignal));
+
+  gAnchorClickedCallBackCalled = false;
+  editor.SetProperty(TextEditor::Property::TEXT, "<a href='https://www.tizen.org'>TIZEN</a>");
+  editor.SetProperty(TextEditor::Property::ENABLE_MARKUP, true);
+  editor.SetProperty(Actor::Property::SIZE, Vector2(100.f, 50.f));
+  editor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
+  editor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+
+  application.SendNotification();
+  application.Render();
+  editor.SetKeyInputFocus();
+
+  // Create a tap event to touch the text editor.
+  TestGenerateTap(application, 5.0f, 5.0f);
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_CHECK(gAnchorClickedCallBackCalled);
+  DALI_TEST_CHECK(anchorClickedSignal);
+
+  gAnchorClickedCallBackNotCalled = true;
+  // Tap the outside of anchor, callback should not be called.
+  TestGenerateTap(application, 150.f, 100.f);
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_CHECK(gAnchorClickedCallBackNotCalled);
+
+  END_TEST;
+}
+
 // Positive test for the textChanged signal.
 int utcDaliTextEditorTextChangedP(void)
 {
@@ -970,36 +1030,27 @@ int utcDaliTextEditorTextChangedP(void)
 
   gTextChangedCallBackCalled = false;
   editor.SetProperty( TextEditor::Property::TEXT, "ABC" );
-  application.SendNotification();
-  application.Render();
   DALI_TEST_CHECK( gTextChangedCallBackCalled );
   DALI_TEST_CHECK( textChangedSignal );
 
+  application.SendNotification();
   editor.SetKeyInputFocus();
 
   gTextChangedCallBackCalled = false;
   application.ProcessEvent( GenerateKey( "D", "", "D", KEY_D_CODE, 0, 0, Integration::KeyEvent::DOWN, "D", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE ) );
-  application.SendNotification();
-  application.Render();
   DALI_TEST_CHECK( gTextChangedCallBackCalled );
 
   // Remove all text
   editor.SetProperty( TextField::Property::TEXT, "" );
-  application.SendNotification();
-  application.Render();
 
   // Pressing backspace key: TextChangedCallback should not be called when there is no text in texteditor.
   gTextChangedCallBackCalled = false;
   application.ProcessEvent( GenerateKey( "", "", "", DALI_KEY_BACKSPACE, 0, 0, Integration::KeyEvent::DOWN, "", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE ) );
-  application.SendNotification();
-  application.Render();
   DALI_TEST_CHECK( !gTextChangedCallBackCalled );
 
   // Pressing delete key: TextChangedCallback should not be called when there is no text in texteditor.
   gTextChangedCallBackCalled = false;
   application.ProcessEvent( GenerateKey( "", "", "", Dali::DevelKey::DALI_KEY_DELETE, 0, 0, Integration::KeyEvent::DOWN, "Delete", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE ) );
-  application.SendNotification();
-  application.Render();
   DALI_TEST_CHECK( !gTextChangedCallBackCalled );
 
   END_TEST;
@@ -3302,3 +3353,36 @@ int UtcDaliTextEditorPrimaryCursorPosition(void)
 
   END_TEST;
 }
+
+int UtcDaliTextEditorLineCountAfterGetNaturalSize(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliTextEditorLineCountAfterGetNaturalSize ");
+
+  TextEditor textEditor = TextEditor::New();
+  textEditor.SetProperty(TextEditor::Property::TEXT, "A\nB\nC\nD\nE\nF\n");
+  textEditor.SetProperty( Actor::Property::SIZE, Vector2( 300.f, 50.f ) );
+  textEditor.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT );
+  textEditor.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT );
+  application.GetScene().Add( textEditor );
+
+  application.SendNotification();
+  application.Render();
+
+  int lineCount = 0;
+  lineCount =  textEditor.GetProperty<int>( TextEditor::Property::LINE_COUNT );
+  DALI_TEST_EQUALS( lineCount, 7, TEST_LOCATION );
+
+  textEditor.GetNaturalSize();
+
+  // Create a tap event to touch the text editor.
+  TestGenerateTap( application, 18.0f, 25.0f );
+
+  application.SendNotification();
+  application.Render();
+
+  lineCount =  textEditor.GetProperty<int>( TextEditor::Property::LINE_COUNT );
+  DALI_TEST_EQUALS( lineCount, 7, TEST_LOCATION );
+
+  END_TEST;
+}
index 4808f00..aa25cf2 100644 (file)
@@ -121,6 +121,8 @@ const int KEY_D_CODE = 40;
 
 const std::string DEFAULT_DEVICE_NAME("hwKeyboard");
 
+static bool gAnchorClickedCallBackCalled;
+static bool gAnchorClickedCallBackNotCalled;
 static bool gTextChangedCallBackCalled;
 static bool gMaxCharactersCallBackCalled;
 static bool gInputStyleChangedCallbackCalled;
@@ -206,6 +208,18 @@ struct CallbackFunctor
   bool* mCallbackFlag;
 };
 
+static void TestAnchorClickedCallback(TextField control, const char* href, unsigned int hrefLength)
+{
+  tet_infoline(" TestAnchorClickedCallback");
+
+  gAnchorClickedCallBackNotCalled = false;
+
+  if (!strcmp(href, "https://www.tizen.org") && hrefLength == strlen(href))
+  {
+    gAnchorClickedCallBackCalled = true;
+  }
+}
+
 static void TestTextChangedCallback( TextField control )
 {
   tet_infoline(" TestTextChangedCallback");
@@ -1022,6 +1036,303 @@ int utcDaliTextFieldAtlasRenderP(void)
   END_TEST;
 }
 
+// Positive test for the anchorClicked signal.
+int utcDaliTextFieldAnchorClicked01(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" utcDaliTextFieldAnchorClicked01");
+  TextField field = TextField::New();
+  DALI_TEST_CHECK(field);
+
+  application.GetScene().Add(field);
+
+  // connect to the anchor clicked signal.
+  ConnectionTracker* testTracker = new ConnectionTracker();
+  DevelTextField::AnchorClickedSignal(field).Connect(&TestAnchorClickedCallback);
+  bool anchorClickedSignal = false;
+  field.ConnectSignal(testTracker, "anchorClicked", CallbackFunctor(&anchorClickedSignal));
+
+  gAnchorClickedCallBackCalled = false;
+  field.SetProperty(TextField::Property::TEXT, "<a href='https://www.tizen.org'>TIZEN</a>");
+  field.SetProperty(TextField::Property::ENABLE_MARKUP, true);
+  field.SetProperty(Actor::Property::SIZE, Vector2(100.f, 50.f));
+  field.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
+  field.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+
+  application.SendNotification();
+  application.Render();
+  field.SetKeyInputFocus();
+
+  // Create a tap event to touch the text field.
+  TestGenerateTap(application, 5.0f, 25.0f);
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_CHECK(gAnchorClickedCallBackCalled);
+  DALI_TEST_CHECK(anchorClickedSignal);
+
+  gAnchorClickedCallBackNotCalled = true;
+  // Tap the outside of anchor, callback should not be called.
+  TestGenerateTap(application, 150.f, 100.f);
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_CHECK(gAnchorClickedCallBackNotCalled);
+
+  END_TEST;
+}
+
+// Positive test for the anchorClicked signal.
+int utcDaliTextFieldAnchorClicked02(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" utcDaliTextFieldAnchorClicked02");
+  TextField field = TextField::New();
+  DALI_TEST_CHECK(field);
+
+  application.GetScene().Add(field);
+
+  // connect to the anchor clicked signal.
+  ConnectionTracker* testTracker = new ConnectionTracker();
+  DevelTextField::AnchorClickedSignal(field).Connect(&TestAnchorClickedCallback);
+  bool anchorClickedSignal = false;
+  field.ConnectSignal(testTracker, "anchorClicked", CallbackFunctor(&anchorClickedSignal));
+
+  gAnchorClickedCallBackCalled = false;
+  field.SetProperty(TextField::Property::TEXT, "<a href='https://www.tizen.org'>TIZEN</a>");
+  field.SetProperty(TextField::Property::ENABLE_MARKUP, true);
+  field.SetProperty(Actor::Property::SIZE, Vector2(100.f, 50.f));
+  field.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
+  field.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+
+  application.SendNotification();
+  application.Render();
+  field.SetKeyInputFocus();
+
+  // Avoid a crash when core load gl resources.
+  application.GetGlAbstraction().SetCheckFramebufferStatusResult(GL_FRAMEBUFFER_COMPLETE);
+
+  // Create a tap event to touch the text field.
+  TestGenerateTap(application, 30.0f, 25.0f);
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_CHECK(gAnchorClickedCallBackCalled);
+  DALI_TEST_CHECK(anchorClickedSignal);
+
+
+  // For coverage InsertTextAnchor, RemoveTextAnchor
+  // first index insert
+  field.SetProperty(TextField::Property::TEXT, "<a href='https://www.tizen.org'>TIZEN</a>");
+  field.SetProperty(DevelTextField::Property::PRIMARY_CURSOR_POSITION, 0);
+  application.SendNotification();
+  application.Render();
+
+  application.ProcessEvent( GenerateKey( "D", "", "D", KEY_D_CODE, 0, 0, Integration::KeyEvent::DOWN, "D", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE ) );
+  application.SendNotification();
+  application.Render();
+
+  gAnchorClickedCallBackCalled = false;
+  // Create a tap event to touch the text field.
+  TestGenerateTap(application, 30.0f, 25.0f);
+  application.SendNotification();
+  field.SetKeyInputFocus();
+
+  DALI_TEST_CHECK(gAnchorClickedCallBackCalled);
+
+  // last index insert
+  field.SetProperty(TextField::Property::TEXT, "<a href='https://www.tizen.org'>TIZEN</a>");
+  field.SetProperty(DevelTextField::Property::PRIMARY_CURSOR_POSITION, 5);
+  application.SendNotification();
+  application.Render();
+
+  application.ProcessEvent( GenerateKey( "D", "", "D", KEY_D_CODE, 0, 0, Integration::KeyEvent::DOWN, "D", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE ) );
+  application.SendNotification();
+  application.Render();
+
+  gAnchorClickedCallBackCalled = false;
+  // Create a tap event to touch the text field.
+  TestGenerateTap(application, 30.0f, 25.0f);
+  application.SendNotification();
+  field.SetKeyInputFocus();
+
+  DALI_TEST_CHECK(gAnchorClickedCallBackCalled);
+
+  // mid index insert
+  field.SetProperty(TextField::Property::TEXT, "<a href='https://www.tizen.org'>TIZEN</a>");
+  field.SetProperty(DevelTextField::Property::PRIMARY_CURSOR_POSITION, 2);
+  application.SendNotification();
+  application.Render();
+
+  application.ProcessEvent( GenerateKey( "D", "", "D", KEY_D_CODE, 0, 0, Integration::KeyEvent::DOWN, "D", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE ) );
+  application.SendNotification();
+  application.Render();
+
+  gAnchorClickedCallBackCalled = false;
+  // Create a tap event to touch the text field.
+  TestGenerateTap(application, 30.0f, 25.0f);
+  application.SendNotification();
+  field.SetKeyInputFocus();
+
+  DALI_TEST_CHECK(gAnchorClickedCallBackCalled);
+
+  // first index remove
+  field.SetProperty(TextField::Property::TEXT, "<a href='https://www.tizen.org'>TIZEN</a>");
+  field.SetProperty(DevelTextField::Property::PRIMARY_CURSOR_POSITION, 0);
+  application.SendNotification();
+  application.Render();
+
+  application.ProcessEvent(GenerateKey("", "", "", DALI_KEY_BACKSPACE, 0, 0, Integration::KeyEvent::DOWN, "", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE));
+  application.ProcessEvent(GenerateKey("Delete", "", "Delete", Dali::DevelKey::DALI_KEY_DELETE, 0, 0, Integration::KeyEvent::DOWN, "Delete", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE));
+  application.SendNotification();
+  application.Render();
+
+  gAnchorClickedCallBackCalled = false;
+  // Create a tap event to touch the text field.
+  TestGenerateTap(application, 30.0f, 25.0f);
+  application.SendNotification();
+  field.SetKeyInputFocus();
+
+  DALI_TEST_CHECK(gAnchorClickedCallBackCalled);
+
+  // last index remove
+  field.SetProperty(TextField::Property::TEXT, "<a href='https://www.tizen.org'>TIZEN</a>");
+  field.SetProperty(DevelTextField::Property::PRIMARY_CURSOR_POSITION, 5);
+  application.SendNotification();
+  application.Render();
+
+  application.ProcessEvent(GenerateKey("", "", "", DALI_KEY_BACKSPACE, 0, 0, Integration::KeyEvent::DOWN, "", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE));
+  application.ProcessEvent(GenerateKey("Delete", "", "Delete", Dali::DevelKey::DALI_KEY_DELETE, 0, 0, Integration::KeyEvent::DOWN, "Delete", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE));
+  application.SendNotification();
+  application.Render();
+
+  gAnchorClickedCallBackCalled = false;
+  // Create a tap event to touch the text field.
+  TestGenerateTap(application, 30.0f, 25.0f);
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_CHECK(gAnchorClickedCallBackCalled);
+
+  // middle index
+  field.SetProperty(TextField::Property::TEXT, "<a href='https://www.tizen.org'>TIZEN</a>");
+  field.SetProperty(DevelTextField::Property::PRIMARY_CURSOR_POSITION, 2);
+  application.SendNotification();
+  application.Render();
+
+  application.ProcessEvent(GenerateKey("", "", "", DALI_KEY_BACKSPACE, 0, 0, Integration::KeyEvent::DOWN, "", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE));
+  application.ProcessEvent(GenerateKey("Delete", "", "Delete", Dali::DevelKey::DALI_KEY_DELETE, 0, 0, Integration::KeyEvent::DOWN, "Delete", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE));
+  application.SendNotification();
+  application.Render();
+
+  gAnchorClickedCallBackCalled = false;
+  // Create a tap event to touch the text field.
+  TestGenerateTap(application, 30.0f, 25.0f);
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_CHECK(gAnchorClickedCallBackCalled);
+
+  // 0 ~ 1 index remove
+  field.SetProperty(TextField::Property::TEXT, "<a href='https://www.tizen.org'>TIZEN</a>");
+  field.SetProperty( DevelTextField::Property::SELECTED_TEXT_START, 0);
+  field.SetProperty( DevelTextField::Property::SELECTED_TEXT_END, 1);
+  application.SendNotification();
+  application.Render();
+
+  application.ProcessEvent(GenerateKey("", "", "", DALI_KEY_BACKSPACE, 0, 0, Integration::KeyEvent::DOWN, "", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE));
+  application.SendNotification();
+  application.Render();
+
+  gAnchorClickedCallBackCalled = false;
+  // Create a tap event to touch the text field.
+  TestGenerateTap(application, 30.0f, 25.0f);
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_CHECK(gAnchorClickedCallBackCalled);
+
+  // 1 ~ 3 index remove
+  field.SetProperty(TextField::Property::TEXT, "<a href='https://www.tizen.org'>TIZEN</a>");
+  field.SetProperty( DevelTextField::Property::SELECTED_TEXT_START, 1);
+  field.SetProperty( DevelTextField::Property::SELECTED_TEXT_END, 3);
+  application.SendNotification();
+  application.Render();
+
+  application.ProcessEvent(GenerateKey("", "", "", DALI_KEY_BACKSPACE, 0, 0, Integration::KeyEvent::DOWN, "", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE));
+  application.SendNotification();
+  application.Render();
+
+  gAnchorClickedCallBackCalled = false;
+  // Create a tap event to touch the text field.
+  TestGenerateTap(application, 30.0f, 25.0f);
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_CHECK(gAnchorClickedCallBackCalled);
+
+  // 3 ~ 4 index remove
+  field.SetProperty(TextField::Property::TEXT, "<a href='https://www.tizen.org'>TIZEN</a>");
+  field.SetProperty( DevelTextField::Property::SELECTED_TEXT_START, 3);
+  field.SetProperty( DevelTextField::Property::SELECTED_TEXT_END, 4);
+  application.SendNotification();
+  application.Render();
+
+  application.ProcessEvent(GenerateKey("", "", "", DALI_KEY_BACKSPACE, 0, 0, Integration::KeyEvent::DOWN, "", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE));
+  application.SendNotification();
+  application.Render();
+
+  gAnchorClickedCallBackCalled = false;
+  // Create a tap event to touch the text field.
+  TestGenerateTap(application, 30.0f, 25.0f);
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_CHECK(gAnchorClickedCallBackCalled);
+
+  // Remove front of anchor
+  field.SetProperty(TextField::Property::TEXT, "TIZEN<a href='https://www.tizen.org'>TIZEN</a>");
+  field.SetProperty(DevelTextField::Property::PRIMARY_CURSOR_POSITION, 3);
+  application.SendNotification();
+  application.Render();
+
+  application.ProcessEvent(GenerateKey("", "", "", DALI_KEY_BACKSPACE, 0, 0, Integration::KeyEvent::DOWN, "", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE));
+  application.SendNotification();
+  application.Render();
+
+  // Remove whole text
+  field.SetProperty(TextField::Property::TEXT, "<a href='https://www.tizen.org'>TIZEN</a>");
+  DevelTextField::SelectWholeText(field);
+  application.SendNotification();
+  application.Render();
+
+  application.ProcessEvent(GenerateKey("", "", "", DALI_KEY_BACKSPACE, 0, 0, Integration::KeyEvent::DOWN, "", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE));
+  application.SendNotification();
+  application.Render();
+
+  // Remove all with backspace
+  field.SetProperty(TextField::Property::TEXT, "<a href='https://www.tizen.org'>T</a>");
+  field.SetProperty(DevelTextField::Property::PRIMARY_CURSOR_POSITION, 1);
+  application.SendNotification();
+  application.Render();
+
+  application.ProcessEvent(GenerateKey("", "", "", DALI_KEY_BACKSPACE, 0, 0, Integration::KeyEvent::DOWN, "", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE));
+  application.SendNotification();
+  application.Render();
+
+  // Remove all with delete
+  field.SetProperty(TextField::Property::TEXT, "<a href='https://www.tizen.org'>T</a>");
+  field.SetProperty(DevelTextField::Property::PRIMARY_CURSOR_POSITION, 0);
+  application.SendNotification();
+  application.Render();
+
+  application.ProcessEvent(GenerateKey("Delete", "", "Delete", Dali::DevelKey::DALI_KEY_DELETE, 0, 0, Integration::KeyEvent::DOWN, "Delete", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE));
+  application.SendNotification();
+  application.Render();
+
+  END_TEST;
+}
+
 // Positive test for the textChanged signal.
 int utcDaliTextFieldTextChangedP(void)
 {
@@ -1040,36 +1351,27 @@ int utcDaliTextFieldTextChangedP(void)
 
   gTextChangedCallBackCalled = false;
   field.SetProperty( TextField::Property::TEXT, "ABC" );
-  application.SendNotification();
-  application.Render();
   DALI_TEST_CHECK( gTextChangedCallBackCalled );
   DALI_TEST_CHECK( textChangedSignal );
 
+  application.SendNotification();
   field.SetKeyInputFocus();
 
   gTextChangedCallBackCalled = false;
   application.ProcessEvent( GenerateKey( "D", "", "D", KEY_D_CODE, 0, 0, Integration::KeyEvent::DOWN, "D", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE ) );
-  application.SendNotification();
-  application.Render();
   DALI_TEST_CHECK( gTextChangedCallBackCalled );
 
   // Remove all text
   field.SetProperty( TextField::Property::TEXT, "" );
-  application.SendNotification();
-  application.Render();
 
   // Pressing backspace key: TextChangedCallback should not be called when there is no text in textfield.
   gTextChangedCallBackCalled = false;
   application.ProcessEvent( GenerateKey( "", "", "", DALI_KEY_BACKSPACE, 0, 0, Integration::KeyEvent::DOWN, "", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE ) );
-  application.SendNotification();
-  application.Render();
   DALI_TEST_CHECK( !gTextChangedCallBackCalled );
 
   // Pressing delete key: TextChangedCallback should not be called when there is no text in textfield.
   gTextChangedCallBackCalled = false;
   application.ProcessEvent( GenerateKey( "", "", "", Dali::DevelKey::DALI_KEY_DELETE, 0, 0, Integration::KeyEvent::DOWN, "Delete", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE ) );
-  application.SendNotification();
-  application.Render();
   DALI_TEST_CHECK( !gTextChangedCallBackCalled );
 
   END_TEST;
index 57862f4..ecefef7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -77,6 +77,35 @@ const char* const PROPERTY_NAME_FONT_SIZE_SCALE = "fontSizeScale";
 const std::string DEFAULT_FONT_DIR( "/resources/fonts" );
 const unsigned int EMOJI_FONT_SIZE = 3840u; // 60 * 64
 
+static bool gAnchorClickedCallBackCalled;
+static bool gAnchorClickedCallBackNotCalled;
+
+struct CallbackFunctor
+{
+  CallbackFunctor(bool* callbackFlag)
+  : mCallbackFlag( callbackFlag )
+  {
+  }
+
+  void operator()()
+  {
+    *mCallbackFlag = true;
+  }
+  bool* mCallbackFlag;
+};
+
+static void TestAnchorClickedCallback(TextLabel control, const char* href, unsigned int hrefLength)
+{
+  tet_infoline(" TestAnchorClickedCallback");
+
+  gAnchorClickedCallBackNotCalled = false;
+
+  if (!strcmp(href, "https://www.tizen.org") && hrefLength == strlen(href))
+  {
+    gAnchorClickedCallBackCalled = true;
+  }
+}
+
 bool DaliTestCheckMaps( const Property::Map& mapGet, const Property::Map& mapSet, const std::vector<std::string>& indexConversionTable = std::vector<std::string>() )
 {
   const Property::Map::SizeType size = mapGet.Count();
@@ -1727,3 +1756,49 @@ int UtcDaliToolkitTextlabelFontSizeScale(void)
 
   END_TEST;
 }
+
+// Positive test for the anchorClicked signal.
+int UtcDaliToolkitTextlabelAnchorClicked(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliToolkitTextlabelAnchorClicked");
+  TextLabel label = TextLabel::New();
+  DALI_TEST_CHECK(label);
+
+  application.GetScene().Add(label);
+
+  // connect to the anchor clicked signal.
+  ConnectionTracker* testTracker = new ConnectionTracker();
+  DevelTextLabel::AnchorClickedSignal(label).Connect(&TestAnchorClickedCallback);
+  bool anchorClickedSignal = false;
+  label.ConnectSignal(testTracker, "anchorClicked", CallbackFunctor(&anchorClickedSignal));
+
+  gAnchorClickedCallBackCalled = false;
+  label.SetProperty(TextLabel::Property::TEXT, "<a href='https://www.tizen.org'>TIZEN</a>");
+  label.SetProperty(TextLabel::Property::ENABLE_MARKUP, true);
+  label.SetProperty(Actor::Property::SIZE, Vector2(100.f, 50.f));
+  label.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
+  label.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+
+  application.SendNotification();
+  application.Render();
+
+  // Create a tap event to touch the text label.
+  TestGenerateTap(application, 5.0f, 25.0f);
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_CHECK(gAnchorClickedCallBackCalled);
+  DALI_TEST_CHECK(anchorClickedSignal);
+
+
+  gAnchorClickedCallBackNotCalled = true;
+  // Tap the outside of anchor, callback should not be called.
+  TestGenerateTap(application, 150.f, 100.f);
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_CHECK(gAnchorClickedCallBackNotCalled);
+
+  END_TEST;
+}
index 04bbf79..11b9f46 100644 (file)
@@ -260,15 +260,18 @@ int UtcDaliToolkitTextSelectionPopupSizeProperties(void)
   const Vector2 optionMaxSize(50.0f, 100.0f);
   const Vector2 optionMinSize(10.0f, 10.0f);
   const Vector2 optionDividerSize(5.0f, 5.0f);
+  const Vector4 optionDividerPadding(20.0f, 20.0f, 10.0f, 10.0f);
   popup.SetProperty(TextSelectionPopup::Property::POPUP_MAX_SIZE, popupMaxSize);
   popup.SetProperty(TextSelectionPopup::Property::OPTION_MAX_SIZE, optionMaxSize);
   popup.SetProperty(TextSelectionPopup::Property::OPTION_MIN_SIZE, optionMinSize);
   popup.SetProperty(TextSelectionPopup::Property::OPTION_DIVIDER_SIZE, optionDividerSize);
+  popup.SetProperty(TextSelectionPopup::Property::OPTION_DIVIDER_PADDING, optionDividerPadding);
 
   DALI_TEST_EQUALS( popup.GetProperty(TextSelectionPopup::Property::POPUP_MAX_SIZE).Get<Vector2>(), popupMaxSize, TEST_LOCATION);
   DALI_TEST_EQUALS( popup.GetProperty(TextSelectionPopup::Property::OPTION_MAX_SIZE).Get<Vector2>(), optionMaxSize, TEST_LOCATION);
   DALI_TEST_EQUALS( popup.GetProperty(TextSelectionPopup::Property::OPTION_MIN_SIZE).Get<Vector2>(), optionMinSize, TEST_LOCATION);
   DALI_TEST_EQUALS( popup.GetProperty(TextSelectionPopup::Property::OPTION_DIVIDER_SIZE).Get<Vector2>(), optionDividerSize, TEST_LOCATION);
+  DALI_TEST_EQUALS( popup.GetProperty(TextSelectionPopup::Property::OPTION_DIVIDER_PADDING).Get<Vector4>(), optionDividerPadding, TEST_LOCATION);
 
   END_TEST;
 }
index 7668926..bc0c261 100755 (executable)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 #include "dali-toolkit-test-utils/toolkit-timer.h"
 
 #include <dali.h>
+#include <dali/devel-api/adaptor-framework/web-engine-certificate.h>
+#include <dali/devel-api/adaptor-framework/web-engine-console-message.h>
+#include <dali/devel-api/adaptor-framework/web-engine-context-menu.h>
+#include <dali/devel-api/adaptor-framework/web-engine-context-menu-item.h>
+#include <dali/devel-api/adaptor-framework/web-engine-frame.h>
+#include <dali/devel-api/adaptor-framework/web-engine-http-auth-handler.h>
+#include <dali/devel-api/adaptor-framework/web-engine-load-error.h>
+#include <dali/devel-api/adaptor-framework/web-engine-policy-decision.h>
+#include <dali/devel-api/adaptor-framework/web-engine-request-interceptor.h>
+#include <dali/devel-api/adaptor-framework/web-engine-context.h>
+#include <dali/devel-api/adaptor-framework/web-engine-security-origin.h>
 #include <dali/integration-api/events/hover-event-integ.h>
 #include <dali/integration-api/events/key-event-integ.h>
 #include <dali/integration-api/events/touch-event-integ.h>
@@ -33,6 +44,7 @@
 #include <dali-toolkit/devel-api/controls/web-view/web-back-forward-list-item.h>
 #include <dali-toolkit/devel-api/controls/web-view/web-context.h>
 #include <dali-toolkit/devel-api/controls/web-view/web-cookie-manager.h>
+#include <dali-toolkit/devel-api/controls/web-view/web-form-repost-decision.h>
 #include <dali-toolkit/devel-api/controls/web-view/web-settings.h>
 #include <dali-toolkit/devel-api/controls/web-view/web-view.h>
 
@@ -48,15 +60,46 @@ const char* const TEST_URL2( "http://www.somewhere.valid2.com" );
 static int gPageLoadStartedCallbackCalled = 0;
 static int gPageLoadInProgressCallbackCalled = 0;
 static int gPageLoadFinishedCallbackCalled = 0;
+static int gPageLoadErrorCallbackCalled = 0;
+static std::shared_ptr<Dali::WebEngineLoadError> gPageLoadErrorInstance = nullptr;
 static int gScrollEdgeReachedCallbackCalled = 0;
 static int gUrlChangedCallbackCalled = 0;
 static int gEvaluateJavaScriptCallbackCalled = 0;
 static int gJavaScriptAlertCallbackCalled = 0;
 static int gJavaScriptConfirmCallbackCalled = 0;
 static int gJavaScriptPromptCallbackCalled = 0;
+static int gScreenshotCapturedCallbackCalled = 0;
+static int gVideoPlayingCallbackCalled = 0;
+static int gGeolocationPermissionCallbackCalled = 0;
 static bool gTouched = false;
 static bool gHovered = false;
 static bool gWheelEventHandled = false;
+static int gFormRepostDecisionCallbackCalled = 0;
+static std::shared_ptr<Dali::Toolkit::WebFormRepostDecision> gFormRepostDecisionInstance = nullptr;
+static int gFrameRenderedCallbackCalled = 0;
+static int gRequestInterceptorCallbackCalled = 0;
+static std::shared_ptr<Dali::WebEngineRequestInterceptor> gRequestInterceptorInstance = nullptr;
+static int gConsoleMessageCallbackCalled = 0;
+static std::shared_ptr<Dali::WebEngineConsoleMessage> gConsoleMessageInstance = nullptr;
+static int gPolicyDecisionCallbackCalled = 0;
+static std::shared_ptr<Dali::WebEnginePolicyDecision> gPolicyDecisionInstance = nullptr;
+static int gCertificateConfirmCallbackCalled = 0;
+static std::shared_ptr<Dali::WebEngineCertificate> gCertificateConfirmInstance = nullptr;
+static int gSslCertificateChangedCallbackCalled = 0;
+static std::shared_ptr<Dali::WebEngineCertificate> gSslCertificateInstance = nullptr;
+static int gHttpAuthHandlerCallbackCalled = 0;
+static std::shared_ptr<Dali::WebEngineHttpAuthHandler> gHttpAuthInstance = nullptr;
+static int gSecurityOriginsAcquiredCallbackCalled = 0;
+static int gStorageUsageAcquiredCallbackCalled = 0;
+static int gFormPasswordsAcquiredCallbackCalled = 0;
+static int gDownloadStartedCallbackCalled = 0;
+static int gMimeOverriddenCallbackCalled = 0;
+static std::vector<std::unique_ptr<Dali::WebEngineSecurityOrigin>> gSecurityOriginList;
+static std::vector<std::unique_ptr<Dali::WebEngineContext::PasswordData>> gPasswordDataList;
+static int gContextMenuCustomizedCallbackCalled = 0;
+static std::shared_ptr<Dali::WebEngineContextMenu> gContextMenuInstance = 0;
+static int gContextMenuItemSelectedCallbackCalled = 0;
+static std::shared_ptr<Dali::WebEngineContextMenuItem> gContextMenuItemInstance = 0;
 
 struct CallbackFunctor
 {
@@ -92,13 +135,21 @@ static void OnScrollEdgeReached( WebView view, Dali::WebEnginePlugin::ScrollEdge
   gScrollEdgeReachedCallbackCalled++;
 }
 
+static void OnPolicyDecisionRequest(WebView view, std::shared_ptr<Dali::WebEnginePolicyDecision> decision)
+{
+  gPolicyDecisionCallbackCalled++;
+  gPolicyDecisionInstance = std::move(decision);
+}
+
 static void OnUrlChanged( WebView view, const std::string& url )
 {
   gUrlChangedCallbackCalled++;
 }
 
-static void OnPageLoadError( WebView view, const std::string& url, WebView::LoadErrorCode errorCode )
+static void OnPageLoadError(WebView view, std::shared_ptr<Dali::WebEngineLoadError> error)
 {
+  gPageLoadErrorCallbackCalled++;
+  gPageLoadErrorInstance = std::move(error);
 }
 
 static void OnEvaluateJavaScript( const std::string& result )
@@ -124,6 +175,22 @@ static bool OnJavaScriptPrompt( const std::string& meesage1, const std::string&
   return true;
 }
 
+static void OnScreenshotCaptured(Dali::Toolkit::ImageView)
+{
+  gScreenshotCapturedCallbackCalled++;
+}
+
+static void OnVideoPlaying(bool isPlaying)
+{
+  gVideoPlayingCallbackCalled++;
+}
+
+static bool OnGeolocationPermission(const std::string&, const std::string&)
+{
+  gGeolocationPermissionCallbackCalled++;
+  return true;
+}
+
 static bool OnTouched( Actor actor, const Dali::TouchEvent& touch )
 {
   gTouched = true;
@@ -142,6 +209,89 @@ static bool OnWheelEvent( Actor actor, const Dali::WheelEvent& wheel )
   return true;
 }
 
+static void OnFormRepostDecision(WebView, std::shared_ptr<Dali::Toolkit::WebFormRepostDecision> decision)
+{
+  gFormRepostDecisionCallbackCalled++;
+  gFormRepostDecisionInstance = std::move(decision);
+}
+
+static void OnFrameRendered(WebView)
+{
+  gFrameRenderedCallbackCalled++;
+}
+
+static void OnRequestInterceptor(WebView view, std::shared_ptr<Dali::WebEngineRequestInterceptor> interceptor)
+{
+  gRequestInterceptorCallbackCalled++;
+  gRequestInterceptorInstance = std::move(interceptor);
+}
+
+static void OnConsoleMessage(WebView view, std::shared_ptr<Dali::WebEngineConsoleMessage> message)
+{
+  gConsoleMessageCallbackCalled++;
+  gConsoleMessageInstance = std::move(message);
+}
+
+static void OnCertificateConfirm(WebView view, std::shared_ptr<Dali::WebEngineCertificate> certificate )
+{
+  gCertificateConfirmCallbackCalled++;
+  gCertificateConfirmInstance = std::move(certificate);
+}
+
+static void OnSslCertificateChanged(WebView view, std::shared_ptr<Dali::WebEngineCertificate> certificate )
+{
+  gSslCertificateChangedCallbackCalled++;
+  gSslCertificateInstance = std::move(certificate);
+}
+
+static void OnHttpAuthHandler( WebView view, std::shared_ptr<Dali::WebEngineHttpAuthHandler> hander )
+{
+  gHttpAuthHandlerCallbackCalled++;
+  gHttpAuthInstance = std::move(hander);
+}
+
+static void OnSecurityOriginsAcquired(std::vector<std::unique_ptr<Dali::WebEngineSecurityOrigin>>& origins)
+{
+  gSecurityOriginsAcquiredCallbackCalled++;
+  gSecurityOriginList.clear();
+  gSecurityOriginList.swap(origins);
+}
+
+static void OnStorageUsageAcquired(uint64_t usage)
+{
+  gStorageUsageAcquiredCallbackCalled++;
+}
+
+static void OnFormPasswordsAcquired(std::vector<std::unique_ptr<Dali::WebEngineContext::PasswordData>>& passwords)
+{
+  gFormPasswordsAcquiredCallbackCalled++;
+  gPasswordDataList.clear();
+  gPasswordDataList.swap(passwords);
+}
+
+static void OnDownloadStarted(const std::string& url)
+{
+  gDownloadStartedCallbackCalled++;
+}
+
+static bool OnMimeOverridden(const std::string&, const std::string&, std::string&)
+{
+  gMimeOverriddenCallbackCalled++;
+  return false;
+}
+
+static void OnContextMenuCustomized(WebView view, std::shared_ptr<Dali::WebEngineContextMenu> menu)
+{
+  gContextMenuCustomizedCallbackCalled++;
+  gContextMenuInstance = std::move(menu);
+}
+
+static void OnContextMenuItemSelected(WebView view, std::shared_ptr<Dali::WebEngineContextMenuItem> item)
+{
+  gContextMenuItemSelectedCallbackCalled++;
+  gContextMenuItemInstance = std::move(item);
+}
+
 } // namespace
 
 void web_view_startup(void)
@@ -172,7 +322,6 @@ int UtcDaliWebViewBasics(void)
   assign = copy;
   DALI_TEST_CHECK( assign == view );
 
-
   // DownCast Test
   tet_infoline( "UtcDaliWebViewBasic DownCast Test" );
   BaseHandle handle(view);
@@ -182,7 +331,6 @@ int UtcDaliWebViewBasics(void)
   DALI_TEST_CHECK( view2 );
   DALI_TEST_CHECK( view == view2 );
 
-
   // TypeRegistry Test
   tet_infoline( "UtcDaliWebViewBasic TypeRegistry Test" );
   TypeRegistry typeRegistry = TypeRegistry::Get();
@@ -218,7 +366,6 @@ int UtcDaliWebViewPageNavigation(void)
   view.PageLoadStartedSignal().Connect( &OnPageLoadStarted );
   view.PageLoadInProgressSignal().Connect( &OnPageLoadInProgress );
   view.PageLoadFinishedSignal().Connect( &OnPageLoadFinished );
-  view.PageLoadErrorSignal().Connect( &OnPageLoadError );
   view.UrlChangedSignal().Connect( &OnUrlChanged );
   bool signal1 = false;
   bool signal2 = false;
@@ -280,6 +427,60 @@ int UtcDaliWebViewPageNavigation(void)
   END_TEST;
 }
 
+int UtcDaliWebViewPageLoadErrorConsoleMessage(void)
+{
+  ToolkitTestApplication application;
+
+  WebView view = WebView::New();
+  view.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT );
+  view.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT );
+  view.SetProperty( Actor::Property::POSITION, Vector2( 0, 0 ));
+  view.SetProperty( Actor::Property::SIZE, Vector2( 800, 600 ) );
+  application.GetScene().Add( view );
+  application.SendNotification();
+  application.Render();
+  DALI_TEST_CHECK( view );
+
+  ConnectionTracker* testTracker = new ConnectionTracker();
+  view.PageLoadErrorSignal().Connect( &OnPageLoadError );
+  view.ConsoleMessageSignal().Connect( &OnConsoleMessage );
+  bool signal1 = false;
+  bool signal2 = false;
+  view.ConnectSignal( testTracker, "pageLoadError", CallbackFunctor(&signal1) );
+  view.ConnectSignal( testTracker, "consoleMessage", CallbackFunctor(&signal2) );
+  DALI_TEST_EQUALS( gPageLoadErrorCallbackCalled, 0, TEST_LOCATION );
+  DALI_TEST_EQUALS( gConsoleMessageCallbackCalled, 0, TEST_LOCATION );
+
+  view.LoadUrl( TEST_URL1 );
+  Test::EmitGlobalTimerSignal();
+  DALI_TEST_EQUALS( gPageLoadErrorCallbackCalled, 1, TEST_LOCATION );
+  DALI_TEST_EQUALS( gConsoleMessageCallbackCalled, 1, TEST_LOCATION );
+  DALI_TEST_CHECK( signal1 & signal2);
+
+  // error code.
+  DALI_TEST_CHECK(gPageLoadErrorInstance);
+  DALI_TEST_EQUALS(gPageLoadErrorInstance->GetUrl(), TEST_URL1, TEST_LOCATION);
+  DALI_TEST_EQUALS(gPageLoadErrorInstance->GetCode(), Dali::WebEngineLoadError::ErrorCode::UNKNOWN, TEST_LOCATION);
+  std::string testErrorDescription("This is an error.");
+  DALI_TEST_EQUALS(gPageLoadErrorInstance->GetDescription(), testErrorDescription, TEST_LOCATION);
+  DALI_TEST_EQUALS(gPageLoadErrorInstance->GetType(), Dali::WebEngineLoadError::ErrorType::NONE, TEST_LOCATION);
+
+  // console message.
+  DALI_TEST_CHECK(gConsoleMessageInstance);
+  std::string testConsoleSource("source");
+  DALI_TEST_EQUALS(gConsoleMessageInstance->GetSource(), testConsoleSource, TEST_LOCATION);
+  DALI_TEST_EQUALS(gConsoleMessageInstance->GetLine(), 10, TEST_LOCATION);
+  DALI_TEST_EQUALS(gConsoleMessageInstance->GetSeverityLevel(), Dali::WebEngineConsoleMessage::SeverityLevel::EMPTY, TEST_LOCATION);
+  std::string testConsoleText("This is a text.");
+  DALI_TEST_EQUALS(gConsoleMessageInstance->GetText(), testConsoleText, TEST_LOCATION);
+
+  // reset
+  gPageLoadErrorInstance = nullptr;
+  gConsoleMessageInstance = nullptr;
+
+  END_TEST;
+}
+
 int UtcDaliWebViewTouchAndKeys(void)
 {
   ToolkitTestApplication application;
@@ -350,6 +551,82 @@ int UtcDaliWebViewFocusGainedAndLost(void)
   END_TEST;
 }
 
+int UtcDaliWebViewPropertyPageZoomFactor(void)
+{
+  ToolkitTestApplication application;
+
+  WebView view = WebView::New();
+  DALI_TEST_CHECK( view );
+
+  view.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT );
+  view.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT );
+  view.SetProperty( Actor::Property::POSITION, Vector2( 0, 0 ));
+  view.SetProperty( Actor::Property::SIZE, Vector2( 800, 600 ) );
+
+  application.GetScene().Add( view );
+  application.SendNotification();
+  application.Render();
+
+  view.SetProperty( WebView::Property::PAGE_ZOOM_FACTOR, 1.5f);
+  float zoomFactor = view.GetProperty<float>( WebView::Property::PAGE_ZOOM_FACTOR );
+  DALI_TEST_EQUALS( zoomFactor, 1.5f, TEST_LOCATION );
+
+  view.SetProperty( WebView::Property::PAGE_ZOOM_FACTOR, 1.0f);
+  zoomFactor = view.GetProperty<float>( WebView::Property::PAGE_ZOOM_FACTOR );
+  DALI_TEST_EQUALS( zoomFactor, 1.0f, TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliWebViewPropertyTextZoomFactor(void)
+{
+  ToolkitTestApplication application;
+
+  WebView view = WebView::New();
+  DALI_TEST_CHECK( view );
+
+  view.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT );
+  view.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT );
+  view.SetProperty( Actor::Property::POSITION, Vector2( 0, 0 ));
+  view.SetProperty( Actor::Property::SIZE, Vector2( 800, 600 ) );
+
+  application.GetScene().Add( view );
+  application.SendNotification();
+  application.Render();
+
+  view.SetProperty( WebView::Property::TEXT_ZOOM_FACTOR, 1.5f);
+  float zoomFactor = view.GetProperty<float>( WebView::Property::TEXT_ZOOM_FACTOR );
+  DALI_TEST_EQUALS( zoomFactor, 1.5f, TEST_LOCATION );
+
+  view.SetProperty( WebView::Property::TEXT_ZOOM_FACTOR, 1.0f);
+  zoomFactor = view.GetProperty<float>( WebView::Property::TEXT_ZOOM_FACTOR );
+  DALI_TEST_EQUALS( zoomFactor, 1.0f, TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliWebViewPropertyLoadProgressPercentage(void)
+{
+  ToolkitTestApplication application;
+
+  WebView view = WebView::New();
+  DALI_TEST_CHECK( view );
+
+  view.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT );
+  view.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT );
+  view.SetProperty( Actor::Property::POSITION, Vector2( 0, 0 ));
+  view.SetProperty( Actor::Property::SIZE, Vector2( 800, 600 ) );
+
+  application.GetScene().Add( view );
+  application.SendNotification();
+  application.Render();
+
+  float percentage = view.GetProperty<float>( WebView::Property::LOAD_PROGRESS_PERCENTAGE );
+  DALI_TEST_EQUALS( percentage, 0.5f, TEST_LOCATION );
+
+  END_TEST;
+}
+
 int UtcDaliWebViewMove(void)
 {
   ToolkitTestApplication application;
@@ -504,6 +781,105 @@ int UtcDaliWebViewHoverAndWheel(void)
   END_TEST;
 }
 
+int UtcDaliWebViewFormRepostDecisionFrameRendering(void)
+{
+  ToolkitTestApplication application;
+
+  WebView view = WebView::New();
+  view.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT );
+  view.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT );
+  view.SetProperty( Actor::Property::POSITION, Vector2( 0, 0 ));
+  view.SetProperty( Actor::Property::SIZE, Vector2( 800, 600 ) );
+  application.GetScene().Add( view );
+  application.SendNotification();
+  application.Render();
+  DALI_TEST_CHECK( view );
+
+  ConnectionTracker* testTracker = new ConnectionTracker();
+  view.FormRepostDecisionSignal().Connect(&OnFormRepostDecision);
+  view.FrameRenderedSignal().Connect(&OnFrameRendered);
+  bool signal1 = false;
+  bool signal2 = false;
+  view.ConnectSignal( testTracker, "formRepostDecision", CallbackFunctor(&signal1) );
+  view.ConnectSignal( testTracker, "frameRendered", CallbackFunctor(&signal2) );
+  DALI_TEST_EQUALS( gFormRepostDecisionCallbackCalled, 0, TEST_LOCATION );
+  DALI_TEST_EQUALS( gFrameRenderedCallbackCalled, 0, TEST_LOCATION );
+
+  view.LoadUrl( TEST_URL1 );
+  Test::EmitGlobalTimerSignal();
+  DALI_TEST_EQUALS( gFormRepostDecisionCallbackCalled, 1, TEST_LOCATION );
+  DALI_TEST_EQUALS( gFrameRenderedCallbackCalled, 1, TEST_LOCATION );
+  DALI_TEST_CHECK( signal1 & signal2);
+
+  // form repost decision.
+  DALI_TEST_CHECK(gFormRepostDecisionInstance);
+  gFormRepostDecisionInstance->Reply(true);
+
+  // reset
+  gFormRepostDecisionInstance = nullptr;
+
+  END_TEST;
+}
+
+int UtcDaliWebViewSslCertificateHttpAuthentication(void)
+{
+  ToolkitTestApplication application;
+
+  WebView view = WebView::New();
+  view.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT );
+  view.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT );
+  view.SetProperty( Actor::Property::POSITION, Vector2( 0, 0 ));
+  view.SetProperty( Actor::Property::SIZE, Vector2( 800, 600 ) );
+  application.GetScene().Add( view );
+  application.SendNotification();
+  application.Render();
+  DALI_TEST_CHECK( view );
+
+  ConnectionTracker* testTracker = new ConnectionTracker();
+  view.CertificateConfirmSignal().Connect(&OnCertificateConfirm);
+  view.SslCertificateChangedSignal().Connect(&OnSslCertificateChanged);
+  view.HttpAuthHandlerSignal().Connect(&OnHttpAuthHandler);
+  bool signal1 = false;
+  bool signal2 = false;
+  bool signal3 = false;
+  view.ConnectSignal( testTracker, "certificateConfirm", CallbackFunctor(&signal1) );
+  view.ConnectSignal( testTracker, "sslCertificateChanged", CallbackFunctor(&signal2) );
+  view.ConnectSignal( testTracker, "httpAuthRequest", CallbackFunctor(&signal3) );
+  DALI_TEST_EQUALS( gCertificateConfirmCallbackCalled, 0, TEST_LOCATION );
+  DALI_TEST_EQUALS( gSslCertificateChangedCallbackCalled, 0, TEST_LOCATION );
+  DALI_TEST_EQUALS( gHttpAuthHandlerCallbackCalled, 0, TEST_LOCATION );
+
+  view.LoadUrl( TEST_URL1 );
+  Test::EmitGlobalTimerSignal();
+  DALI_TEST_EQUALS( gCertificateConfirmCallbackCalled, 1, TEST_LOCATION );
+  DALI_TEST_EQUALS( gSslCertificateChangedCallbackCalled, 1, TEST_LOCATION );
+  DALI_TEST_EQUALS( gHttpAuthHandlerCallbackCalled, 1, TEST_LOCATION );
+  DALI_TEST_CHECK( signal1 & signal2 & signal3);
+
+  // certificate.
+  DALI_TEST_CHECK(gCertificateConfirmInstance);
+  gCertificateConfirmInstance->Allow(true);
+  DALI_TEST_CHECK(gCertificateConfirmInstance->IsFromMainFrame());
+
+  DALI_TEST_CHECK(gSslCertificateInstance);
+  DALI_TEST_EQUALS(gSslCertificateInstance->GetPem(), "abc", TEST_LOCATION);
+  DALI_TEST_CHECK(gSslCertificateInstance->IsContextSecure());
+
+  // http authentication.
+  DALI_TEST_CHECK(gHttpAuthInstance);
+  gHttpAuthInstance->Suspend();
+  gHttpAuthInstance->UseCredential("", "");
+  gHttpAuthInstance->CancelCredential();
+  DALI_TEST_EQUALS(gHttpAuthInstance->GetRealm(), "test", TEST_LOCATION);
+
+  // reset
+  gCertificateConfirmInstance = nullptr;
+  gSslCertificateInstance = nullptr;
+  gHttpAuthInstance = nullptr;
+
+  END_TEST;
+}
+
 int UtcDaliWebViewGetWebBackForwardList(void)
 {
   ToolkitTestApplication application;
@@ -631,9 +1007,30 @@ int UtcDaliWebViewProperty9(void)
   END_TEST;
 }
 
+int UtcDaliWebViewPropertyBackgroundColorSelectedTextEtc(void)
+{
+  ToolkitTestApplication application;
+
+  WebView view = WebView::New();
+  DALI_TEST_CHECK( view );
+
+  Dali::Vector4 testValue = Dali::Vector4(0.0f, 0.0f, 0.0f, 0.0f);
+  view.SetProperty(WebView::Property::DOCUMENT_BACKGROUND_COLOR, testValue);
+  view.SetProperty(WebView::Property::TILES_CLEARED_WHEN_HIDDEN, true);
+  view.SetProperty(WebView::Property::TILE_COVER_AREA_MULTIPLIER, 1.0f);
+  view.SetProperty(WebView::Property::CURSOR_ENABLED_BY_CLIENT, true);
+
+  // Check default value
+  std::string testText("test");
+  std::string output;
+  view.GetProperty(WebView::Property::SELECTED_TEXT).Get(output);
+  DALI_TEST_EQUALS(output, testText, TEST_LOCATION);
+
+  END_TEST;
+}
+
 int UtcDaliWebViewPropertyTitleFavicon(void)
 {
-  // SCROLL_POSITION
   ToolkitTestApplication application;
 
   char argv[] = "--test";
@@ -658,6 +1055,67 @@ int UtcDaliWebViewPropertyTitleFavicon(void)
   END_TEST;
 }
 
+int UtcDaliWebViewContextMenuCustomizedAndItemSelected(void)
+{
+  ToolkitTestApplication application;
+
+  WebView view = WebView::New();
+  DALI_TEST_CHECK( view );
+
+  // load url.
+  ConnectionTracker* testTracker = new ConnectionTracker();
+  view.ContextMenuCustomizedSignal().Connect( &OnContextMenuCustomized );
+  view.ContextMenuItemSelectedSignal().Connect( &OnContextMenuItemSelected );
+  bool signal1 = false;
+  bool signal2 = false;
+  view.ConnectSignal( testTracker, "contextMenuCustomized", CallbackFunctor(&signal1) );
+  view.ConnectSignal( testTracker, "contextMenuItemSelected", CallbackFunctor(&signal2) );
+  DALI_TEST_EQUALS( gContextMenuCustomizedCallbackCalled, 0, TEST_LOCATION );
+  DALI_TEST_EQUALS( gContextMenuItemSelectedCallbackCalled, 0, TEST_LOCATION );
+  DALI_TEST_CHECK(gContextMenuInstance == 0);
+  DALI_TEST_CHECK(gContextMenuItemInstance == 0);
+
+  view.LoadUrl( TEST_URL1 );
+  Test::EmitGlobalTimerSignal();
+  DALI_TEST_EQUALS( gContextMenuCustomizedCallbackCalled, 1, TEST_LOCATION );
+  DALI_TEST_EQUALS( gContextMenuItemSelectedCallbackCalled, 1, TEST_LOCATION );
+  DALI_TEST_CHECK( signal1 );
+  DALI_TEST_CHECK( signal2 );
+
+  // check context meun & its items.
+  DALI_TEST_CHECK(gContextMenuInstance != 0);
+  std::unique_ptr<Dali::WebEngineContextMenuItem> item = gContextMenuInstance->GetItemAt(0);
+  DALI_TEST_CHECK(item.get() != 0);
+  std::vector<std::unique_ptr<Dali::WebEngineContextMenuItem>> itemList = gContextMenuInstance->GetItemList();
+  DALI_TEST_CHECK(itemList.size() == 1);
+  Dali::Vector2 testPosition = Dali::Vector2(100, 100);
+  DALI_TEST_EQUALS(gContextMenuInstance->GetPosition(), testPosition, TEST_LOCATION);
+  DALI_TEST_CHECK(gContextMenuInstance->RemoveItem(*(item.get())));
+  DALI_TEST_CHECK(gContextMenuInstance->AppendItemAsAction(WebEngineContextMenuItem::ItemTag::NO_ACTION, "", false));
+  DALI_TEST_CHECK(gContextMenuInstance->AppendItem(WebEngineContextMenuItem::ItemTag::NO_ACTION, "", "", false));
+  DALI_TEST_CHECK(gContextMenuInstance->SelectItem(*(item.get())));
+  DALI_TEST_CHECK(gContextMenuInstance->Hide());
+
+  DALI_TEST_CHECK(gContextMenuItemInstance != 0);
+  Dali::WebEngineContextMenuItem::ItemTag testItemTag = Dali::WebEngineContextMenuItem::ItemTag::NO_ACTION;
+  DALI_TEST_EQUALS(gContextMenuItemInstance->GetTag(), testItemTag, TEST_LOCATION);
+  Dali::WebEngineContextMenuItem::ItemType testItemType = Dali::WebEngineContextMenuItem::ItemType::ACTION;
+  DALI_TEST_EQUALS(gContextMenuItemInstance->GetType(), testItemType, TEST_LOCATION);
+  DALI_TEST_CHECK(gContextMenuItemInstance->IsEnabled());
+  std::string testLinkUrl("http://test.html");
+  DALI_TEST_EQUALS(gContextMenuItemInstance->GetLinkUrl(), testLinkUrl, TEST_LOCATION);
+  std::string testImageUrl("http://test.jpg");
+  DALI_TEST_EQUALS(gContextMenuItemInstance->GetImageUrl(), testImageUrl, TEST_LOCATION);
+  std::string testTitle("title");
+  DALI_TEST_EQUALS(gContextMenuItemInstance->GetTitle(), testTitle, TEST_LOCATION);
+  DALI_TEST_CHECK(gContextMenuItemInstance->GetParentMenu().get() == 0);
+
+  gContextMenuInstance = nullptr;
+  gContextMenuItemInstance = nullptr;
+
+  END_TEST;
+}
+
 int UtcDaliWebViewScrollBy(void)
 {
   ToolkitTestApplication application;
@@ -691,6 +1149,190 @@ int UtcDaliWebViewScrollBy(void)
   DALI_TEST_EQUALS( gScrollEdgeReachedCallbackCalled, 1, TEST_LOCATION );
   DALI_TEST_CHECK( signal1 );
 
+  // scroll by and trigger scrollEdgeReached event.
+  bool result = view.ScrollEdgeBy( 50, 50 );
+  DALI_TEST_CHECK( result );
+  Test::EmitGlobalTimerSignal();
+
+  view.GetProperty( WebView::Property::SCROLL_POSITION ).Get( output );
+  DALI_TEST_CHECK( output.x == 200 && output.y == 200 );
+  DALI_TEST_EQUALS( gScrollEdgeReachedCallbackCalled, 2, TEST_LOCATION );
+  DALI_TEST_CHECK( signal1 );
+
+  END_TEST;
+}
+
+int UtcDaliWebViewSetGetScaleFactorActivateAccessibility(void)
+{
+  ToolkitTestApplication application;
+
+  WebView view = WebView::New();
+  DALI_TEST_CHECK( view );
+
+  view.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT );
+  view.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT );
+  view.SetProperty( Actor::Property::POSITION, Vector2( 0, 0 ));
+  view.SetProperty( Actor::Property::SIZE, Vector2( 800, 600 ) );
+
+  application.GetScene().Add( view );
+  application.SendNotification();
+  application.Render();
+
+  view.ActivateAccessibility(true);
+  view.AddDynamicCertificatePath("host", "test/to/path");
+  bool found = view.HighlightText("test", Dali::WebEnginePlugin::FindOption::CASE_INSENSITIVE, 2);
+  DALI_TEST_CHECK( found );
+
+  view.SetScaleFactor(1.5f, Dali::Vector2(0.0f, 0.0f));
+  float result = view.GetScaleFactor();
+  DALI_TEST_EQUALS( result, 1.5f, TEST_LOCATION );
+
+  view.SetScaleFactor(1.0f, Dali::Vector2(0.0f, 0.0f));
+  result = view.GetScaleFactor();
+  DALI_TEST_EQUALS( result, 1.0f, TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliWebViewGetScreenshotSyncAndAsync(void)
+{
+  // SCROLL_POSITION
+  ToolkitTestApplication application;
+
+  char argv[] = "--test";
+  WebView view = WebView::New( 1, (char**)&argv );
+  DALI_TEST_CHECK( view );
+
+  // Check GetScreenshot
+  Dali::Rect<int> viewArea;
+  viewArea.x = 100;
+  viewArea.y = 100;
+  viewArea.width = 10;
+  viewArea.height = 10;
+  Dali::Toolkit::ImageView screenshot = view.GetScreenshot(viewArea, 1.0f);
+  DALI_TEST_CHECK( screenshot );
+  Dali::Vector3 shotsize = screenshot.GetProperty< Vector3 >( Dali::Actor::Property::SIZE );
+  DALI_TEST_CHECK( ( int )shotsize.width == viewArea.width && ( int )shotsize.height == viewArea.height );
+
+  // Check GetScreenshotAsynchronously
+  viewArea.x = 100;
+  viewArea.y = 100;
+  viewArea.width = 100;
+  viewArea.height = 100;
+  bool result = view.GetScreenshotAsynchronously(viewArea, 1.0f, &OnScreenshotCaptured);
+  DALI_TEST_CHECK( result );
+
+  Test::EmitGlobalTimerSignal();
+
+  Test::EmitGlobalTimerSignal();
+  DALI_TEST_EQUALS( gScreenshotCapturedCallbackCalled, 1, TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliWebViewVideoPlayingGeolocationPermission(void)
+{
+  // SCROLL_POSITION
+  ToolkitTestApplication application;
+
+  char argv[] = "--test";
+  WebView view = WebView::New( 1, (char**)&argv );
+  DALI_TEST_CHECK( view );
+
+  // Check CheckVideoPlayingAsynchronously
+  bool result = view.CheckVideoPlayingAsynchronously(&OnVideoPlaying);
+  DALI_TEST_CHECK( result );
+  Test::EmitGlobalTimerSignal();
+  DALI_TEST_EQUALS( gVideoPlayingCallbackCalled, 1, TEST_LOCATION );
+
+  // Check RegisterGeolocationPermissionCallback
+  view.RegisterGeolocationPermissionCallback(&OnGeolocationPermission);
+  Test::EmitGlobalTimerSignal();
+  DALI_TEST_EQUALS( gGeolocationPermissionCallbackCalled, 1, TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliWebViewHttpRequestInterceptor(void)
+{
+  ToolkitTestApplication application;
+
+  WebView view = WebView::New();
+  DALI_TEST_CHECK( view );
+
+  // load url.
+  ConnectionTracker* testTracker = new ConnectionTracker();
+  view.RequestInterceptorSignal().Connect( &OnRequestInterceptor );
+  bool signal1 = false;
+  view.ConnectSignal( testTracker, "requestInterceptor", CallbackFunctor(&signal1) );
+  DALI_TEST_EQUALS( gRequestInterceptorCallbackCalled, 0, TEST_LOCATION );
+  DALI_TEST_CHECK(gRequestInterceptorInstance == 0);
+
+  view.LoadUrl( TEST_URL1 );
+  Test::EmitGlobalTimerSignal();
+  DALI_TEST_EQUALS( gRequestInterceptorCallbackCalled, 1, TEST_LOCATION );
+  DALI_TEST_CHECK( signal1 );
+
+  // check request interceptor.
+  DALI_TEST_CHECK(gRequestInterceptorInstance != 0);
+  DALI_TEST_CHECK(gRequestInterceptorInstance->Ignore());
+  DALI_TEST_CHECK(gRequestInterceptorInstance->SetResponseStatus(400, "error"));
+  DALI_TEST_CHECK(gRequestInterceptorInstance->AddResponseHeader("key", "value"));
+  DALI_TEST_CHECK(gRequestInterceptorInstance->AddResponseBody("test", 4));
+  std::string testUrl("http://test.html");
+  DALI_TEST_EQUALS(gRequestInterceptorInstance->GetUrl(), testUrl, TEST_LOCATION);
+
+  gRequestInterceptorInstance = nullptr;
+
+  END_TEST;
+}
+
+int UtcDaliWebViewPolicyDecisionRequest(void)
+{
+  ToolkitTestApplication application;
+
+  WebView view = WebView::New();
+  DALI_TEST_CHECK( view );
+
+  // load url.
+  ConnectionTracker* testTracker = new ConnectionTracker();
+  view.PolicyDecisionSignal().Connect( &OnPolicyDecisionRequest );
+  bool signal1 = false;
+  view.ConnectSignal( testTracker, "policyDecision", CallbackFunctor(&signal1) );
+  DALI_TEST_EQUALS( gPolicyDecisionCallbackCalled, 0, TEST_LOCATION );
+  DALI_TEST_CHECK(gPolicyDecisionInstance == 0);
+
+  view.LoadUrl( TEST_URL1 );
+  Test::EmitGlobalTimerSignal();
+  DALI_TEST_EQUALS( gPolicyDecisionCallbackCalled, 1, TEST_LOCATION );
+  DALI_TEST_CHECK( signal1 );
+
+  // check policy decision & its frame.
+  DALI_TEST_CHECK(gPolicyDecisionInstance != 0);
+  std::string testUrl("http://test.html");
+  DALI_TEST_EQUALS(gPolicyDecisionInstance->GetUrl(), testUrl, TEST_LOCATION);
+  std::string testCookie("test:abc");
+  DALI_TEST_EQUALS(gPolicyDecisionInstance->GetCookie(), testCookie, TEST_LOCATION);
+  Dali::WebEnginePolicyDecision::DecisionType testDecisionType = Dali::WebEnginePolicyDecision::DecisionType::USE;
+  DALI_TEST_EQUALS(gPolicyDecisionInstance->GetDecisionType(), testDecisionType, TEST_LOCATION);
+  std::string testResponseMime("txt/xml");
+  DALI_TEST_EQUALS(gPolicyDecisionInstance->GetResponseMime(), testResponseMime, TEST_LOCATION);
+  int32_t ResponseStatusCode = 500;
+  DALI_TEST_EQUALS(gPolicyDecisionInstance->GetResponseStatusCode(), ResponseStatusCode, TEST_LOCATION);
+  Dali::WebEnginePolicyDecision::NavigationType testNavigationType = Dali::WebEnginePolicyDecision::NavigationType::LINK_CLICKED;
+  DALI_TEST_EQUALS(gPolicyDecisionInstance->GetNavigationType(), testNavigationType, TEST_LOCATION);
+  std::string testScheme("test");
+  DALI_TEST_EQUALS(gPolicyDecisionInstance->GetScheme(), testScheme, TEST_LOCATION);
+  DALI_TEST_CHECK(gPolicyDecisionInstance->Use());
+  DALI_TEST_CHECK(gPolicyDecisionInstance->Ignore());
+  DALI_TEST_CHECK(gPolicyDecisionInstance->Suspend());
+
+  Dali::WebEngineFrame* webFrame = &(gPolicyDecisionInstance->GetFrame());
+  DALI_TEST_CHECK(webFrame);
+  DALI_TEST_CHECK(webFrame->IsMainFrame());
+
+  gPolicyDecisionInstance = nullptr;
+
   END_TEST;
 }
 
@@ -737,6 +1379,71 @@ int UtcDaliWebViewJavaScriptAlertConfirmPrompt(void)
   END_TEST;
 }
 
+int UtcDaliWebViewLoadHtmlStringOverrideCurrentEntryAndContents(void)
+{
+  ToolkitTestApplication application;
+
+  WebView view = WebView::New( "ko-KR", "Asia/Seoul" );
+  DALI_TEST_CHECK( view );
+
+  std::string html("<body>Hello World!</body>");
+  std::string basicUri("http://basicurl");
+  std::string unreachableUrl("http://unreachableurl");
+  bool result = view.LoadHtmlStringOverrideCurrentEntry( html, basicUri, unreachableUrl );
+  DALI_TEST_CHECK( result );
+
+  application.SendNotification();
+  application.Render();
+  Test::EmitGlobalTimerSignal();
+
+  result = view.LoadContents( html, html.length(), "html/text", "utf-8", basicUri );
+  DALI_TEST_CHECK( result );
+
+  END_TEST;
+}
+
+int UtcDaliWebViewReloadSuspendResumeNetworkLoadingCustomHeader(void)
+{
+  ToolkitTestApplication application;
+
+  WebView view = WebView::New();
+  view.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT );
+  view.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT );
+  view.SetProperty( Actor::Property::POSITION, Vector2( 0, 0 ));
+  view.SetProperty( Actor::Property::SIZE, Vector2( 800, 600 ) );
+
+  application.GetScene().Add( view );
+  application.SendNotification();
+  application.Render();
+  DALI_TEST_CHECK( view );
+
+  view.LoadUrl( "http://test.html" );
+  bool result = view.AddCustomHeader("key", "value");
+  DALI_TEST_CHECK( result );
+
+  result = view.ReloadWithoutCache();
+  DALI_TEST_CHECK( result );
+
+  uint32_t portNumber = view.StartInspectorServer(5000);
+  DALI_TEST_EQUALS( portNumber, 5000, TEST_LOCATION );
+
+  application.SendNotification();
+  application.Render();
+  Test::EmitGlobalTimerSignal();
+
+  result = view.StopInspectorServer();
+  DALI_TEST_CHECK( result );
+
+  view.SuspendNetworkLoading();
+
+  result = view.RemoveCustomHeader("key");
+  DALI_TEST_CHECK( result );
+
+  view.ResumeNetworkLoading();
+
+  END_TEST;
+}
+
 int UtcDaliWebViewMethodsForCoverage(void)
 {
   ToolkitTestApplication application;
@@ -809,8 +1516,8 @@ int UtcDaliWebContextGetSetCacheModel(void)
   context->SetCertificateFilePath( kDefaultValue );
   context->DisableCache( false );
   context->SetDefaultProxyAuth( kDefaultValue, kDefaultValue );
-  context->DeleteWebDatabase();
-  context->DeleteWebStorage();
+  context->DeleteAllWebDatabase();
+  context->DeleteAllWebStorage();
   context->DeleteLocalFileSystem();
   context->ClearCache();
 
@@ -826,6 +1533,76 @@ int UtcDaliWebContextGetSetCacheModel(void)
   END_TEST;
 }
 
+int UtcDaliWebContextGetWebDatabaseStorageOrigins(void)
+{
+  ToolkitTestApplication application;
+
+  WebView view = WebView::New();
+  DALI_TEST_CHECK( view );
+
+  Dali::Toolkit::WebContext* context = view.GetContext();
+  DALI_TEST_CHECK( context != 0 )
+
+  std::string kDefaultValue;
+
+  // get origins of web database
+  bool result = context->GetWebDatabaseOrigins(&OnSecurityOriginsAcquired);
+  DALI_TEST_CHECK( result );
+
+  Test::EmitGlobalTimerSignal();
+  DALI_TEST_EQUALS( gSecurityOriginsAcquiredCallbackCalled, 1, TEST_LOCATION );
+  DALI_TEST_CHECK(gSecurityOriginList.size() == 1);
+
+  Dali::WebEngineSecurityOrigin* origin = gSecurityOriginList[0].get();
+  DALI_TEST_CHECK( origin );
+
+  result = context->DeleteWebDatabase(*origin);
+  DALI_TEST_CHECK( result );
+
+  // get origins of web storage
+  result = context->GetWebStorageOrigins(&OnSecurityOriginsAcquired);
+  DALI_TEST_CHECK( result );
+
+  Test::EmitGlobalTimerSignal();
+  DALI_TEST_EQUALS( gSecurityOriginsAcquiredCallbackCalled, 2, TEST_LOCATION );
+  DALI_TEST_CHECK(gSecurityOriginList.size() == 1);
+
+  origin = gSecurityOriginList[0].get();
+  DALI_TEST_CHECK( origin );
+
+  result = context->GetWebStorageUsageForOrigin(*origin, &OnStorageUsageAcquired);
+  DALI_TEST_CHECK( result );
+  Test::EmitGlobalTimerSignal();
+  DALI_TEST_EQUALS( gStorageUsageAcquiredCallbackCalled, 1, TEST_LOCATION );
+
+  result = context->DeleteWebStorageOrigin(*origin);
+  DALI_TEST_CHECK( result );
+
+  result = context->DeleteApplicationCache(*origin);
+  DALI_TEST_CHECK( result );
+
+  // form passwords, download state, mime type.
+  context->GetFormPasswordList(&OnFormPasswordsAcquired);
+  Test::EmitGlobalTimerSignal();
+  DALI_TEST_EQUALS(gFormPasswordsAcquiredCallbackCalled, 1, TEST_LOCATION);
+  DALI_TEST_CHECK(gPasswordDataList.size() == 1);
+  DALI_TEST_EQUALS(gPasswordDataList[0]->url, "http://test.html", TEST_LOCATION);
+  DALI_TEST_CHECK(gPasswordDataList[0]->useFingerprint == false);
+
+  context->RegisterDownloadStartedCallback(&OnDownloadStarted);
+  Test::EmitGlobalTimerSignal();
+  DALI_TEST_EQUALS(gDownloadStartedCallbackCalled, 1, TEST_LOCATION);
+
+  context->RegisterMimeOverriddenCallback(&OnMimeOverridden);
+  Test::EmitGlobalTimerSignal();
+  DALI_TEST_EQUALS(gMimeOverriddenCallbackCalled, 1, TEST_LOCATION);
+
+  gSecurityOriginList.clear();
+  gPasswordDataList.clear();
+
+  END_TEST;
+}
+
 // test cases for web cookie manager.
 
 int UtcDaliWebCookieManagerGetSetCookieAcceptPolicy(void)
index a7bc0e6..8be2625 100644 (file)
@@ -472,9 +472,9 @@ IF( ENABLE_COVERAGE )
     ADD_CUSTOM_TARGET( ${DALI_TOOLKIT_PREFIX}rename_cov_data ./rename-cov-data )
 
     ADD_CUSTOM_TARGET( ${DALI_TOOLKIT_PREFIX}cov_data ${LCOV_BIN} ${LCOV_OPTS} --base-directory . --directory . -c -o dali.info
-      COMMAND ${LCOV_BIN} ${LCOV_OPTS} --remove dali.info \"*/dali-env/*\" \"/usr/include/*\" "*/dali-env/*" "*solid-color-actor*" "*/dali-toolkit/third-party/*" \"*/dali-scene-loader/third-party/*\" -o dali.info )
+      COMMAND ${LCOV_BIN} ${LCOV_OPTS} --remove dali.info \"*/dali-env/*\" \"/usr/include/*\" \"*/dali-env/*\" \"*solid-color-actor*\" \"*/dali-toolkit/third-party/*\" \"*/dali-scene-loader/third-party/*\" -o dali.info )
 
-    ADD_CUSTOM_TARGET( ${DALI_TOOLKIT_PREFIX}coverage genhtml ${LCOV_OPTS} -o ${COVERAGE_OUTPUT_DIR} dali.info
+    ADD_CUSTOM_TARGET( ${DALI_TOOLKIT_PREFIX}coverage genhtml -p ${ROOT_SRC_DIR} ${LCOV_OPTS} -o ${COVERAGE_OUTPUT_DIR} dali.info
       DEPENDS cov_data )
 
     ADD_CUSTOM_TARGET( ${DALI_TOOLKIT_PREFIX}reset_coverage @${LCOV_BIN} -z --directory `pwd` )
index d3ebe7d..ae7fea2 100644 (file)
@@ -68,63 +68,6 @@ if (ENABLE_PKG_CONFIGURE)
        configure_file(${CMAKE_CURRENT_LIST_DIR}/${core_pkg_cfg_file}.in ${core_pkg_cfg_file} @ONLY)
 endif()
 
-if (ENABLE_COVERAGE)
-       find_program(lcov_bin "lcov")
-       if (${lcov_bin})
-               set(cov_dir ".cov")
-               set(cov_output_dir "doc/coverage")
-
-               execute_process(COMMAND bash -c "${lcov_bin} --version | cut -d' ' -f4" OUTPUT_VARIABLE lcov_version)
-               string(REPLACE "." ";" lcov_vlist ${lcov_version})
-               if (NOT $<VERSION_LESS:${lcov_version},"1.10"> )
-                       set(lcov_opts --rc lcov_branch_coverage=1)
-               endif()
-
-               add_custom_target(${prefix}rename_cov_data ./rename-cov-data)
-
-               add_custom_target(${prefix}cov_data
-                       ${lcov_bin} ${lcov_opts} --base-directory . --directory . -c -o dali.info
-                       COMMAND ${lcov_bin} ${lcov_opts} --remove dali.info \"*/dali-env/*\" \"/usr/include/*\" \"/usr/local/include/*\" \"*/dali-env/*\" \"*/dali-scene-loader/third-party/*\" -o dali.info
-               )
-
-               add_custom_target(${prefix}coverage genhtml ${lcov_opts} -o ${cov_output_dir} dali.info)
-
-               add_custom_target(${prefix}reset_coverage @${lcov_bin} -\ --direwctory `pwd`)
-
-               add_custom_target(${prefix}distclean @echo cleaning for source distribution)
-               add_custom_command(
-                       DEPENDS ${prefix}clean
-                       COMMENT "distribution clean"
-                       COMMAND find
-                       ARGS .
-                       -not -name config.cmake -and \(
-                       -name tester.c -or
-                       -name Testing -or
-                       -name CMakeFiles -or
-                       -name doc -or
-                       -name cmake.depends -or
-                       -name cmake.check_depends -or
-                       -name CMakeCache.txt -or
-                       -name cmake.check_cache -or
-                       -name *.cmake -or
-                       -name Makefile -or
-                       -name core -or
-                       -name core.* -or
-                       -name gmon.out -or
-                       -name install_manifest.txt -or
-                       -name *.pc -or
-                       -name *.gcov -or
-                       -name *.gcno -or
-                       -name *.gcda -or
-                       -name *~ -or
-                       -name libdali*.so* \)
-                       | grep -v TC | xargs rm -rf
-                       TARGET  ${DALI_TOOLKIT_PREFIX}distclean
-                       VERBATIM
-               )
-       endif()
-endif()
-
 set(scene_loader_src_files "")
 include("${scene_loader_dir}/internal/file.list")
 include("${scene_loader_dir}/public-api/file.list")
index 69292e2..8317803 100644 (file)
@@ -470,6 +470,11 @@ void MeshDefinition::Blob::ApplyMinMax(const std::vector<float>& min, const std:
                                                    value = std::min(std::max(min[i], value), max[i]);
                                                  });
 
+  if(!clampFn)
+  {
+    return;
+  }
+
   auto end = values + count * numComponents;
   while(values != end)
   {
index cd0ddc9..d03fa0b 100644 (file)
@@ -177,7 +177,7 @@ struct DALI_SCENE_LOADER_API MeshDefinition
     std::vector<uint16_t> mIndices;
     std::vector<Attrib>   mAttribs;
 
-    unsigned int        mBlendShapeBufferOffset;
+    unsigned int        mBlendShapeBufferOffset{0};
     Dali::Vector<float> mBlendShapeUnnormalizeFactor;
     PixelData           mBlendShapeData;
   };
index 026e9a7..5b46e0f 100644 (file)
@@ -33,7 +33,7 @@ struct DALI_SCENE_LOADER_API MeshGeometry
   Geometry      geometry;                    ///< The array of vertices.
   Texture       blendShapeGeometry;          ///< The array of vertices of the different blend shapes encoded inside a texture with power of two dimensions.
   Vector<float> blendShapeUnnormalizeFactor; ///< Factor used to unnormalize the geometry of the blend shape.
-  unsigned int  blendShapeBufferOffset;      ///< Offset used to calculate the start of each blend shape.
+  unsigned int  blendShapeBufferOffset{0};   ///< Offset used to calculate the start of each blend shape.
 };
 
 } // namespace SceneLoader
index be4735b..dd1fc93 100644 (file)
@@ -35,15 +35,15 @@ AccessibleImpl::AccessibleImpl(Dali::Actor self, Dali::Accessibility::Role role,
 : self(self),
   modal(modal)
 {
-  auto control = Dali::Toolkit::Control::DownCast(self);
+  auto control = Dali::Toolkit::Control::DownCast(Self());
 
   Internal::Control&       internalControl = Toolkit::Internal::GetImplementation(control);
   Internal::Control::Impl& controlImpl     = Internal::Control::Impl::Get(internalControl);
   if(controlImpl.mAccessibilityRole == Dali::Accessibility::Role::UNKNOWN)
     controlImpl.mAccessibilityRole = role;
 
-  self.PropertySetSignal().Connect(&controlImpl, [this, &controlImpl](Dali::Handle& handle, Dali::Property::Index index, Dali::Property::Value value) {
-    if(this->self != Dali::Accessibility::Accessible::GetCurrentlyHighlightedActor())
+  Self().PropertySetSignal().Connect(&controlImpl, [this, &controlImpl](Dali::Handle& handle, Dali::Property::Index index, Dali::Property::Value value) {
+    if(this->Self() != Dali::Accessibility::Accessible::GetCurrentlyHighlightedActor())
     {
       return;
     }
@@ -68,7 +68,7 @@ AccessibleImpl::AccessibleImpl(Dali::Actor self, Dali::Accessibility::Role role,
 
 std::string AccessibleImpl::GetName()
 {
-  auto control = Dali::Toolkit::Control::DownCast(self);
+  auto control = Dali::Toolkit::Control::DownCast(Self());
 
   Internal::Control&       internalControl = Toolkit::Internal::GetImplementation(control);
   Internal::Control::Impl& controlImpl     = Internal::Control::Impl::Get(internalControl);
@@ -86,7 +86,7 @@ std::string AccessibleImpl::GetName()
   if(auto raw = GetNameRaw(); !raw.empty())
     return raw;
 
-  return self.GetProperty<std::string>(Actor::Property::NAME);
+  return Self().GetProperty<std::string>(Actor::Property::NAME);
 }
 
 std::string AccessibleImpl::GetNameRaw()
@@ -96,7 +96,7 @@ std::string AccessibleImpl::GetNameRaw()
 
 std::string AccessibleImpl::GetDescription()
 {
-  auto control = Dali::Toolkit::Control::DownCast(self);
+  auto control = Dali::Toolkit::Control::DownCast(Self());
 
   Internal::Control&       internalControl = Toolkit::Internal::GetImplementation(control);
   Internal::Control::Impl& controlImpl     = Internal::Control::Impl::Get(internalControl);
@@ -121,22 +121,22 @@ std::string AccessibleImpl::GetDescriptionRaw()
 
 Dali::Accessibility::Accessible* AccessibleImpl::GetParent()
 {
-  return Dali::Accessibility::Accessible::Get(self.GetParent());
+  return Dali::Accessibility::Accessible::Get(Self().GetParent());
 }
 
 size_t AccessibleImpl::GetChildCount()
 {
-  return self.GetChildCount();
+  return Self().GetChildCount();
 }
 
 Dali::Accessibility::Accessible* AccessibleImpl::GetChildAtIndex(size_t index)
 {
-  return Dali::Accessibility::Accessible::Get(self.GetChildAt(static_cast<unsigned int>(index)));
+  return Dali::Accessibility::Accessible::Get(Self().GetChildAt(static_cast<unsigned int>(index)));
 }
 
 size_t AccessibleImpl::GetIndexInParent()
 {
-  auto s      = self;
+  auto s      = Self();
   auto parent = s.GetParent();
   DALI_ASSERT_ALWAYS(parent && "can't call GetIndexInParent on object without parent");
   auto count = parent.GetChildCount();
@@ -152,11 +152,12 @@ size_t AccessibleImpl::GetIndexInParent()
 
 Dali::Accessibility::Role AccessibleImpl::GetRole()
 {
-  return self.GetProperty<Dali::Accessibility::Role>(Toolkit::DevelControl::Property::ACCESSIBILITY_ROLE);
+  return Self().GetProperty<Dali::Accessibility::Role>(Toolkit::DevelControl::Property::ACCESSIBILITY_ROLE);
 }
 
 Dali::Accessibility::States AccessibleImpl::CalculateStates()
 {
+  Dali::Actor self = Self();
   Dali::Accessibility::States s;
   s[Dali::Accessibility::State::FOCUSABLE] = self.GetProperty<bool>(Actor::Property::KEYBOARD_FOCUSABLE);
   s[Dali::Accessibility::State::FOCUSED]   = Toolkit::KeyboardFocusManager::Get().GetCurrentFocusActor() == self;
@@ -187,7 +188,7 @@ Dali::Accessibility::States AccessibleImpl::GetStates()
 Dali::Accessibility::Attributes AccessibleImpl::GetAttributes()
 {
   std::unordered_map<std::string, std::string> attribute_map;
-  auto                                         q = Dali::Toolkit::Control::DownCast(self);
+  auto                                         q = Dali::Toolkit::Control::DownCast(Self());
   auto                                         w =
     q.GetProperty(Dali::Toolkit::DevelControl::Property::ACCESSIBILITY_ATTRIBUTES);
   auto z = w.GetMap();
@@ -221,6 +222,7 @@ Dali::Accessibility::ComponentLayer AccessibleImpl::GetLayer()
 
 Dali::Rect<> AccessibleImpl::GetExtents(Dali::Accessibility::CoordType ctype)
 {
+  Dali::Actor self = Self();
   Vector2 screenPosition =
     self.GetProperty(Dali::DevelActor::Property::SCREEN_POSITION)
       .Get<Vector2>();
@@ -248,7 +250,7 @@ double AccessibleImpl::GetAlpha()
 
 bool AccessibleImpl::GrabFocus()
 {
-  return Toolkit::KeyboardFocusManager::Get().SetCurrentFocusActor(self);
+  return Toolkit::KeyboardFocusManager::Get().SetCurrentFocusActor(Self());
 }
 
 static Dali::Actor CreateHighlightIndicatorActor()
@@ -268,6 +270,7 @@ static Dali::Actor CreateHighlightIndicatorActor()
 
 bool AccessibleImpl::GrabHighlight()
 {
+  Dali::Actor self = Self();
   auto old = GetCurrentlyHighlightedActor();
 
   if(!Dali::Accessibility::IsUp())
@@ -304,6 +307,8 @@ bool AccessibleImpl::GrabHighlight()
 
 bool AccessibleImpl::ClearHighlight()
 {
+  Dali::Actor self = Self();
+
   if(!Dali::Accessibility::IsUp())
     return false;
   if(GetCurrentlyHighlightedActor() == self)
@@ -321,7 +326,7 @@ std::string AccessibleImpl::GetActionName(size_t index)
 {
   if(index >= GetActionCount()) return "";
   Dali::TypeInfo type;
-  self.GetTypeInfo(type);
+  Self().GetTypeInfo(type);
   DALI_ASSERT_ALWAYS(type && "no TypeInfo object");
   return type.GetActionName(index);
 }
@@ -340,7 +345,7 @@ std::string AccessibleImpl::GetActionDescription(size_t index)
 size_t AccessibleImpl::GetActionCount()
 {
   Dali::TypeInfo type;
-  self.GetTypeInfo(type);
+  Self().GetTypeInfo(type);
   DALI_ASSERT_ALWAYS(type && "no TypeInfo object");
   return type.GetActionCount();
 }
@@ -353,17 +358,17 @@ std::string AccessibleImpl::GetActionKeyBinding(size_t index)
 bool AccessibleImpl::DoAction(size_t index)
 {
   std::string actionName = GetActionName(index);
-  return self.DoAction(actionName, {});
+  return Self().DoAction(actionName, {});
 }
 
 bool AccessibleImpl::DoAction(const std::string& name)
 {
-  return self.DoAction(name, {});
+  return Self().DoAction(name, {});
 }
 
 bool AccessibleImpl::DoGesture(const Dali::Accessibility::GestureInfo& gestureInfo)
 {
-  auto control = Dali::Toolkit::Control::DownCast(self);
+  auto control = Dali::Toolkit::Control::DownCast(Self());
 
   Internal::Control&       internalControl = Toolkit::Internal::GetImplementation(control);
   Internal::Control::Impl& controlImpl     = Internal::Control::Impl::Get(internalControl);
@@ -380,7 +385,7 @@ bool AccessibleImpl::DoGesture(const Dali::Accessibility::GestureInfo& gestureIn
 
 std::vector<Dali::Accessibility::Relation> AccessibleImpl::GetRelationSet()
 {
-  auto control = Dali::Toolkit::Control::DownCast(self);
+  auto control = Dali::Toolkit::Control::DownCast(Self());
 
   Internal::Control&       internalControl = Toolkit::Internal::GetImplementation(control);
   Internal::Control::Impl& controlImpl     = Internal::Control::Impl::Get(internalControl);
@@ -408,7 +413,7 @@ void AccessibleImpl::EnsureSelfVisible()
   auto parent = dynamic_cast<AccessibleImpl*>(GetParent());
   if(parent)
   {
-    parent->EnsureChildVisible(self);
+    parent->EnsureChildVisible(Self());
   }
 }
 
index ff31c1e..ed09487 100644 (file)
@@ -46,10 +46,23 @@ struct DALI_TOOLKIT_API AccessibleImpl : public virtual Dali::Accessibility::Acc
                                          public virtual Dali::Accessibility::Collection,
                                          public virtual Dali::Accessibility::Action
 {
-  Dali::Actor self;
+protected:
+  Dali::WeakHandle<Dali::Actor> self;
   Dali::WeakHandle<Dali::Actor> currentHighlightActor;
   bool        modal = false, root = false;
 
+  Dali::Actor Self()
+  {
+    auto handle = self.GetHandle();
+
+    // Control::Impl holds a std::unique_ptr to the Accessible object,
+    // so that one does not outlive the other.
+    DALI_ASSERT_ALWAYS(handle);
+
+    return handle;
+  }
+
+public:
   AccessibleImpl(Dali::Actor self, Dali::Accessibility::Role role, bool modal = false);
 
   /**
diff --git a/dali-toolkit/devel-api/controls/canvas-view/canvas-view.cpp b/dali-toolkit/devel-api/controls/canvas-view/canvas-view.cpp
new file mode 100644 (file)
index 0000000..d6ebc63
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali-toolkit/devel-api/controls/canvas-view/canvas-view.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/controls/canvas-view/canvas-view-impl.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+CanvasView::CanvasView()
+{
+}
+
+CanvasView::CanvasView(const CanvasView& canvasView)
+: Control(canvasView)
+{
+}
+
+CanvasView::CanvasView(CanvasView&& rhs) = default;
+
+CanvasView& CanvasView::operator=(const CanvasView& rhs)
+{
+  if(&rhs != this)
+  {
+    Control::operator=(rhs);
+  }
+  return *this;
+}
+
+CanvasView& CanvasView::operator=(CanvasView&& rhs) = default;
+
+CanvasView::~CanvasView()
+{
+}
+
+CanvasView CanvasView::New(const Vector2& viewBox)
+{
+  CanvasView canvasView = Internal::CanvasView::New(viewBox);
+  return canvasView;
+}
+
+CanvasView CanvasView::DownCast(BaseHandle handle)
+{
+  return Control::DownCast<CanvasView, Internal::CanvasView>(handle);
+}
+
+void CanvasView::AddDrawable(Dali::CanvasRenderer::Drawable& drawable)
+{
+  Dali::Toolkit::GetImpl(*this).AddDrawable(drawable);
+}
+
+CanvasView::CanvasView(Internal::CanvasView& implementation)
+: Control(implementation)
+{
+}
+
+CanvasView::CanvasView(Dali::Internal::CustomActor* internal)
+: Control(internal)
+{
+  VerifyCustomActorPointer<Internal::CanvasView>(internal);
+}
+
+} // namespace Toolkit
+
+} // namespace Dali
diff --git a/dali-toolkit/devel-api/controls/canvas-view/canvas-view.h b/dali-toolkit/devel-api/controls/canvas-view/canvas-view.h
new file mode 100644 (file)
index 0000000..9e59722
--- /dev/null
@@ -0,0 +1,151 @@
+#ifndef DALI_TOOLKIT_CANVAS_VIEW_H
+#define DALI_TOOLKIT_CANVAS_VIEW_H
+
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/public-api/controls/control.h>
+
+// EXTERNAL INCLUDES
+#include <dali/devel-api/adaptor-framework/canvas-renderer-drawable.h>
+#include <dali/devel-api/adaptor-framework/canvas-renderer-shape.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Internal DALI_INTERNAL
+{
+class CanvasView;
+}
+/**
+ * @addtogroup dali_toolkit_controls_canvas_view
+ * @{
+ */
+
+/**
+ * @brief CanvasView is a class for displaying an vector primitives.
+ *
+ * @code
+ *    auto myCanvasView = CanvasView::New( viewBox ) ); //The viewBox is the size of viewbox of CanvasView.
+ *
+ *    //Create shape and set properties.
+ *    auto shape = Dali::CanvasRenderer::Shape::New();
+ *    shape.AddRect( 0, 0, 10, 10, 0, 0 );
+ *    shape.SetFillColor( Vector4( 1.0, 1.0, 1.0, 1.0 ) );
+ *    myCanvasView.AddDrawable( shape );
+ * @endcode
+ *
+ *
+ */
+class DALI_TOOLKIT_API CanvasView : public Control
+{
+public:
+  /**
+   * @brief Creates an uninitialized CanvasView.
+   */
+  CanvasView();
+
+  /**
+   * @brief Creates an initialized CanvasView
+   *
+   * @param [in] viewBox The width and height.
+   * @return A handle to a newly allocated CanvasView
+   */
+  static CanvasView New(const Vector2& viewBox);
+
+  /**
+   * @brief Destructor.
+   *
+   * This is non-virtual since derived Handle types must not contain data or virtual methods.
+   */
+  ~CanvasView();
+
+  /**
+   * @brief Copy constructor.
+   *
+   * @param[in] canvasView CanvasView to copy. The copied CanvasView will point at the same implementation
+   */
+  CanvasView(const CanvasView& canvasView);
+
+  /**
+   * @brief Move constructor
+   *
+   * @param[in] rhs A reference to the moved handle
+   */
+  CanvasView(CanvasView&& rhs);
+
+  /**
+   * @brief Assignment operator.
+   *
+   * @param[in] canvasView The CanvasView to assign from
+   * @return The updated CanvasView
+   */
+  CanvasView& operator=(const CanvasView& canvasView);
+
+  /**
+   * @brief Move assignment
+   *
+   * @param[in] rhs A reference to the moved handle
+   * @return A reference to this
+   */
+  CanvasView& operator=(CanvasView&& rhs);
+
+  /**
+   * @brief Downcasts a handle to CanvasView handle.
+   *
+   * If handle points to a CanvasView, the downcast produces valid handle.
+   * If not, the returned handle is left uninitialized.
+   *
+   * @param[in] handle Handle to an object
+   * @return Handle to a CanvasView or an uninitialized handle
+   */
+  static CanvasView DownCast(BaseHandle handle);
+
+  /**
+   * @brief Add drawable object to the CanvasView.
+   * This method is similar to registration. The added shape is drawn on the inner canvas.
+   */
+  void AddDrawable(Dali::CanvasRenderer::Drawable& drawable);
+
+public: // Not intended for application developers
+  /// @cond internal
+  /**
+   * @brief Creates a handle using the Toolkit::Internal implementation.
+   *
+   * @param[in] implementation The CanvasView implementation
+   */
+  DALI_INTERNAL CanvasView(Internal::CanvasView& implementation);
+
+  /**
+   * @brief Allows the creation of this CanvasView from an Internal::CustomActor pointer.
+   *
+   * @param[in] internal A pointer to the internal CustomActor
+   */
+  DALI_INTERNAL CanvasView(Dali::Internal::CustomActor* internal);
+  /// @endcond
+};
+
+/**
+ * @}
+ */
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_CANVAS_VIEW_H
index abe3389..37678d8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,6 +35,11 @@ MaxLengthReachedSignalType& MaxLengthReachedSignal(TextEditor textEditor)
   return GetImpl(textEditor).MaxLengthReachedSignal();
 }
 
+AnchorClickedSignalType& AnchorClickedSignal(TextEditor textEditor)
+{
+  return GetImpl(textEditor).AnchorClickedSignal();
+}
+
 void SelectWholeText(TextEditor textEditor)
 {
   GetImpl(textEditor).SelectWholeText();
index 77ed805..c73c582 100644 (file)
@@ -217,6 +217,27 @@ using MaxLengthReachedSignalType = Signal<void(TextEditor)>;
 DALI_TOOLKIT_API MaxLengthReachedSignalType& MaxLengthReachedSignal(TextEditor textEditor);
 
 /**
+ * @brief Anchor clicked signal type.
+ *
+ * @note Signal
+ *  - const char* : href of clicked anchor.
+ *  - uint32_t    : length of href.
+ */
+using AnchorClickedSignalType = Signal<void(TextEditor, const char*, uint32_t)>;
+
+/**
+ * @brief This signal is emitted when the anchor is clicked.
+ *
+ * A callback of the following type may be connected:
+ * @code
+ *   void YourCallbackName(TextEditor textEditor, const char* href, uint32_t hrefLength);
+ * @endcode
+ * @param[in] textEditor The instance of TextEditor.
+ * @return The signal to connect to.
+ */
+DALI_TOOLKIT_API AnchorClickedSignalType& AnchorClickedSignal(TextEditor textEditor);
+
+/**
  * @brief Select the whole text of TextEditor.
  *
  * @param[in] textEditor The instance of TextEditor.
index 29c3730..fdfac30 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -30,6 +30,11 @@ InputMethodContext GetInputMethodContext(TextField textField)
   return GetImpl(textField).GetInputMethodContext();
 }
 
+AnchorClickedSignalType& AnchorClickedSignal(TextField textField)
+{
+  return GetImpl(textField).AnchorClickedSignal();
+}
+
 void SelectWholeText(TextField textField)
 {
   GetImpl(textField).SelectWholeText();
index ac239ef..3367bec 100644 (file)
@@ -185,6 +185,27 @@ enum
 DALI_TOOLKIT_API InputMethodContext GetInputMethodContext(TextField textField);
 
 /**
+ * @brief Anchor clicked signal type.
+ *
+ * @note Signal
+ *  - const char* : href of clicked anchor.
+ *  - uint32_t    : length of href.
+ */
+using AnchorClickedSignalType = Signal<void(TextField, const char*, uint32_t)>;
+
+/**
+ * @brief This signal is emitted when the anchor is clicked.
+ *
+ * A callback of the following type may be connected:
+ * @code
+ *   void YourCallbackName(TextField textField, const char* href, uint32_t hrefLength);
+ * @endcode
+ * @param[in] textField The instance of TextField.
+ * @return The signal to connect to.
+ */
+DALI_TOOLKIT_API AnchorClickedSignalType& AnchorClickedSignal(TextField textField);
+
+/**
  * @brief Select the whole text of TextField.
  *
  * @param[in] textField The instance of TextField.
diff --git a/dali-toolkit/devel-api/controls/text-controls/text-label-devel.cpp b/dali-toolkit/devel-api/controls/text-controls/text-label-devel.cpp
new file mode 100644 (file)
index 0000000..0d6cd0b
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/devel-api/controls/text-controls/text-label-devel.h>
+#include <dali-toolkit/internal/controls/text-controls/text-label-impl.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace DevelTextLabel
+{
+AnchorClickedSignalType& AnchorClickedSignal(TextLabel textLabel)
+{
+  return GetImpl(textLabel).AnchorClickedSignal();
+}
+
+} // namespace DevelTextLabel
+
+} // namespace Toolkit
+
+} // namespace Dali
index 9b3e4db..efdad10 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_TEXT_LABEL_DEVEL_H
 
 /*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -158,6 +158,27 @@ enum Type
 
 } // namespace Property
 
+/**
+ * @brief Anchor clicked signal type.
+ *
+ * @note Signal
+ *  - const char* : href of clicked anchor.
+ *  - uint32_t    : length of href.
+ */
+using AnchorClickedSignalType = Signal<void(TextLabel, const char*, uint32_t)>;
+
+/**
+ * @brief This signal is emitted when the anchor is clicked.
+ *
+ * A callback of the following type may be connected:
+ * @code
+ *   void YourCallbackName(TextLabel textLabel, const char* href, uint32_t hrefLength);
+ * @endcode
+ * @param[in] textLabel The instance of TextLabel.
+ * @return The signal to connect to.
+ */
+DALI_TOOLKIT_API AnchorClickedSignalType& AnchorClickedSignal(TextLabel textLabel);
+
 } // namespace DevelTextLabel
 
 } // namespace Toolkit
index 551066f..4080c90 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_TEXT_SELECTION_POPUP_H
 
 /*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -103,6 +103,12 @@ public:
       OPTION_DIVIDER_SIZE,
 
       /**
+       * @brief The padding of the divider between options.
+       * @details Name "optionDividerPadding", type Vector4.
+       */
+      OPTION_DIVIDER_PADDING,
+
+      /**
        * @brief The image to use as the popup clipboard icon.
        * @details Name "popupClipboardButtonImage", type string.
        */
index c72012c..413f5ca 100644 (file)
@@ -18,6 +18,9 @@
 // CLASS HEADER
 #include <dali-toolkit/devel-api/controls/web-view/web-context.h>
 
+// EXTERNAL INCLUDES
+#include <dali/devel-api/adaptor-framework/web-engine-security-origin.h>
+
 namespace Dali
 {
 namespace Toolkit
@@ -61,14 +64,39 @@ void WebContext::SetDefaultProxyAuth(const std::string& username, const std::str
   mWebEngineContext.SetDefaultProxyAuth(username, password);
 }
 
-void WebContext::DeleteWebDatabase()
+void WebContext::DeleteAllWebDatabase()
+{
+  mWebEngineContext.DeleteAllWebDatabase();
+}
+
+bool WebContext::GetWebDatabaseOrigins(Dali::WebEngineContext::WebEngineSecurityOriginAcquiredCallback callback)
 {
-  mWebEngineContext.DeleteWebDatabase();
+  return mWebEngineContext.GetWebDatabaseOrigins(callback);
 }
 
-void WebContext::DeleteWebStorage()
+bool WebContext::DeleteWebDatabase(Dali::WebEngineSecurityOrigin& origin)
 {
-  mWebEngineContext.DeleteWebStorage();
+  return mWebEngineContext.DeleteWebDatabase(origin);
+}
+
+bool WebContext::GetWebStorageOrigins(Dali::WebEngineContext::WebEngineSecurityOriginAcquiredCallback callback)
+{
+  return mWebEngineContext.GetWebStorageOrigins(callback);
+}
+
+bool WebContext::GetWebStorageUsageForOrigin(Dali::WebEngineSecurityOrigin& origin, Dali::WebEngineContext::WebEngineStorageUsageAcquiredCallback callback)
+{
+  return mWebEngineContext.GetWebStorageUsageForOrigin(origin, callback);
+}
+
+void WebContext::DeleteAllWebStorage()
+{
+  mWebEngineContext.DeleteAllWebStorage();
+}
+
+bool WebContext::DeleteWebStorageOrigin(Dali::WebEngineSecurityOrigin& origin)
+{
+  return mWebEngineContext.DeleteWebStorageOrigin(origin);
 }
 
 void WebContext::DeleteLocalFileSystem()
@@ -81,6 +109,25 @@ void WebContext::ClearCache()
   mWebEngineContext.ClearCache();
 }
 
-} // namespace Toolkit
+bool WebContext::DeleteApplicationCache(Dali::WebEngineSecurityOrigin& origin)
+{
+  return mWebEngineContext.DeleteApplicationCache(origin);
+}
+
+void WebContext::GetFormPasswordList(Dali::WebEngineContext::WebEngineFormPasswordAcquiredCallback callback)
+{
+  mWebEngineContext.GetFormPasswordList(callback);
+}
 
+void WebContext::RegisterDownloadStartedCallback(Dali::WebEngineContext::WebEngineDownloadStartedCallback callback)
+{
+  mWebEngineContext.RegisterDownloadStartedCallback(callback);
+}
+
+void WebContext::RegisterMimeOverriddenCallback(Dali::WebEngineContext::WebEngineMimeOverriddenCallback callback)
+{
+  mWebEngineContext.RegisterMimeOverriddenCallback(callback);
+}
+
+} // namespace Toolkit
 } // namespace Dali
old mode 100644 (file)
new mode 100755 (executable)
index ead4efd..cdf7f0e
@@ -27,6 +27,8 @@
 
 namespace Dali
 {
+class WebEngineSecurityOrigin;
+
 namespace Toolkit
 {
 /**
@@ -35,16 +37,16 @@ namespace Toolkit
  */
 
 /**
- * @brief WebContext is a control for settings of WebView.
+ * @brief WebContext is a control for context of WebView.
  *
- * For working WebContext, a WebView should be provided.
+ * For working WebContext, a WebEngineContext should be provided.
  *
  */
 class DALI_TOOLKIT_API WebContext
 {
 public:
   /**
-   * @brief Creates a WebContext.
+   * @brief Create a WebContext.
    *
    * @param[in] context The context of web engine.
    */
@@ -56,28 +58,28 @@ public:
   virtual ~WebContext() final;
 
   /**
-   * @brief Returns the cache model type.
+   * @brief Return the cache model type.
    *
    * @return #Dali::WebEngineContext::CacheModel
    */
   Dali::WebEngineContext::CacheModel GetCacheModel() const;
 
   /**
-   * @brief Requests to set the cache model.
+   * @brief Request to set the cache model.
    *
    * @param[in] cacheModel The cache model
    */
   void SetCacheModel(Dali::WebEngineContext::CacheModel cacheModel);
 
   /**
-   * @brief Sets the given proxy URI to network backend of specific context.
+   * @brief Set the given proxy URI to network backend of specific context.
    *
    * @param[in] uri The proxy URI to set
    */
   void SetProxyUri(const std::string& uri);
 
   /**
-   * Adds CA certificates to persistent NSS certificate database
+   * @brief Add CA certificates to persistent NSS certificate database
    *
    * Function accepts a path to a CA certificate file, a path to a directory
    * containing CA certificate files, or a colon-seprarated list of those.
@@ -89,7 +91,7 @@ public:
   void SetCertificateFilePath(const std::string& certificatePath);
 
   /**
-   * Toggles the cache to be enabled or disabled
+   * @brief Toggle the cache to be enabled or disabled
    *
    * Function works asynchronously.
    * By default the cache is disabled resulting in not storing network data on disk.
@@ -99,7 +101,7 @@ public:
   void DisableCache(bool cacheDisabled);
 
   /**
-   * @brief Sets a proxy auth credential to network backend of specific context.
+   * @brief Set a proxy auth credential to network backend of specific context.
    *
    * @param[in] username username to set
    * @param[in] password password to set
@@ -107,20 +109,66 @@ public:
   void SetDefaultProxyAuth(const std::string& username, const std::string& password);
 
   /**
-   * Requests for deleting all web databases.
+   * @brief Requests for deleting all web databases.
+   */
+  void DeleteAllWebDatabase();
+
+  /**
+   * @brief Request for getting web database origins.
+   *
+   * @param[in] callback callback called after getting web database origins
+   *
+   * @return true if succeeded, false otherwise
+   */
+  bool GetWebDatabaseOrigins(Dali::WebEngineContext::WebEngineSecurityOriginAcquiredCallback callback);
+
+  /**
+   * @brief Request for deleting web databases for origin.
+   *
+   * @param[in] origin database origin
+   *
+   * @return true if succeeded, false otherwise
+   */
+  bool DeleteWebDatabase(Dali::WebEngineSecurityOrigin& origin);
+
+  /**
+   * @brief Gets list of origins that is stored in web storage db.
+   *
+   * @param[in] callback callback called after getting web storage origins
+   *
+   * @return true if succeeded, false otherwise
    */
-  void DeleteWebDatabase();
+  bool GetWebStorageOrigins(Dali::WebEngineContext::WebEngineSecurityOriginAcquiredCallback callback);
 
   /**
-   * @brief Deletes web storage.
+   * @brief Get list of origins that is stored in web storage db.
+   *
+   * @param[in] origin storage origin
+   * @param[in] callback callback called after getting web storage origins
+   *
+   * @return true if succeeded, false otherwise
+   */
+  bool GetWebStorageUsageForOrigin(Dali::WebEngineSecurityOrigin& origin, Dali::WebEngineContext::WebEngineStorageUsageAcquiredCallback callback);
+
+  /**
+   * @brief Delete all web storage.
    *
    * @details This function does not ensure that all data will be removed.
    *          Should be used to extend free physical memory.
    */
-  void DeleteWebStorage();
+  void DeleteAllWebStorage();
 
   /**
-   * @brief Requests for deleting all local file systems.
+   * @brief Delete origin that is stored in web storage db.
+   *
+   * @param[in] origin origin of db
+   *
+   * @return true if succeeded, false otherwise
+   */
+  bool DeleteWebStorageOrigin(Dali::WebEngineSecurityOrigin& origin);
+
+  /**
+   * @brief Request for deleting all local file systems.
    */
   void DeleteLocalFileSystem();
 
@@ -129,6 +177,36 @@ public:
    */
   void ClearCache();
 
+  /**
+   * @brief Request for deleting web application cache for origin.
+   *
+   * @param[in] origin application cache origin
+   *
+   * @return true if succeeded, false otherwise
+   */
+  bool DeleteApplicationCache(Dali::WebEngineSecurityOrigin& origin);
+
+  /**
+   * @brief Asynchronous request to get list of all password data.
+   *
+   * @param[in] callback callback called after getting form password
+   */
+  void GetFormPasswordList(Dali::WebEngineContext::WebEngineFormPasswordAcquiredCallback callback);
+
+  /**
+   * @brief Register callback for download started.
+   *
+   * @param[in] callback callback for download started
+   */
+  void RegisterDownloadStartedCallback(Dali::WebEngineContext::WebEngineDownloadStartedCallback callback);
+
+  /**
+   * @brief Register callback for mime overridden.
+   *
+   * @param[in] callback callback for mime overridden
+   */
+  void RegisterMimeOverriddenCallback(Dali::WebEngineContext::WebEngineMimeOverriddenCallback callback);
+
 private:
   Dali::WebEngineContext& mWebEngineContext;
 };
old mode 100644 (file)
new mode 100755 (executable)
index a332e06..adb133a
@@ -37,7 +37,7 @@ namespace Toolkit
  */
 
 /**
- * @brief WebCookieManager is a control for settings of WebView.
+ * @brief WebCookieManager is a control for cookie manager of WebView.
  *
  *
  * For working WebCookieManager, a WebView should be provided.
diff --git a/dali-toolkit/devel-api/controls/web-view/web-form-repost-decision.cpp b/dali-toolkit/devel-api/controls/web-view/web-form-repost-decision.cpp
new file mode 100644 (file)
index 0000000..219d2ca
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali-toolkit/devel-api/controls/web-view/web-form-repost-decision.h>
+
+// EXTERNAL INCLUDES
+#include <dali/devel-api/adaptor-framework/web-engine-form-repost-decision.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+WebFormRepostDecision::WebFormRepostDecision(std::shared_ptr<Dali::WebEngineFormRepostDecision> decision)
+: mFormRepostDecision(std::move(decision))
+{
+}
+
+WebFormRepostDecision::~WebFormRepostDecision()
+{
+}
+
+void WebFormRepostDecision::Reply(bool allowed)
+{
+  if(mFormRepostDecision)
+  {
+    mFormRepostDecision->Reply(allowed);
+  }
+}
+
+} // namespace Toolkit
+
+} // namespace Dali
diff --git a/dali-toolkit/devel-api/controls/web-view/web-form-repost-decision.h b/dali-toolkit/devel-api/controls/web-view/web-form-repost-decision.h
new file mode 100755 (executable)
index 0000000..755fe57
--- /dev/null
@@ -0,0 +1,78 @@
+#ifndef DALI_TOOLKIT_WEB_FORM_REPOST_DECISION_H
+#define DALI_TOOLKIT_WEB_FORM_REPOST_DECISION_H
+
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <memory>
+#include <string>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/public-api/dali-toolkit-common.h>
+
+namespace Dali
+{
+class WebEngineFormRepostDecision;
+
+namespace Toolkit
+{
+/**
+ * @addtogroup dali_toolkit_controls_web_view
+ * @{
+ */
+
+/**
+ * @brief WebFormRepostDecision is a class for form repost decision of WebView.
+ *
+ *
+ * For working WebFormRepostDecision, a Dali::WebEngineFormRepostDecision should be provided.
+ *
+ */
+class DALI_TOOLKIT_API WebFormRepostDecision
+{
+public:
+  /**
+   * @brief Creates a WebFormRepostDecision.
+   */
+  WebFormRepostDecision(std::shared_ptr<Dali::WebEngineFormRepostDecision> decision);
+
+  /**
+   * @brief Destructor.
+   */
+  virtual ~WebFormRepostDecision() final;
+
+  /**
+   * @brief Reply the result about form repost decision.
+   *
+   * @param[in] allowed Whether allow form repost decision request or not
+   */
+  void Reply(bool allowed);
+
+private:
+  std::shared_ptr<Dali::WebEngineFormRepostDecision> mFormRepostDecision;
+};
+
+/**
+ * @}
+ */
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_WEB_FORM_REPOST_DECISION_H
old mode 100644 (file)
new mode 100755 (executable)
index 201f280..f73e9dc
@@ -104,11 +104,26 @@ void WebView::LoadHtmlString(const std::string& htmlString)
   Dali::Toolkit::GetImpl(*this).LoadHtmlString(htmlString);
 }
 
+bool WebView::LoadHtmlStringOverrideCurrentEntry(const std::string& html, const std::string& basicUri, const std::string& unreachableUrl)
+{
+  return Dali::Toolkit::GetImpl(*this).LoadHtmlStringOverrideCurrentEntry(html, basicUri, unreachableUrl);
+}
+
+bool WebView::LoadContents(const std::string& contents, uint32_t contentSize, const std::string& mimeType, const std::string& encoding, const std::string& baseUri)
+{
+  return Dali::Toolkit::GetImpl(*this).LoadContents(contents, contentSize, mimeType, encoding, baseUri);
+}
+
 void WebView::Reload()
 {
   Dali::Toolkit::GetImpl(*this).Reload();
 }
 
+bool WebView::ReloadWithoutCache()
+{
+  return Dali::Toolkit::GetImpl(*this).ReloadWithoutCache();
+}
+
 void WebView::StopLoading()
 {
   Dali::Toolkit::GetImpl(*this).StopLoading();
@@ -124,11 +139,46 @@ void WebView::Resume()
   Dali::Toolkit::GetImpl(*this).Resume();
 }
 
+void WebView::SuspendNetworkLoading()
+{
+  Dali::Toolkit::GetImpl(*this).SuspendNetworkLoading();
+}
+
+void WebView::ResumeNetworkLoading()
+{
+  Dali::Toolkit::GetImpl(*this).ResumeNetworkLoading();
+}
+
+bool WebView::AddCustomHeader(const std::string& name, const std::string& value)
+{
+  return Dali::Toolkit::GetImpl(*this).AddCustomHeader(name, value);
+}
+
+bool WebView::RemoveCustomHeader(const std::string& name)
+{
+  return Dali::Toolkit::GetImpl(*this).RemoveCustomHeader(name);
+}
+
+uint32_t WebView::StartInspectorServer(uint32_t port)
+{
+  return Dali::Toolkit::GetImpl(*this).StartInspectorServer(port);
+}
+
+bool WebView::StopInspectorServer()
+{
+  return Dali::Toolkit::GetImpl(*this).StopInspectorServer();
+}
+
 void WebView::ScrollBy(int deltaX, int deltaY)
 {
   Dali::Toolkit::GetImpl(*this).ScrollBy(deltaX, deltaY);
 }
 
+bool WebView::ScrollEdgeBy(int deltaX, int deltaY)
+{
+  return Dali::Toolkit::GetImpl(*this).ScrollEdgeBy(deltaX, deltaY);
+}
+
 bool WebView::CanGoForward()
 {
   return Dali::Toolkit::GetImpl(*this).CanGoForward();
@@ -164,34 +214,34 @@ void WebView::AddJavaScriptMessageHandler(const std::string& exposedObjectName,
   Dali::Toolkit::GetImpl(*this).AddJavaScriptMessageHandler(exposedObjectName, handler);
 }
 
-void WebView::RegisterJavaScriptAlertCallback( Dali::WebEnginePlugin::JavaScriptAlertCallback callback )
+void WebView::RegisterJavaScriptAlertCallback(Dali::WebEnginePlugin::JavaScriptAlertCallback callback)
 {
-  Dali::Toolkit::GetImpl( *this ).RegisterJavaScriptAlertCallback( callback );
+  Dali::Toolkit::GetImpl(*this).RegisterJavaScriptAlertCallback(callback);
 }
 
 void WebView::JavaScriptAlertReply()
 {
-  Dali::Toolkit::GetImpl( *this ).JavaScriptAlertReply();
+  Dali::Toolkit::GetImpl(*this).JavaScriptAlertReply();
 }
 
-void WebView::RegisterJavaScriptConfirmCallback( Dali::WebEnginePlugin::JavaScriptConfirmCallback callback )
+void WebView::RegisterJavaScriptConfirmCallback(Dali::WebEnginePlugin::JavaScriptConfirmCallback callback)
 {
-  Dali::Toolkit::GetImpl( *this ).RegisterJavaScriptConfirmCallback( callback );
+  Dali::Toolkit::GetImpl(*this).RegisterJavaScriptConfirmCallback(callback);
 }
 
-void WebView::JavaScriptConfirmReply( bool confirmed )
+void WebView::JavaScriptConfirmReply(bool confirmed)
 {
-  Dali::Toolkit::GetImpl( *this ).JavaScriptConfirmReply( confirmed );
+  Dali::Toolkit::GetImpl(*this).JavaScriptConfirmReply(confirmed);
 }
 
-void WebView::RegisterJavaScriptPromptCallback( Dali::WebEnginePlugin::JavaScriptPromptCallback callback )
+void WebView::RegisterJavaScriptPromptCallback(Dali::WebEnginePlugin::JavaScriptPromptCallback callback)
 {
-  Dali::Toolkit::GetImpl( *this ).RegisterJavaScriptPromptCallback( callback );
+  Dali::Toolkit::GetImpl(*this).RegisterJavaScriptPromptCallback(callback);
 }
 
-void WebView::JavaScriptPromptReply( const std::string& result )
+void WebView::JavaScriptPromptReply(const std::string& result)
 {
-  Dali::Toolkit::GetImpl( *this ).JavaScriptPromptReply( result );
+  Dali::Toolkit::GetImpl(*this).JavaScriptPromptReply(result);
 }
 
 void WebView::ClearHistory()
@@ -201,7 +251,52 @@ void WebView::ClearHistory()
 
 void WebView::ClearAllTilesResources()
 {
-  Dali::Toolkit::GetImpl( *this ).ClearAllTilesResources();
+  Dali::Toolkit::GetImpl(*this).ClearAllTilesResources();
+}
+
+void WebView::SetScaleFactor(float scaleFactor, Dali::Vector2 point)
+{
+  Dali::Toolkit::GetImpl(*this).SetScaleFactor(scaleFactor, point);
+}
+
+float WebView::GetScaleFactor() const
+{
+  return Dali::Toolkit::GetImpl(*this).GetScaleFactor();
+}
+
+void WebView::ActivateAccessibility(bool activated)
+{
+  Dali::Toolkit::GetImpl(*this).ActivateAccessibility(activated);
+}
+
+bool WebView::HighlightText(const std::string& text, Dali::WebEnginePlugin::FindOption options, uint32_t maxMatchCount)
+{
+  return Dali::Toolkit::GetImpl(*this).HighlightText(text, options, maxMatchCount);
+}
+
+void WebView::AddDynamicCertificatePath(const std::string& host, const std::string& certPath)
+{
+  Dali::Toolkit::GetImpl(*this).AddDynamicCertificatePath(host, certPath);
+}
+
+Dali::Toolkit::ImageView WebView::GetScreenshot(Dali::Rect<int> viewArea, float scaleFactor)
+{
+  return Dali::Toolkit::GetImpl(*this).GetScreenshot(viewArea, scaleFactor);
+}
+
+bool WebView::GetScreenshotAsynchronously(Dali::Rect<int> viewArea, float scaleFactor, Dali::Toolkit::WebView::WebViewScreenshotCapturedCallback callback)
+{
+  return Dali::Toolkit::GetImpl(*this).GetScreenshotAsynchronously(viewArea, scaleFactor, callback);
+}
+
+bool WebView::CheckVideoPlayingAsynchronously(Dali::WebEnginePlugin::VideoPlayingCallback callback)
+{
+  return Dali::Toolkit::GetImpl(*this).CheckVideoPlayingAsynchronously(callback);
+}
+
+void WebView::RegisterGeolocationPermissionCallback(Dali::WebEnginePlugin::GeolocationPermissionCallback callback)
+{
+  Dali::Toolkit::GetImpl(*this).RegisterGeolocationPermissionCallback(callback);
 }
 
 WebView::WebViewPageLoadSignalType& WebView::PageLoadStartedSignal()
@@ -211,7 +306,7 @@ WebView::WebViewPageLoadSignalType& WebView::PageLoadStartedSignal()
 
 WebView::WebViewPageLoadSignalType& WebView::PageLoadInProgressSignal()
 {
-  return Dali::Toolkit::GetImpl( *this ).PageLoadInProgressSignal();
+  return Dali::Toolkit::GetImpl(*this).PageLoadInProgressSignal();
 }
 
 WebView::WebViewPageLoadSignalType& WebView::PageLoadFinishedSignal()
@@ -231,7 +326,57 @@ WebView::WebViewScrollEdgeReachedSignalType& WebView::ScrollEdgeReachedSignal()
 
 WebView::WebViewUrlChangedSignalType& WebView::UrlChangedSignal()
 {
-  return Dali::Toolkit::GetImpl( *this ).UrlChangedSignal();
+  return Dali::Toolkit::GetImpl(*this).UrlChangedSignal();
+}
+
+WebView::WebViewFormRepostDecisionSignalType& WebView::FormRepostDecisionSignal()
+{
+  return Dali::Toolkit::GetImpl(*this).FormRepostDecisionSignal();
+}
+
+WebView::WebViewFrameRenderedSignalType& WebView::FrameRenderedSignal()
+{
+  return Dali::Toolkit::GetImpl(*this).FrameRenderedSignal();
+}
+
+WebView::WebViewRequestInterceptorSignalType& WebView::RequestInterceptorSignal()
+{
+  return Dali::Toolkit::GetImpl(*this).RequestInterceptorSignal();
+}
+
+WebView::WebViewConsoleMessageSignalType& WebView::ConsoleMessageSignal()
+{
+  return Dali::Toolkit::GetImpl(*this).ConsoleMessageSignal();
+}
+
+WebView::WebViewPolicyDecisionSignalType& WebView::PolicyDecisionSignal()
+{
+  return Dali::Toolkit::GetImpl(*this).PolicyDecisionSignal();
+}
+
+WebView::WebViewCertificateSignalType& WebView::CertificateConfirmSignal()
+{
+  return Dali::Toolkit::GetImpl(*this).CertificateConfirmSignal();
+}
+
+WebView::WebViewCertificateSignalType& WebView::SslCertificateChangedSignal()
+{
+  return Dali::Toolkit::GetImpl(*this).SslCertificateChangedSignal();
+}
+
+WebView::WebViewHttpAuthHandlerSignalType& WebView::HttpAuthHandlerSignal()
+{
+  return Dali::Toolkit::GetImpl(*this).HttpAuthHandlerSignal();
+}
+
+WebView::WebViewContextMenuCustomizedSignalType& WebView::ContextMenuCustomizedSignal()
+{
+  return Dali::Toolkit::GetImpl(*this).ContextMenuCustomizedSignal();
+}
+
+WebView::WebViewContextMenuItemSelectedSignalType& WebView::ContextMenuItemSelectedSignal()
+{
+  return Dali::Toolkit::GetImpl(*this).ContextMenuItemSelectedSignal();
 }
 
 WebView::WebView(Internal::WebView& implementation)
old mode 100644 (file)
new mode 100755 (executable)
index d347824..6d8d3b9
@@ -20,6 +20,7 @@
 
 // EXTERNAL INCLUDES
 #include <functional>
+#include <memory>
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/public-api/controls/control.h>
@@ -32,7 +33,10 @@ namespace Toolkit
 class ImageView;
 class WebBackForwardList;
 class WebContext;
+class WebContextMenu;
+class WebContextMenuItem;
 class WebCookieManager;
+class WebFormRepostDecision;
 class WebSettings;
 
 namespace Internal DALI_INTERNAL
@@ -131,30 +135,63 @@ public:
        * @note Default is true.
        */
       KEY_EVENTS_ENABLED,
+
+      /**
+       * @brief The background color of web page.
+       * @details name "documentBackgroundColor", type Property::VECTOR4.
+       */
+      DOCUMENT_BACKGROUND_COLOR,
+
+      /**
+       * @brief Whether tiles can be cleared or not when hidden.
+       * @details name "tilesClearedWhenHidden", type BOOLEAN.
+       */
+      TILES_CLEARED_WHEN_HIDDEN,
+
+      /**
+       * @brief The multiplier of cover area of tile when rendering web page.
+       * @details name "tileCoverAreaMultiplier", type FLOAT.
+       */
+      TILE_COVER_AREA_MULTIPLIER,
+
+      /**
+       * @brief Whether cursor is enabled or not by client.
+       * @details name "cursorEnabledByClient", type BOOLEAN.
+       */
+      CURSOR_ENABLED_BY_CLIENT,
+
+      /**
+       * @brief The selected text of web page.
+       * @details name "selectedText", type Property::STRING.
+       * @note The value is read-only.
+       */
+      SELECTED_TEXT,
+
+      /**
+       * @brief Zoom factor of web page.
+       * @details name "pageZoomFactor", type Property::FLOAT.
+       */
+      PAGE_ZOOM_FACTOR,
+
+      /**
+       * @brief Zoom factor of text.
+       * @details name "textZoomFactor", type Property::FLOAT.
+       */
+      TEXT_ZOOM_FACTOR,
+
+      /**
+       * @brief progress percentage of loading a web page.
+       * @details name "loadProgressPercentage", type Property::FLOAT.
+       * @note The value is read-only.
+       */
+      LOAD_PROGRESS_PERCENTAGE,
     };
   };
 
   /**
-   * @brief Enumeration for indicating error code of page loading.
+   * @brief WebView callback related with screen-shot captured.
    */
-  enum class LoadErrorCode
-  {
-    UNKNOWN = 0,           ///< Unknown.
-    CANCELED,              ///< User canceled.
-    CANT_SUPPORT_MIMETYPE, ///< Can't show the page for this MIME type.
-    FAILED_FILE_IO,        ///< File IO error.
-    CANT_CONNECT,          ///< Cannot connect to the network.
-    CANT_LOOKUP_HOST,      ///< Fail to look up host from the DNS.
-    FAILED_TLS_HANDSHAKE,  ///< Fail to SSL/TLS handshake.
-    INVALID_CERTIFICATE,   ///< Received certificate is invalid.
-    REQUEST_TIMEOUT,       ///< Connection timeout.
-    TOO_MANY_REDIRECTS,    ///< Too many redirects.
-    TOO_MANY_REQUESTS,     ///< Too many requests during this load.
-    BAD_URL,               ///< Malformed URL.
-    UNSUPPORTED_SCHEME,    ///< Unsupported scheme.
-    AUTHENTICATION,        ///< User authentication failed on the server.
-    INTERNAL_SERVER        ///< Web server has an internal server error.
-  };
+  using WebViewScreenshotCapturedCallback = std::function<void(Dali::Toolkit::ImageView)>;
 
   /**
    * @brief WebView signal type related with page loading.
@@ -164,7 +201,7 @@ public:
   /**
    * @brief WebView signal type related with page loading error.
    */
-  using WebViewPageLoadErrorSignalType = Signal<void(WebView, const std::string&, LoadErrorCode)>;
+  using WebViewPageLoadErrorSignalType = Signal<void(WebView, std::shared_ptr<Dali::WebEngineLoadError>)>;
 
   /**
    * @brief WebView signal type related with scroll edge reached.
@@ -176,6 +213,51 @@ public:
    */
   using WebViewUrlChangedSignalType = Signal<void(WebView, const std::string&)>;
 
+  /**
+   * @brief WebView signal type related with form repost decision.
+   */
+  using WebViewFormRepostDecisionSignalType = Signal<void(WebView, std::shared_ptr<Dali::Toolkit::WebFormRepostDecision>)>;
+
+  /**
+   * @brief WebView signal type related with frame rendered.
+   */
+  using WebViewFrameRenderedSignalType = Signal<void(WebView)>;
+
+  /**
+   * @brief WebView signal type related with http request interceptor.
+   */
+  using WebViewRequestInterceptorSignalType = Signal<void(WebView, std::shared_ptr<Dali::WebEngineRequestInterceptor>)>;
+
+  /**
+   * @brief WebView signal type related with console message.
+   */
+  using WebViewConsoleMessageSignalType = Signal<void(WebView, std::shared_ptr<Dali::WebEngineConsoleMessage>)>;
+
+  /**
+   * @brief WebView signal type related with policy decision.
+   */
+  using WebViewPolicyDecisionSignalType = Signal<void(WebView, std::shared_ptr<Dali::WebEnginePolicyDecision>)>;
+
+  /**
+   * @brief WebView signal type related with certificate changed.
+   */
+  using WebViewCertificateSignalType = Signal<void(WebView, std::shared_ptr<Dali::WebEngineCertificate>)>;
+
+  /**
+   * @brief WebView signal type related with http authentication.
+   */
+  using WebViewHttpAuthHandlerSignalType = Signal<void(WebView, std::shared_ptr<Dali::WebEngineHttpAuthHandler>)>;
+
+  /**
+   * @brief WebView signal type related with context menu customized.
+   */
+  using WebViewContextMenuCustomizedSignalType = Signal<void(WebView, std::shared_ptr<Dali::WebEngineContextMenu>)>;
+
+  /**
+   * @brief WebView signal type related with context menu item selected.
+   */
+  using WebViewContextMenuItemSelectedSignalType = Signal<void(WebView, std::shared_ptr<Dali::WebEngineContextMenuItem>)>;
+
 public:
   /**
    * @brief Creates an initialized WebView.
@@ -281,11 +363,40 @@ public:
   void LoadHtmlString(const std::string& htmlString);
 
   /**
+   * @brief Load the specified html string as the content of the view overriding current history entry
+   *
+   * @param[in] html HTML data to load
+   * @param[in] basicUri Base URL used for relative paths to external objects
+   * @param[in] unreachableUrl URL that could not be reached
+   *
+   * @return true if successfully loaded, false otherwise
+   */
+  bool LoadHtmlStringOverrideCurrentEntry(const std::string& html, const std::string& basicUri, const std::string& unreachableUrl);
+
+  /**
+   * @brief Requests loading the given contents by MIME type into the view object
+   *
+   * @param[in] contents The content to load
+   * @param[in] contentSize The size of contents (in bytes)
+   * @param[in] mimeType The type of contents, if 0 is given "text/html" is assumed
+   * @param[in] encoding The encoding for contents, if 0 is given "UTF-8" is assumed
+   * @param[in] baseUri The base URI to use for relative resources
+   *
+   * @return true if successfully request, false otherwise
+   */
+  bool LoadContents(const std::string& contents, uint32_t contentSize, const std::string& mimeType, const std::string& encoding, const std::string& baseUri);
+
+  /**
    * @brief Reloads the Web.
    */
   void Reload();
 
   /**
+   * @brief Reloads the current page's document without cache
+   */
+  bool ReloadWithoutCache();
+
+  /**
    * @brief Stops loading web contents on the current page.
    */
   void StopLoading();
@@ -301,13 +412,68 @@ public:
   void Resume();
 
   /**
-   * @brief Scrolls the webpage of view by deltaX and deltaY.
+   * @brief To suspend all url loading
+   */
+  void SuspendNetworkLoading();
+
+  /**
+   * @brief To resume new url network loading
+   */
+  void ResumeNetworkLoading();
+
+  /**
+   * @brief Add custom header
+   *
+   * @param[in] name custom header name to add the custom header
+   * @param[in] value custom header value to add the custom header
+   *
+   * @return true if succeeded, false otherwise
+   */
+  bool AddCustomHeader(const std::string& name, const std::string& value);
+
+  /**
+   * @brief Remove custom header
+   *
+   * @param[in] name custom header name to remove the custom header
+   *
+   * @return true if succeeded, false otherwise
+   */
+  bool RemoveCustomHeader(const std::string& name);
+
+  /**
+   * @brief Start the inspector server
+   *
+   * @param[in] port port number
+   *
+   * @return the port number
+   */
+  uint32_t StartInspectorServer(uint32_t port);
+
+  /**
+   * @brief Stop the inspector server
+   *
+   * @return true if succeeded, false otherwise
+   */
+  bool StopInspectorServer();
+
+  /**
+   * @brief Scrolls web page of view by deltaX and deltaY.
    * @param[in] deltaX The delta x of scroll
    * @param[in] deltaY The delta y of scroll
    */
   void ScrollBy(int deltaX, int deltaY);
 
   /**
+   * @brief Scrolls edge of view by deltaX and deltaY.
+   *
+   * @param[in] deltaX horizontal offset to scroll
+   * @param[in] deltaY vertical offset to scroll
+   *
+   * @return true if succeeded, false otherwise
+   */
+  bool ScrollEdgeBy(int deltaX, int deltaY);
+
+  /**
    * @brief Returns whether forward is possible.
    *
    * @return True if forward is possible, false otherwise
@@ -335,7 +501,7 @@ public:
    * @brief Evaluates JavaScript code represented as a string.
    *
    * @param[in] script The JavaScript code
-   * @param[in] resultHandler The callback function to be called by the JavaScript runtime. This carries evaluation result.
+   * @param[in] resultHandler The callback function to be called by the JavaScript runtime. This carries evaluation result
    */
   void EvaluateJavaScript(const std::string& script, std::function<void(const std::string&)> resultHandler);
 
@@ -421,47 +587,190 @@ public:
   void ClearAllTilesResources();
 
   /**
-   * @brief Connects to this signal to be notified when page loading is started.
+   * @brief Scales the current page, centered at the given point.
+   * @param[in] scaleFactor a new factor to be scaled.
+   * @param[in] point a center coordinate.
+   */
+  void SetScaleFactor(float scaleFactor, Dali::Vector2 point);
+
+  /**
+   * @brief Gets the current scale factor of the page.
+   * @return The current scale factor.
+   */
+  float GetScaleFactor() const;
+
+  /**
+   * @brief Request to activate/deactivate the accessibility usage set by web app.
+   * @param[in] activated Activate accessibility or not.
+   */
+  void ActivateAccessibility(bool activated);
+
+  /**
+   * @brief Searches and highlights the given string in the document.
+   * @param[in] text The text to find
+   * @param[in] options The options to find
+   * @param[in] maxMatchCount The maximum match count to find
+   *
+   * @return true if found & highlighted, false otherwise
+   */
+  bool HighlightText(const std::string& text, Dali::WebEnginePlugin::FindOption options, uint32_t maxMatchCount);
+
+  /**
+   * @brief Add dynamic certificate path.
+   * @param[in] host host that required client authentication
+   * @param[in] certPath the file path stored certificate
+   */
+  void AddDynamicCertificatePath(const std::string& host, const std::string& certPath);
+
+  /**
+   * @brief Get snapshot of the specified viewArea of page.
+   *
+   * @param[in] viewArea The rectangle of screen shot
+   * @param[in] scaleFactor The scale factor
+   *
+   * @return image view of screen shot
+   */
+  Dali::Toolkit::ImageView GetScreenshot(Dali::Rect<int> viewArea, float scaleFactor);
+
+  /**
+   * @brief Request to get snapshot of the specified viewArea of page asynchronously.
+   *
+   * @param[in] viewArea The rectangle of screen shot
+   * @param[in] scaleFactor The scale factor
+   * @param[in] callback The callback for screen shot
+   *
+   * @return true if requested successfully, false otherwise
+   */
+  bool GetScreenshotAsynchronously(Dali::Rect<int> viewArea, float scaleFactor, WebViewScreenshotCapturedCallback callback);
+
+  /**
+   * @brief Asynchronous request to check if there is a video playing in the given view.
+   *
+   * @param[in] callback The callback called after checking if video is playing or not
+   *
+   * @return true if requested successfully, false otherwise
+   */
+  bool CheckVideoPlayingAsynchronously(Dali::WebEnginePlugin::VideoPlayingCallback callback);
+
+  /**
+   * @brief Set callback which will be called upon geolocation permission request.
+   *
+   * @param[in] callback The callback for requesting geolocation permission
+   */
+  void RegisterGeolocationPermissionCallback(Dali::WebEnginePlugin::GeolocationPermissionCallback callback);
+
+  /**
+   * @brief Connect to this signal to be notified when page loading is started.
    *
    * @return A signal object to connect with
    */
   WebViewPageLoadSignalType& PageLoadStartedSignal();
 
   /**
-   * @brief Connects to this signal to be notified when page loading is in progress.
+   * @brief Connect to this signal to be notified when page loading is in progress.
    *
-   * @return A signal object to connect with.
+   * @return A signal object to connect with
    */
   WebViewPageLoadSignalType& PageLoadInProgressSignal();
 
   /**
-   * @brief Connects to this signal to be notified when page loading is finished.
+   * @brief Connect to this signal to be notified when page loading is finished.
    *
    * @return A signal object to connect with
    */
   WebViewPageLoadSignalType& PageLoadFinishedSignal();
 
   /**
-   * @brief Connects to this signal to be notified when an error occurs in page loading.
+   * @brief Connect to this signal to be notified when an error occurs in page loading.
    *
-   * @return A signal object to connect with.
+   * @return A signal object to connect with
    */
   WebViewPageLoadErrorSignalType& PageLoadErrorSignal();
 
   /**
-   * @brief Connects to this signal to be notified when scroll edge is reached.
+   * @brief Connect to this signal to be notified when scroll edge is reached.
    *
-   * @return A signal object to connect with.
+   * @return A signal object to connect with
    */
   WebViewScrollEdgeReachedSignalType& ScrollEdgeReachedSignal();
 
   /**
-   * @brief Connects to this signal to be notified when url is changed.
+   * @brief Connect to this signal to be notified when url is changed.
    *
-   * @return A signal object to connect with.
+   * @return A signal object to connect with
    */
   WebViewUrlChangedSignalType& UrlChangedSignal();
 
+  /**
+   * @brief Connect to this signal to be notified when form repost decision is requested.
+   *
+   * @return A signal object to connect with.
+   */
+  WebViewFormRepostDecisionSignalType& FormRepostDecisionSignal();
+
+  /**
+   * @brief Connect to this signal to be notified when frame is rendered.
+   *
+   * @return A signal object to connect with.
+   */
+  WebViewFrameRenderedSignalType& FrameRenderedSignal();
+
+  /**
+   * @brief Connect to this signal to be notified when http request need be intercepted.
+   *
+   * @return A signal object to connect with.
+   */
+  WebViewRequestInterceptorSignalType& RequestInterceptorSignal();
+
+  /**
+   * @brief Connect to this signal to be notified when console message will be logged.
+   *
+   * @return A signal object to connect with.
+   */
+  WebViewConsoleMessageSignalType& ConsoleMessageSignal();
+
+  /**
+   * @brief Connect to this signal to be notified when new policy would be decided.
+   *
+   * @return A signal object to connect with.
+   */
+  WebViewPolicyDecisionSignalType& PolicyDecisionSignal();
+
+  /**
+   * @brief Connect to this signal to be notified when certificate need be confirmed.
+   *
+   * @return A signal object to connect with.
+   */
+  WebViewCertificateSignalType& CertificateConfirmSignal();
+
+  /**
+   * @brief Connect to this signal to be notified when ssl certificate is changed.
+   *
+   * @return A signal object to connect with.
+   */
+  WebViewCertificateSignalType& SslCertificateChangedSignal();
+
+  /**
+   * @brief Connect to this signal to be notified when http authentication need be confirmed.
+   *
+   * @return A signal object to connect with.
+   */
+  WebViewHttpAuthHandlerSignalType& HttpAuthHandlerSignal();
+
+  /**
+   * @brief Connect to this signal to be notified when context menu would be customized.
+   *
+   * @return A signal object to connect with.
+   */
+  WebViewContextMenuCustomizedSignalType& ContextMenuCustomizedSignal();
+
+  /**
+   * @brief Connect to this signal to be notified when context menu item is selected.
+   *
+   * @return A signal object to connect with.
+   */
+  WebViewContextMenuItemSelectedSignalType& ContextMenuItemSelectedSignal();
+
 public: // Not intended for application developers
   /// @cond internal
   /**
index 0e1ec7d..5516ac8 100755 (executable)
@@ -10,6 +10,7 @@ SET( devel_api_src_files
   ${devel_api_src_dir}/builder/json-parser.cpp
   ${devel_api_src_dir}/builder/tree-node.cpp
   ${devel_api_src_dir}/controls/accessible-impl.cpp
+  ${devel_api_src_dir}/controls/canvas-view/canvas-view.cpp
   ${devel_api_src_dir}/controls/control-devel.cpp
   ${devel_api_src_dir}/controls/control-wrapper.cpp
   ${devel_api_src_dir}/controls/control-wrapper-impl.cpp
@@ -33,6 +34,7 @@ SET( devel_api_src_files
   ${devel_api_src_dir}/controls/table-view/table-view.cpp
   ${devel_api_src_dir}/controls/text-controls/text-editor-devel.cpp
   ${devel_api_src_dir}/controls/text-controls/text-field-devel.cpp
+  ${devel_api_src_dir}/controls/text-controls/text-label-devel.cpp
   ${devel_api_src_dir}/controls/text-controls/text-selection-popup.cpp
   ${devel_api_src_dir}/controls/text-controls/text-selection-toolbar.cpp
   ${devel_api_src_dir}/controls/tool-bar/tool-bar.cpp
@@ -41,6 +43,7 @@ SET( devel_api_src_files
   ${devel_api_src_dir}/controls/web-view/web-back-forward-list-item.cpp
   ${devel_api_src_dir}/controls/web-view/web-context.cpp
   ${devel_api_src_dir}/controls/web-view/web-cookie-manager.cpp
+  ${devel_api_src_dir}/controls/web-view/web-form-repost-decision.cpp
   ${devel_api_src_dir}/controls/web-view/web-settings.cpp
   ${devel_api_src_dir}/controls/web-view/web-view.cpp
   ${devel_api_src_dir}/focus-manager/keyinput-focus-manager.cpp
@@ -83,6 +86,7 @@ SET( devel_api_accessibility-manager_header_files
 
 SET( devel_api_controls_header_files
   ${devel_api_src_dir}/controls/accessible-impl.h
+  ${devel_api_src_dir}/controls/canvas-view/canvas-view.h
   ${devel_api_src_dir}/controls/control-depth-index-ranges.h
   ${devel_api_src_dir}/controls/control-devel.h
   ${devel_api_src_dir}/controls/control-wrapper.h
@@ -256,6 +260,7 @@ SET( devel_api_web_view_header_files
   ${devel_api_src_dir}/controls/web-view/web-back-forward-list-item.h
   ${devel_api_src_dir}/controls/web-view/web-context.h
   ${devel_api_src_dir}/controls/web-view/web-cookie-manager.h
+  ${devel_api_src_dir}/controls/web-view/web-form-repost-decision.h
   ${devel_api_src_dir}/controls/web-view/web-settings.h
   ${devel_api_src_dir}/controls/web-view/web-view.h
 )
index 0112e32..1441dc4 100644 (file)
@@ -172,7 +172,8 @@ void ShapeTextPreprocess(const RendererParameters& textParameters, TextAbstracti
 
   MarkupProcessData markupProcessData(colorRuns,
                                       fontDescriptionRuns,
-                                      textModel->mLogicalModel->mEmbeddedItems);
+                                      textModel->mLogicalModel->mEmbeddedItems,
+                                      textModel->mLogicalModel->mAnchors);
 
   if(textParameters.markupEnabled)
   {
index 2b830fa..54cf75f 100644 (file)
@@ -1306,7 +1306,7 @@ Padding Button::GetForegroundPadding()
 std::string Button::AccessibleImpl::GetNameRaw()
 {
   std::string   labelText;
-  auto          slf      = Toolkit::Button::DownCast(self);
+  auto          slf      = Toolkit::Button::DownCast(Self());
   Property::Map labelMap = slf.GetProperty<Property::Map>(Toolkit::Button::Property::LABEL);
 
   Property::Value* textPropertyPtr = labelMap.Find(Toolkit::TextVisual::Property::TEXT);
@@ -1321,7 +1321,7 @@ std::string Button::AccessibleImpl::GetNameRaw()
 Property::Index Button::AccessibleImpl::GetNamePropertyIndex()
 {
   Property::Index label    = Toolkit::Button::Property::LABEL;
-  Property::Map   labelMap = self.GetProperty<Property::Map>(label);
+  Property::Map   labelMap = Self().GetProperty<Property::Map>(label);
 
   if(MapContainsTextString(labelMap))
     return label;
@@ -1333,7 +1333,7 @@ Dali::Accessibility::States Button::AccessibleImpl::CalculateStates()
 {
   auto tmp                                    = DevelControl::AccessibleImpl::CalculateStates();
   tmp[Dali::Accessibility::State::SELECTABLE] = true;
-  auto slf                                    = Toolkit::Button::DownCast(self);
+  auto slf                                    = Toolkit::Button::DownCast(Self());
   tmp[Dali::Accessibility::State::ENABLED]    = !slf.GetProperty<bool>(Toolkit::Button::Property::DISABLED);
   tmp[Dali::Accessibility::State::CHECKED]    = slf.GetProperty<bool>(Toolkit::Button::Property::SELECTED);
   return tmp;
index c01b2f2..8308ce1 100644 (file)
@@ -86,7 +86,7 @@ void CheckBoxButton::OnInitialize()
 Dali::Accessibility::States CheckBoxButton::AccessibleImpl::CalculateStates()
 {
   auto tmp = Button::AccessibleImpl::CalculateStates();
-  auto slf = Toolkit::Button::DownCast(self);
+  auto slf = Toolkit::Button::DownCast(Self());
   if(slf.GetProperty<bool>(Toolkit::Button::Property::SELECTED))
     tmp[Dali::Accessibility::State::CHECKED] = true;
   return tmp;
index ee9f9f1..2dc4385 100644 (file)
@@ -197,7 +197,7 @@ Property::Value PushButton::GetProperty(BaseObject* object, Property::Index prop
 Dali::Accessibility::States PushButton::AccessibleImpl::CalculateStates()
 {
   auto tmp                                 = Button::AccessibleImpl::CalculateStates();
-  auto slf                                 = Toolkit::Button::DownCast(self);
+  auto slf                                 = Toolkit::Button::DownCast(Self());
   tmp[Dali::Accessibility::State::PRESSED] = slf.GetProperty<bool>(Toolkit::Button::Property::SELECTED);
   return tmp;
 }
index aae430b..f17a8c9 100644 (file)
@@ -115,7 +115,7 @@ void RadioButton::OnStateChange(State newState)
 Dali::Accessibility::States RadioButton::AccessibleImpl::CalculateStates()
 {
   auto tmp = Button::AccessibleImpl::CalculateStates();
-  auto slf = Toolkit::Button::DownCast(self);
+  auto slf = Toolkit::Button::DownCast(Self());
   if(slf.GetProperty<bool>(Toolkit::Button::Property::SELECTED))
     tmp[Dali::Accessibility::State::CHECKED] = true;
   tmp[Dali::Accessibility::State::SELECTABLE] = true;
index 8ec931f..311f6b3 100644 (file)
@@ -375,7 +375,7 @@ void ToggleButton::OnPressed()
 Dali::Accessibility::States ToggleButton::AccessibleImpl::CalculateStates()
 {
   auto states = Button::AccessibleImpl::CalculateStates();
-  auto button = Toolkit::ToggleButton::DownCast(self);
+  auto button = Toolkit::ToggleButton::DownCast(Self());
   if(button.GetProperty<int>(Toolkit::ToggleButton::Property::CURRENT_STATE_INDEX))
     states[Dali::Accessibility::State::CHECKED] = true;
   return states;
@@ -383,7 +383,7 @@ Dali::Accessibility::States ToggleButton::AccessibleImpl::CalculateStates()
 
 std::string ToggleButton::AccessibleImpl::GetDescriptionRaw()
 {
-  auto button   = Toolkit::ToggleButton::DownCast(self);
+  auto button   = Toolkit::ToggleButton::DownCast(Self());
   auto index    = button.GetProperty<int>(Toolkit::ToggleButton::Property::CURRENT_STATE_INDEX);
   auto tooltips = button.GetProperty<Property::Array>(Toolkit::ToggleButton::Property::TOOLTIPS);
 
diff --git a/dali-toolkit/internal/controls/canvas-view/canvas-view-impl.cpp b/dali-toolkit/internal/controls/canvas-view/canvas-view-impl.cpp
new file mode 100644 (file)
index 0000000..07c77d9
--- /dev/null
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include "canvas-view-impl.h"
+
+// EXTERNAL INCLUDES
+#include <dali/devel-api/scripting/scripting.h>
+#include <dali/integration-api/adaptor-framework/adaptor.h>
+#include <dali/public-api/object/type-registry-helper.h>
+#include <dali/public-api/object/type-registry.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/devel-api/controls/canvas-view/canvas-view.h>
+#include <dali-toolkit/devel-api/controls/control-devel.h>
+#include <dali-toolkit/internal/controls/control/control-data-impl.h>
+#include <dali-toolkit/internal/graphics/builtin-shader-extern-gen.h>
+#include <dali-toolkit/internal/visuals/visual-factory-cache.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Internal
+{
+namespace
+{
+BaseHandle Create()
+{
+  return BaseHandle();
+}
+// Setup properties, signals and actions using the type-registry.
+DALI_TYPE_REGISTRATION_BEGIN(Toolkit::CanvasView, Toolkit::Control, Create);
+DALI_TYPE_REGISTRATION_END()
+} // anonymous namespace
+
+using namespace Dali;
+
+CanvasView::CanvasView(const Vector2& viewBox)
+: Control(ControlBehaviour(CONTROL_BEHAVIOUR_DEFAULT)),
+  mCanvasRenderer(CanvasRenderer::New(viewBox)),
+  mTexture(),
+  mChanged(false)
+{
+}
+
+CanvasView::~CanvasView()
+{
+  if(Adaptor::IsAvailable())
+  {
+    Adaptor::Get().UnregisterProcessor(*this);
+  }
+}
+
+Toolkit::CanvasView CanvasView::New(const Vector2& viewBox)
+{
+  CanvasView* impl = new CanvasView(viewBox);
+
+  Toolkit::CanvasView handle = Toolkit::CanvasView(*impl);
+
+  // Second-phase init of the implementation
+  // This can only be done after the CustomActor connection has been made...
+  impl->Initialize();
+
+  return handle;
+}
+
+/////////////////////////////////////////////////////////////
+
+void CanvasView::OnInitialize()
+{
+  // CanvasView can relayout in the OnImageReady, alternative to a signal would be to have a upcall from the Control to CanvasView
+  Dali::Toolkit::Control handle(GetOwner());
+
+  DevelControl::SetAccessibilityConstructor(Self(), [](Dali::Actor actor) {
+    return std::unique_ptr<Dali::Accessibility::Accessible>(
+      new DevelControl::AccessibleImpl(actor, Dali::Accessibility::Role::IMAGE));
+  });
+
+  Self().SetProperty(Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, true);
+
+  Adaptor::Get().RegisterProcessor(*this);
+}
+
+void CanvasView::OnRelayout(const Vector2& size, RelayoutContainer& container)
+{
+  if(!mCanvasRenderer ||
+     mCanvasRenderer.GetSize() == size ||
+     !mCanvasRenderer.SetSize(size))
+  {
+    return;
+  }
+  mChanged = true;
+}
+
+void CanvasView::OnSizeSet(const Vector3& targetSize)
+{
+  Control::OnSizeSet(targetSize);
+
+  if(!mCanvasRenderer ||
+     mCanvasRenderer.GetSize() == Vector2(targetSize) ||
+     !mCanvasRenderer.SetSize(Vector2(targetSize)))
+  {
+    return;
+  }
+  mChanged = true;
+}
+
+void CanvasView::Process()
+{
+  if(!mCanvasRenderer)
+  {
+    return;
+  }
+  Commit();
+}
+
+void CanvasView::Commit()
+{
+  if(mCanvasRenderer && mCanvasRenderer.Commit())
+  {
+    Devel::PixelBuffer pixbuf = mCanvasRenderer.GetPixelBuffer();
+    auto               width  = pixbuf.GetWidth();
+    auto               height = pixbuf.GetHeight();
+
+    Dali::PixelData pixelData = Devel::PixelBuffer::Convert(pixbuf);
+    if(!pixelData)
+    {
+      return;
+    }
+
+    if(!mTexture || mChanged)
+    {
+      mTexture = Texture::New(TextureType::TEXTURE_2D, Dali::Pixel::RGBA8888, width, height);
+      mTexture.Upload(pixelData);
+      TextureSet textureSet = TextureSet::New();
+      textureSet.SetTexture(0, mTexture);
+      Geometry geometry = VisualFactoryCache::CreateQuadGeometry();
+      Shader   shader   = Shader::New(SHADER_CANVAS_VIEW_VERT, SHADER_CANVAS_VIEW_FRAG);
+      Renderer renderer = Renderer::New(geometry, shader);
+      renderer.SetTextures(textureSet);
+      renderer.SetProperty(Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA, true);
+
+      Self().AddRenderer(renderer);
+      mChanged = false;
+    }
+    else
+    {
+      //Update texture
+      mTexture.Upload(pixelData);
+    }
+  }
+}
+
+bool CanvasView::AddDrawable(Dali::CanvasRenderer::Drawable& drawable)
+{
+  if(mCanvasRenderer && mCanvasRenderer.AddDrawable(drawable))
+  {
+    return true;
+  }
+  return false;
+}
+} // namespace Internal
+} // namespace Toolkit
+} // namespace Dali
diff --git a/dali-toolkit/internal/controls/canvas-view/canvas-view-impl.h b/dali-toolkit/internal/controls/canvas-view/canvas-view-impl.h
new file mode 100644 (file)
index 0000000..bc5c708
--- /dev/null
@@ -0,0 +1,125 @@
+#ifndef DALI_TOOLKIT_INTERNAL_CANVAS_VIEW_H
+#define DALI_TOOLKIT_INTERNAL_CANVAS_VIEW_H
+
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/devel-api/adaptor-framework/canvas-renderer-drawable.h>
+#include <dali/devel-api/adaptor-framework/canvas-renderer-shape.h>
+#include <dali/devel-api/adaptor-framework/canvas-renderer.h>
+#include <dali/devel-api/rendering/renderer-devel.h>
+#include <dali/integration-api/processor-interface.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/devel-api/controls/canvas-view/canvas-view.h>
+#include <dali-toolkit/public-api/controls/control-impl.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+class CanvasView;
+
+namespace Internal
+{
+class CanvasView : public Control, public Integration::Processor
+{
+public:
+  /**
+   * Construct a new CanvasView.
+   */
+  CanvasView(const Vector2& viewBox);
+
+  /**
+   * A reference counted object may only be deleted by calling Unreference()
+   */
+  virtual ~CanvasView();
+
+public:
+  /**
+   * Create a new CanvasView.
+   * @return A smart-pointer to the newly allocated CanvasView.
+   */
+  static Toolkit::CanvasView New(const Vector2& viewBox);
+
+  /**
+   * @copydoc Toolkit::Control::CanvasView::AddDrawable
+   */
+  bool AddDrawable(Dali::CanvasRenderer::Drawable& drawable);
+
+private: // From Control
+  /**
+   * @copydoc Control::OnRelayout
+   */
+  void OnRelayout(const Vector2& size, RelayoutContainer& container) override;
+
+  /**
+   * @copydoc Toolkit::Control::OnSizeSet()
+   */
+  void OnSizeSet(const Vector3& targetSize) override;
+
+  /**
+   * @copydoc Toolkit::Control::OnInitialize
+   */
+  void OnInitialize() override;
+
+protected: // Implementation of Processor
+  /**
+   * @copydoc Dali::Integration::Processor::Process()
+   */
+  void Process() override;
+
+private:
+  /**
+   * @brief Draw drawables added to CanvasView on inner canvas.
+   * Then make that buffer into a texture and add it to renderer.
+   */
+  void Commit();
+
+private:
+  CanvasView(const CanvasView&) = delete;
+  CanvasView& operator=(const CanvasView&) = delete;
+
+private:
+  CanvasRenderer mCanvasRenderer;
+  Dali::Texture  mTexture;
+  bool           mChanged;
+};
+
+} // namespace Internal
+
+// Helpers for public-api forwarding methods
+inline Toolkit::Internal::CanvasView& GetImpl(Toolkit::CanvasView& obj)
+{
+  DALI_ASSERT_ALWAYS(obj);
+  Dali::RefObject& handle = obj.GetImplementation();
+  return static_cast<Toolkit::Internal::CanvasView&>(handle);
+}
+
+inline const Toolkit::Internal::CanvasView& GetImpl(const Toolkit::CanvasView& obj)
+{
+  DALI_ASSERT_ALWAYS(obj);
+  const Dali::RefObject& handle = obj.GetImplementation();
+  return static_cast<const Toolkit::Internal::CanvasView&>(handle);
+}
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_INTERNAL_CANVAS_VIEW_H
index edb0929..cc65de9 100644 (file)
@@ -2004,7 +2004,7 @@ void Popup::SetupTouch()
 
 std::string Popup::AccessibleImpl::GetNameRaw()
 {
-  auto        popup = Toolkit::Popup::DownCast(self);
+  auto        popup = Toolkit::Popup::DownCast(Self());
   std::string title;
   Actor       popupTitle = popup.GetTitle();
   if(popupTitle)
@@ -2027,7 +2027,7 @@ std::string Popup::AccessibleImpl::GetNameRaw()
 Dali::Accessibility::States Popup::AccessibleImpl::CalculateStates()
 {
   auto states       = DevelControl::AccessibleImpl::CalculateStates();
-  auto popup        = Toolkit::Popup::DownCast(self);
+  auto popup        = Toolkit::Popup::DownCast(Self());
   auto displayState = popup.GetProperty<std::string>(Toolkit::Popup::Property::DISPLAY_STATE);
 
   states[Dali::Accessibility::State::SHOWING] = (displayState == "SHOWN" || displayState == "SHOWING");
index 2df2b77..48dfaad 100644 (file)
@@ -683,7 +683,7 @@ double ProgressBar::AccessibleImpl::GetMinimum()
 
 double ProgressBar::AccessibleImpl::GetCurrent()
 {
-  auto p = Toolkit::ProgressBar::DownCast(self);
+  auto p = Toolkit::ProgressBar::DownCast(Self());
   return p.GetProperty(Toolkit::ProgressBar::Property::PROGRESS_VALUE)
     .Get<float>();
 }
@@ -697,7 +697,7 @@ bool ProgressBar::AccessibleImpl::SetCurrent(double current)
 {
   if(current < GetMinimum() || current > GetMaximum())
     return false;
-  auto p = Toolkit::ProgressBar::DownCast(self);
+  auto p = Toolkit::ProgressBar::DownCast(Self());
   p.SetProperty(Toolkit::ProgressBar::Property::PROGRESS_VALUE,
                 static_cast<float>(current));
   return true;
index 5716c5e..fcf0b91 100644 (file)
@@ -863,21 +863,21 @@ Toolkit::ScrollBar ScrollBar::New(Toolkit::ScrollBar::Direction direction)
 
 double ScrollBar::AccessibleImpl::GetMinimum()
 {
-  auto   p                = Toolkit::ScrollBar::DownCast(self);
+  auto   p                = Toolkit::ScrollBar::DownCast(Self());
   Handle scrollableHandle = GetImpl(p).mScrollableObject.GetHandle();
   return scrollableHandle ? scrollableHandle.GetCurrentProperty<float>(GetImpl(p).mPropertyMinScrollPosition) : 0.0f;
 }
 
 double ScrollBar::AccessibleImpl::GetCurrent()
 {
-  auto   p                = Toolkit::ScrollBar::DownCast(self);
+  auto   p                = Toolkit::ScrollBar::DownCast(Self());
   Handle scrollableHandle = GetImpl(p).mScrollableObject.GetHandle();
   return scrollableHandle ? scrollableHandle.GetCurrentProperty<float>(GetImpl(p).mPropertyScrollPosition) : 0.0f;
 }
 
 double ScrollBar::AccessibleImpl::GetMaximum()
 {
-  auto   p                = Toolkit::ScrollBar::DownCast(self);
+  auto   p                = Toolkit::ScrollBar::DownCast(Self());
   Handle scrollableHandle = GetImpl(p).mScrollableObject.GetHandle();
   return scrollableHandle ? scrollableHandle.GetCurrentProperty<float>(GetImpl(p).mPropertyMaxScrollPosition) : 1.0f;
 }
@@ -889,7 +889,7 @@ bool ScrollBar::AccessibleImpl::SetCurrent(double current)
 
   auto value_before = GetCurrent();
 
-  auto   p                = Toolkit::ScrollBar::DownCast(self);
+  auto   p                = Toolkit::ScrollBar::DownCast(Self());
   Handle scrollableHandle = GetImpl(p).mScrollableObject.GetHandle();
   if(!scrollableHandle)
     return false;
index 699aee4..ecc25b2 100644 (file)
@@ -1348,7 +1348,7 @@ void ItemView::OnKeyboardFocusChangeCommitted(Actor commitedFocusableActor)
 void ItemView::AccessibleImpl::EnsureChildVisible(Actor child)
 {
   EnsureSelfVisible();
-  auto itemView = Dali::Toolkit::ItemView::DownCast(self);
+  auto itemView = Dali::Toolkit::ItemView::DownCast(Self());
   Toolkit::GetImpl(itemView).OnKeyboardFocusChangeCommitted(child);
 }
 
index a318c6d..ac062ff 100644 (file)
@@ -1825,7 +1825,7 @@ Toolkit::ScrollView::SnapStartedSignalType& ScrollView::SnapStartedSignal()
 
 void ScrollView::AccessibleImpl::EnsureChildVisible(Actor child)
 {
-  auto scrollView = Dali::Toolkit::ScrollView::DownCast(self);
+  auto scrollView = Dali::Toolkit::ScrollView::DownCast(Self());
   scrollView.ScrollTo(child);
 }
 
index 34da9ff..fdbbbd9 100644 (file)
@@ -1413,19 +1413,19 @@ Property::Value Slider::GetProperty(BaseObject* object, Property::Index property
 
 double Slider::AccessibleImpl::GetMinimum()
 {
-  auto p = Toolkit::Slider::DownCast(self);
+  auto p = Toolkit::Slider::DownCast(Self());
   return p.GetProperty(Toolkit::Slider::Property::LOWER_BOUND).Get<float>();
 }
 
 double Slider::AccessibleImpl::GetCurrent()
 {
-  auto p = Toolkit::Slider::DownCast(self);
+  auto p = Toolkit::Slider::DownCast(Self());
   return p.GetProperty(Toolkit::Slider::Property::VALUE).Get<float>();
 }
 
 double Slider::AccessibleImpl::GetMaximum()
 {
-  auto p = Toolkit::Slider::DownCast(self);
+  auto p = Toolkit::Slider::DownCast(Self());
   return p.GetProperty(Toolkit::Slider::Property::UPPER_BOUND).Get<float>();
 }
 
@@ -1434,7 +1434,7 @@ bool Slider::AccessibleImpl::SetCurrent(double current)
   if(current < GetMinimum() || current > GetMaximum())
     return false;
 
-  auto  p    = Toolkit::Slider::DownCast(self);
+  auto  p    = Toolkit::Slider::DownCast(Self());
   auto& impl = Toolkit::GetImpl(p);
 
   const float prev = p.GetProperty<float>(Toolkit::Slider::Property::VALUE);
@@ -1477,7 +1477,7 @@ bool Slider::AccessibleImpl::SetCurrent(double current)
 
 double Slider::AccessibleImpl::GetMinimumIncrement()
 {
-  auto p = Toolkit::Slider::DownCast(self);
+  auto p = Toolkit::Slider::DownCast(Self());
 
   bool  hasMarks  = !p.GetProperty<Property::Array>(Toolkit::Slider::Property::MARKS).Empty();
   float tolerance = p.GetProperty<float>(Toolkit::Slider::Property::MARK_TOLERANCE);
index 19c26c5..7347c00 100644 (file)
@@ -151,6 +151,7 @@ DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextEditor, "grabHandleColor
 DALI_SIGNAL_REGISTRATION(Toolkit, TextEditor, "textChanged",        SIGNAL_TEXT_CHANGED       )
 DALI_SIGNAL_REGISTRATION(Toolkit, TextEditor, "inputStyleChanged",  SIGNAL_INPUT_STYLE_CHANGED)
 DALI_SIGNAL_REGISTRATION(Toolkit, TextEditor, "maxLengthReached",   SIGNAL_MAX_LENGTH_REACHED )
+DALI_SIGNAL_REGISTRATION(Toolkit, TextEditor, "anchorClicked",      SIGNAL_ANCHOR_CLICKED     )
 
 DALI_TYPE_REGISTRATION_END()
 // clang-format on
@@ -1204,6 +1205,11 @@ DevelTextEditor::MaxLengthReachedSignalType& TextEditor::MaxLengthReachedSignal(
   return mMaxLengthReachedSignal;
 }
 
+DevelTextEditor::AnchorClickedSignalType& TextEditor::AnchorClickedSignal()
+{
+  return mAnchorClickedSignal;
+}
+
 Text::ControllerPtr TextEditor::getController()
 {
   return mController;
@@ -1232,6 +1238,14 @@ bool TextEditor::DoConnectSignal(BaseObject* object, ConnectionTrackerInterface*
       editorImpl.MaxLengthReachedSignal().Connect(tracker, functor);
     }
   }
+  else if(0 == strcmp(signalName.c_str(), SIGNAL_ANCHOR_CLICKED))
+  {
+    if(editor)
+    {
+      Internal::TextEditor& editorImpl(GetImpl(editor));
+      editorImpl.AnchorClickedSignal().Connect(tracker, functor);
+    }
+  }
   else
   {
     // signalName does not match any signal
@@ -1260,7 +1274,7 @@ void TextEditor::OnInitialize()
 {
   Actor self = Self();
 
-  mController = Text::Controller::New(this, this, this);
+  mController = Text::Controller::New(this, this, this, this);
 
   mDecorator = Text::Decorator::New(*mController,
                                     *mController);
@@ -1465,9 +1479,7 @@ void TextEditor::OnRelayout(const Vector2& size, RelayoutContainer& container)
     // If there is text changed, callback is called.
     if(mTextChanged)
     {
-      Dali::Toolkit::TextEditor handle(GetOwner());
-      mTextChangedSignal.Emit(handle);
-      mTextChanged = false;
+      EmitTextChangedSignal();
     }
   }
 
@@ -1612,6 +1624,7 @@ void TextEditor::OnTap(const TapGesture& gesture)
   padding                   = Self().GetProperty<Extents>(Toolkit::Control::Property::PADDING);
   const Vector2& localPoint = gesture.GetLocalPoint();
   mController->TapEvent(gesture.GetNumberOfTaps(), localPoint.x - padding.start, localPoint.y - padding.top);
+  mController->AnchorEvent(localPoint.x - padding.start, localPoint.y - padding.top);
 
   SetKeyInputFocus();
 }
@@ -1682,9 +1695,23 @@ void TextEditor::CaretMoved(unsigned int position)
   }
 }
 
-void TextEditor::TextChanged()
+void TextEditor::TextChanged(bool immediate)
+{
+  if(immediate) // Emits TextChangedSignal immediately
+  {
+    EmitTextChangedSignal();
+  }
+  else
+  {
+    mTextChanged = true;
+  }
+}
+
+void TextEditor::EmitTextChangedSignal()
 {
-  mTextChanged = true;
+  Dali::Toolkit::TextEditor handle(GetOwner());
+  mTextChangedSignal.Emit(handle);
+  mTextChanged = false;
 }
 
 void TextEditor::MaxLengthReached()
@@ -1747,6 +1774,12 @@ void TextEditor::InputStyleChanged(Text::InputStyle::Mask inputStyleMask)
   mInputStyleChangedSignal.Emit(handle, editorInputStyleMask);
 }
 
+void TextEditor::AnchorClicked(const std::string& href)
+{
+  Dali::Toolkit::TextEditor handle(GetOwner());
+  mAnchorClickedSignal.Emit(handle, href.c_str(), href.length());
+}
+
 void TextEditor::AddDecoration(Actor& actor, bool needsClipping)
 {
   if(actor)
@@ -2024,7 +2057,7 @@ TextEditor::~TextEditor()
 
 std::string TextEditor::AccessibleImpl::GetName()
 {
-  auto slf = Toolkit::TextEditor::DownCast(self);
+  auto slf = Toolkit::TextEditor::DownCast(Self());
   return slf.GetProperty(Toolkit::TextEditor::Property::TEXT)
     .Get<std::string>();
 }
@@ -2035,7 +2068,7 @@ std::string TextEditor::AccessibleImpl::GetText(size_t startOffset,
   if(endOffset <= startOffset)
     return {};
 
-  auto slf = Toolkit::TextEditor::DownCast(self);
+  auto slf = Toolkit::TextEditor::DownCast(Self());
   auto txt =
     slf.GetProperty(Toolkit::TextEditor::Property::TEXT).Get<std::string>();
 
@@ -2047,7 +2080,7 @@ std::string TextEditor::AccessibleImpl::GetText(size_t startOffset,
 
 size_t TextEditor::AccessibleImpl::GetCharacterCount()
 {
-  auto slf = Toolkit::TextEditor::DownCast(self);
+  auto slf = Toolkit::TextEditor::DownCast(Self());
   auto txt =
     slf.GetProperty(Toolkit::TextEditor::Property::TEXT).Get<std::string>();
 
@@ -2056,13 +2089,13 @@ size_t TextEditor::AccessibleImpl::GetCharacterCount()
 
 size_t TextEditor::AccessibleImpl::GetCaretOffset()
 {
-  auto slf = Toolkit::TextEditor::DownCast(self);
+  auto slf = Toolkit::TextEditor::DownCast(Self());
   return Dali::Toolkit::GetImpl(slf).getController()->GetCursorPosition();
 }
 
 bool TextEditor::AccessibleImpl::SetCaretOffset(size_t offset)
 {
-  auto slf = Toolkit::TextEditor::DownCast(self);
+  auto slf = Toolkit::TextEditor::DownCast(Self());
   auto txt = slf.GetProperty(Toolkit::TextEditor::Property::TEXT).Get<std::string>();
   if(offset > txt.size())
     return false;
@@ -2076,7 +2109,7 @@ bool TextEditor::AccessibleImpl::SetCaretOffset(size_t offset)
 Dali::Accessibility::Range TextEditor::AccessibleImpl::GetTextAtOffset(
   size_t offset, Dali::Accessibility::TextBoundary boundary)
 {
-  auto slf      = Toolkit::TextEditor::DownCast(self);
+  auto slf      = Toolkit::TextEditor::DownCast(Self());
   auto txt      = slf.GetProperty(Toolkit::TextEditor::Property::TEXT).Get<std::string>();
   auto txt_size = txt.size();
 
@@ -2156,7 +2189,7 @@ TextEditor::AccessibleImpl::GetSelection(size_t selectionNum)
   if(selectionNum > 0)
     return {};
 
-  auto        slf  = Toolkit::TextEditor::DownCast(self);
+  auto        slf  = Toolkit::TextEditor::DownCast(Self());
   auto        ctrl = Dali::Toolkit::GetImpl(slf).getController();
   std::string ret;
   ctrl->RetrieveSelection(ret);
@@ -2171,7 +2204,7 @@ bool TextEditor::AccessibleImpl::RemoveSelection(size_t selectionNum)
   if(selectionNum > 0)
     return false;
 
-  auto slf = Toolkit::TextEditor::DownCast(self);
+  auto slf = Toolkit::TextEditor::DownCast(Self());
   Dali::Toolkit::GetImpl(slf).getController()->SetSelection(0, 0);
   return true;
 }
@@ -2184,7 +2217,7 @@ bool TextEditor::AccessibleImpl::SetSelection(size_t selectionNum,
   if(selectionNum > 0)
     return false;
 
-  auto slf = Toolkit::TextEditor::DownCast(self);
+  auto slf = Toolkit::TextEditor::DownCast(Self());
   Dali::Toolkit::GetImpl(slf).getController()->SetSelection(startOffset,
                                                             endOffset);
   return true;
@@ -2196,7 +2229,7 @@ bool TextEditor::AccessibleImpl::CopyText(size_t startPosition,
   if(endPosition <= startPosition)
     return false;
 
-  auto slf = Toolkit::TextEditor::DownCast(self);
+  auto slf = Toolkit::TextEditor::DownCast(Self());
   auto txt = slf.GetProperty(Toolkit::TextEditor::Property::TEXT).Get<std::string>();
   Dali::Toolkit::GetImpl(slf).getController()->CopyStringToClipboard(txt.substr(startPosition, endPosition - startPosition));
 
@@ -2209,7 +2242,7 @@ bool TextEditor::AccessibleImpl::CutText(size_t startPosition,
   if(endPosition <= startPosition)
     return false;
 
-  auto slf = Toolkit::TextEditor::DownCast(self);
+  auto slf = Toolkit::TextEditor::DownCast(Self());
   auto txt = slf.GetProperty(Toolkit::TextEditor::Property::TEXT).Get<std::string>();
   Dali::Toolkit::GetImpl(slf).getController()->CopyStringToClipboard(txt.substr(startPosition, endPosition - startPosition));
 
index 4c408ca..d0609b6 100644 (file)
@@ -31,6 +31,7 @@
 #include <dali-toolkit/internal/controls/control/control-data-impl.h>
 #include <dali-toolkit/internal/text/decorator/text-decorator.h>
 #include <dali-toolkit/internal/text/rendering/text-renderer.h>
+#include <dali-toolkit/internal/text/text-anchor-control-interface.h>
 #include <dali-toolkit/internal/text/text-control-interface.h>
 #include <dali-toolkit/internal/text/text-controller.h>
 #include <dali-toolkit/internal/text/text-editable-control-interface.h>
@@ -48,7 +49,7 @@ namespace Internal
 /**
  * @brief A control which renders a long text string with styles.
  */
-class TextEditor : public Control, public Text::ControlInterface, public Text::EditableControlInterface, public Text::SelectableControlInterface
+class TextEditor : public Control, public Text::ControlInterface, public Text::EditableControlInterface, public Text::SelectableControlInterface, public Text::AnchorControlInterface
 {
 public:
   /**
@@ -87,6 +88,11 @@ public:
   DevelTextEditor::MaxLengthReachedSignalType& MaxLengthReachedSignal();
 
   /**
+   * @copydoc Dali::Toollkit::TextEditor::AnchorClickedSignal()
+   */
+  DevelTextEditor::AnchorClickedSignalType& AnchorClickedSignal();
+
+  /**
    * Connects a callback function with the object's signals.
    * @param[in] object The object providing the signal.
    * @param[in] tracker Used to disconnect the signal.
@@ -205,7 +211,7 @@ private: // From Control
   /**
    * @copydoc Text::EditableControlInterface::TextChanged()
    */
-  void TextChanged() override;
+  void TextChanged(bool immediate) override;
 
   /**
    * @copydoc Text::EditableControlInterface::MaxLengthReached()
@@ -276,7 +282,15 @@ public:
   /**
    * @copydoc Text::EditableControlInterface::SetEditable()
    */
-  void                SetEditable(bool editable) override;
+  void SetEditable(bool editable) override;
+
+  // From AnchorControlInterface
+
+  /**
+   * @copydoc Text::AnchorControlInterface::AnchorClicked()
+   */
+  void AnchorClicked(const std::string& href) override;
+
   Text::ControllerPtr getController();
 
 private: // Implementation
@@ -329,6 +343,11 @@ private: // Implementation
   void OnIdleSignal();
 
   /**
+   * @brief Emits TextChanged signal.
+   */
+  void EmitTextChangedSignal();
+
+  /**
    * @brief set RenderActor's position with new scrollPosition
    *
    * Apply updated scroll position or start scroll animation if VerticalScrollAnimation is enabled
@@ -378,6 +397,7 @@ private: // Data
   Toolkit::TextEditor::InputStyleChangedSignalType     mInputStyleChangedSignal;
   Toolkit::TextEditor::ScrollStateChangedSignalType    mScrollStateChangedSignal;
   Toolkit::DevelTextEditor::MaxLengthReachedSignalType mMaxLengthReachedSignal;
+  Toolkit::DevelTextEditor::AnchorClickedSignalType    mAnchorClickedSignal;
 
   InputMethodContext            mInputMethodContext;
   Text::ControllerPtr           mController;
@@ -402,7 +422,7 @@ private: // Data
   bool  mScrollAnimationEnabled : 1;
   bool  mScrollBarEnabled : 1;
   bool  mScrollStarted : 1;
-  bool  mTextChanged : 1;
+  bool  mTextChanged : 1; ///< If true, emits TextChangedSignal in next OnRelayout().
 
   struct AccessibleImpl : public DevelControl::AccessibleImpl,
                           public virtual Dali::Accessibility::Text,
index d29bfad..7fc3eca 100644 (file)
@@ -142,6 +142,7 @@ DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextField, "grabHandleColor"
 DALI_SIGNAL_REGISTRATION(Toolkit, TextField, "textChanged",       SIGNAL_TEXT_CHANGED       )
 DALI_SIGNAL_REGISTRATION(Toolkit, TextField, "maxLengthReached",  SIGNAL_MAX_LENGTH_REACHED )
 DALI_SIGNAL_REGISTRATION(Toolkit, TextField, "inputStyleChanged", SIGNAL_INPUT_STYLE_CHANGED)
+DALI_SIGNAL_REGISTRATION(Toolkit, TextField, "anchorClicked",     SIGNAL_ANCHOR_CLICKED     )
 
 DALI_TYPE_REGISTRATION_END()
 // clang-format on
@@ -1195,6 +1196,14 @@ bool TextField::DoConnectSignal(BaseObject* object, ConnectionTrackerInterface*
   {
     field.InputStyleChangedSignal().Connect(tracker, functor);
   }
+  else if(0 == strcmp(signalName.c_str(), SIGNAL_ANCHOR_CLICKED))
+  {
+    if(field)
+    {
+      Internal::TextField& fieldImpl(GetImpl(field));
+      fieldImpl.AnchorClickedSignal().Connect(tracker, functor);
+    }
+  }
   else
   {
     // signalName does not match any signal
@@ -1219,11 +1228,16 @@ Toolkit::TextField::InputStyleChangedSignalType& TextField::InputStyleChangedSig
   return mInputStyleChangedSignal;
 }
 
+DevelTextField::AnchorClickedSignalType& TextField::AnchorClickedSignal()
+{
+  return mAnchorClickedSignal;
+}
+
 void TextField::OnInitialize()
 {
   Actor self = Self();
 
-  mController = Text::Controller::New(this, this, this);
+  mController = Text::Controller::New(this, this, this, this);
 
   // When using the vector-based rendering, the size of the GLyphs are different
   TextAbstraction::GlyphType glyphType = (DevelText::RENDERING_VECTOR_BASED == mRenderingBackend) ? TextAbstraction::VECTOR_GLYPH : TextAbstraction::BITMAP_GLYPH;
@@ -1416,9 +1430,7 @@ void TextField::OnRelayout(const Vector2& size, RelayoutContainer& container)
     // If there is text changed, callback is called.
     if(mTextChanged)
     {
-      Dali::Toolkit::TextField handle(GetOwner());
-      mTextChangedSignal.Emit(handle);
-      mTextChanged = false;
+      EmitTextChangedSignal();
     }
   }
 
@@ -1621,6 +1633,7 @@ void TextField::OnTap(const TapGesture& gesture)
   padding                   = Self().GetProperty<Extents>(Toolkit::Control::Property::PADDING);
   const Vector2& localPoint = gesture.GetLocalPoint();
   mController->TapEvent(gesture.GetNumberOfTaps(), localPoint.x - padding.start, localPoint.y - padding.top);
+  mController->AnchorEvent(localPoint.x - padding.start, localPoint.y - padding.top);
 
   SetKeyInputFocus();
 }
@@ -1710,9 +1723,23 @@ void TextField::CaretMoved(unsigned int position)
   }
 }
 
-void TextField::TextChanged()
+void TextField::TextChanged(bool immediate)
+{
+  if(immediate) // Emits TextChangedSignal immediately
+  {
+    EmitTextChangedSignal();
+  }
+  else
+  {
+    mTextChanged = true;
+  }
+}
+
+void TextField::EmitTextChangedSignal()
 {
-  mTextChanged = true;
+  Dali::Toolkit::TextField handle(GetOwner());
+  mTextChangedSignal.Emit(handle);
+  mTextChanged = false;
 }
 
 void TextField::MaxLengthReached()
@@ -1771,6 +1798,12 @@ void TextField::InputStyleChanged(Text::InputStyle::Mask inputStyleMask)
   mInputStyleChangedSignal.Emit(handle, fieldInputStyleMask);
 }
 
+void TextField::AnchorClicked(const std::string& href)
+{
+  Dali::Toolkit::TextField handle(GetOwner());
+  mAnchorClickedSignal.Emit(handle, href.c_str(), href.length());
+}
+
 void TextField::AddDecoration(Actor& actor, bool needsClipping)
 {
   if(actor)
@@ -1906,7 +1939,7 @@ TextField::~TextField()
 
 std::string TextField::AccessibleImpl::GetName()
 {
-  auto slf = Toolkit::TextField::DownCast(self);
+  auto slf = Toolkit::TextField::DownCast(Self());
   return slf.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
 }
 
@@ -1916,7 +1949,7 @@ std::string TextField::AccessibleImpl::GetText(size_t startOffset,
   if(endOffset <= startOffset)
     return {};
 
-  auto slf = Toolkit::TextField::DownCast(self);
+  auto slf = Toolkit::TextField::DownCast(Self());
   auto txt =
     slf.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
 
@@ -1928,7 +1961,7 @@ std::string TextField::AccessibleImpl::GetText(size_t startOffset,
 
 size_t TextField::AccessibleImpl::GetCharacterCount()
 {
-  auto slf = Toolkit::TextField::DownCast(self);
+  auto slf = Toolkit::TextField::DownCast(Self());
   auto txt =
     slf.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
 
@@ -1937,13 +1970,13 @@ size_t TextField::AccessibleImpl::GetCharacterCount()
 
 size_t TextField::AccessibleImpl::GetCaretOffset()
 {
-  auto slf = Toolkit::TextField::DownCast(self);
+  auto slf = Toolkit::TextField::DownCast(Self());
   return Dali::Toolkit::GetImpl(slf).getController()->GetCursorPosition();
 }
 
 bool TextField::AccessibleImpl::SetCaretOffset(size_t offset)
 {
-  auto slf = Toolkit::TextField::DownCast(self);
+  auto slf = Toolkit::TextField::DownCast(Self());
   auto txt = slf.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
   if(offset > txt.size())
     return false;
@@ -1957,7 +1990,7 @@ bool TextField::AccessibleImpl::SetCaretOffset(size_t offset)
 Dali::Accessibility::Range TextField::AccessibleImpl::GetTextAtOffset(
   size_t offset, Dali::Accessibility::TextBoundary boundary)
 {
-  auto slf      = Toolkit::TextField::DownCast(self);
+  auto slf      = Toolkit::TextField::DownCast(Self());
   auto txt      = slf.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
   auto txt_size = txt.size();
 
@@ -2037,7 +2070,7 @@ TextField::AccessibleImpl::GetSelection(size_t selectionNum)
   if(selectionNum > 0)
     return {};
 
-  auto        slf  = Toolkit::TextField::DownCast(self);
+  auto        slf  = Toolkit::TextField::DownCast(Self());
   auto        ctrl = Dali::Toolkit::GetImpl(slf).getController();
   std::string ret;
   ctrl->RetrieveSelection(ret);
@@ -2052,7 +2085,7 @@ bool TextField::AccessibleImpl::RemoveSelection(size_t selectionNum)
   if(selectionNum > 0)
     return false;
 
-  auto slf = Toolkit::TextField::DownCast(self);
+  auto slf = Toolkit::TextField::DownCast(Self());
   Dali::Toolkit::GetImpl(slf).getController()->SetSelection(0, 0);
   return true;
 }
@@ -2065,7 +2098,7 @@ bool TextField::AccessibleImpl::SetSelection(size_t selectionNum,
   if(selectionNum > 0)
     return false;
 
-  auto slf = Toolkit::TextField::DownCast(self);
+  auto slf = Toolkit::TextField::DownCast(Self());
   Dali::Toolkit::GetImpl(slf).getController()->SetSelection(startOffset,
                                                             endOffset);
   return true;
@@ -2077,7 +2110,7 @@ bool TextField::AccessibleImpl::CopyText(size_t startPosition,
   if(endPosition <= startPosition)
     return false;
 
-  auto slf = Toolkit::TextField::DownCast(self);
+  auto slf = Toolkit::TextField::DownCast(Self());
   auto txt = slf.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
   Dali::Toolkit::GetImpl(slf).getController()->CopyStringToClipboard(txt.substr(startPosition, endPosition - startPosition));
 
@@ -2090,7 +2123,7 @@ bool TextField::AccessibleImpl::CutText(size_t startPosition,
   if(endPosition <= startPosition)
     return false;
 
-  auto slf = Toolkit::TextField::DownCast(self);
+  auto slf = Toolkit::TextField::DownCast(Self());
   auto txt = slf.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
   Dali::Toolkit::GetImpl(slf).getController()->CopyStringToClipboard(txt.substr(startPosition, endPosition - startPosition));
 
index 07a7a37..670b81c 100644 (file)
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/devel-api/controls/control-devel.h>
+#include <dali-toolkit/devel-api/controls/text-controls/text-field-devel.h>
 #include <dali-toolkit/internal/controls/control/control-data-impl.h>
 #include <dali-toolkit/internal/text/decorator/text-decorator.h>
 #include <dali-toolkit/internal/text/rendering/text-renderer.h>
+#include <dali-toolkit/internal/text/text-anchor-control-interface.h>
 #include <dali-toolkit/internal/text/text-control-interface.h>
 #include <dali-toolkit/internal/text/text-controller.h>
 #include <dali-toolkit/internal/text/text-editable-control-interface.h>
@@ -43,7 +45,7 @@ namespace Internal
 /**
  * @brief A control which renders a short text string.
  */
-class TextField : public Control, public Text::ControlInterface, public Text::EditableControlInterface, public Text::SelectableControlInterface
+class TextField : public Control, public Text::ControlInterface, public Text::EditableControlInterface, public Text::SelectableControlInterface, public Text::AnchorControlInterface
 {
 public:
   /**
@@ -102,6 +104,11 @@ public:
    */
   Toolkit::TextField::InputStyleChangedSignalType& InputStyleChangedSignal();
 
+  /**
+   * @copydoc TextField::AnchorClickedSignal()
+   */
+  DevelTextField::AnchorClickedSignalType& AnchorClickedSignal();
+
   Text::ControllerPtr getController();
 
 private: // From Control
@@ -197,7 +204,7 @@ private: // From Control
   /**
    * @copydoc Text::EditableControlInterface::TextChanged()
    */
-  void TextChanged() override;
+  void TextChanged(bool immediate) override;
 
   /**
    * @copydoc Text::EditableControlInterface::MaxLengthReached()
@@ -251,6 +258,13 @@ public:
    */
   void SetEditable(bool editable) override;
 
+  // From AnchorControlInterface
+
+  /**
+   * @copydoc Text::AnchorControlInterface::AnchorClicked()
+   */
+  void AnchorClicked(const std::string& href) override;
+
 private: // Implementation
   /**
    * @copydoc Dali::Toolkit::Text::Controller::(InputMethodContext& inputMethodContext, const InputMethodContext::EventData& inputMethodContextEvent)
@@ -299,6 +313,11 @@ private: // Implementation
   void OnIdleSignal();
 
   /**
+   * @brief Emits TextChanged signal.
+   */
+  void EmitTextChangedSignal();
+
+  /**
    * Construct a new TextField.
    */
   TextField();
@@ -336,9 +355,10 @@ public: // For UTC only
 
 private: // Data
   // Signals
-  Toolkit::TextField::TextChangedSignalType       mTextChangedSignal;
-  Toolkit::TextField::MaxLengthReachedSignalType  mMaxLengthReachedSignal;
-  Toolkit::TextField::InputStyleChangedSignalType mInputStyleChangedSignal;
+  Toolkit::TextField::TextChangedSignalType        mTextChangedSignal;
+  Toolkit::TextField::MaxLengthReachedSignalType   mMaxLengthReachedSignal;
+  Toolkit::TextField::InputStyleChangedSignalType  mInputStyleChangedSignal;
+  Toolkit::DevelTextField::AnchorClickedSignalType mAnchorClickedSignal;
 
   InputMethodContext       mInputMethodContext;
   Text::ControllerPtr      mController;
@@ -357,7 +377,7 @@ private: // Data
   int   mRenderingBackend;
   int   mExceedPolicy;
   bool  mHasBeenStaged : 1;
-  bool  mTextChanged : 1;
+  bool  mTextChanged : 1; ///< If true, emits TextChangedSignal in next OnRelayout().
 
 protected:
   struct AccessibleImpl : public DevelControl::AccessibleImpl,
index 3ee507d..1beb1c2 100644 (file)
@@ -139,6 +139,9 @@ DALI_ANIMATABLE_PROPERTY_COMPONENT_REGISTRATION(Toolkit,    TextLabel, "textColo
 DALI_ANIMATABLE_PROPERTY_COMPONENT_REGISTRATION(Toolkit,    TextLabel, "textColorGreen", TEXT_COLOR_GREEN, TEXT_COLOR, 1)
 DALI_ANIMATABLE_PROPERTY_COMPONENT_REGISTRATION(Toolkit,    TextLabel, "textColorBlue",  TEXT_COLOR_BLUE,  TEXT_COLOR, 2)
 DALI_ANIMATABLE_PROPERTY_COMPONENT_REGISTRATION(Toolkit,    TextLabel, "textColorAlpha", TEXT_COLOR_ALPHA, TEXT_COLOR, 3)
+
+DALI_SIGNAL_REGISTRATION(Toolkit, TextLabel, "anchorClicked", SIGNAL_ANCHOR_CLICKED)
+
 DALI_TYPE_REGISTRATION_END()
 // clang-format on
 
@@ -720,6 +723,35 @@ Property::Value TextLabel::GetProperty(BaseObject* object, Property::Index index
   return value;
 }
 
+bool TextLabel::DoConnectSignal(BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor)
+{
+  Dali::BaseHandle handle(object);
+
+  bool               connected(true);
+  Toolkit::TextLabel label = Toolkit::TextLabel::DownCast(handle);
+
+  if(0 == strcmp(signalName.c_str(), SIGNAL_ANCHOR_CLICKED))
+  {
+    if(label)
+    {
+      Internal::TextLabel& labelImpl(GetImpl(label));
+      labelImpl.AnchorClickedSignal().Connect(tracker, functor);
+    }
+  }
+  else
+  {
+    // signalName does not match any signal
+    connected = false;
+  }
+
+  return connected;
+}
+
+DevelTextLabel::AnchorClickedSignalType& TextLabel::AnchorClickedSignal()
+{
+  return mAnchorClickedSignal;
+}
+
 void TextLabel::OnInitialize()
 {
   Actor self = Self();
@@ -736,6 +768,7 @@ void TextLabel::OnInitialize()
   DALI_ASSERT_DEBUG(mController && "Invalid Text Controller")
 
   mController->SetControlInterface(this);
+  mController->SetAnchorControlInterface(this);
 
   // Use height-for-width negotiation by default
   self.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH);
@@ -752,6 +785,10 @@ void TextLabel::OnInitialize()
   Dali::LayoutDirection::Type layoutDirection = static_cast<Dali::LayoutDirection::Type>(stage.GetRootLayer().GetProperty(Dali::Actor::Property::LAYOUT_DIRECTION).Get<int>());
   mController->SetLayoutDirection(layoutDirection);
 
+  // Forward input events to controller
+  EnableGestureDetection(static_cast<GestureType::Value>(GestureType::TAP));
+  GetTapGestureDetector().SetMaximumTapsRequired(1);
+
   Layout::Engine& engine = mController->GetLayoutEngine();
   engine.SetCursorWidth(0u); // Do not layout space for the cursor.
 
@@ -793,6 +830,23 @@ void TextLabel::OnStyleChange(Toolkit::StyleManager styleManager, StyleChange::T
   Control::OnStyleChange(styleManager, change);
 }
 
+void TextLabel::OnTap(const TapGesture& gesture)
+{
+  DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextLabel::OnTap %p\n", mController.Get());
+
+  // Deliver the tap before the focus event to controller; this allows us to detect when focus is gained due to tap-gestures
+  Extents padding;
+  padding                   = Self().GetProperty<Extents>(Toolkit::Control::Property::PADDING);
+  const Vector2& localPoint = gesture.GetLocalPoint();
+  mController->AnchorEvent(localPoint.x - padding.start, localPoint.y - padding.top);
+}
+
+void TextLabel::AnchorClicked(const std::string& href)
+{
+  Dali::Toolkit::TextLabel handle(GetOwner());
+  mAnchorClickedSignal.Emit(handle, href.c_str(), href.length());
+}
+
 Vector3 TextLabel::GetNaturalSize()
 {
   Extents padding;
@@ -1003,7 +1057,7 @@ TextLabel::~TextLabel()
 
 std::string TextLabel::AccessibleImpl::GetNameRaw()
 {
-  auto slf = Toolkit::TextLabel::DownCast(self);
+  auto slf = Toolkit::TextLabel::DownCast(Self());
   return slf.GetProperty(Toolkit::TextLabel::Property::TEXT).Get<std::string>();
 }
 
@@ -1018,7 +1072,7 @@ std::string TextLabel::AccessibleImpl::GetText(size_t startOffset,
   if(endOffset <= startOffset)
     return {};
 
-  auto slf = Toolkit::TextLabel::DownCast(self);
+  auto slf = Toolkit::TextLabel::DownCast(Self());
   auto txt =
     slf.GetProperty(Toolkit::TextLabel::Property::TEXT).Get<std::string>();
 
@@ -1030,7 +1084,7 @@ std::string TextLabel::AccessibleImpl::GetText(size_t startOffset,
 
 size_t TextLabel::AccessibleImpl::GetCharacterCount()
 {
-  auto slf = Toolkit::TextLabel::DownCast(self);
+  auto slf = Toolkit::TextLabel::DownCast(Self());
   auto txt =
     slf.GetProperty(Toolkit::TextLabel::Property::TEXT).Get<std::string>();
 
@@ -1050,7 +1104,7 @@ bool TextLabel::AccessibleImpl::SetCaretOffset(size_t offset)
 Dali::Accessibility::Range TextLabel::AccessibleImpl::GetTextAtOffset(
   size_t offset, Dali::Accessibility::TextBoundary boundary)
 {
-  auto slf      = Toolkit::TextLabel::DownCast(self);
+  auto slf      = Toolkit::TextLabel::DownCast(Self());
   auto txt      = slf.GetProperty(Toolkit::TextLabel::Property::TEXT).Get<std::string>();
   auto txt_size = txt.size();
 
@@ -1130,7 +1184,7 @@ TextLabel::AccessibleImpl::GetSelection(size_t selectionNum)
   if(selectionNum > 0)
     return {};
 
-  auto        slf  = Toolkit::TextLabel::DownCast(self);
+  auto        slf  = Toolkit::TextLabel::DownCast(Self());
   auto        ctrl = Dali::Toolkit::GetImpl(slf).getController();
   std::string ret;
   ctrl->RetrieveSelection(ret);
@@ -1145,7 +1199,7 @@ bool TextLabel::AccessibleImpl::RemoveSelection(size_t selectionNum)
   if(selectionNum > 0)
     return false;
 
-  auto slf = Toolkit::TextLabel::DownCast(self);
+  auto slf = Toolkit::TextLabel::DownCast(Self());
   Dali::Toolkit::GetImpl(slf).getController()->SetSelection(0, 0);
   return true;
 }
@@ -1158,7 +1212,7 @@ bool TextLabel::AccessibleImpl::SetSelection(size_t selectionNum,
   if(selectionNum > 0)
     return false;
 
-  auto slf = Toolkit::TextLabel::DownCast(self);
+  auto slf = Toolkit::TextLabel::DownCast(Self());
   Dali::Toolkit::GetImpl(slf).getController()->SetSelection(startOffset,
                                                             endOffset);
   return true;
index e9ad7a7..a204be6 100644 (file)
@@ -24,6 +24,7 @@
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/controls/control/control-data-impl.h>
 #include <dali-toolkit/internal/text/rendering/text-renderer.h>
+#include <dali-toolkit/internal/text/text-anchor-control-interface.h>
 #include <dali-toolkit/internal/text/text-control-interface.h>
 #include <dali-toolkit/internal/text/text-controller.h>
 #include <dali-toolkit/internal/text/text-scroller-interface.h>
@@ -41,7 +42,7 @@ namespace Internal
 /**
  * @brief A control which renders a short text string.
  */
-class TextLabel : public Control, public Text::ControlInterface, public Text::ScrollerInterface
+class TextLabel : public Control, public Text::ControlInterface, public Text::ScrollerInterface, public Text::AnchorControlInterface
 {
 public:
   /**
@@ -69,6 +70,22 @@ public:
    */
   static Property::Value GetProperty(BaseObject* object, Property::Index index);
 
+  /**
+   * @copydoc Dali::Toollkit::TextLabel::AnchorClickedSignal()
+   */
+  DevelTextLabel::AnchorClickedSignalType& AnchorClickedSignal();
+
+  /**
+   * Connects a callback function with the object's signals.
+   * @param[in] object The object providing the signal.
+   * @param[in] tracker Used to disconnect the signal.
+   * @param[in] signalName The signal to connect to.
+   * @param[in] functor A newly allocated FunctorDelegate.
+   * @return True if the signal was connected.
+   * @post If a signal was connected, ownership of functor was passed to CallbackBase. Otherwise the caller is responsible for deleting the unused functor.
+   */
+  static bool DoConnectSignal(BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor);
+
   Text::ControllerPtr getController();
 
 private: // From Control
@@ -88,6 +105,11 @@ private: // From Control
   void OnRelayout(const Vector2& size, RelayoutContainer& container) override;
 
   /**
+   * @copydoc Control::OnTap()
+   */
+  void OnTap(const TapGesture& tap) override;
+
+  /**
    * @copydoc Control::GetNaturalSize()
    */
   Vector3 GetNaturalSize() override;
@@ -115,6 +137,12 @@ private: // from TextScroller
    */
   void ScrollingFinished() override;
 
+public: // From AnchorControlInterface
+  /**
+   * @copydoc Text::AnchorControlInterface::AnchorClicked()
+   */
+  void AnchorClicked(const std::string& href) override;
+
 private: // Implementation
   /**
    * Construct a new TextLabel.
@@ -155,6 +183,9 @@ private: // Data
 
   Toolkit::Visual::Base mVisual;
 
+  // Signals
+  Toolkit::DevelTextLabel::AnchorClickedSignalType mAnchorClickedSignal;
+
   int  mRenderingBackend;
   bool mTextUpdateNeeded : 1;
 
index bccfe84..e2d9f91 100644 (file)
@@ -107,6 +107,7 @@ DALI_PROPERTY_REGISTRATION(Toolkit, TextSelectionPopup, "popupMinSize", VECTOR2,
 DALI_PROPERTY_REGISTRATION(Toolkit, TextSelectionPopup, "optionMaxSize", VECTOR2, OPTION_MAX_SIZE)
 DALI_PROPERTY_REGISTRATION(Toolkit, TextSelectionPopup, "optionMinSize", VECTOR2, OPTION_MIN_SIZE)
 DALI_PROPERTY_REGISTRATION(Toolkit, TextSelectionPopup, "optionDividerSize", VECTOR2, OPTION_DIVIDER_SIZE)
+DALI_PROPERTY_REGISTRATION(Toolkit, TextSelectionPopup, "optionDividerPadding", VECTOR4, OPTION_DIVIDER_PADDING)
 DALI_PROPERTY_REGISTRATION(Toolkit, TextSelectionPopup, "popupClipboardButtonImage", STRING, POPUP_CLIPBOARD_BUTTON_ICON_IMAGE)
 DALI_PROPERTY_REGISTRATION(Toolkit, TextSelectionPopup, "popupCutButtonImage", STRING, POPUP_CUT_BUTTON_ICON_IMAGE)
 DALI_PROPERTY_REGISTRATION(Toolkit, TextSelectionPopup, "popupCopyButtonImage", STRING, POPUP_COPY_BUTTON_ICON_IMAGE)
@@ -172,6 +173,12 @@ void TextSelectionPopup::SetProperty(BaseObject* object, Property::Index index,
         impl.SetDimensionToCustomise(OPTION_DIVIDER_SIZE, value.Get<Vector2>());
         break;
       }
+      case Toolkit::TextSelectionPopup::Property::OPTION_DIVIDER_PADDING:
+      {
+        Vector4 padding(value.Get<Vector4>());
+        impl.SetOptionDividerPadding(Padding(padding.x, padding.y, padding.z, padding.w));
+        break;
+      }
       case Toolkit::TextSelectionPopup::Property::POPUP_CLIPBOARD_BUTTON_ICON_IMAGE:
       {
         impl.SetButtonImage(Toolkit::TextSelectionPopup::CLIPBOARD, value.Get<std::string>());
@@ -274,6 +281,12 @@ Property::Value TextSelectionPopup::GetProperty(BaseObject* object, Property::In
         value = impl.GetDimensionToCustomise(OPTION_DIVIDER_SIZE);
         break;
       }
+      case Toolkit::TextSelectionPopup::Property::OPTION_DIVIDER_PADDING:
+      {
+        Padding padding = impl.GetOptionDividerPadding();
+        value           = Vector4(padding.left, padding.right, padding.top, padding.bottom);
+        break;
+      }
       case Toolkit::TextSelectionPopup::Property::POPUP_CLIPBOARD_BUTTON_ICON_IMAGE:
       {
         value = impl.GetButtonImage(Toolkit::TextSelectionPopup::CLIPBOARD);
@@ -628,6 +641,17 @@ std::string TextSelectionPopup::GetPressedImage() const
   return mPressedImage;
 }
 
+void TextSelectionPopup::SetOptionDividerPadding(const Padding& padding)
+{
+  DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextSelectionPopup::SetOptionDividerPadding padding(%f,%f,%f,%f)\n", padding.left, padding.right, padding.top, padding.bottom);
+  mOptionDividerPadding = Padding(padding.left, padding.right, padding.top, padding.bottom);
+}
+
+Padding TextSelectionPopup::GetOptionDividerPadding() const
+{
+  return mOptionDividerPadding;
+}
+
 void TextSelectionPopup::CreateOrderedListOfPopupOptions()
 {
   mOrderListOfButtons.clear();
@@ -734,7 +758,8 @@ void TextSelectionPopup::AddOption(const ButtonRequirement& button, bool showDiv
   // 6. Add the divider
   if(showDivider)
   {
-    const Size size(mOptionDividerSize.width, 0.0f); // Height FILL_TO_PARENT
+    const Size    size(mOptionDividerSize.width, 0.0f); // Height FILL_TO_PARENT
+    const Padding padding(mOptionDividerPadding);
 
     Toolkit::Control divider = Toolkit::Control::New();
 #ifdef DECORATOR_DEBUG
@@ -742,6 +767,7 @@ void TextSelectionPopup::AddOption(const ButtonRequirement& button, bool showDiv
 #endif
     divider.SetProperty(Actor::Property::SIZE, size);
     divider.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::HEIGHT);
+    divider.SetProperty(Actor::Property::PADDING, padding);
     divider.SetBackgroundColor(mDividerColor);
     mToolbar.AddDivider(divider);
   }
@@ -843,6 +869,7 @@ TextSelectionPopup::TextSelectionPopup(TextSelectionPopupCallbackInterface* call
   mOptionMaxSize(),
   mOptionMinSize(),
   mOptionDividerSize(),
+  mOptionDividerPadding(),
   mEnabledButtons(Toolkit::TextSelectionPopup::NONE),
   mCallbackInterface(callbackInterface),
   mPressedColor(DEFAULT_OPTION_PRESSED_COLOR),
index 82947a1..64130e1 100644 (file)
@@ -229,6 +229,18 @@ private: // Implementation
    */
   std::string GetPressedImage() const;
 
+  /**
+   * Set option divider padding
+   * @param[in] padding BEGIN END BOTTOM TOP
+   */
+  void SetOptionDividerPadding(const Padding& padding);
+
+  /**
+   * Get option divider padding
+   * @return Padding
+   */
+  Padding GetOptionDividerPadding() const;
+
   void CreateOrderedListOfPopupOptions();
 
   void AddOption(const ButtonRequirement& button, bool showDivider, bool showIcons, bool showCaption);
@@ -272,10 +284,11 @@ private: // Data
   std::string mSelectIconImage;
   std::string mSelectAllIconImage;
 
-  Size mPopupMaxSize;      // Maximum size of the Popup
-  Size mOptionMaxSize;     // Maximum size of an Option button
-  Size mOptionMinSize;     // Minimum size of an Option button
-  Size mOptionDividerSize; // Size of divider line
+  Size    mPopupMaxSize;         // Maximum size of the Popup
+  Size    mOptionMaxSize;        // Maximum size of an Option button
+  Size    mOptionMinSize;        // Minimum size of an Option button
+  Size    mOptionDividerSize;    // Size of divider line
+  Padding mOptionDividerPadding; // Padding of divider line
 
   std::vector<ButtonRequirement> mOrderListOfButtons; // List of buttons in the order to be displayed and a flag to indicate if needed.
 
index 8053564..0dd6834 100644 (file)
 
 // EXTERNAL INCLUDES
 #include <dali/devel-api/adaptor-framework/web-engine-back-forward-list.h>
+#include <dali/devel-api/adaptor-framework/web-engine-certificate.h>
+#include <dali/devel-api/adaptor-framework/web-engine-console-message.h>
+#include <dali/devel-api/adaptor-framework/web-engine-context-menu-item.h>
+#include <dali/devel-api/adaptor-framework/web-engine-context-menu.h>
 #include <dali/devel-api/adaptor-framework/web-engine-context.h>
 #include <dali/devel-api/adaptor-framework/web-engine-cookie-manager.h>
+#include <dali/devel-api/adaptor-framework/web-engine-form-repost-decision.h>
+#include <dali/devel-api/adaptor-framework/web-engine-http-auth-handler.h>
+#include <dali/devel-api/adaptor-framework/web-engine-load-error.h>
+#include <dali/devel-api/adaptor-framework/web-engine-policy-decision.h>
+#include <dali/devel-api/adaptor-framework/web-engine-request-interceptor.h>
 #include <dali/devel-api/adaptor-framework/web-engine-settings.h>
 #include <dali/devel-api/common/stage.h>
 #include <dali/devel-api/scripting/enum-helper.h>
 #include <dali/public-api/object/type-registry-helper.h>
 #include <dali/public-api/object/type-registry.h>
 #include <cstring>
+#include <memory>
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/devel-api/controls/control-devel.h>
 #include <dali-toolkit/devel-api/controls/web-view/web-back-forward-list.h>
 #include <dali-toolkit/devel-api/controls/web-view/web-context.h>
 #include <dali-toolkit/devel-api/controls/web-view/web-cookie-manager.h>
+#include <dali-toolkit/devel-api/controls/web-view/web-form-repost-decision.h>
 #include <dali-toolkit/devel-api/controls/web-view/web-settings.h>
 #include <dali-toolkit/devel-api/image-loader/texture-manager.h>
 #include <dali-toolkit/internal/visuals/visual-factory-impl.h>
@@ -58,22 +69,40 @@ BaseHandle Create()
 // clang-format off
 DALI_TYPE_REGISTRATION_BEGIN(Toolkit::WebView, Toolkit::Control, Create)
 
-DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "url",                STRING,  URL                 )
-DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "userAgent",          STRING,  USER_AGENT          )
-DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "scrollPosition",     VECTOR2, SCROLL_POSITION     )
-DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "scrollSize",         VECTOR2, SCROLL_SIZE         )
-DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "contentSize",        VECTOR2, CONTENT_SIZE        )
-DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "title",              STRING,  TITLE               )
-DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "videoHoleEnabled",   BOOLEAN, VIDEO_HOLE_ENABLED  )
-DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "mouseEventsEnabled", BOOLEAN, MOUSE_EVENTS_ENABLED)
-DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "keyEventsEnabled",   BOOLEAN, KEY_EVENTS_ENABLED  )
-
-DALI_SIGNAL_REGISTRATION(Toolkit, WebView, "pageLoadStarted",    PAGE_LOAD_STARTED_SIGNAL    )
-DALI_SIGNAL_REGISTRATION(Toolkit, WebView, "pageLoadInProgress", PAGE_LOAD_IN_PROGRESS_SIGNAL)
-DALI_SIGNAL_REGISTRATION(Toolkit, WebView, "pageLoadFinished",   PAGE_LOAD_FINISHED_SIGNAL   )
-DALI_SIGNAL_REGISTRATION(Toolkit, WebView, "pageLoadError",      PAGE_LOAD_ERROR_SIGNAL      )
-DALI_SIGNAL_REGISTRATION(Toolkit, WebView, "scrollEdgeReached",  SCROLL_EDGE_REACHED_SIGNAL  )
-DALI_SIGNAL_REGISTRATION(Toolkit, WebView, "urlChanged",         URL_CHANGED_SIGNAL          )
+DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "url",                     STRING,  URL                       )
+DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "userAgent",               STRING,  USER_AGENT                )
+DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "scrollPosition",          VECTOR2, SCROLL_POSITION           )
+DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "scrollSize",              VECTOR2, SCROLL_SIZE               )
+DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "contentSize",             VECTOR2, CONTENT_SIZE              )
+DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "title",                   STRING,  TITLE                     )
+DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "videoHoleEnabled",        BOOLEAN, VIDEO_HOLE_ENABLED        )
+DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "mouseEventsEnabled",      BOOLEAN, MOUSE_EVENTS_ENABLED      )
+DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "keyEventsEnabled",        BOOLEAN, KEY_EVENTS_ENABLED        )
+DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "documentBackgroundColor", VECTOR4, DOCUMENT_BACKGROUND_COLOR )
+DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "tilesClearedWhenHidden",  BOOLEAN, TILES_CLEARED_WHEN_HIDDEN )
+DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "tileCoverAreaMultiplier", FLOAT,   TILE_COVER_AREA_MULTIPLIER)
+DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "cursorEnabledByClient",   BOOLEAN, CURSOR_ENABLED_BY_CLIENT  )
+DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "selectedText",            STRING,  SELECTED_TEXT             )
+DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "pageZoomFactor",          FLOAT,   PAGE_ZOOM_FACTOR          )
+DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "textZoomFactor",          FLOAT,   TEXT_ZOOM_FACTOR          )
+DALI_PROPERTY_REGISTRATION(Toolkit, WebView, "loadProgressPercentage",  FLOAT,   LOAD_PROGRESS_PERCENTAGE  )
+
+DALI_SIGNAL_REGISTRATION(Toolkit, WebView, "pageLoadStarted",         PAGE_LOAD_STARTED_SIGNAL         )
+DALI_SIGNAL_REGISTRATION(Toolkit, WebView, "pageLoadInProgress",      PAGE_LOAD_IN_PROGRESS_SIGNAL     )
+DALI_SIGNAL_REGISTRATION(Toolkit, WebView, "pageLoadFinished",        PAGE_LOAD_FINISHED_SIGNAL        )
+DALI_SIGNAL_REGISTRATION(Toolkit, WebView, "pageLoadError",           PAGE_LOAD_ERROR_SIGNAL           )
+DALI_SIGNAL_REGISTRATION(Toolkit, WebView, "scrollEdgeReached",       SCROLL_EDGE_REACHED_SIGNAL       )
+DALI_SIGNAL_REGISTRATION(Toolkit, WebView, "urlChanged",              URL_CHANGED_SIGNAL               )
+DALI_SIGNAL_REGISTRATION(Toolkit, WebView, "formRepostDecision",      FORM_REPOST_DECISION_SIGNAL      )
+DALI_SIGNAL_REGISTRATION(Toolkit, WebView, "frameRendered",           FRAME_RENDERED_SIGNAL            )
+DALI_SIGNAL_REGISTRATION(Toolkit, WebView, "requestInterceptor",      REQUEST_INTERCEPTOR_SIGNAL       )
+DALI_SIGNAL_REGISTRATION(Toolkit, WebView, "consoleMessage",          CONSOLE_MESSAGE_SIGNAL           )
+DALI_SIGNAL_REGISTRATION(Toolkit, WebView, "policyDecision",          POLICY_DECISION                  )
+DALI_SIGNAL_REGISTRATION(Toolkit, WebView, "certificateConfirm",      CERTIFICATE_CONFIRM_SIGNAL       )
+DALI_SIGNAL_REGISTRATION(Toolkit, WebView, "sslCertificateChanged",   SSL_CERTIFICATE_CHANGED_SIGNAL   )
+DALI_SIGNAL_REGISTRATION(Toolkit, WebView, "httpAuthRequest",         HTTP_AUTH_REQUEST_SIGNAL         )
+DALI_SIGNAL_REGISTRATION(Toolkit, WebView, "contextMenuCustomized",   CONTEXT_MENU_CUSTOMIZED_SIGNAL   )
+DALI_SIGNAL_REGISTRATION(Toolkit, WebView, "contextMenuItemSelected", CONTEXT_MENU_ITEM_SELECTED_SIGNAL)
 
 DALI_TYPE_REGISTRATION_END()
 // clang-format on
@@ -97,9 +126,9 @@ WebView::WebView(const std::string& locale, const std::string& timezoneId)
   mPageLoadStartedSignal(),
   mPageLoadFinishedSignal(),
   mPageLoadErrorSignal(),
-  mVideoHoleEnabled(true),
-  mWebViewArea(0, 0, mWebViewSize.width, mWebViewSize.height),
   mUrlChangedSignal(),
+  mWebViewArea(0, 0, mWebViewSize.width, mWebViewSize.height),
+  mVideoHoleEnabled(true),
   mMouseEventsEnabled(true),
   mKeyEventsEnabled(true)
 {
@@ -121,9 +150,9 @@ WebView::WebView(int argc, char** argv)
   mPageLoadStartedSignal(),
   mPageLoadFinishedSignal(),
   mPageLoadErrorSignal(),
-  mVideoHoleEnabled(true),
-  mWebViewArea(0, 0, mWebViewSize.width, mWebViewSize.height),
   mUrlChangedSignal(),
+  mWebViewArea(0, 0, mWebViewSize.width, mWebViewSize.height),
+  mVideoHoleEnabled(true),
   mMouseEventsEnabled(true),
   mKeyEventsEnabled(true)
 {
@@ -184,6 +213,7 @@ void WebView::OnInitialize()
   self.TouchedSignal().Connect(this, &WebView::OnTouchEvent);
   self.HoveredSignal().Connect(this, &WebView::OnHoverEvent);
   self.WheelEventSignal().Connect(this, &WebView::OnWheelEvent);
+  Dali::DevelActor::VisibilityChangedSignal(self).Connect(this, &WebView::OnVisibilityChanged);
 
   mPositionUpdateNotification = self.AddPropertyNotification(Actor::Property::WORLD_POSITION, StepCondition(1.0f, 1.0f));
   mSizeUpdateNotification     = self.AddPropertyNotification(Actor::Property::SIZE, StepCondition(1.0f, 1.0f));
@@ -200,6 +230,16 @@ void WebView::OnInitialize()
     mWebEngine.PageLoadErrorSignal().Connect(this, &WebView::OnPageLoadError);
     mWebEngine.ScrollEdgeReachedSignal().Connect(this, &WebView::OnScrollEdgeReached);
     mWebEngine.UrlChangedSignal().Connect(this, &WebView::OnUrlChanged);
+    mWebEngine.FormRepostDecisionSignal().Connect(this, &WebView::OnFormRepostDecision);
+    mWebEngine.FrameRenderedSignal().Connect(this, &WebView::OnFrameRendered);
+    mWebEngine.RequestInterceptorSignal().Connect(this, &WebView::OnInterceptRequest);
+    mWebEngine.ConsoleMessageSignal().Connect(this, &WebView::OnConsoleMessage);
+    mWebEngine.PolicyDecisionSignal().Connect(this, &WebView::OnPolicyDecisionRequest);
+    mWebEngine.CertificateConfirmSignal().Connect(this, &WebView::OnCertificateConfirm);
+    mWebEngine.SslCertificateChangedSignal().Connect(this, &WebView::OnSslCertificateChanged);
+    mWebEngine.HttpAuthHandlerSignal().Connect(this, &WebView::OnHttpAuthenticationRequest);
+    mWebEngine.ContextMenuCustomizedSignal().Connect(this, &WebView::OnContextMenuCustomized);
+    mWebEngine.ContextMenuItemSelectedSignal().Connect(this, &WebView::OnContextMenuItemSelected);
 
     mWebContext         = std::unique_ptr<Dali::Toolkit::WebContext>(new WebContext(mWebEngine.GetContext()));
     mWebCookieManager   = std::unique_ptr<Dali::Toolkit::WebCookieManager>(new WebCookieManager(mWebEngine.GetCookieManager()));
@@ -233,10 +273,7 @@ Dali::Toolkit::ImageView& WebView::GetFavicon()
   if(mWebEngine)
   {
     Dali::PixelData pixelData = mWebEngine.GetFavicon();
-    std::string     url       = Dali::Toolkit::Image::GenerateUrl(pixelData);
-    mFaviconView              = Dali::Toolkit::ImageView::New(url);
-    mFaviconView.SetResizePolicy(ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS);
-    mFaviconView.SetProperty(Dali::Actor::Property::SIZE, Vector2(pixelData.GetWidth(), pixelData.GetHeight()));
+    mFaviconView              = CreateImageView(pixelData);
   }
   return mFaviconView;
 }
@@ -289,6 +326,56 @@ void WebView::LoadHtmlString(const std::string& htmlString)
   }
 }
 
+bool WebView::LoadHtmlStringOverrideCurrentEntry(const std::string& html, const std::string& basicUri, const std::string& unreachableUrl)
+{
+  if(!mWebEngine)
+    return false;
+
+  Texture           texture        = Dali::Texture::New(*mWebEngine.GetNativeImageSource());
+  const std::string nativeImageUrl = Dali::Toolkit::TextureManager::AddTexture(texture);
+  mVisual                          = Toolkit::VisualFactory::Get().CreateVisual(
+    {{Toolkit::Visual::Property::TYPE, Toolkit::Visual::IMAGE},
+     {Toolkit::ImageVisual::Property::URL, nativeImageUrl}});
+
+  bool result = false;
+  if(mVisual)
+  {
+    DevelControl::RegisterVisual(*this, Toolkit::WebView::Property::URL, mVisual);
+    result = mWebEngine.LoadHtmlStringOverrideCurrentEntry(html, basicUri, unreachableUrl);
+  }
+
+  if(mVideoHoleEnabled)
+  {
+    EnableBlendMode(false);
+  }
+  return result;
+}
+
+bool WebView::LoadContents(const std::string& contents, uint32_t contentSize, const std::string& mimeType, const std::string& encoding, const std::string& baseUri)
+{
+  if(!mWebEngine)
+    return false;
+
+  Texture           texture        = Dali::Texture::New(*mWebEngine.GetNativeImageSource());
+  const std::string nativeImageUrl = Dali::Toolkit::TextureManager::AddTexture(texture);
+  mVisual                          = Toolkit::VisualFactory::Get().CreateVisual(
+    {{Toolkit::Visual::Property::TYPE, Toolkit::Visual::IMAGE},
+     {Toolkit::ImageVisual::Property::URL, nativeImageUrl}});
+
+  bool result = false;
+  if(mVisual)
+  {
+    DevelControl::RegisterVisual(*this, Toolkit::WebView::Property::URL, mVisual);
+    result = mWebEngine.LoadContents(contents, contentSize, mimeType, encoding, baseUri);
+  }
+
+  if(mVideoHoleEnabled)
+  {
+    EnableBlendMode(false);
+  }
+  return result;
+}
+
 void WebView::Reload()
 {
   if(mWebEngine)
@@ -297,6 +384,11 @@ void WebView::Reload()
   }
 }
 
+bool WebView::ReloadWithoutCache()
+{
+  return mWebEngine ? mWebEngine.ReloadWithoutCache() : false;
+}
+
 void WebView::StopLoading()
 {
   if(mWebEngine)
@@ -321,6 +413,42 @@ void WebView::Resume()
   }
 }
 
+void WebView::SuspendNetworkLoading()
+{
+  if(mWebEngine)
+  {
+    mWebEngine.SuspendNetworkLoading();
+  }
+}
+
+void WebView::ResumeNetworkLoading()
+{
+  if(mWebEngine)
+  {
+    mWebEngine.ResumeNetworkLoading();
+  }
+}
+
+bool WebView::AddCustomHeader(const std::string& name, const std::string& value)
+{
+  return mWebEngine ? mWebEngine.AddCustomHeader(name, value) : false;
+}
+
+bool WebView::RemoveCustomHeader(const std::string& name)
+{
+  return mWebEngine ? mWebEngine.RemoveCustomHeader(name) : false;
+}
+
+uint32_t WebView::StartInspectorServer(uint32_t port)
+{
+  return mWebEngine ? mWebEngine.StartInspectorServer(port) : false;
+}
+
+bool WebView::StopInspectorServer()
+{
+  return mWebEngine ? mWebEngine.StopInspectorServer() : false;
+}
+
 void WebView::ScrollBy(int deltaX, int deltaY)
 {
   if(mWebEngine)
@@ -329,6 +457,11 @@ void WebView::ScrollBy(int deltaX, int deltaY)
   }
 }
 
+bool WebView::ScrollEdgeBy(int deltaX, int deltaY)
+{
+  return mWebEngine ? mWebEngine.ScrollEdgeBy(deltaX, deltaY) : false;
+}
+
 bool WebView::CanGoForward()
 {
   return mWebEngine ? mWebEngine.CanGoForward() : false;
@@ -427,6 +560,78 @@ void WebView::ClearHistory()
   }
 }
 
+void WebView::ClearAllTilesResources()
+{
+  if(mWebEngine)
+  {
+    mWebEngine.ClearAllTilesResources();
+  }
+}
+
+void WebView::SetScaleFactor(float scaleFactor, Dali::Vector2 point)
+{
+  if(mWebEngine)
+  {
+    mWebEngine.SetScaleFactor(scaleFactor, point);
+  }
+}
+
+float WebView::GetScaleFactor() const
+{
+  return mWebEngine ? mWebEngine.GetScaleFactor() : 0.0f;
+}
+
+void WebView::ActivateAccessibility(bool activated)
+{
+  if(mWebEngine)
+  {
+    mWebEngine.ActivateAccessibility(activated);
+  }
+}
+
+bool WebView::HighlightText(const std::string& text, Dali::WebEnginePlugin::FindOption options, uint32_t maxMatchCount)
+{
+  return mWebEngine ? mWebEngine.HighlightText(text, options, maxMatchCount) : false;
+}
+
+void WebView::AddDynamicCertificatePath(const std::string& host, const std::string& certPath)
+{
+  if(mWebEngine)
+  {
+    mWebEngine.AddDynamicCertificatePath(host, certPath);
+  }
+}
+
+Dali::Toolkit::ImageView WebView::GetScreenshot(Dali::Rect<int> viewArea, float scaleFactor)
+{
+  Dali::Toolkit::ImageView imageView;
+  if(mWebEngine)
+  {
+    Dali::PixelData pixelData = mWebEngine.GetScreenshot(viewArea, scaleFactor);
+    imageView                 = CreateImageView(pixelData);
+  }
+  return imageView;
+}
+
+bool WebView::GetScreenshotAsynchronously(Dali::Rect<int> viewArea, float scaleFactor, Dali::Toolkit::WebView::WebViewScreenshotCapturedCallback callback)
+{
+  mScreenshotCapturedCallback = callback;
+  return mWebEngine ? mWebEngine.GetScreenshotAsynchronously(viewArea, scaleFactor, std::bind(&WebView::OnScreenshotCaptured, this, std::placeholders::_1)) : false;
+}
+
+bool WebView::CheckVideoPlayingAsynchronously(Dali::WebEnginePlugin::VideoPlayingCallback callback)
+{
+  return mWebEngine ? mWebEngine.CheckVideoPlayingAsynchronously(callback) : false;
+}
+
+void WebView::RegisterGeolocationPermissionCallback(Dali::WebEnginePlugin::GeolocationPermissionCallback callback)
+{
+  if(mWebEngine)
+  {
+    mWebEngine.RegisterGeolocationPermissionCallback(callback);
+  }
+}
+
 void WebView::UpdateDisplayArea(Dali::PropertyNotification& /*source*/)
 {
   if(!mWebEngine)
@@ -480,12 +685,12 @@ void WebView::EnableBlendMode(bool blendEnabled)
   }
 }
 
-void WebView::ClearAllTilesResources()
+Dali::Toolkit::ImageView WebView::CreateImageView(Dali::PixelData pixel)
 {
-  if(mWebEngine)
-  {
-    mWebEngine.ClearAllTilesResources();
-  }
+  std::string              url       = Dali::Toolkit::Image::GenerateUrl(pixel);
+  Dali::Toolkit::ImageView imageView = Dali::Toolkit::ImageView::New(url);
+  imageView.SetProperty(Dali::Actor::Property::SIZE, Vector2(pixel.GetWidth(), pixel.GetHeight()));
+  return imageView;
 }
 
 Dali::Toolkit::WebView::WebViewPageLoadSignalType& WebView::PageLoadStartedSignal()
@@ -518,6 +723,56 @@ Dali::Toolkit::WebView::WebViewUrlChangedSignalType& WebView::UrlChangedSignal()
   return mUrlChangedSignal;
 }
 
+Dali::Toolkit::WebView::WebViewFormRepostDecisionSignalType& WebView::FormRepostDecisionSignal()
+{
+  return mFormRepostDecisionSignal;
+}
+
+Dali::Toolkit::WebView::WebViewFrameRenderedSignalType& WebView::FrameRenderedSignal()
+{
+  return mFrameRenderedSignal;
+}
+
+Dali::Toolkit::WebView::WebViewRequestInterceptorSignalType& WebView::RequestInterceptorSignal()
+{
+  return mRequestInterceptorSignal;
+}
+
+Dali::Toolkit::WebView::WebViewConsoleMessageSignalType& WebView::ConsoleMessageSignal()
+{
+  return mConsoleMessageSignal;
+}
+
+Dali::Toolkit::WebView::WebViewPolicyDecisionSignalType& WebView::PolicyDecisionSignal()
+{
+  return mPolicyDecisionSignal;
+}
+
+Dali::Toolkit::WebView::WebViewCertificateSignalType& WebView::CertificateConfirmSignal()
+{
+  return mCertificateConfirmSignal;
+}
+
+Dali::Toolkit::WebView::WebViewCertificateSignalType& WebView::SslCertificateChangedSignal()
+{
+  return mSslCertificateChangedSignal;
+}
+
+Dali::Toolkit::WebView::WebViewHttpAuthHandlerSignalType& WebView::HttpAuthHandlerSignal()
+{
+  return mHttpAuthHandlerSignal;
+}
+
+Dali::Toolkit::WebView::WebViewContextMenuCustomizedSignalType& WebView::ContextMenuCustomizedSignal()
+{
+  return mContextMenuCustomizedSignal;
+}
+
+Dali::Toolkit::WebView::WebViewContextMenuItemSelectedSignalType& WebView::ContextMenuItemSelectedSignal()
+{
+  return mContextMenuItemSelectedSignal;
+}
+
 void WebView::OnPageLoadStarted(const std::string& url)
 {
   if(!mPageLoadStartedSignal.Empty())
@@ -545,12 +800,12 @@ void WebView::OnPageLoadFinished(const std::string& url)
   }
 }
 
-void WebView::OnPageLoadError(const std::string& url, int errorCode)
+void WebView::OnPageLoadError(std::shared_ptr<Dali::WebEngineLoadError> error)
 {
   if(!mPageLoadErrorSignal.Empty())
   {
     Dali::Toolkit::WebView handle(GetOwner());
-    mPageLoadErrorSignal.Emit(handle, url, static_cast<Toolkit::WebView::LoadErrorCode>(errorCode));
+    mPageLoadErrorSignal.Emit(handle, std::move(error));
   }
 }
 
@@ -572,6 +827,114 @@ void WebView::OnUrlChanged(const std::string& url)
   }
 }
 
+void WebView::OnFormRepostDecision(std::shared_ptr<Dali::WebEngineFormRepostDecision> decision)
+{
+  if(!mFormRepostDecisionSignal.Empty())
+  {
+    Dali::Toolkit::WebView                                handle(GetOwner());
+    std::shared_ptr<Dali::Toolkit::WebFormRepostDecision> repostDecision(new Dali::Toolkit::WebFormRepostDecision(decision));
+    mFormRepostDecisionSignal.Emit(handle, std::move(repostDecision));
+  }
+}
+
+void WebView::OnFrameRendered()
+{
+  if(!mFrameRenderedSignal.Empty())
+  {
+    Dali::Toolkit::WebView handle(GetOwner());
+    mFrameRenderedSignal.Emit(handle);
+  }
+}
+
+void WebView::OnVisibilityChanged(Actor actor, bool isVisible, Dali::DevelActor::VisibilityChange::Type type)
+{
+  if(type == Dali::DevelActor::VisibilityChange::Type::SELF)
+  {
+    SetVisibility(isVisible);
+  }
+}
+
+void WebView::OnScreenshotCaptured(Dali::PixelData pixel)
+{
+  if(mScreenshotCapturedCallback)
+  {
+    Dali::Toolkit::ImageView imageView = CreateImageView(pixel);
+    mScreenshotCapturedCallback(imageView);
+  }
+}
+
+void WebView::OnInterceptRequest(std::shared_ptr<Dali::WebEngineRequestInterceptor> interceptor)
+{
+  if(!mRequestInterceptorSignal.Empty())
+  {
+    Dali::Toolkit::WebView handle(GetOwner());
+    mRequestInterceptorSignal.Emit(handle, std::move(interceptor));
+  }
+}
+
+void WebView::OnConsoleMessage(std::shared_ptr<Dali::WebEngineConsoleMessage> message)
+{
+  if(!mConsoleMessageSignal.Empty())
+  {
+    Dali::Toolkit::WebView handle(GetOwner());
+    mConsoleMessageSignal.Emit(handle, std::move(message));
+  }
+}
+
+void WebView::OnPolicyDecisionRequest(std::shared_ptr<Dali::WebEnginePolicyDecision> decision)
+{
+  if(!mPolicyDecisionSignal.Empty())
+  {
+    Dali::Toolkit::WebView handle(GetOwner());
+    mPolicyDecisionSignal.Emit(handle, std::move(decision));
+  }
+}
+
+void WebView::OnCertificateConfirm(std::shared_ptr<Dali::WebEngineCertificate> certificate)
+{
+  if(!mCertificateConfirmSignal.Empty())
+  {
+    Dali::Toolkit::WebView handle(GetOwner());
+    mCertificateConfirmSignal.Emit(handle, std::move(certificate));
+  }
+}
+
+void WebView::OnSslCertificateChanged(std::shared_ptr<Dali::WebEngineCertificate> certificate)
+{
+  if(!mSslCertificateChangedSignal.Empty())
+  {
+    Dali::Toolkit::WebView handle(GetOwner());
+    mSslCertificateChangedSignal.Emit(handle, std::move(certificate));
+  }
+}
+
+void WebView::OnHttpAuthenticationRequest(std::shared_ptr<Dali::WebEngineHttpAuthHandler> handler)
+{
+  if(!mHttpAuthHandlerSignal.Empty())
+  {
+    Dali::Toolkit::WebView handle(GetOwner());
+    mHttpAuthHandlerSignal.Emit(handle, std::move(handler));
+  }
+}
+
+void WebView::OnContextMenuCustomized(std::shared_ptr<Dali::WebEngineContextMenu> menu)
+{
+  if(!mContextMenuCustomizedSignal.Empty())
+  {
+    Dali::Toolkit::WebView handle(GetOwner());
+    mContextMenuCustomizedSignal.Emit(handle, std::move(menu));
+  }
+}
+
+void WebView::OnContextMenuItemSelected(std::shared_ptr<Dali::WebEngineContextMenuItem> item)
+{
+  if(!mContextMenuItemSelectedSignal.Empty())
+  {
+    Dali::Toolkit::WebView handle(GetOwner());
+    mContextMenuItemSelectedSignal.Emit(handle, std::move(item));
+  }
+}
+
 bool WebView::DoConnectSignal(BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor)
 {
   Dali::BaseHandle handle(object);
@@ -609,6 +972,56 @@ bool WebView::DoConnectSignal(BaseObject* object, ConnectionTrackerInterface* tr
     webView.UrlChangedSignal().Connect(tracker, functor);
     connected = true;
   }
+  else if(0 == strcmp(signalName.c_str(), FORM_REPOST_DECISION_SIGNAL))
+  {
+    webView.FormRepostDecisionSignal().Connect(tracker, functor);
+    connected = true;
+  }
+  else if(0 == strcmp(signalName.c_str(), FRAME_RENDERED_SIGNAL))
+  {
+    webView.FrameRenderedSignal().Connect(tracker, functor);
+    connected = true;
+  }
+  else if(0 == strcmp(signalName.c_str(), REQUEST_INTERCEPTOR_SIGNAL))
+  {
+    webView.RequestInterceptorSignal().Connect(tracker, functor);
+    connected = true;
+  }
+  else if(0 == strcmp(signalName.c_str(), CONSOLE_MESSAGE_SIGNAL))
+  {
+    webView.ConsoleMessageSignal().Connect(tracker, functor);
+    connected = true;
+  }
+  else if(0 == strcmp(signalName.c_str(), POLICY_DECISION))
+  {
+    webView.PolicyDecisionSignal().Connect(tracker, functor);
+    connected = true;
+  }
+  else if(0 == strcmp(signalName.c_str(), CERTIFICATE_CONFIRM_SIGNAL))
+  {
+    webView.CertificateConfirmSignal().Connect(tracker, functor);
+    connected = true;
+  }
+  else if(0 == strcmp(signalName.c_str(), SSL_CERTIFICATE_CHANGED_SIGNAL))
+  {
+    webView.SslCertificateChangedSignal().Connect(tracker, functor);
+    connected = true;
+  }
+  else if(0 == strcmp(signalName.c_str(), HTTP_AUTH_REQUEST_SIGNAL))
+  {
+    webView.HttpAuthHandlerSignal().Connect(tracker, functor);
+    connected = true;
+  }
+  else if(0 == strcmp(signalName.c_str(), CONTEXT_MENU_CUSTOMIZED_SIGNAL))
+  {
+    webView.ContextMenuCustomizedSignal().Connect(tracker, functor);
+    connected = true;
+  }
+  else if(0 == strcmp(signalName.c_str(), CONTEXT_MENU_ITEM_SELECTED_SIGNAL))
+  {
+    webView.ContextMenuItemSelectedSignal().Connect(tracker, functor);
+    connected = true;
+  }
 
   return connected;
 }
@@ -695,6 +1108,62 @@ void WebView::SetProperty(BaseObject* object, Property::Index index, const Prope
         }
         break;
       }
+      case Toolkit::WebView::Property::DOCUMENT_BACKGROUND_COLOR:
+      {
+        Vector4 input;
+        if(value.Get(input))
+        {
+          impl.SetDocumentBackgroundColor(input);
+        }
+        break;
+      }
+      case Toolkit::WebView::Property::TILES_CLEARED_WHEN_HIDDEN:
+      {
+        bool input;
+        if(value.Get(input))
+        {
+          impl.ClearTilesWhenHidden(input);
+        }
+        break;
+      }
+      case Toolkit::WebView::Property::TILE_COVER_AREA_MULTIPLIER:
+      {
+        float input;
+        if(value.Get(input))
+        {
+          impl.SetTileCoverAreaMultiplier(input);
+        }
+        break;
+      }
+      case Toolkit::WebView::Property::CURSOR_ENABLED_BY_CLIENT:
+      {
+        bool input;
+        if(value.Get(input))
+        {
+          impl.EnableCursorByClient(input);
+        }
+        break;
+      }
+      case Toolkit::WebView::Property::PAGE_ZOOM_FACTOR:
+      {
+        float input;
+        if(value.Get(input))
+        {
+          impl.SetPageZoomFactor(input);
+        }
+        break;
+      }
+      case Toolkit::WebView::Property::TEXT_ZOOM_FACTOR:
+      {
+        float input;
+        if(value.Get(input))
+        {
+          impl.SetTextZoomFactor(input);
+        }
+        break;
+      }
+      default:
+        break;
     }
   }
 }
@@ -755,6 +1224,26 @@ Property::Value WebView::GetProperty(BaseObject* object, Property::Index propert
         value = impl.mKeyEventsEnabled;
         break;
       }
+      case Toolkit::WebView::Property::SELECTED_TEXT:
+      {
+        value = impl.GetSelectedText();
+        break;
+      }
+      case Toolkit::WebView::Property::PAGE_ZOOM_FACTOR:
+      {
+        value = impl.GetPageZoomFactor();
+        break;
+      }
+      case Toolkit::WebView::Property::TEXT_ZOOM_FACTOR:
+      {
+        value = impl.GetTextZoomFactor();
+        break;
+      }
+      case Toolkit::WebView::Property::LOAD_PROGRESS_PERCENTAGE:
+      {
+        value = impl.GetLoadProgressPercentage();
+        break;
+      }
       default:
         break;
     }
@@ -853,6 +1342,43 @@ std::string WebView::GetTitle() const
   return mWebEngine ? mWebEngine.GetTitle() : kEmptyString;
 }
 
+void WebView::SetDocumentBackgroundColor(Dali::Vector4 color)
+{
+  if(mWebEngine)
+  {
+    mWebEngine.SetDocumentBackgroundColor(color);
+  }
+}
+
+void WebView::ClearTilesWhenHidden(bool cleared)
+{
+  if(mWebEngine)
+  {
+    mWebEngine.ClearTilesWhenHidden(cleared);
+  }
+}
+
+void WebView::SetTileCoverAreaMultiplier(float multiplier)
+{
+  if(mWebEngine)
+  {
+    mWebEngine.SetTileCoverAreaMultiplier(multiplier);
+  }
+}
+
+void WebView::EnableCursorByClient(bool enabled)
+{
+  if(mWebEngine)
+  {
+    mWebEngine.EnableCursorByClient(enabled);
+  }
+}
+
+std::string WebView::GetSelectedText() const
+{
+  return mWebEngine ? mWebEngine.GetSelectedText() : kEmptyString;
+}
+
 const std::string& WebView::GetUserAgent() const
 {
   return mWebEngine ? mWebEngine.GetUserAgent() : kEmptyString;
@@ -884,6 +1410,42 @@ void WebView::EnableKeyEvents(bool enabled)
   }
 }
 
+void WebView::SetPageZoomFactor(float zoomFactor)
+{
+  if(mWebEngine)
+  {
+    mWebEngine.SetPageZoomFactor(zoomFactor);
+  }
+}
+
+float WebView::GetPageZoomFactor() const
+{
+  return mWebEngine ? mWebEngine.GetPageZoomFactor() : 0.0f;
+}
+
+void WebView::SetTextZoomFactor(float zoomFactor)
+{
+  if(mWebEngine)
+  {
+    mWebEngine.SetTextZoomFactor(zoomFactor);
+  }
+}
+
+float WebView::GetTextZoomFactor() const
+{
+  return mWebEngine ? mWebEngine.GetTextZoomFactor() : 0.0f;
+}
+
+float WebView::GetLoadProgressPercentage() const
+{
+  return mWebEngine ? mWebEngine.GetLoadProgressPercentage() : 0.0f;
+}
+
+bool WebView::SetVisibility(bool visible)
+{
+  return mWebEngine ? mWebEngine.SetVisibility(visible) : false;
+}
+
 #undef GET_ENUM_STRING
 #undef GET_ENUM_VALUE
 
old mode 100644 (file)
new mode 100755 (executable)
index 9abfd49..99a964c
@@ -19,6 +19,7 @@
  */
 
 // EXTERNAL INCLUDES
+#include <dali/devel-api/actors/actor-devel.h>
 #include <dali/devel-api/adaptor-framework/web-engine.h>
 #include <dali/public-api/images/image-operations.h>
 #include <dali/public-api/object/property-notification.h>
@@ -67,6 +68,11 @@ public:
   static Toolkit::WebView New(const std::string& locale, const std::string& timezoneId);
 
   /**
+   * @copydoc Dali::Toolkit::WebView::New( int, char** )
+   */
+  static Toolkit::WebView New(int argc, char** argv);
+
+  /**
    * @brief Get settings of WebEngine.
    */
   Dali::Toolkit::WebSettings* GetSettings() const;
@@ -87,11 +93,6 @@ public:
   Dali::Toolkit::WebBackForwardList* GetBackForwardList() const;
 
   /**
-   * @copydoc Dali::Toolkit::WebView::New( int, char** )
-   */
-  static Toolkit::WebView New(int argc, char** argv);
-
-  /**
    * @brief Get Favicon of web page.
    *
    * @return Handle to a fav icon
@@ -109,11 +110,26 @@ public:
   void LoadHtmlString(const std::string& htmlString);
 
   /**
+   * @copydoc Dali::WebEngine::LoadHtmlStringOverrideCurrentEntry()
+   */
+  bool LoadHtmlStringOverrideCurrentEntry(const std::string& html, const std::string& basicUri, const std::string& unreachableUrl);
+
+  /**
+   * @copydoc Dali::WebEngine::LoadContents()
+   */
+  bool LoadContents(const std::string& contents, uint32_t contentSize, const std::string& mimeType, const std::string& encoding, const std::string& baseUri);
+
+  /**
    * @copydoc Dali::Toolkit::WebView::Reload()
    */
   void Reload();
 
   /**
+   * @copydoc Dali::WebEngine::ReloadWithoutCache()
+   */
+  bool ReloadWithoutCache();
+
+  /**
    * @copydoc Dali::Toolkit::WebView::StopLoading()
    */
   void StopLoading();
@@ -129,11 +145,46 @@ public:
   void Resume();
 
   /**
+   * @copydoc Dali::WebEngine::SuspendNetworkLoading()
+   */
+  void SuspendNetworkLoading();
+
+  /**
+   * @copydoc Dali::WebEngine::ResumeNetworkLoading()
+   */
+  void ResumeNetworkLoading();
+
+  /**
+   * @copydoc Dali::WebEngine::AddCustomHeader()
+   */
+  bool AddCustomHeader(const std::string& name, const std::string& value);
+
+  /**
+   * @copydoc Dali::WebEngine::RemoveCustomHeader()
+   */
+  bool RemoveCustomHeader(const std::string& name);
+
+  /**
+   * @copydoc Dali::WebEngine::StartInspectorServer()
+   */
+  uint32_t StartInspectorServer(uint32_t port);
+
+  /**
+   * @copydoc Dali::WebEngine::StopInspectorServer()
+   */
+  bool StopInspectorServer();
+
+  /**
    * @copydoc Dali::Toolkit::WebView::ScrollBy()
    */
   void ScrollBy(int deltaX, int deltaY);
 
   /**
+   * @copydoc Dali::WebEngine::ScrollEdgeBy()
+   */
+  bool ScrollEdgeBy(int deltaX, int deltaY);
+
+  /**
    * @copydoc Dali::Toolkit::WebView::CanGoForward()
    */
   bool CanGoForward();
@@ -199,11 +250,56 @@ public:
   void ClearHistory();
 
   /**
-   * @brief Clears all tiles resources of Web.
+   * @copydoc Dali::Toolkit::WebView::ClearAllTilesResources()
    */
   void ClearAllTilesResources();
 
   /**
+   * @copydoc Dali::Toolkit::WebView::SetScaleFactor()
+   */
+  void SetScaleFactor(float scaleFactor, Dali::Vector2 point);
+
+  /**
+   * @copydoc Dali::Toolkit::WebView::GetScaleFactor()
+   */
+  float GetScaleFactor() const;
+
+  /**
+   * @copydoc Dali::Toolkit::WebView::ActivateAccessibility()
+   */
+  void ActivateAccessibility(bool activated);
+
+  /**
+   * @copydoc Dali::Toolkit::WebView::HighlightText()
+   */
+  bool HighlightText(const std::string& text, Dali::WebEnginePlugin::FindOption options, uint32_t maxMatchCount);
+
+  /**
+   * @copydoc Dali::Toolkit::WebView::AddDynamicCertificatePath()
+   */
+  void AddDynamicCertificatePath(const std::string& host, const std::string& certPath);
+
+  /**
+   * @copydoc Dali::Toolkit::WebView::GetScreenshot()
+   */
+  Dali::Toolkit::ImageView GetScreenshot(Dali::Rect<int> viewArea, float scaleFactor);
+
+  /**
+   * @copydoc Dali::Toolkit::WebView::GetScreenshotAsynchronously()
+   */
+  bool GetScreenshotAsynchronously(Dali::Rect<int> viewArea, float scaleFactor, Dali::Toolkit::WebView::WebViewScreenshotCapturedCallback callback);
+
+  /**
+   * @copydoc Dali::Toolkit::WebView::CheckVideoPlayingAsynchronously()
+   */
+  bool CheckVideoPlayingAsynchronously(Dali::WebEnginePlugin::VideoPlayingCallback callback);
+
+  /**
+   * @copydoc Dali::Toolkit::WebView::RegisterGeolocationPermissionCallback()
+   */
+  void RegisterGeolocationPermissionCallback(Dali::WebEnginePlugin::GeolocationPermissionCallback callback);
+
+  /**
    * @copydoc Dali::Toolkit::WebView::PageLoadStartedSignal()
    */
   Dali::Toolkit::WebView::WebViewPageLoadSignalType& PageLoadStartedSignal();
@@ -233,6 +329,56 @@ public:
    */
   Dali::Toolkit::WebView::WebViewUrlChangedSignalType& UrlChangedSignal();
 
+  /**
+   * @copydoc Dali::Toolkit::WebView::FormRepostDecisionSignal()
+   */
+  Dali::Toolkit::WebView::WebViewFormRepostDecisionSignalType& FormRepostDecisionSignal();
+
+  /**
+   * @copydoc Dali::Toolkit::WebView::FrameRenderedSignal()
+   */
+  Dali::Toolkit::WebView::WebViewFrameRenderedSignalType& FrameRenderedSignal();
+
+  /**
+   * @copydoc Dali::Toolkit::WebView::RequestInterceptorSignal()
+   */
+  Dali::Toolkit::WebView::WebViewRequestInterceptorSignalType& RequestInterceptorSignal();
+
+  /**
+   * @copydoc Dali::Toolkit::WebView::ConsoleMessageSignal()
+   */
+  Dali::Toolkit::WebView::WebViewConsoleMessageSignalType& ConsoleMessageSignal();
+
+  /**
+   * @copydoc Dali::Toolkit::WebView::PolicyDecisionSignal()
+   */
+  Dali::Toolkit::WebView::WebViewPolicyDecisionSignalType& PolicyDecisionSignal();
+
+  /**
+   * @copydoc Dali::Toolkit::WebView::CertificateConfirmSignal()
+   */
+  Dali::Toolkit::WebView::WebViewCertificateSignalType& CertificateConfirmSignal();
+
+  /**
+   * @copydoc Dali::Toolkit::WebView::SslCertificateChangedSignal()
+   */
+  Dali::Toolkit::WebView::WebViewCertificateSignalType& SslCertificateChangedSignal();
+
+  /**
+   * @copydoc Dali::Toolkit::WebView::HttpAuthHandlerSignal()
+   */
+  Dali::Toolkit::WebView::WebViewHttpAuthHandlerSignalType& HttpAuthHandlerSignal();
+
+  /**
+   * @copydoc Dali::Toolkit::WebView::ContextMenuCustomizedSignal()
+   */
+  Dali::Toolkit::WebView::WebViewContextMenuCustomizedSignalType& ContextMenuCustomizedSignal();
+
+  /**
+   * @copydoc Dali::Toolkit::WebView::ContextMenuItemSelectedSignal()
+   */
+  Dali::Toolkit::WebView::WebViewContextMenuItemSelectedSignalType& ContextMenuItemSelectedSignal();
+
 public: // Properties
   /**
    * @brief Called when a property of an object of this type is set.
@@ -301,7 +447,7 @@ private:
   WebView& operator=(const WebView& webView);
 
   /**
-   * @brief Sets an absolute scroll of the given view.
+   * @brief Set an absolute scroll of the given view.
    * @param[in] x The coordinate x of scroll
    * @param[in] y The coordinate y of scroll
    */
@@ -315,27 +461,59 @@ private:
   Dali::Vector2 GetScrollPosition() const;
 
   /**
-   * @brief Gets the possible scroll size of the given view.
+   * @brief Get the possible scroll size of the given view.
    * @param[out] width The width of scroll size
    * @param[out] height The height of scroll size
    */
   Dali::Vector2 GetScrollSize() const;
 
   /**
-   * @brief Gets the last known content's size.
+   * @brief Get the last known content's size.
    * @param[out] width The width of content's size
    * @param[out] height The height of content's size
    */
   Dali::Vector2 GetContentSize() const;
 
   /**
-   * @brief Returns the title of the Web.
+   * @brief Return the title of the Web.
    *
    * @return The title of web page
    */
   std::string GetTitle() const;
 
   /**
+   * @brief Set the background color of web page.
+   * @param[in] color The value of background color.
+   */
+  void SetDocumentBackgroundColor(Dali::Vector4 color);
+
+  /**
+   * @brief Clear tiles when hidden.
+   *
+   * @param[in] cleared Whether tiles are cleared or not
+   */
+  void ClearTilesWhenHidden(bool cleared);
+
+  /**
+   * @brief Set multiplier of cover area of tile.
+   *
+   * @param[in] multiplier The multiplier of cover area
+   */
+  void SetTileCoverAreaMultiplier(float multiplier);
+
+  /**
+   * @brief Enable cursor by client.
+   * @param[in] enabled Whether cursor is enabled or not.
+   */
+  void EnableCursorByClient(bool enabled);
+
+  /**
+   * @brief Get the selected text.
+   * @return The selected text
+   */
+  std::string GetSelectedText() const;
+
+  /**
    * @brief Get user agent string.
    * @return The string value of user agent
    */
@@ -348,7 +526,45 @@ private:
   void SetUserAgent(const std::string& userAgent);
 
   /**
-   * @brief Updates display area of web view.
+   * @brief Set zoom factor of the current page.
+   * @param[in] zoomFactor a new factor to be set.
+   */
+  void SetPageZoomFactor(float zoomFactor);
+
+  /**
+   * @brief Query the current zoom factor of the page。
+   * @return The current page zoom factor.
+   */
+  float GetPageZoomFactor() const;
+
+  /**
+   * @brief Set the current text zoom level。.
+   * @param[in] zoomFactor a new factor to be set.
+   */
+  void SetTextZoomFactor(float zoomFactor);
+
+  /**
+   * @brief Get the current text zoom level.
+   * @return The current text zoom factor.
+   */
+  float GetTextZoomFactor() const;
+
+  /**
+   * @brief Get the current load progress of the page.
+   * @return The load progress of the page.
+   */
+  float GetLoadProgressPercentage() const;
+
+  /**
+   * @brief Request to set the current page's visibility.
+   * @param[in] visible Visible or not.
+   *
+   * @return true if succeeded, false otherwise
+   */
+  bool SetVisibility(bool visible);
+
+  /**
+   * @brief Update display area of web view.
    * @param[in] source The soource triggers Notification.
    */
   void UpdateDisplayArea(Dali::PropertyNotification& source);
@@ -366,20 +582,27 @@ private:
   void EnableBlendMode(bool blendEnabled);
 
   /**
-   * @brief Enables/disables mouse events. The default is enabled.
+   * @brief Enable/disable mouse events. The default is enabled.
    *
    * @param[in] enabled True if mouse events are enabled, false otherwise
    */
   void EnableMouseEvents(bool enabled);
 
   /**
-   * @brief Enables/disables key events. The default is enabled.
+   * @brief Enable/disable key events. The default is enabled.
    *
    * @param[in] enabled True if key events enabled, false otherwise
    */
   void EnableKeyEvents(bool enabled);
 
   /**
+   * @brief Create image view by pixel data.
+   * @param[in] pixel Pixel data
+   * @return The new image view
+   */
+  Dali::Toolkit::ImageView CreateImageView(Dali::PixelData pixel);
+
+  /**
    * @brief Callback function to be called when page load started.
    * @param[in] url The url currently being loaded
    */
@@ -402,11 +625,11 @@ private:
    * @param[in] url The url currently being loaded
    * @param[in] errorCode The error code
    */
-  void OnPageLoadError(const std::string& url, int errorCode);
+  void OnPageLoadError(std::shared_ptr<Dali::WebEngineLoadError> error);
 
   /**
    * @brief Callback function to be called when scroll edge is reached.
-   * @param[in] e The scroll edge reached.
+   * @param[in] edge The scroll edge reached.
    */
   void OnScrollEdgeReached(Dali::WebEnginePlugin::ScrollEdge edge);
 
@@ -440,32 +663,118 @@ private:
    */
   bool OnWheelEvent(Actor actor, const Dali::WheelEvent& wheel);
 
+  /**
+   * @brief Callback function to be called when form repost decision need be checked.
+   * @param[in] decision The new decision for form repost
+   */
+  void OnFormRepostDecision(std::shared_ptr<Dali::WebEngineFormRepostDecision> decision);
+
+  /**
+   * @brief Callback function to be called when frame is rendered.
+   */
+  void OnFrameRendered();
+
+  /**
+   * @brief Callback function to be called when visibility is changed.
+   * @param[in] actor The actor, or child of actor, whose visibility has changed
+   * @param[in] isVisible Whether the actor is now visible or not
+   * @param[in] type, Whether the actor's visible property has changed or a parent's
+   */
+  void OnVisibilityChanged(Actor actor, bool isVisible, Dali::DevelActor::VisibilityChange::Type type);
+
+  /**
+   * @brief callback for screen shot captured.
+   * @param[in] pixel Pixel data of screen shot.
+   */
+  void OnScreenshotCaptured(Dali::PixelData pixel);
+
+  /**
+   * @brief Callback function to be called when http request need be intercepted.
+   * @param [in] request The http request interceptor.
+   */
+  void OnInterceptRequest(std::shared_ptr<Dali::WebEngineRequestInterceptor> interceptor);
+
+  /**
+   * @brief Callback function to be called when console message will be logged.
+   * @param[in] message The message logged.
+   */
+  void OnConsoleMessage(std::shared_ptr<Dali::WebEngineConsoleMessage> message);
+
+  /**
+   * @brief Callback function to be called when policy need be decided.
+   * @param[in] decision The policy decided.
+   */
+  void OnPolicyDecisionRequest(std::shared_ptr<Dali::WebEnginePolicyDecision> decision);
+
+  /**
+   * @brief Callback function to be called when certificate need be confirmed.
+   * @param[in] certificate The certificate policy decision.
+   */
+  void OnCertificateConfirm(std::shared_ptr<Dali::WebEngineCertificate> certificate);
+
+  /**
+   * @brief Callback function to be called when ssl certificate is changed.
+   * @param[in] certificate The certificate information received.
+   */
+  void OnSslCertificateChanged(std::shared_ptr<Dali::WebEngineCertificate> certificate);
+
+  /**
+   * @brief Callback function to be called when http authentication need be confirmed.
+   * @param[in] handler The handler for http authentication
+   */
+  void OnHttpAuthenticationRequest(std::shared_ptr<Dali::WebEngineHttpAuthHandler> handler);
+
+  /**
+   * @brief Callback function to be called when context menu would be customized.
+   * @param[in] e The scroll edge reached.
+   */
+  void OnContextMenuCustomized(std::shared_ptr<Dali::WebEngineContextMenu> menu);
+
+  /**
+   * @brief Callback function to be called when context menu item is selected.
+   * @param[in] url The url currently being loaded
+   */
+  void OnContextMenuItemSelected(std::shared_ptr<Dali::WebEngineContextMenuItem> item);
+
 private:
   std::string                 mUrl;
   Dali::Toolkit::Visual::Base mVisual;
   Dali::Size                  mWebViewSize;
   Dali::WebEngine             mWebEngine;
 
-  Dali::Toolkit::WebView::WebViewPageLoadSignalType          mPageLoadStartedSignal;
-  Dali::Toolkit::WebView::WebViewPageLoadSignalType          mPageLoadInProgressSignal;
-  Dali::Toolkit::WebView::WebViewPageLoadSignalType          mPageLoadFinishedSignal;
-  Dali::Toolkit::WebView::WebViewPageLoadErrorSignalType     mPageLoadErrorSignal;
-  Dali::Toolkit::WebView::WebViewScrollEdgeReachedSignalType mScrollEdgeReachedSignal;
+  Dali::Toolkit::WebView::WebViewPageLoadSignalType                mPageLoadStartedSignal;
+  Dali::Toolkit::WebView::WebViewPageLoadSignalType                mPageLoadInProgressSignal;
+  Dali::Toolkit::WebView::WebViewPageLoadSignalType                mPageLoadFinishedSignal;
+  Dali::Toolkit::WebView::WebViewPageLoadErrorSignalType           mPageLoadErrorSignal;
+  Dali::Toolkit::WebView::WebViewUrlChangedSignalType              mUrlChangedSignal;
+  Dali::Toolkit::WebView::WebViewScrollEdgeReachedSignalType       mScrollEdgeReachedSignal;
+  Dali::Toolkit::WebView::WebViewFormRepostDecisionSignalType      mFormRepostDecisionSignal;
+  Dali::Toolkit::WebView::WebViewFrameRenderedSignalType           mFrameRenderedSignal;
+  Dali::Toolkit::WebView::WebViewRequestInterceptorSignalType      mRequestInterceptorSignal;
+  Dali::Toolkit::WebView::WebViewConsoleMessageSignalType          mConsoleMessageSignal;
+  Dali::Toolkit::WebView::WebViewPolicyDecisionSignalType          mPolicyDecisionSignal;
+  Dali::Toolkit::WebView::WebViewCertificateSignalType             mCertificateConfirmSignal;
+  Dali::Toolkit::WebView::WebViewCertificateSignalType             mSslCertificateChangedSignal;
+  Dali::Toolkit::WebView::WebViewHttpAuthHandlerSignalType         mHttpAuthHandlerSignal;
+  Dali::Toolkit::WebView::WebViewContextMenuCustomizedSignalType   mContextMenuCustomizedSignal;
+  Dali::Toolkit::WebView::WebViewContextMenuItemSelectedSignalType mContextMenuItemSelectedSignal;
 
   std::unique_ptr<Dali::Toolkit::WebContext>         mWebContext;
   std::unique_ptr<Dali::Toolkit::WebCookieManager>   mWebCookieManager;
   std::unique_ptr<Dali::Toolkit::WebSettings>        mWebSettings;
   std::unique_ptr<Dali::Toolkit::WebBackForwardList> mWebBackForwardList;
-  Dali::Toolkit::ImageView                           mFaviconView;
-
-  Dali::PropertyNotification                          mPositionUpdateNotification;
-  Dali::PropertyNotification                          mSizeUpdateNotification;
-  Dali::PropertyNotification                          mScaleUpdateNotification;
-  bool                                                mVideoHoleEnabled;
-  Dali::Rect<int>                                     mWebViewArea;
-  Dali::Toolkit::WebView::WebViewUrlChangedSignalType mUrlChangedSignal;
-  bool                                                mMouseEventsEnabled;
-  bool                                                mKeyEventsEnabled;
+
+  Dali::Toolkit::ImageView mFaviconView;
+
+  Dali::PropertyNotification mPositionUpdateNotification;
+  Dali::PropertyNotification mSizeUpdateNotification;
+  Dali::PropertyNotification mScaleUpdateNotification;
+  Dali::Rect<int>            mWebViewArea;
+  bool                       mVideoHoleEnabled;
+  bool                       mMouseEventsEnabled;
+  bool                       mKeyEventsEnabled;
+
+  Dali::Toolkit::WebView::WebViewScreenshotCapturedCallback mScreenshotCapturedCallback;
 };
 
 } // namespace Internal
index 4703752..ede26c1 100644 (file)
@@ -61,6 +61,7 @@ SET( toolkit_src_files
    ${toolkit_src_dir}/controls/buttons/push-button-impl.cpp
    ${toolkit_src_dir}/controls/buttons/radio-button-impl.cpp
    ${toolkit_src_dir}/controls/buttons/toggle-button-impl.cpp
+   ${toolkit_src_dir}/controls/canvas-view/canvas-view-impl.cpp
    ${toolkit_src_dir}/controls/control/control-data-impl.cpp
    ${toolkit_src_dir}/controls/control/control-debug.cpp
    ${toolkit_src_dir}/controls/control/control-renderers.cpp
@@ -133,6 +134,7 @@ SET( toolkit_src_files
    ${toolkit_src_dir}/text/markup-processor.cpp
    ${toolkit_src_dir}/text/markup-processor-color.cpp
    ${toolkit_src_dir}/text/markup-processor-embedded-item.cpp
+   ${toolkit_src_dir}/text/markup-processor-anchor.cpp
    ${toolkit_src_dir}/text/markup-processor-font.cpp
    ${toolkit_src_dir}/text/markup-processor-helper-functions.cpp
    ${toolkit_src_dir}/text/multi-language-support.cpp
diff --git a/dali-toolkit/internal/graphics/shaders/canvas-view.frag b/dali-toolkit/internal/graphics/shaders/canvas-view.frag
new file mode 100644 (file)
index 0000000..e122bca
--- /dev/null
@@ -0,0 +1,8 @@
+uniform lowp vec4 uColor;
+varying mediump vec2 vTexCoord;
+uniform sampler2D sTexture;
+
+void main()
+{
+  gl_FragColor = texture2D(sTexture, vTexCoord) * uColor;
+}
diff --git a/dali-toolkit/internal/graphics/shaders/canvas-view.vert b/dali-toolkit/internal/graphics/shaders/canvas-view.vert
new file mode 100644 (file)
index 0000000..6988993
--- /dev/null
@@ -0,0 +1,10 @@
+attribute mediump vec2 aPosition;
+varying mediump vec2 vTexCoord;
+uniform highp mat4 uMvpMatrix;
+uniform highp vec3 uSize;
+
+void main()
+{
+  gl_Position = uMvpMatrix * vec4(aPosition * uSize.xy, 0.0, 1.0);
+  vTexCoord = aPosition + vec2(0.5);
+}
index f2025a7..df817b2 100644 (file)
@@ -1,5 +1,6 @@
 INPUT mediump vec2 vPosition;
 INPUT mediump vec2 vRectSize;
+INPUT mediump float vCornerRadius;
 
 uniform lowp vec4 uColor;
 uniform lowp vec3 mixColor;
@@ -7,7 +8,55 @@ uniform mediump float blurRadius;
 
 void main()
 {
-  mediump vec2 blur = 1.0 - smoothstep( vRectSize - blurRadius * 2.0, vRectSize, abs( vPosition ) );
   OUT_COLOR = vec4(mixColor, 1.0) * uColor;
-  OUT_COLOR.a *= blur.x * blur.y;
-}
\ No newline at end of file
+
+  mediump vec2 v = abs(vPosition) - vRectSize;
+  mediump float cy = vCornerRadius + blurRadius;
+  mediump float cr = vCornerRadius + blurRadius;
+
+  cy = min(cy, min(vRectSize.x, vRectSize.y));
+  v = vec2(min(v.x, v.y), max(v.x, v.y));
+  v = v + cy;
+
+  mediump float blur = 1.0;
+  mediump float potential = 0.0;
+  mediump float alias = min(vCornerRadius, 1.0);
+  mediump float potentialMin = cy + vCornerRadius - blurRadius - alias;
+  mediump float potentialMax = cy + vCornerRadius + blurRadius + alias;
+
+  // move center of circles for reduce defact
+  mediump float cyDiff = min(cy, 0.2 * blurRadius);
+  cy -= cyDiff;
+  cr += cyDiff;
+
+  mediump float diffFromBaseline = cy * v.y - (cy + cr) * v.x;
+
+  if(diffFromBaseline > 0.0)
+  {
+    // out of calculation bound.
+    potential = v.y;
+
+    // for anti-alias when blurRaidus = 0.0
+    mediump float heuristicBaselineScale = max(1.0 , cr * (cr + cy));
+    mediump float potentialDiff = min(alias, diffFromBaseline / heuristicBaselineScale);
+    potentialMin += potentialDiff;
+    potentialMax -= potentialDiff;
+  }
+  else
+  {
+    // get some circle centered (x, x) and radius (r = cr / cy * x)
+    // s.t. point v is on that circle
+    // highest point of that circle is (x, x + r) and potential is x + r
+
+    // solve (v.x - x)^2 + (v.y - x)^2 = (cr / cy * x)^2
+
+    mediump float A = (cr * cr - 2.0 * cy * cy);
+    mediump float B = cy * (v.x + v.y);
+    mediump float V = dot(v,v);
+    mediump float D = B * B + A * V;
+    potential = V * (cr + cy) / (sqrt(D) + B);
+  }
+
+  blur = 1.0 - smoothstep(potentialMin, potentialMax, potential);
+  OUT_COLOR.a *= blur;
+}
index 65849eb..e20110b 100644 (file)
@@ -1,8 +1,9 @@
 INPUT mediump vec2 aPosition;
 OUTPUT mediump vec2 vPosition;
 OUTPUT mediump vec2 vRectSize;
+OUTPUT mediump float vCornerRadius;
 
-uniform highp   mat4 uMvpMatrix;
+uniform highp mat4 uMvpMatrix;
 uniform highp vec3 uSize;
 
 //Visual size and offset
@@ -13,17 +14,22 @@ uniform mediump vec4 offsetSizeMode;
 uniform mediump vec2 origin;
 uniform mediump vec2 anchorPoint;
 uniform mediump float blurRadius;
+uniform mediump float cornerRadius;
+uniform mediump float cornerRadiusPolicy;
 
 vec4 ComputeVertexPosition()
 {
-  vec2 visualSize = mix(uSize.xy*size, size, offsetSizeMode.zw ) + extraSize + blurRadius * 2.0;
+  vec2 visualSize = mix(uSize.xy*size, size, offsetSizeMode.zw ) + extraSize;
   vec2 visualOffset = mix( offset, offset/uSize.xy, offsetSizeMode.xy);
-  vRectSize = visualSize / 2.0;
-  vPosition = aPosition* visualSize;
+  mediump float minSize = min( visualSize.x, visualSize.y );
+  vCornerRadius = mix( cornerRadius * minSize, cornerRadius, cornerRadiusPolicy );
+  vCornerRadius = min( vCornerRadius, minSize * 0.5 );
+  vRectSize = visualSize / 2.0 - vec2( vCornerRadius );
+  vPosition = aPosition * (visualSize + 2.0 * blurRadius);
   return vec4( vPosition + anchorPoint*visualSize + (visualOffset + origin)*uSize.xy, 0.0, 1.0 );
 }
 
 void main()
 {
   gl_Position = uMvpMatrix * ComputeVertexPosition();
-}
\ No newline at end of file
+}
diff --git a/dali-toolkit/internal/text/anchor.h b/dali-toolkit/internal/text/anchor.h
new file mode 100644 (file)
index 0000000..d2c7384
--- /dev/null
@@ -0,0 +1,46 @@
+#ifndef DALI_TOOLKIT_TEXT_ANCHOR_H
+#define DALI_TOOLKIT_TEXT_ANCHOR_H
+
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/text-definitions.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Text
+{
+/**
+ * @brief An anchor within the text.
+ */
+struct Anchor
+{
+  CharacterIndex startIndex; ///< The character's start index of the anchor within the string.
+  CharacterIndex endIndex;   ///< The character's end index of the anchor within the string.
+  char*          href;       ///< The url path
+};
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_TEXT_ANCHOR_H
\ No newline at end of file
index 8ecab1f..12929fc 100644 (file)
@@ -55,6 +55,16 @@ void FreeEmbeddedItems(Vector<EmbeddedItem>& embeddedItem)
   embeddedItem.Clear();
 }
 
+void FreeAnchors(Vector<Anchor>& anchors)
+{
+  for(auto&& anchor : anchors)
+  {
+    delete[] anchor.href;
+  }
+
+  anchors.Clear();
+}
+
 LogicalModelPtr LogicalModel::New()
 {
   return LogicalModelPtr(new LogicalModel());
@@ -573,6 +583,11 @@ void LogicalModel::ClearEmbeddedImages()
   FreeEmbeddedItems(mEmbeddedItems);
 }
 
+void LogicalModel::ClearAnchors()
+{
+  FreeAnchors(mAnchors);
+}
+
 LogicalModel::~LogicalModel()
 {
   ClearFontDescriptionRuns();
index 4702c38..921d911 100644 (file)
@@ -24,6 +24,7 @@
 #include <dali/public-api/object/ref-object.h>
 
 // INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/anchor.h>
 #include <dali-toolkit/internal/text/bidirectional-line-info-run.h>
 #include <dali-toolkit/internal/text/bidirectional-paragraph-info-run.h>
 #include <dali-toolkit/internal/text/color-run.h>
@@ -181,6 +182,11 @@ public:
    */
   void ClearEmbeddedImages();
 
+  /**
+   * @brief Clears the anchors.
+   */
+  void ClearAnchors();
+
 protected:
   /**
    * @brief A reference counted object may only be deleted by calling Unreference().
@@ -212,6 +218,7 @@ public:
   Vector<CharacterDirection>            mCharacterDirections; ///< For each character, whether is right to left. ( @e flase is left to right, @e true right to left ).
   Vector<BidirectionalLineInfoRun>      mBidirectionalLineInfo;
   Vector<EmbeddedItem>                  mEmbeddedItems;
+  Vector<Anchor>                        mAnchors;
 
   BidirectionalLineRunIndex mBidirectionalLineIndex; ///< The last fetched bidirectional line info.
 };
diff --git a/dali-toolkit/internal/text/markup-processor-anchor.cpp b/dali-toolkit/internal/text/markup-processor-anchor.cpp
new file mode 100644 (file)
index 0000000..4c4bb29
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// FILE HEADER
+#include <dali-toolkit/internal/text/markup-processor-anchor.h>
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/common/dali-vector.h>
+#include <memory.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/anchor.h>
+#include <dali-toolkit/internal/text/markup-processor-helper-functions.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Text
+{
+namespace
+{
+const std::string XHTML_HREF_ATTRIBUTE("href");
+} // namespace
+
+void ProcessAnchor(const Tag& tag, Anchor& anchor)
+{
+  anchor.href = nullptr;
+
+  for(auto&& attribute : tag.attributes)
+  {
+    if(TokenComparison(XHTML_HREF_ATTRIBUTE, attribute.nameBuffer, attribute.nameLength))
+    {
+      Length hrefLength = attribute.valueLength + 1;
+      anchor.href       = new char[hrefLength];
+      memcpy(anchor.href, attribute.valueBuffer, hrefLength);
+      anchor.href[hrefLength - 1] = '\0';
+      // The memory is freed when the font run is removed from the logical model.
+    }
+  }
+}
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
\ No newline at end of file
diff --git a/dali-toolkit/internal/text/markup-processor-anchor.h b/dali-toolkit/internal/text/markup-processor-anchor.h
new file mode 100644 (file)
index 0000000..7c1d181
--- /dev/null
@@ -0,0 +1,47 @@
+#ifndef DALI_TOOLKIT_TEXT_MARKUP_PROCESSOR_ANCHOR_H
+#define DALI_TOOLKIT_TEXT_MARKUP_PROCESSOR_ANCHOR_H
+
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+struct Tag;
+struct Anchor;
+
+/**
+ * @brief Retrieves the @e anchor from the @p tag.
+ *
+ * @param[in] tag The anchor tag and its attributes.
+ * @param[in,out] anchor The anchor.
+ */
+void ProcessAnchor( const Tag& tag, Anchor& anchor );
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_TEXT_MARKUP_PROCESSOR_ANCHOR_H
\ No newline at end of file
index 20a5825..a8a6ecc 100644 (file)
@@ -25,6 +25,7 @@
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/text/character-set-conversion.h>
+#include <dali-toolkit/internal/text/markup-processor-anchor.h>
 #include <dali-toolkit/internal/text/markup-processor-color.h>
 #include <dali-toolkit/internal/text/markup-processor-embedded-item.h>
 #include <dali-toolkit/internal/text/markup-processor-font.h>
@@ -51,6 +52,7 @@ const std::string XHTML_SHADOW_TAG("shadow");
 const std::string XHTML_GLOW_TAG("glow");
 const std::string XHTML_OUTLINE_TAG("outline");
 const std::string XHTML_ITEM_TAG("item");
+const std::string XHTML_ANCHOR_TAG("a");
 
 const char LESS_THAN      = '<';
 const char GREATER_THAN   = '>';
@@ -580,6 +582,38 @@ void ProcessItemTag(
 }
 
 /**
+ * @brief Processes the anchor tag
+ *
+ * @param[in/out] markupProcessData The markup process data
+ * @param[in] tag The current tag
+ * @param[in/out] characterIndex The current character index
+ */
+void ProcessAnchorTag(
+  MarkupProcessData& markupProcessData,
+  const Tag          tag,
+  CharacterIndex&    characterIndex)
+{
+  if(!tag.isEndTag)
+  {
+    // Create an anchor instance.
+    Anchor anchor;
+    anchor.startIndex = characterIndex;
+    anchor.endIndex   = 0u;
+    ProcessAnchor(tag, anchor);
+    markupProcessData.anchors.PushBack(anchor);
+  }
+  else
+  {
+    // Update end index.
+    unsigned int count = markupProcessData.anchors.Count();
+    if(count > 0)
+    {
+      markupProcessData.anchors[count - 1].endIndex = characterIndex;
+    }
+  }
+}
+
+/**
  * @brief Resizes the model's vectors
  *
  * @param[in/out] markupProcessData The markup process data
@@ -763,6 +797,18 @@ void ProcessMarkupString(const std::string& markupString, MarkupProcessData& mar
         ProcessTagForRun<FontDescriptionRun>(
           markupProcessData.fontRuns, styleStack, tag, characterIndex, fontRunIndex, fontTagReference, [](const Tag& tag, FontDescriptionRun& fontRun) { ProcessFontTag(tag, fontRun); });
       } // <font></font>
+      else if(TokenComparison(XHTML_ANCHOR_TAG, tag.buffer, tag.length))
+      {
+        /* Anchor */
+        ProcessAnchorTag(markupProcessData, tag, characterIndex);
+        /* Color */
+        ProcessTagForRun<ColorRun>(
+          markupProcessData.colorRuns, styleStack, tag, characterIndex, colorRunIndex, colorTagReference, [](const Tag& tag, ColorRun& run) {
+            run.color = Color::BLUE;
+            ProcessColorTag(tag, run);
+          });
+        /* TODO - underline */
+      } // <a href=https://www.tizen.org>tizen</a>
       else if(TokenComparison(XHTML_SHADOW_TAG, tag.buffer, tag.length))
       {
         // TODO: If !tag.isEndTag, then create a new shadow run.
index fee7ae1..c75ca0c 100644 (file)
@@ -23,6 +23,7 @@
 #include <string>
 
 // INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/anchor.h>
 #include <dali-toolkit/internal/text/color-run.h>
 #include <dali-toolkit/internal/text/embedded-item.h>
 #include <dali-toolkit/internal/text/font-description-run.h>
@@ -40,10 +41,12 @@ struct MarkupProcessData
 {
   MarkupProcessData(Vector<ColorRun>&           colorRuns,
                     Vector<FontDescriptionRun>& fontRuns,
-                    Vector<EmbeddedItem>&       items)
+                    Vector<EmbeddedItem>&       items,
+                    Vector<Anchor>&             anchors)
   : colorRuns(colorRuns),
     fontRuns(fontRuns),
     items(items),
+    anchors(anchors),
     markupProcessedText()
   {
   }
@@ -51,6 +54,7 @@ struct MarkupProcessData
   Vector<ColorRun>&           colorRuns;           ///< The color runs.
   Vector<FontDescriptionRun>& fontRuns;            ///< The font description runs.
   Vector<EmbeddedItem>&       items;               ///< The embedded items.
+  Vector<Anchor>&             anchors;             ///< The anchors.
   std::string                 markupProcessedText; ///< The mark-up string.
 };
 
diff --git a/dali-toolkit/internal/text/text-anchor-control-interface.h b/dali-toolkit/internal/text/text-anchor-control-interface.h
new file mode 100644 (file)
index 0000000..5c6a84f
--- /dev/null
@@ -0,0 +1,50 @@
+#ifndef DALI_TOOLKIT_TEXT_ANCHOR_CONTROL_INTERFACE_H
+#define DALI_TOOLKIT_TEXT_ANCHOR_CONTROL_INTERFACE_H
+
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Text
+{
+/**
+ * @brief An interface that the Text::Controller used for anchor functionality.
+ */
+class AnchorControlInterface
+{
+public:
+  /**
+   * @brief Virtual destructor.
+   */
+  virtual ~AnchorControlInterface() = default;
+
+  /**
+   * @brief Called to signal that anchor has been clicked.
+   */
+  virtual void AnchorClicked(const std::string& href) = 0;
+};
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_TEXT_ANCHOR_CONTROL_INTERFACE_H
index c6c4058..c17c820 100644 (file)
@@ -24,6 +24,7 @@
 #include <dali/integration-api/debug.h>
 
 // INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/cursor-helper-functions.h>
 #include <dali-toolkit/internal/text/text-controller-impl.h>
 #include <dali-toolkit/internal/text/text-editable-control-interface.h>
 
@@ -287,12 +288,52 @@ bool Controller::EventHandler::KeyEvent(Controller& controller, const Dali::KeyE
      (NULL != controller.mImpl->mEditableControlInterface))
   {
     // Do this last since it provides callbacks into application code
-    controller.mImpl->mEditableControlInterface->TextChanged();
+    controller.mImpl->mEditableControlInterface->TextChanged(false);
   }
 
   return true;
 }
 
+void Controller::EventHandler::AnchorEvent(Controller& controller, float x, float y)
+{
+  if(!controller.mImpl->mMarkupProcessorEnabled ||
+     !controller.mImpl->mModel->mLogicalModel->mAnchors.Count() ||
+     !controller.mImpl->IsShowingRealText())
+  {
+    return;
+  }
+
+  CharacterIndex cursorPosition = 0u;
+
+  // Convert from control's coords to text's coords.
+  const float xPosition = x - controller.mImpl->mModel->mScrollPosition.x;
+  const float yPosition = y - controller.mImpl->mModel->mScrollPosition.y;
+
+  // Whether to touch point hits on a glyph.
+  bool matchedCharacter = false;
+  cursorPosition        = Text::GetClosestCursorIndex(controller.mImpl->mModel->mVisualModel,
+                                               controller.mImpl->mModel->mLogicalModel,
+                                               controller.mImpl->mMetrics,
+                                               xPosition,
+                                               yPosition,
+                                               CharacterHitTest::TAP,
+                                               matchedCharacter);
+
+  for(const auto& anchor : controller.mImpl->mModel->mLogicalModel->mAnchors)
+  {
+    // Anchor clicked if the calculated cursor position is within the range of anchor.
+    if(cursorPosition >= anchor.startIndex && cursorPosition < anchor.endIndex)
+    {
+      if(controller.mImpl->mAnchorControlInterface && anchor.href)
+      {
+        std::string href(anchor.href);
+        controller.mImpl->mAnchorControlInterface->AnchorClicked(href);
+        break;
+      }
+    }
+  }
+}
+
 void Controller::EventHandler::TapEvent(Controller& controller, unsigned int tapCount, float x, float y)
 {
   DALI_ASSERT_DEBUG(controller.mImpl->mEventData && "Unexpected TapEvent");
@@ -742,7 +783,7 @@ InputMethodContext::CallbackData Controller::EventHandler::OnInputMethodContextE
      (NULL != controller.mImpl->mEditableControlInterface))
   {
     // Do this last since it provides callbacks into application code
-    controller.mImpl->mEditableControlInterface->TextChanged();
+    controller.mImpl->mEditableControlInterface->TextChanged(false);
   }
 
   return callbackData;
@@ -852,7 +893,7 @@ void Controller::EventHandler::TextPopupButtonTouched(Controller& controller, Da
 
       if(NULL != controller.mImpl->mEditableControlInterface)
       {
-        controller.mImpl->mEditableControlInterface->TextChanged();
+        controller.mImpl->mEditableControlInterface->TextChanged(true);
       }
       break;
     }
index 67902fb..092ac58 100644 (file)
@@ -40,6 +40,7 @@ struct Controller::EventHandler
   static void KeyboardFocusGainEvent(Controller& controller);
   static void KeyboardFocusLostEvent(Controller& controller);
   static bool KeyEvent(Controller& controller, const Dali::KeyEvent& keyEvent);
+  static void AnchorEvent(Controller& controller, float x, float y);
   static void TapEvent(Controller& controller, unsigned int tapCount, float x, float y);
   static void PanEvent(Controller& controller, GestureState state, const Vector2& displacement);
   static void LongPressEvent(Controller& controller, GestureState state, float x, float y);
index 414faf5..ef4bb69 100644 (file)
@@ -49,6 +49,7 @@ struct ControllerImplEventHandler;
 struct SelectionHandleController;
 
 class SelectableControlInterface;
+class AnchorControlInterface;
 
 struct Event
 {
@@ -314,10 +315,12 @@ struct Controller::Impl
 {
   Impl(ControlInterface*           controlInterface,
        EditableControlInterface*   editableControlInterface,
-       SelectableControlInterface* selectableControlInterface)
+       SelectableControlInterface* selectableControlInterface,
+       AnchorControlInterface*     anchorControlInterface)
   : mControlInterface(controlInterface),
     mEditableControlInterface(editableControlInterface),
     mSelectableControlInterface(selectableControlInterface),
+    mAnchorControlInterface(anchorControlInterface),
     mModel(),
     mFontDefaults(NULL),
     mUnderlineDefaults(NULL),
@@ -786,6 +789,7 @@ public:
   ControlInterface*           mControlInterface;           ///< Reference to the text controller.
   EditableControlInterface*   mEditableControlInterface;   ///< Reference to the editable text controller.
   SelectableControlInterface* mSelectableControlInterface; ///< Reference to the selectable text controller.
+  AnchorControlInterface*     mAnchorControlInterface;     ///< Reference to the anchor controller.
   ModelPtr                    mModel;                      ///< Pointer to the text's model.
   FontDefaults*               mFontDefaults;               ///< Avoid allocating this when the user does not specify a font.
   UnderlineDefaults*          mUnderlineDefaults;          ///< Avoid allocating this when the user does not specify underline parameters.
index a900601..227d889 100644 (file)
@@ -61,6 +61,9 @@ Vector3 Controller::Relayouter::GetNaturalSize(Controller& controller)
   VisualModelPtr&   visualModel = model->mVisualModel;
   if(impl.mRecalculateNaturalSize)
   {
+    // Store the pending operations mask so that it can be restored later on with no modifications made on it
+    // while getting the natural size were reflected on the original mask.
+    OperationsMask operationsPendingBackUp = static_cast<OperationsMask>(impl.mOperationsPending);
     // Operations that can be done only once until the text changes.
     const OperationsMask onlyOnceOperations = static_cast<OperationsMask>(CONVERT_TO_UTF32 |
                                                                           GET_SCRIPTS |
@@ -93,15 +96,6 @@ Vector3 Controller::Relayouter::GetNaturalSize(Controller& controller)
                                            LAYOUT | REORDER),
                naturalSize.GetVectorXY());
 
-    // Do not do again the only once operations.
-    operationsPending = static_cast<OperationsMask>(operationsPending & ~onlyOnceOperations);
-
-    // Do the size related operations again.
-    const OperationsMask sizeOperations = static_cast<OperationsMask>(LAYOUT |
-                                                                      ALIGN |
-                                                                      REORDER);
-    operationsPending                   = static_cast<OperationsMask>(operationsPending | sizeOperations);
-
     // Stores the natural size to avoid recalculate it again
     // unless the text/style changes.
     visualModel->SetNaturalSize(naturalSize.GetVectorXY());
@@ -114,7 +108,8 @@ Vector3 Controller::Relayouter::GetNaturalSize(Controller& controller)
 
     // Restore the actual control's size.
     visualModel->mControlSize = actualControlSize;
-
+    // Restore the previously backed-up pending operations' mask without the only once operations.
+    impl.mOperationsPending = static_cast<OperationsMask>(operationsPendingBackUp & ~onlyOnceOperations);
     DALI_LOG_INFO(gLogFilter, Debug::Verbose, "<--Controller::GetNaturalSize calculated %f,%f,%f\n", naturalSize.x, naturalSize.y, naturalSize.z);
   }
   else
@@ -244,6 +239,9 @@ float Controller::Relayouter::GetHeightForWidth(Controller& controller, float wi
      textUpdateInfo.mFullRelayoutNeeded ||
      textUpdateInfo.mClearAll)
   {
+    // Store the pending operations mask so that it can be restored later on with no modifications made on it
+    // while getting the natural size were reflected on the original mask.
+    OperationsMask operationsPendingBackUp = static_cast<OperationsMask>(impl.mOperationsPending);
     // Operations that can be done only once until the text changes.
     const OperationsMask onlyOnceOperations = static_cast<OperationsMask>(CONVERT_TO_UTF32 |
                                                                           GET_SCRIPTS |
@@ -275,23 +273,14 @@ float Controller::Relayouter::GetHeightForWidth(Controller& controller, float wi
                                            LAYOUT),
                layoutSize);
 
-    // Do not do again the only once operations.
-    operationsPending = static_cast<OperationsMask>(operationsPending & ~onlyOnceOperations);
-
-    // Do the size related operations again.
-    const OperationsMask sizeOperations = static_cast<OperationsMask>(LAYOUT |
-                                                                      ALIGN |
-                                                                      REORDER);
-
-    operationsPending = static_cast<OperationsMask>(operationsPending | sizeOperations);
-
     // Clear the update info. This info will be set the next time the text is updated.
     textUpdateInfo.Clear();
     textUpdateInfo.mClearAll = true;
 
     // Restore the actual control's width.
     visualModel->mControlSize.width = actualControlWidth;
-
+    // Restore the previously backed-up pending operations' mask without the only once operations.
+    impl.mOperationsPending = static_cast<OperationsMask>(operationsPendingBackUp & ~onlyOnceOperations);
     DALI_LOG_INFO(gLogFilter, Debug::Verbose, "<--Controller::GetHeightForWidth calculated %f\n", layoutSize.height);
   }
   else
index c22e207..69e05bf 100644 (file)
@@ -81,7 +81,8 @@ void Controller::TextUpdater::SetText(Controller& controller, const std::string&
 
     MarkupProcessData markupProcessData(logicalModel->mColorRuns,
                                         logicalModel->mFontDescriptionRuns,
-                                        logicalModel->mEmbeddedItems);
+                                        logicalModel->mEmbeddedItems,
+                                        logicalModel->mAnchors);
 
     Length         textSize = 0u;
     const uint8_t* utf8     = NULL;
@@ -153,7 +154,7 @@ void Controller::TextUpdater::SetText(Controller& controller, const std::string&
   // Do this last since it provides callbacks into application code.
   if(NULL != impl.mEditableControlInterface)
   {
-    impl.mEditableControlInterface->TextChanged();
+    impl.mEditableControlInterface->TextChanged(true);
   }
 }
 
@@ -377,6 +378,11 @@ void Controller::TextUpdater::InsertText(Controller& controller, const std::stri
       textUpdateInfo.mNumberOfCharactersToAdd += maxSizeOfNewText;
     }
 
+    if(impl.mMarkupProcessorEnabled)
+    {
+      InsertTextAnchor(controller, maxSizeOfNewText, cursorIndex);
+    }
+
     // Update the cursor index.
     cursorIndex += maxSizeOfNewText;
 
@@ -433,7 +439,7 @@ void Controller::TextUpdater::PasteText(Controller& controller, const std::strin
   if(NULL != impl.mEditableControlInterface)
   {
     // Do this last since it provides callbacks into application code
-    impl.mEditableControlInterface->TextChanged();
+    impl.mEditableControlInterface->TextChanged(true);
   }
 }
 
@@ -461,8 +467,8 @@ bool Controller::TextUpdater::RemoveText(
   if(!impl.IsShowingPlaceholderText())
   {
     // Delete at current cursor position
-    Vector<Character>& currentText    = logicalModel->mText;
-    CharacterIndex&    oldCursorIndex = eventData->mPrimaryCursorPosition;
+    Vector<Character>& currentText         = logicalModel->mText;
+    CharacterIndex&    previousCursorIndex = eventData->mPrimaryCursorPosition;
 
     CharacterIndex cursorIndex = 0;
 
@@ -547,8 +553,13 @@ bool Controller::TextUpdater::RemoveText(
 
       currentText.Erase(first, last);
 
+      if(impl.mMarkupProcessorEnabled)
+      {
+        RemoveTextAnchor(controller, cursorOffset, numberOfCharacters, previousCursorIndex);
+      }
+
       // Cursor position retreat
-      oldCursorIndex = cursorIndex;
+      previousCursorIndex = cursorIndex;
 
       eventData->mScrollAfterDelete = true;
 
@@ -580,6 +591,16 @@ bool Controller::TextUpdater::RemoveSelectedText(Controller& controller)
     {
       textRemoved = true;
       impl.ChangeState(EventData::EDITING);
+
+      if(impl.mMarkupProcessorEnabled)
+      {
+        int             cursorOffset        = -1;
+        int             numberOfCharacters  = removedString.length();
+        CharacterIndex& cursorIndex         = impl.mEventData->mPrimaryCursorPosition;
+        CharacterIndex  previousCursorIndex = cursorIndex + numberOfCharacters;
+
+        RemoveTextAnchor(controller, cursorOffset, numberOfCharacters, previousCursorIndex);
+      }
     }
   }
 
@@ -597,6 +618,9 @@ void Controller::TextUpdater::ResetText(Controller& controller)
   // Reset the embedded images buffer.
   logicalModel->ClearEmbeddedImages();
 
+  // Reset the anchors buffer.
+  logicalModel->ClearAnchors();
+
   // We have cleared everything including the placeholder-text
   impl.PlaceholderCleared();
 
@@ -617,6 +641,128 @@ void Controller::TextUpdater::ResetText(Controller& controller)
   impl.mOperationsPending = ALL_OPERATIONS;
 }
 
+void Controller::TextUpdater::InsertTextAnchor(Controller& controller, int numberOfCharacters, CharacterIndex previousCursorIndex)
+{
+  Controller::Impl& impl         = *controller.mImpl;
+  ModelPtr&         model        = impl.mModel;
+  LogicalModelPtr&  logicalModel = model->mLogicalModel;
+
+  for(auto& anchor : logicalModel->mAnchors)
+  {
+    if(anchor.endIndex < previousCursorIndex) //      [anchor]  CUR
+    {
+      continue;
+    }
+    if(anchor.startIndex < previousCursorIndex) //      [anCURr]
+    {
+      anchor.endIndex += numberOfCharacters;
+    }
+    else // CUR  [anchor]
+    {
+      anchor.startIndex += numberOfCharacters;
+      anchor.endIndex += numberOfCharacters;
+    }
+    DALI_LOG_INFO(gLogFilter, Debug::General, "Controller::InsertTextAnchor[%p] Anchor[%s] start[%d] end[%d]\n", &controller, anchor.href, anchor.startIndex, anchor.endIndex);
+  }
+}
+
+void Controller::TextUpdater::RemoveTextAnchor(Controller& controller, int cursorOffset, int numberOfCharacters, CharacterIndex previousCursorIndex)
+{
+  Controller::Impl&        impl         = *controller.mImpl;
+  ModelPtr&                model        = impl.mModel;
+  LogicalModelPtr&         logicalModel = model->mLogicalModel;
+  Vector<Anchor>::Iterator it           = logicalModel->mAnchors.Begin();
+
+  while(it != logicalModel->mAnchors.End())
+  {
+    Anchor& anchor = *it;
+
+    if(anchor.endIndex <= previousCursorIndex && cursorOffset == 0) // [anchor]    CUR >>
+    {
+      // Nothing happens.
+    }
+    else if(anchor.endIndex <= previousCursorIndex && cursorOffset == -1) // [anchor] << CUR
+    {
+      int endIndex = anchor.endIndex;
+      int offset   = previousCursorIndex - endIndex;
+      int index    = endIndex - (numberOfCharacters - offset);
+
+      if(index < endIndex)
+      {
+        endIndex = index;
+      }
+
+      if((int)anchor.startIndex >= endIndex)
+      {
+        if(anchor.href)
+        {
+          delete[] anchor.href;
+        }
+        it = logicalModel->mAnchors.Erase(it);
+        continue;
+      }
+      else
+      {
+        anchor.endIndex = endIndex;
+      }
+    }
+    else if(anchor.startIndex >= previousCursorIndex && cursorOffset == -1) // << CUR    [anchor]
+    {
+      anchor.startIndex -= numberOfCharacters;
+      anchor.endIndex -= numberOfCharacters;
+    }
+    else if(anchor.startIndex >= previousCursorIndex && cursorOffset == 0) //    CUR >> [anchor]
+    {
+      int startIndex = anchor.startIndex;
+      int endIndex   = anchor.endIndex;
+      int index      = previousCursorIndex + numberOfCharacters - 1;
+
+      if(startIndex > index)
+      {
+        anchor.startIndex -= numberOfCharacters;
+        anchor.endIndex -= numberOfCharacters;
+      }
+      else if(endIndex > index + 1)
+      {
+        anchor.endIndex -= numberOfCharacters;
+      }
+      else
+      {
+        if(anchor.href)
+        {
+          delete[] anchor.href;
+        }
+        it = logicalModel->mAnchors.Erase(it);
+        continue;
+      }
+    }
+    else if(cursorOffset == -1) // [<< CUR]
+    {
+      int startIndex = anchor.startIndex;
+      int index      = previousCursorIndex - numberOfCharacters;
+
+      if(startIndex >= index)
+      {
+        anchor.startIndex = index;
+      }
+      anchor.endIndex -= numberOfCharacters;
+    }
+    else if(cursorOffset == 0) // [CUR >>]
+    {
+      anchor.endIndex -= numberOfCharacters;
+    }
+    else
+    {
+      // When this condition is reached, someting is wrong.
+      DALI_LOG_ERROR("Controller::RemoveTextAnchor[%p] Invaild state cursorOffset[%d]\n", &controller, cursorOffset);
+    }
+
+    DALI_LOG_INFO(gLogFilter, Debug::General, "Controller::RemoveTextAnchor[%p] Anchor[%s] start[%d] end[%d]\n", &controller, anchor.href, anchor.startIndex, anchor.endIndex);
+
+    it++;
+  }
+}
+
 } // namespace Text
 
 } // namespace Toolkit
index ba7e3b9..f512940 100644 (file)
@@ -58,6 +58,14 @@ struct Controller::TextUpdater
   /// @copydoc Text::Contoller::ResetText
   /// @param[in] controller The controller
   static void ResetText(Controller& controller);
+
+  /// @copydoc Text::Contoller::InsertTextAnchor
+  /// @param[in] controller The controller
+  static void InsertTextAnchor(Controller& controller, int numberOfCharacters, CharacterIndex previousCursorIndex);
+
+  /// @copydoc Text::Contoller::RemoveTextAnchor
+  /// @param[in] controller The controller
+  static void RemoveTextAnchor(Controller& controller, int cursorOffset, int numberOfCharacters, CharacterIndex previousCursorIndex);
 };
 
 } // namespace Text
index f29ab22..15db50b 100644 (file)
@@ -75,11 +75,13 @@ ControllerPtr Controller::New(ControlInterface* controlInterface)
 
 ControllerPtr Controller::New(ControlInterface*           controlInterface,
                               EditableControlInterface*   editableControlInterface,
-                              SelectableControlInterface* selectableControlInterface)
+                              SelectableControlInterface* selectableControlInterface,
+                              AnchorControlInterface*     anchorControlInterface)
 {
   return ControllerPtr(new Controller(controlInterface,
                                       editableControlInterface,
-                                      selectableControlInterface));
+                                      selectableControlInterface,
+                                      anchorControlInterface));
 }
 
 // public : Configure the text controller.
@@ -1722,6 +1724,11 @@ bool Controller::KeyEvent(const Dali::KeyEvent& keyEvent)
   return EventHandler::KeyEvent(*this, keyEvent);
 }
 
+void Controller::AnchorEvent(float x, float y)
+{
+  EventHandler::AnchorEvent(*this, x, y);
+}
+
 void Controller::TapEvent(unsigned int tapCount, float x, float y)
 {
   EventHandler::TapEvent(*this, tapCount, x, y);
@@ -1936,6 +1943,19 @@ bool Controller::RemoveSelectedText()
   return TextUpdater::RemoveSelectedText(*this);
 }
 
+void Controller::InsertTextAnchor(int            numberOfCharacters,
+                                  CharacterIndex previousCursorIndex)
+{
+  TextUpdater::InsertTextAnchor(*this, numberOfCharacters, previousCursorIndex);
+}
+
+void Controller::RemoveTextAnchor(int            cursorOffset,
+                                  int            numberOfCharacters,
+                                  CharacterIndex previousCursorIndex)
+{
+  TextUpdater::RemoveTextAnchor(*this, cursorOffset, numberOfCharacters, previousCursorIndex);
+}
+
 // private : Relayout.
 
 bool Controller::DoRelayout(const Size&    size,
@@ -2060,6 +2080,11 @@ void Controller::SetControlInterface(ControlInterface* controlInterface)
   mImpl->mControlInterface = controlInterface;
 }
 
+void Controller::SetAnchorControlInterface(AnchorControlInterface* anchorControlInterface)
+{
+  mImpl->mAnchorControlInterface = anchorControlInterface;
+}
+
 bool Controller::ShouldClearFocusOnEscape() const
 {
   return mImpl->mShouldClearFocusOnEscape;
@@ -2073,19 +2098,20 @@ Actor Controller::CreateBackgroundActor()
 // private : Private contructors & copy operator.
 
 Controller::Controller()
-: Controller(nullptr, nullptr, nullptr)
+: Controller(nullptr, nullptr, nullptr, nullptr)
 {
 }
 
 Controller::Controller(ControlInterface* controlInterface)
-: Controller(controlInterface, nullptr, nullptr)
+: Controller(controlInterface, nullptr, nullptr, nullptr)
 {
 }
 
 Controller::Controller(ControlInterface*           controlInterface,
                        EditableControlInterface*   editableControlInterface,
-                       SelectableControlInterface* selectableControlInterface)
-: mImpl(new Controller::Impl(controlInterface, editableControlInterface, selectableControlInterface))
+                       SelectableControlInterface* selectableControlInterface,
+                       AnchorControlInterface*     anchorControlInterface)
+: mImpl(new Controller::Impl(controlInterface, editableControlInterface, selectableControlInterface, anchorControlInterface))
 {
 }
 
index 40286ef..aaa3a66 100644 (file)
@@ -29,6 +29,7 @@
 #include <dali-toolkit/internal/text/decorator/text-decorator.h>
 #include <dali-toolkit/internal/text/hidden-text.h>
 #include <dali-toolkit/internal/text/layouts/layout-engine.h>
+#include <dali-toolkit/internal/text/text-anchor-control-interface.h>
 #include <dali-toolkit/internal/text/text-model-interface.h>
 #include <dali-toolkit/internal/text/text-selectable-control-interface.h>
 #include <dali-toolkit/public-api/text/text-enumerations.h>
@@ -184,12 +185,14 @@ public: // Constructor.
    * @param[in] controlInterface The control's interface.
    * @param[in] editableControlInterface The editable control's interface.
    * @param[in] selectableControlInterface The selectable control's interface.
+   * @param[in] anchorControlInterface The anchor control's interface.
    *
    * @return A pointer to a new Controller.
    */
   static ControllerPtr New(ControlInterface*           controlInterface,
                            EditableControlInterface*   editableControlInterface,
-                           SelectableControlInterface* selectableControlInterface);
+                           SelectableControlInterface* selectableControlInterface,
+                           AnchorControlInterface*     anchorControlInterface);
 
 public: // Configure the text controller.
   /**
@@ -1295,6 +1298,13 @@ public: // Default style & Input style
    */
   void SetControlInterface(ControlInterface* controlInterface);
 
+  /**
+   * @brief Set the anchor control's interface.
+   *
+   * @param[in] anchorControlInterface The control's interface.
+   */
+  void SetAnchorControlInterface(AnchorControlInterface* anchorControlInterface);
+
 public: // Queries & retrieves.
   /**
    * @brief Return the layout engine.
@@ -1494,6 +1504,13 @@ public: // Text-input Event Queuing.
   bool KeyEvent(const Dali::KeyEvent& event);
 
   /**
+   * @brief Called by anchor when a tap gesture occurs.
+   * @param[in] x The x position relative to the top-left of the parent control.
+   * @param[in] y The y position relative to the top-left of the parent control.
+   */
+  void AnchorEvent(float x, float y);
+
+  /**
    * @brief Called by editable UI controls when a tap gesture occurs.
    * @param[in] tapCount The number of taps.
    * @param[in] x The x position relative to the top-left of the parent control.
@@ -1700,6 +1717,26 @@ private: // Update.
    */
   bool RemoveSelectedText();
 
+  /**
+   * @brief Update anchor position from given number of inserted characters.
+   *
+   * @param[in] numberOfCharacters The number of inserted characters.
+   * @param[in] previousCursorIndex A cursor position before event occurs.
+   */
+  void InsertTextAnchor(int            numberOfCharacters,
+                        CharacterIndex previousCursorIndex);
+
+  /**
+   * @brief Update anchor position from given number of removed characters.
+   *
+   * @param[in] cursorOffset Start position from the current cursor position to start deleting characters.
+   * @param[in] numberOfCharacters The number of removed characters.
+   * @param[in] previousCursorIndex A cursor position before event occurs.
+   */
+  void RemoveTextAnchor(int            cursorOffset,
+                        int            numberOfCharacters,
+                        CharacterIndex previousCursorIndex);
+
 private: // Relayout.
   /**
    * @brief Lays-out the text.
@@ -1792,7 +1829,8 @@ private: // Private contructors & copy operator.
    */
   Controller(ControlInterface*           controlInterface,
              EditableControlInterface*   editableControlInterface,
-             SelectableControlInterface* selectableControlInterface);
+             SelectableControlInterface* selectableControlInterface,
+             AnchorControlInterface*     anchorControlInterface);
 
   // Undefined
   Controller(const Controller& handle);
index 0f55494..4bd0de0 100644 (file)
@@ -59,8 +59,10 @@ public:
 
   /**
    * @brief Called to signal that text has been inserted or deleted.
+   * 
+   * @param[in] immediate If true, it immediately emits the signal, if false, only emits once the signal when OnRelayout() is called next time.
    */
-  virtual void TextChanged() = 0;
+  virtual void TextChanged(bool immediate) = 0;
 
   /**
    * @brief Called when the number of characters to be inserted exceeds the maximum limit
index 678df91..6a74642 100644 (file)
@@ -29,7 +29,7 @@ namespace Toolkit
 {
 const unsigned int TOOLKIT_MAJOR_VERSION = 2;
 const unsigned int TOOLKIT_MINOR_VERSION = 0;
-const unsigned int TOOLKIT_MICRO_VERSION = 19;
+const unsigned int TOOLKIT_MICRO_VERSION = 20;
 const char* const  TOOLKIT_BUILD_DATE    = __DATE__ " " __TIME__;
 
 #ifdef DEBUG_ENABLED
index 3627ef4..3b5d1ce 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
  *
  * This file is part of Dali Toolkit
  *
     },
     "TextSelectionPopup":
     {
-      "popupMaxSize":[656,72],
-      "optionDividerSize":[2,0],
-      "popupDividerColor":[0.23,0.72,0.8,0.11],
+      "popupMaxSize":[656,36],
+      "optionDividerSize":[1,0],
+      "optionDividerPadding":[0.0,0.0,6.0,6.0],
+      "popupDividerColor":[1.0,1.0,1.0,1.0],
       "popupIconColor":[1.0,1.0,1.0,1.0],
       "popupPressedColor":[0.24,0.72,0.8,0.11],
       "background": {
         "visualType": "IMAGE",
-        "url": "{DALI_IMAGE_DIR}selection-popup-background.9.png"
+        "url": "{DALI_IMAGE_DIR}IoT-selection-popup-background.9.png",
+        "mixColor":[0.0,0.05,0.17,0.9]
         },
       "backgroundBorder": {
         "visualType": "IMAGE",
         "url": "{DALI_IMAGE_DIR}selection-popup-border.9.png",
-        "mixColor":[0.24,0.72,0.8,1.0]
+        "mixColor":[0.0,0.0,0.0,0.0]
         },
       "popupFadeInDuration":0.25,
       "popupFadeOutDuration":0.25
     },
     "TextSelectionPopupButton":
     {
+      "minimumSize":[0,36],
+      "labelPadding":[0.0,0.0,0.0,0.0],
       "label":
       {
         "visualType":"TEXT",
-        "pointSize":8
+        "pointSize":18,
+        "textColor":[1.0,1.0,1.0,1.0],
+        "fontFamily":"BreezeSans",
+        "fontStyle" : {"weight":"light"}
       },
       "unselectedBackgroundVisual":
       {
     "TextSelectionToolbar":
     {
       "enableOvershoot":true,
-      "enableScrollBar":true,
+      "enableScrollBar":false,
       "scrollView":
       {
         "overshootAnimationSpeed":360.0,
diff --git a/dali-toolkit/styles/images-common/IoT-selection-popup-background.9.png b/dali-toolkit/styles/images-common/IoT-selection-popup-background.9.png
new file mode 100644 (file)
index 0000000..7903ae2
Binary files /dev/null and b/dali-toolkit/styles/images-common/IoT-selection-popup-background.9.png differ
index 5765d9c..ce364eb 100755 (executable)
  *     @defgroup dali_toolkit_controls_buttons Buttons
  *     @brief Button is a small object on UI that you can press.
 
+ *     @defgroup dali_toolkit_controls_canvas_view CanvasView
+ *     @brief CanvasView is a class for displaying an vector primitives.
+ *
  *     @defgroup dali_toolkit_controls_gaussian_blur_view Gaussian Blur View
  *     @brief GaussianBlurView provides a render process that blurs an image.
 
index b356f6f..4abbec0 100644 (file)
@@ -1,6 +1,6 @@
 Name:       dali2-toolkit
 Summary:    Dali 3D engine Toolkit
-Version:    2.0.19
+Version:    2.0.20
 Release:    1
 Group:      System/Libraries
 License:    Apache-2.0 and BSD-3-Clause and MIT