Refactoring WebView
authorSeungkeun Lee <sngn.lee@samsung.com>
Tue, 21 Apr 2015 07:36:37 +0000 (16:36 +0900)
committerSeungkeun Lee <sngn.lee@samsung.com>
Wed, 22 Apr 2015 11:06:34 +0000 (20:06 +0900)
 - Split Interface , Implements
 - Split Initialize function
 - Deinitilize callbacks

Change-Id: I4d9a2da48359da55f046ddf4cbbe6b9f68d45b7d

src/runtime/CMakeLists.txt
src/runtime/web_view.cc
src/runtime/web_view.h
src/runtime/web_view_impl.cc [new file with mode: 0755]
src/runtime/web_view_impl.h [new file with mode: 0755]

index e8f75ba..2c003cb 100755 (executable)
@@ -51,6 +51,7 @@ SET(TARGET_RUNTIME_SRCS
   ${BASE_SRCDIR}/runtime/web_application.cc
   ${BASE_SRCDIR}/runtime/runtime.cc
   ${BASE_SRCDIR}/runtime/web_view.cc
+  ${BASE_SRCDIR}/runtime/web_view_impl.cc
   ${BASE_SRCDIR}/runtime/vibration_manager.cc
   ${BASE_SRCDIR}/runtime/locale_manager.cc
 )
index dd9588a..c105038 100755 (executable)
 #include <sstream>
 
 #include "runtime/native_window.h"
