WebView Implements
authorSeungkeun Lee <sngn.lee@samsung.com>
Mon, 6 Apr 2015 09:36:41 +0000 (18:36 +0900)
committerSeungkeun Lee <sngn.lee@samsung.com>
Tue, 7 Apr 2015 04:27:25 +0000 (13:27 +0900)
Change-Id: Ie44813a731036c555965a694b1fa641fc1d2c9b0

packaging/wrt.spec
src/runtime/CMakeLists.txt
src/runtime/native_window.cc
src/runtime/native_window.h
src/runtime/web_application.cc
src/runtime/web_application.h
src/runtime/web_view.cc
src/runtime/web_view.h

index 3dfacd3..44fd16c 100755 (executable)
@@ -14,6 +14,7 @@ BuildRequires: cmake
 BuildRequires: pkgconfig(dlog)
 BuildRequires: pkgconfig(elementary)
 BuildRequires: pkgconfig(capi-appfw-application)
+BuildRequires: pkgconfig(efl-assist)
 %if %{with x}
 BuildRequires: pkgconfig(ecore-x)
 %endif
index 004deaa..f3c6496 100755 (executable)
@@ -16,6 +16,7 @@ PKG_CHECK_MODULES(TARGET_RUNTIME_DEPS
   elementary
   capi-appfw-application
   chromium-efl
+  efl-assist
   REQUIRED
 )
 
index 2422720..aa66515 100755 (executable)
@@ -219,4 +219,8 @@ void NativeWindow::SetAutoRotation() {
   rotation_ = elm_win_rotation_get(window_);
 }
 
+void NativeWindow::Show() {
+  evas_object_show(window_);
+}
+
 }  // namespace wrt