+#include "runtime/web_view_impl.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 90:
-      return -90;
-    case 270:
-      return 90;
-  }
-  return r;
-}
-
-static int ToNativeRotation(int r) {
-  switch (r) {
-    case -90:
-      return 90;
-    case 90:
-      return 270;
-  }
-  return r;
-}
-
-}  // namespace
-
-
-WebView::WebView(NativeWindow* window, Ewk_Context* context)
-    : window_(window),
-      context_(context),
-      ewk_view_(NULL),
-      listener_(NULL) {
-  Initialize();
+WebView::WebView(wrt::NativeWindow* window, Ewk_Context* context)
+    : impl_(new WebViewImpl(this, window, context)) {
 }
 
 WebView::~WebView() {
-  window_->RemoveRotationHandler(rotation_handler_id_);
-  evas_object_del(ewk_view_);
+  delete impl_;
 }
 
 void WebView::LoadUrl(const std::string& url) {
-  ewk_view_url_set(ewk_view_, url.c_str());
+  impl_->LoadUrl(url);
+}
+
+std::string WebView::GetUrl() {
+  return impl_->GetUrl();
 }
 
 void WebView::Suspend() {
-  // suspend webview
-  ewk_view_suspend(ewk_view_);
+  impl_->Suspend();
 }
 
 void WebView::Resume() {
-  // resume webview
-  ewk_view_resume(ewk_view_);
+  impl_->Resume();
 }
 
 void WebView::Reload() {
-  ewk_view_reload(ewk_view_);
+  impl_->Reload();
 }
 
 void WebView::SetVisibility(bool show) {
-  ewk_view_visibility_set(ewk_view_, show ? EINA_TRUE : EINA_FALSE);
+  impl_->SetVisibility(show);
 }
 
-
 bool WebView::EvalJavascript(const std::string& script) {
-  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);
-
-  // callback for database quota exceeded
-  auto database_exceeded_callback = [](Evas_Object* view,
-                                       Ewk_Security_Origin* origin,
-                                       const char*,
-                                       uint64_t,
-                                       void*) -> Eina_Bool {
-    std::string protocol(ewk_security_origin_protocol_get(origin));
-    if (protocol == "file://" || protocol == "app://") {
-      // Allow for local origin
-      ewk_view_exceeded_database_quota_reply(view, EINA_TRUE);
-    } else {
-      // Deny for remote origin
-      ewk_view_exceeded_database_quota_reply(view, EINA_FALSE);
-    }
-    return EINA_TRUE;
-  };
-  ewk_view_exceeded_database_quota_callback_set(
-    ewk_view_,
-    database_exceeded_callback,
-    NULL);
-
-  // callback for indexed database quota exceeded
-  auto indexed_db_exceeded_callback = [](Evas_Object* view,
-                                       Ewk_Security_Origin* origin,
-                                       int64_t,
-                                       void*) -> Eina_Bool {
-    std::string protocol(ewk_security_origin_protocol_get(origin));
-    if (protocol == "file://" || protocol == "app://") {
-      // Allow for local origin
-      ewk_view_exceeded_indexed_database_quota_reply(view, EINA_TRUE);
-    } else {
-      // Deny for remote origin
-      ewk_view_exceeded_indexed_database_quota_reply(view, EINA_FALSE);
-    }
-    return EINA_TRUE;
-  };
-  ewk_view_exceeded_indexed_database_quota_callback_set(
-    ewk_view_,
-    indexed_db_exceeded_callback,
-    NULL);
-
-  // callback for localfile quota exceeded
-  auto localfile_exceeded_callback = [](Evas_Object* view,
-                                       Ewk_Security_Origin* origin,
-                                       int64_t,
-                                       void*) -> Eina_Bool {
-    std::string protocol(ewk_security_origin_protocol_get(origin));
-    if (protocol == "file://" || protocol == "app://") {
-      // Allow for local origin
-      ewk_view_exceeded_local_file_system_quota_reply(view, EINA_TRUE);
-    } else {
-      // Deny for remote origin
-      ewk_view_exceeded_local_file_system_quota_reply(view, EINA_FALSE);
-    }
-    return EINA_TRUE;
-  };
-  ewk_view_exceeded_local_file_system_quota_callback_set(
-    ewk_view_,
-    localfile_exceeded_callback,
-    NULL);
-
-  // wrt,message
-  auto wrt_message_callback = [](void* user_data,
-                                 Evas_Object*,
-                                 void* event_info) {
-    WebView* self = static_cast<WebView*>(user_data);
-    Ewk_IPC_Wrt_Message_Data* msg =
-        static_cast<Ewk_IPC_Wrt_Message_Data*>(event_info);
-    if (self->listener_)
-      self->listener_->OnReceivedWrtMessage(self, msg);
-  };
-  evas_object_smart_callback_add(ewk_view_,
-                                 "wrt,message",
-                                 wrt_message_callback,
-                                 this);
-
-  // Orientation lock callback
-  auto orientation_lock_callback = [](Evas_Object* o,
-                                      Eina_Bool need_lock,
-                                      int orientation,
-                                      void* user_data) -> Eina_Bool {
-    WebView* self = static_cast<WebView*>(user_data);
-    if (self->listener_) {
-      self->listener_->OnOrientationLock(self,
-                                         need_lock,
-                                         ToNativeRotation(orientation));
-    }
-    return EINA_TRUE;
-  };
-  ewk_view_orientation_lock_callback_set(ewk_view_,
-                                         orientation_lock_callback,
-                                         this);
-
-  auto console_message_callback = [](void* user_data,
-                                 Evas_Object*,
-                                 void* event_info) {
-    WebView* self = static_cast<WebView*>(user_data);
-    if (!self->listener_) {
-      return;
-    }
-    Ewk_Console_Message* msg = static_cast<Ewk_Console_Message*>(event_info);
-    unsigned int line_number = ewk_console_message_line_get(msg);
-
-    std::stringstream buf;
-    if (line_number) {
-        buf << ewk_console_message_source_get(msg) << ":";
-        buf << line_number << ":";
-    }
-    buf << ewk_console_message_text_get(msg);
-    int level = ewk_console_message_level_get(msg);
-    self->listener_->OnConsoleMessage(buf.str(), level);
-  };
-  // console log
-  evas_object_smart_callback_add(ewk_view_,
-                                 "console,message",
-                                 console_message_callback,
-                                 this);
-
-
-  auto custom_context_menu = [](void* user_data,
-                                Evas_Object*,
-                                void* event_info) {
-    Ewk_Context_Menu* contextmenu = static_cast<Ewk_Context_Menu*>(event_info);
-    WebView* self = static_cast<WebView*>(user_data);
-    bool disabled = false;
-    if (self->listener_ && self->listener_->OnContextMenuDisabled(self)) {
-      disabled = true;
-    }
-    int cnt = ewk_context_menu_item_count(contextmenu);
-    for (unsigned idx = cnt-1; idx > 0; --idx) {
-      auto* item = ewk_context_menu_nth_item_get(contextmenu, idx);
-      Ewk_Context_Menu_Item_Tag tag = ewk_context_menu_item_tag_get(item);
-      switch (tag) {
-        case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_IMAGE_IN_NEW_WINDOW:
-        case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_LINK_IN_NEW_WINDOW:
-        case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_FRAME_IN_NEW_WINDOW:
-        case EWK_CONTEXT_MENU_ITEM_TAG_SEARCH_WEB:
-        case EWK_CONTEXT_MENU_ITEM_TAG_DOWNLOAD_IMAGE_TO_DISK:
-          ewk_context_menu_item_remove(contextmenu, item);
-          break;
-        default:
-          if (disabled)
-            ewk_context_menu_item_remove(contextmenu, item);
-      }
-    }
-  };
-
-  // rotation support
-  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_);
+  return impl_->EvalJavascript(script);
 }
 
-std::string WebView::GetUrl() {
-  return std::string(ewk_view_url_get(ewk_view_));
+void WebView::SetEventListener(EventListener* listener) {
+  impl_->SetEventListener(listener);
 }
 
 Evas_Object* WebView::evas_object() const {
-  return ewk_view_;
-}
-
-void WebView::OnRotation(int degree) {
-  ewk_view_orientation_send(ewk_view_, ToWebRotation(degree));
+  return impl_->evas_object();
 }
 
-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);
-}
-
-void WebView::SetEventListener(EventListener* listener) {
-  listener_ = listener;
-}
-
-
 }  // namespace wrt
 
index bc503f5..e451b64 100755 (executable)
@@ -6,7 +6,6 @@
 #define WRT_RUNTIME_WEB_VIEW_H_
 
 #include <Elementary.h>
-#include <efl_assist.h>
 #include <ewk_ipc_message.h>
 #include <string>
 
@@ -14,6 +13,7 @@ class Ewk_Context;
 
 namespace wrt {
 class NativeWindow;
+class WebViewImpl;
 
 class WebView {
  public:
@@ -59,14 +59,7 @@ 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_;
-  int rotation_handler_id_;
+  WebViewImpl* impl_;
 };
 
 }  // namespace wrt
diff --git a/src/runtime/web_view_impl.cc b/src/runtime/web_view_impl.cc
new file mode 100755 (executable)
index 0000000..912dcfe
--- /dev/null
@@ -0,0 +1,470 @@
+// Copyright 2015 Samsung Electronics Co, Ltd. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "runtime/web_view_impl.h"
+
+#include <ewk_chromium.h>
+#include <functional>
+#include <sstream>
+
+#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 90:
+      return -90;
+    case 270:
+      return 90;
+  }
+  return r;
+}
+
+static int ToNativeRotation(int r) {
+  switch (r) {
+    case -90:
+      return 90;
+    case 90:
+      return 270;
+  }
+  return r;
+}
+
+}  // namespace
+
+WebViewImpl::WebViewImpl(WebView* view,
+                         NativeWindow* window,
+                         Ewk_Context* context)
+    : window_(window),
+      context_(context),
+      ewk_view_(NULL),
+      listener_(NULL),
+      view_(view) {
+  Initialize();
+}
+
+WebViewImpl::~WebViewImpl() {
+  Deinitialize();
+  evas_object_del(ewk_view_);
+}
+
+void WebViewImpl::LoadUrl(const std::string& url) {
+  ewk_view_url_set(ewk_view_, url.c_str());
+}
+
+void WebViewImpl::Suspend() {
+  // suspend webview
+  ewk_view_suspend(ewk_view_);
+}
+
+void WebViewImpl::Resume() {
+  // resume webview
+  ewk_view_resume(ewk_view_);
+}
+
+void WebViewImpl::Reload() {
+  ewk_view_reload(ewk_view_);
+}
+
+void WebViewImpl::SetVisibility(bool show) {
+  ewk_view_visibility_set(ewk_view_, show ? EINA_TRUE : EINA_FALSE);
+}
+
+
+bool WebViewImpl::EvalJavascript(const std::string& script) {
+  return ewk_view_script_execute(ewk_view_, script.c_str(), NULL, NULL);
+}
+
+void WebViewImpl::Initialize() {
+  ewk_view_ = ewk_view_add_with_context(window_->evas_object(), context_);
+
+  InitKeyCallback();
+  InitLoaderCallback();
+  InitPolicyDecideCallback();
+  InitQuotaExceededCallback();
+  InitIPCMessageCallback();
+  InitOrientaionLockCallback();
+  InitConsoleMessageCallback();
+  InitCustomContextMenuCallback();
+  InitRotationCallback();
+
+  // Show webview
+  evas_object_show(ewk_view_);
+}
+
+void WebViewImpl::Deinitialize() {
+  auto it = smart_callbacks_.begin();
+  for ( ; it != smart_callbacks_.end(); ++it) {
+    evas_object_smart_callback_del(
+        ewk_view_,
+        it->first.c_str(),
+        it->second);
+  }
+  ea_object_event_callback_del(ewk_view_,
+                               EA_CALLBACK_BACK,
+                               smart_callbacks_["key_callback"]);
+  ewk_view_exceeded_database_quota_callback_set(
+      ewk_view_,
+      NULL,
+      NULL);
+  ewk_view_exceeded_indexed_database_quota_callback_set(
+      ewk_view_,
+      NULL,
+      NULL);
+  ewk_view_exceeded_local_file_system_quota_callback_set(
+      ewk_view_,
+      NULL,
+      NULL);
+  ewk_view_orientation_lock_callback_set(
+      ewk_view_,
+      NULL,
+      NULL);
+  window_->RemoveRotationHandler(rotation_handler_id_);
+}
+
+void WebViewImpl::InitKeyCallback() {
+  auto key_callback = [](void* user_data,
+                         Evas_Object* /*obj*/,
+                         void* event_info) -> void {
+    WebViewImpl* self = static_cast<WebViewImpl*>(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,
+                               view_);
+  ea_object_event_callback_add(ewk_view_,
+                               EA_CALLBACK_MORE,
+                               key_callback,
+                               view_);
+  smart_callbacks_["key_callback"] = key_callback;
+}
+
+void WebViewImpl::InitLoaderCallback() {
+  // load statred callback
+  auto loadstart_callback = [](void* user_data,
+                               Evas_Object* /*obj*/,
+                               void*) {
+    WebViewImpl* self = static_cast<WebViewImpl*>(user_data);
+    if (self->listener_)
+      self->listener_->OnLoadStart(self->view_);
+  };
+  evas_object_smart_callback_add(ewk_view_,
+                                 "load,started",
+                                 loadstart_callback,
+                                 this);
+  // load finished callback
+  auto loadfinished_callback = [](void* user_data,
+                                  Evas_Object*,
+                                  void*) {
+    WebViewImpl* self = static_cast<WebViewImpl*>(user_data);
+    if (self->listener_)
+      self->listener_->OnLoadFinished(self->view_);
+  };
+  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) {
+    WebViewImpl* self = static_cast<WebViewImpl*>(user_data);
+    double* progress = static_cast<double*>(event_info);
+    if (self->listener_)
+      self->listener_->OnLoadProgress(self->view_, *progress);
+  };
+  evas_object_smart_callback_add(ewk_view_,
+                                 "load,progress",
+                                 loadprogress_callback,
+                                 this);
+  // rendered callback
+  auto rendered_callback = [](void* user_data,
+                              Evas_Object*,
+                              void*) {
+    WebViewImpl* self = static_cast<WebViewImpl*>(user_data);
+    if (self->listener_)
+      self->listener_->OnRendered(self->view_);
+  };
+  evas_object_smart_callback_add(ewk_view_,
+                                 "frame,rendered",
+                                 rendered_callback,
+                                 this);
+  smart_callbacks_["load,started"] = loadstart_callback;
+  smart_callbacks_["load,finished"] = loadfinished_callback;
+  smart_callbacks_["load,progress"] = loadprogress_callback;
+  smart_callbacks_["frame,rendered"] = rendered_callback;
+}
+
+void WebViewImpl::InitPolicyDecideCallback() {
+  // "policy,navigation,decide"
+  auto navigation_decide_callback = [](void* user_data,
+                                       Evas_Object*,
+                                       void* event_info) {
+    WebViewImpl* self = static_cast<WebViewImpl*>(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->view_, 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) {
+    WebViewImpl* self = static_cast<WebViewImpl*>(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->view_, url) &&
+         self->listener_->OnDidOpenWindow(self->view_, 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);
+  smart_callbacks_["policy,navigation,decide"] = navigation_decide_callback;
+  smart_callbacks_["policy,newwindow,decide"] = newwindow_decide_callback;
+}
+
+void WebViewImpl::InitQuotaExceededCallback() {
+  // callback for database quota exceeded
+  auto database_exceeded_callback = [](Evas_Object* view,
+                                       Ewk_Security_Origin* origin,
+                                       const char*,
+                                       uint64_t,
+                                       void*) -> Eina_Bool {
+    std::string protocol(ewk_security_origin_protocol_get(origin));
+    if (protocol == "file://" || protocol == "app://") {
+      // Allow for local origin
+      ewk_view_exceeded_database_quota_reply(view, EINA_TRUE);
+    } else {
+      // Deny for remote origin
+      ewk_view_exceeded_database_quota_reply(view, EINA_FALSE);
+    }
+    return EINA_TRUE;
+  };
+  ewk_view_exceeded_database_quota_callback_set(
+    ewk_view_,
+    database_exceeded_callback,
+    NULL);
+
+  // callback for indexed database quota exceeded
+  auto indexed_db_exceeded_callback = [](Evas_Object* view,
+                                       Ewk_Security_Origin* origin,
+                                       int64_t,
+                                       void*) -> Eina_Bool {
+    std::string protocol(ewk_security_origin_protocol_get(origin));
+    if (protocol == "file://" || protocol == "app://") {
+      // Allow for local origin
+      ewk_view_exceeded_indexed_database_quota_reply(view, EINA_TRUE);
+    } else {
+      // Deny for remote origin
+      ewk_view_exceeded_indexed_database_quota_reply(view, EINA_FALSE);
+    }
+    return EINA_TRUE;
+  };
+  ewk_view_exceeded_indexed_database_quota_callback_set(
+    ewk_view_,
+    indexed_db_exceeded_callback,
+    NULL);
+
+  // callback for localfile quota exceeded
+  auto localfile_exceeded_callback = [](Evas_Object* view,
+                                       Ewk_Security_Origin* origin,
+                                       int64_t,
+                                       void*) -> Eina_Bool {
+    std::string protocol(ewk_security_origin_protocol_get(origin));
+    if (protocol == "file://" || protocol == "app://") {
+      // Allow for local origin
+      ewk_view_exceeded_local_file_system_quota_reply(view, EINA_TRUE);
+    } else {
+      // Deny for remote origin
+      ewk_view_exceeded_local_file_system_quota_reply(view, EINA_FALSE);
+    }
+    return EINA_TRUE;
+  };
+  ewk_view_exceeded_local_file_system_quota_callback_set(
+    ewk_view_,
+    localfile_exceeded_callback,
+    NULL);
+}
+
+void WebViewImpl::InitIPCMessageCallback() {
+  // wrt,message
+  auto wrt_message_callback = [](void* user_data,
+                                 Evas_Object*,
+                                 void* event_info) {
+    WebViewImpl* self = static_cast<WebViewImpl*>(user_data);
+    Ewk_IPC_Wrt_Message_Data* msg =
+        static_cast<Ewk_IPC_Wrt_Message_Data*>(event_info);
+    if (self->listener_)
+      self->listener_->OnReceivedWrtMessage(self->view_, msg);
+  };
+  evas_object_smart_callback_add(ewk_view_,
+                                 "wrt,message",
+                                 wrt_message_callback,
+                                 this);
+  smart_callbacks_["wrt,message"] = wrt_message_callback;
+}
+
+void WebViewImpl::InitOrientaionLockCallback() {
+  // Orientation lock callback
+  auto orientation_lock_callback = [](Evas_Object* o,
+                                      Eina_Bool need_lock,
+                                      int orientation,
+                                      void* user_data) -> Eina_Bool {
+    WebViewImpl* self = static_cast<WebViewImpl*>(user_data);
+    if (self->listener_) {
+      self->listener_->OnOrientationLock(self->view_,
+                                         need_lock,
+                                         ToNativeRotation(orientation));
+    }
+    return EINA_TRUE;
+  };
+  ewk_view_orientation_lock_callback_set(ewk_view_,
+                                         orientation_lock_callback,
+                                         this);
+}
+
+void WebViewImpl::InitConsoleMessageCallback() {
+  // console log
+  auto console_message_callback = [](void* user_data,
+                                 Evas_Object*,
+                                 void* event_info) {
+    WebViewImpl* self = static_cast<WebViewImpl*>(user_data);
+    if (!self->listener_) {
+      return;
+    }
+    Ewk_Console_Message* msg = static_cast<Ewk_Console_Message*>(event_info);
+    unsigned int line_number = ewk_console_message_line_get(msg);
+
+    std::stringstream buf;
+    if (line_number) {
+        buf << ewk_console_message_source_get(msg) << ":";
+        buf << line_number << ":";
+    }
+    buf << ewk_console_message_text_get(msg);
+    int level = ewk_console_message_level_get(msg);
+    self->listener_->OnConsoleMessage(buf.str(), level);
+  };
+  evas_object_smart_callback_add(ewk_view_,
+                                 "console,message",
+                                 console_message_callback,
+                                 this);
+  smart_callbacks_["console,message"] = console_message_callback;
+}
+
+void WebViewImpl::InitCustomContextMenuCallback() {
+  auto custom_context_menu_callback = [](void* user_data,
+                                         Evas_Object*,
+                                         void* event_info) {
+    Ewk_Context_Menu* contextmenu = static_cast<Ewk_Context_Menu*>(event_info);
+    WebViewImpl* self = static_cast<WebViewImpl*>(user_data);
+    bool disabled = false;
+    if (self->listener_ &&
+        self->listener_->OnContextMenuDisabled(self->view_)) {
+      disabled = true;
+    }
+    int cnt = ewk_context_menu_item_count(contextmenu);
+    for (unsigned idx = cnt-1; idx > 0; --idx) {
+      auto* item = ewk_context_menu_nth_item_get(contextmenu, idx);
+      Ewk_Context_Menu_Item_Tag tag = ewk_context_menu_item_tag_get(item);
+      switch (tag) {
+        case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_IMAGE_IN_NEW_WINDOW:
+        case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_LINK_IN_NEW_WINDOW:
+        case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_FRAME_IN_NEW_WINDOW:
+        case EWK_CONTEXT_MENU_ITEM_TAG_SEARCH_WEB:
+        case EWK_CONTEXT_MENU_ITEM_TAG_DOWNLOAD_IMAGE_TO_DISK:
+          ewk_context_menu_item_remove(contextmenu, item);
+          break;
+        default:
+          if (disabled)
+            ewk_context_menu_item_remove(contextmenu, item);
+      }
+    }
+  };
+  evas_object_smart_callback_add(ewk_view_,
+                                 "contextmenu,customize",
+                                 custom_context_menu_callback,
+                                 this);
+  smart_callbacks_["contextmenu,customize"] = custom_context_menu_callback;
+}
+
+void WebViewImpl::InitRotationCallback() {
+  // rotation support
+  ewk_view_orientation_send(ewk_view_, ToWebRotation(window_->rotation()));
+  rotation_handler_id_ = window_->AddRotationHandler(
+                                  std::bind(&WebViewImpl::OnRotation,
+                                  this,
+                                  std::placeholders::_1));
+}
+
+std::string WebViewImpl::GetUrl() {
+  return std::string(ewk_view_url_get(ewk_view_));
+}
+
+Evas_Object* WebViewImpl::evas_object() const {
+  return ewk_view_;
+}
+
+void WebViewImpl::OnRotation(int degree) {
+  ewk_view_orientation_send(ewk_view_, ToWebRotation(degree));
+}
+
+void WebViewImpl::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(view_, keyname);
+}
+
+void WebViewImpl::SetEventListener(WebView::EventListener* listener) {
+  listener_ = listener;
+}
+
+}  // namespace wrt
+
+
diff --git a/src/runtime/web_view_impl.h b/src/runtime/web_view_impl.h
new file mode 100755 (executable)
index 0000000..dd25077
--- /dev/null
@@ -0,0 +1,63 @@
+// Copyright 2015 Samsung Electronics Co, Ltd. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef WRT_RUNTIME_WEB_VIEW_IMPL_H_
+#define WRT_RUNTIME_WEB_VIEW_IMPL_H_
+
+
+#include <Elementary.h>
+#include <efl_assist.h>
+#include <string>
+#include <map>
+
+#include "runtime/web_view.h"
+
+class Ewk_Context;
+
+namespace wrt {
+class NativeWindow;
+class WebViewImpl {
+ public:
+  WebViewImpl(WebView* view, wrt::NativeWindow* window, Ewk_Context* context);
+  virtual ~WebViewImpl();
+
+  void LoadUrl(const std::string& url);
+  std::string GetUrl();
+
+  void Suspend();
+  void Resume();
+  void Reload();
+  void SetVisibility(bool show);
+  bool EvalJavascript(const std::string& script);
+
+  void SetEventListener(WebView::EventListener* listener);
+  Evas_Object* evas_object() const;
+
+ private:
+  void OnKeyEvent(Ea_Callback_Type key_type);
+  void OnRotation(int degree);
+  void Initialize();
+  void Deinitialize();
+
+  void InitKeyCallback();
+  void InitLoaderCallback();
+  void InitPolicyDecideCallback();
+  void InitQuotaExceededCallback();
+  void InitIPCMessageCallback();
+  void InitOrientaionLockCallback();
+  void InitConsoleMessageCallback();
+  void InitCustomContextMenuCallback();
+  void InitRotationCallback();
+
+  NativeWindow* window_;
+  Ewk_Context* context_;
+  Evas_Object* ewk_view_;
+  WebView::EventListener* listener_;
+  int rotation_handler_id_;
+  WebView* view_;
+  std::map<const std::string, Evas_Smart_Cb> smart_callbacks_;
+};
+}  // namespace wrt
+
+#endif  // WRT_RUNTIME_WEB_VIEW_IMPL_H_