index 8377346..9965e46 100755 (executable)
@@ -27,6 +27,7 @@ class NativeWindow {
   int AddRotationHandler(RotationHandler handler);
   void RemoveRotationHandler(int id);
   int rotation() const;
+  void Show();
 
  protected:
   virtual Evas_Object* createWindowInternal() = 0;
index 12b9e50..e884482 100755 (executable)
@@ -75,6 +75,11 @@ void WebApplication::Launch() {
   view->LoadUrl("index.html");
   view_stack_.push_front(view);
   window_->SetContent(view->evas_object());
+
+  // TODO(sngn.lee): check the below code location.
+  // in Wearable, webkit can render contents before show window
+  // but Mobile, webkit can't render contents before show window
+  window_->Show();
 }
 
 void WebApplication::AppControl() {
@@ -161,4 +166,7 @@ std::string WebApplication::GetDataPath() const {
   return std::string("./");
 }
 
+void WebApplication::OnRendered(WebView* view) {
+}
+
 }  // namespace wrt
index 2f6edfd..e70f1bb 100755 (executable)
@@ -30,6 +30,7 @@ class WebApplication : public WebView::EventListener {
 
   virtual void OnCreatedNewWebView(WebView* view, WebView* new_view);
   virtual void OnClosedWebView(WebView * view);
+  virtual void OnRendered(WebView* view);
 
  private:
   void ClearViewStack();
index 5f60e8d..39f41b8 100755 (executable)
@@ -4,20 +4,42 @@
 
 #include "runtime/web_view.h"
 
+#include <ewk_chromium.h>
 #include <functional>
 
 #include "runtime/native_window.h"
 
 namespace wrt {
 
+namespace {
+
+// TODO(sngn.lee) : It should be declare in common header
+const char* kKeyNameBack = "back";
+const char* kKeyNameMenu = "menu";
+
+static int ToWebRotation(int r) {
+  switch (r) {
+    case 0:
+    case 180:
+      return r;
+    case 90:
+      return -90;
+    case 270:
+      return 90;
+  }
+  return r;
+}
+
+}  // namespace
+
+
 WebView::WebView(NativeWindow* window, Ewk_Context* context)
     : window_(window),
       context_(context),
+      ewk_view_(NULL),
+      listener_(NULL),
       always_run_(false) {
-  rotation_handler_id_ = window->AddRotationHandler(
-                                    std::bind(&WebView::OnRotation,
-                                    this,
-                                    std::placeholders::_1));
+  Initialize();
 }
 
 WebView::~WebView() {
@@ -25,24 +47,30 @@ WebView::~WebView() {
 }
 
 void WebView::LoadUrl(const std::string& url) {
-  // TODO(sngn.lee): To be implemented
+  ewk_view_url_set(ewk_view_, url.c_str());
 }
 
 void WebView::Suspend() {
+  // change the visibility
+  ewk_view_visibility_set(ewk_view_, EINA_FALSE);
+
   if (!always_run_) {
     // suspend webview
+    ewk_view_suspend(ewk_view_);
   }
-  // change the visibility
 }
 
 void WebView::Resume() {
   if (!always_run_) {
     // resume webview
+    ewk_view_resume(ewk_view_);
   }
   // change the visiblity
+  ewk_view_visibility_set(ewk_view_, EINA_TRUE);
 }
 
 void WebView::Reload() {
+  ewk_view_reload(ewk_view_);
 }
 
 void WebView::AlwaysRun(bool run) {
@@ -50,24 +78,171 @@ void WebView::AlwaysRun(bool run) {
 }
 
 bool WebView::EvalJavascript(const std::string& script) {
-  return false;
+  return ewk_view_script_execute(ewk_view_, script.c_str(), NULL, NULL);
 }
 
 void WebView::Initialize() {
+  ewk_view_ = ewk_view_add_with_context(window_->evas_object(), context_);
+
+  // TODO(sngn.lee): To be implemented - orientation lock
+
+
+  auto key_callback = [](void* user_data,
+                         Evas_Object* /*obj*/,
+                         void* event_info) -> void {
+    WebView* self = static_cast<WebView*>(user_data);
+    Ea_Callback_Type key = static_cast<Ea_Callback_Type>(
+                              reinterpret_cast<int>(event_info));
+    self->OnKeyEvent(key);
+  };
+  ea_object_event_callback_add(ewk_view_,
+                               EA_CALLBACK_BACK,
+                               key_callback,
+                               this);
+  ea_object_event_callback_add(ewk_view_,
+                               EA_CALLBACK_MORE,
+                               key_callback,
+                               this);
+
+
+  // load statred callback
+  auto loadstart_callback = [](void* user_data,
+                               Evas_Object* /*obj*/,
+                               void*) {
+    WebView* self = static_cast<WebView*>(user_data);
+    if (self->listener_)
+      self->listener_->OnLoadStart(self);
+  };
+  evas_object_smart_callback_add(ewk_view_,
+                                 "load,started",
+                                 loadstart_callback,
+                                 this);
+  // load finished callback
+  auto loadfinished_callback = [](void* user_data,
+                                  Evas_Object*,
+                                  void*) {
+    WebView* self = static_cast<WebView*>(user_data);
+    if (self->listener_)
+      self->listener_->OnLoadFinished(self);
+  };
+  evas_object_smart_callback_add(ewk_view_,
+                                 "load,finished",
+                                 loadfinished_callback,
+                                 this);
+
+  // load progress callback
+  auto loadprogress_callback = [](void* user_data,
+                                  Evas_Object*,
+                                  void* event_info) {
+    WebView* self = static_cast<WebView*>(user_data);
+    double* progress = static_cast<double*>(event_info);
+    if (self->listener_)
+      self->listener_->OnLoadProgress(self, *progress);
+  };
+  evas_object_smart_callback_add(ewk_view_,
+                                 "load,progress",
+                                 loadprogress_callback,
+                                 this);
+  // rendered callback
+  auto rendered_callback = [](void* user_data,
+                              Evas_Object*,
+                              void*) {
+    WebView* self = static_cast<WebView*>(user_data);
+    if (self->listener_)
+      self->listener_->OnRendered(self);
+  };
+  evas_object_smart_callback_add(ewk_view_,
+                                 "frame,rendered",
+                                 rendered_callback,
+                                 this);
+
+  // "policy,navigation,decide"
+  auto navigation_decide_callback = [](void* user_data,
+                                       Evas_Object*,
+                                       void* event_info) {
+    WebView* self = static_cast<WebView*>(user_data);
+    Ewk_Policy_Decision* policy =
+            static_cast<Ewk_Policy_Decision*>(event_info);
+    const char* url = ewk_policy_decision_url_get(policy);
+
+    if (self->listener_) {
+      if (self->listener_->OnDidNavigation(self, url))
+        ewk_policy_decision_use(policy);
+      else
+        ewk_policy_decision_ignore(policy);
+    } else {
+      ewk_policy_decision_use(policy);
+    }
+  };
+  evas_object_smart_callback_add(ewk_view_,
+                                 "policy,navigation,decide",
+                                 navigation_decide_callback,
+                                 this);
+
+  // policy,newwindow,decide
+  auto newwindow_decide_callback = [](void* user_data,
+                                      Evas_Object*,
+                                      void* event_info) {
+    WebView* self = static_cast<WebView*>(user_data);
+    Ewk_Policy_Decision* policy =
+            static_cast<Ewk_Policy_Decision*>(event_info);
+
+    const char* url = ewk_policy_decision_url_get(policy);
+
+    if (self->listener_) {
+      if (self->listener_->OnDidNavigation(self, url) &&
+         self->listener_->OnDidOpenWindow(self, url)) {
+         ewk_policy_decision_use(policy);
+      } else {
+        ewk_policy_decision_ignore(policy);
+      }
+    } else {
+      ewk_policy_decision_use(policy);
+    }
+  };
+  evas_object_smart_callback_add(ewk_view_,
+                                 "policy,newwindow,decide",
+                                 newwindow_decide_callback,
+                                 this);
+
+  ewk_view_orientation_send(ewk_view_, ToWebRotation(window_->rotation()));
+  rotation_handler_id_ = window_->AddRotationHandler(
+                                  std::bind(&WebView::OnRotation,
+                                  this,
+                                  std::placeholders::_1));
+  // Show webview
+  evas_object_show(ewk_view_);
 }
 
 std::string WebView::GetUrl() {
-  return std::string();
+  return std::string(ewk_view_url_get(ewk_view_));
 }
 
 Evas_Object* WebView::evas_object() const {
-  // TODO(sngn.lee): To be implemented
-  return NULL;
+  return ewk_view_;
 }
 
 void WebView::OnRotation(int degree) {
-  // TOOD(sngn.lee): To be impelmented
+  ewk_view_orientation_send(ewk_view_, ToWebRotation(degree));
+}
+
+void WebView::OnKeyEvent(Ea_Callback_Type key_type) {
+  std::string keyname;
+  if (key_type == EA_CALLBACK_BACK) {
+    if (EINA_TRUE == ewk_view_text_selection_clear(ewk_view_)) {
+      return;
+    }
+    keyname = kKeyNameBack;
+  } else if (key_type == EA_CALLBACK_MORE) {
+    keyname = kKeyNameMenu;
+  } else {
+    return;
+  }
+
+  if (listener_)
+    listener_->OnHardwareKey(this, keyname);
 }
 
+
 }  // namespace wrt
 
index e420165..bee55a8 100755 (executable)
@@ -4,8 +4,9 @@
 
 #ifndef WRT_RUNTIME_WEB_VIEW_H_
 #define WRT_RUNTIME_WEB_VIEW_H_
-#include <string>
 #include <Elementary.h>
+#include <efl_assist.h>
+#include <string>
 
 class Ewk_Context;
 
@@ -24,7 +25,12 @@ class WebView {
                                      WebView* /*new_view*/) {}
     virtual void OnClosedWebView(WebView* /*view*/) {}
     virtual void OnCrashed(WebView* /*view*/) {}
-    virtual bool OnDidOpenWindow(WebView* /*view*/) { return true; }
+    virtual bool OnDidOpenWindow(WebView* /*view*/,
+                                 const std::string& /*url*/) { return true; }
+    virtual bool OnDidNavigation(WebView* /*view*/,
+                                 const std::string& /*url*/) { return true; }
+    virtual void OnHardwareKey(WebView* /*void*/,
+                               const std::string& /*keyname*/) {}
   };
 
   WebView(wrt::NativeWindow* window, Ewk_Context* context);
@@ -43,10 +49,13 @@ class WebView {
   Evas_Object* evas_object() const;
 
  private:
+  void OnKeyEvent(Ea_Callback_Type key_type);
   void OnRotation(int degree);
   void Initialize();
   NativeWindow* window_;
   Ewk_Context* context_;
+  Evas_Object* ewk_view_;
+  EventListener* listener_;
   bool always_run_;
   int rotation_handler_id_;
 };